You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ho...@apache.org on 2016/03/01 18:06:44 UTC

[01/50] [abbrv] lucene-solr git commit: SOLR-8671: Added note about date stats 'sum' now using double in the upgrade section

Repository: lucene-solr
Updated Branches:
  refs/heads/jira/SOLR-445 0f0571928 -> 2401c9495
  refs/heads/master 2a7314b59 -> ff6557cbc


SOLR-8671: Added note about date stats 'sum' now using double in the upgrade section


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/a0e72f10
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/a0e72f10
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/a0e72f10

Branch: refs/heads/jira/SOLR-445
Commit: a0e72f10a8625c2158a24fe664b711b43d2fdec1
Parents: 20b7453
Author: Tomás Fernández Löbbe <tf...@apache.org>
Authored: Mon Feb 29 09:16:01 2016 -0800
Committer: Tomás Fernández Löbbe <tf...@apache.org>
Committed: Mon Feb 29 09:16:01 2016 -0800

----------------------------------------------------------------------
 solr/CHANGES.txt | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a0e72f10/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 68a35ce..99ae09e 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -80,6 +80,8 @@ Upgrading from Solr 5.x
 
 * SOLR-8698: 'useParams' attribute specified in request handler cannot be overridden from request params
 
+* When requesting stats in date fields, "sum" is now a double value instead of a date. See SOLR-8671
+
 Detailed Change List
 ----------------------
 


[32/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxStrategy.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxStrategy.java
new file mode 100644
index 0000000..9565cbf
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxStrategy.java
@@ -0,0 +1,588 @@
+/*
+ * 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.bbox;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.document.LegacyDoubleField;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.FieldType;
+import org.apache.lucene.document.StringField;
+import org.apache.lucene.index.DocValuesType;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.ConstantScoreQuery;
+import org.apache.lucene.search.LegacyNumericRangeQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.spatial.SpatialStrategy;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.apache.lucene.spatial.query.UnsupportedSpatialOperation;
+import org.apache.lucene.spatial.util.DistanceToShapeValueSource;
+import org.apache.lucene.util.BytesRefBuilder;
+import org.apache.lucene.util.LegacyNumericUtils;
+
+
+/**
+ * A SpatialStrategy for indexing and searching Rectangles by storing its
+ * coordinates in numeric fields. It supports all {@link SpatialOperation}s and
+ * has a custom overlap relevancy. It is based on GeoPortal's <a
+ * href="http://geoportal.svn.sourceforge.net/svnroot/geoportal/Geoportal/trunk/src/com/esri/gpt/catalog/lucene/SpatialClauseAdapter.java">SpatialClauseAdapter</a>.
+ * <p>
+ * <b>Characteristics:</b>
+ * <br>
+ * <ul>
+ * <li>Only indexes Rectangles; just one per field value. Other shapes can be provided
+ * and the bounding box will be used.</li>
+ * <li>Can query only by a Rectangle. Providing other shapes is an error.</li>
+ * <li>Supports most {@link SpatialOperation}s but not Overlaps.</li>
+ * <li>Uses the DocValues API for any sorting / relevancy.</li>
+ * </ul>
+ * <p>
+ * <b>Implementation:</b>
+ * <p>
+ * This uses 4 double fields for minX, maxX, minY, maxY
+ * and a boolean to mark a dateline cross. Depending on the particular {@link
+ * SpatialOperation}s, there are a variety of {@link org.apache.lucene.search.LegacyNumericRangeQuery}s to be
+ * done.
+ * The {@link #makeOverlapRatioValueSource(com.spatial4j.core.shape.Rectangle, double)}
+ * works by calculating the query bbox overlap percentage against the indexed
+ * shape overlap percentage. The indexed shape's coordinates are retrieved from
+ * {@link org.apache.lucene.index.LeafReader#getNumericDocValues}.
+ *
+ * @lucene.experimental
+ */
+public class BBoxStrategy extends SpatialStrategy {
+
+  public static final String SUFFIX_MINX = "__minX";
+  public static final String SUFFIX_MAXX = "__maxX";
+  public static final String SUFFIX_MINY = "__minY";
+  public static final String SUFFIX_MAXY = "__maxY";
+  public static final String SUFFIX_XDL  = "__xdl";
+
+  /*
+   * The Bounding Box gets stored as four fields for x/y min/max and a flag
+   * that says if the box crosses the dateline (xdl).
+   */
+  protected final String field_bbox;
+  protected final String field_minX;
+  protected final String field_minY;
+  protected final String field_maxX;
+  protected final String field_maxY;
+  protected final String field_xdl; // crosses dateline
+
+  protected FieldType fieldType;//for the 4 numbers
+  protected FieldType xdlFieldType;
+
+  public BBoxStrategy(SpatialContext ctx, String fieldNamePrefix) {
+    super(ctx, fieldNamePrefix);
+    field_bbox = fieldNamePrefix;
+    field_minX = fieldNamePrefix + SUFFIX_MINX;
+    field_maxX = fieldNamePrefix + SUFFIX_MAXX;
+    field_minY = fieldNamePrefix + SUFFIX_MINY;
+    field_maxY = fieldNamePrefix + SUFFIX_MAXY;
+    field_xdl = fieldNamePrefix + SUFFIX_XDL;
+
+    FieldType fieldType = new FieldType(LegacyDoubleField.TYPE_NOT_STORED);
+    fieldType.setNumericPrecisionStep(8);//Solr's default
+    fieldType.setDocValuesType(DocValuesType.NUMERIC);
+    setFieldType(fieldType);
+  }
+
+  private int getPrecisionStep() {
+    return fieldType.numericPrecisionStep();
+  }
+
+  public FieldType getFieldType() {
+    return fieldType;
+  }
+
+  /** Used to customize the indexing options of the 4 number fields, and to a lesser degree the XDL field too. Search
+   * requires indexed=true, and relevancy requires docValues. If these features aren't needed then disable them.
+   * {@link FieldType#freeze()} is called on the argument. */
+  public void setFieldType(FieldType fieldType) {
+    fieldType.freeze();
+    this.fieldType = fieldType;
+    //only double's supported right now
+    if (fieldType.numericType() != FieldType.LegacyNumericType.DOUBLE)
+      throw new IllegalArgumentException("BBoxStrategy only supports doubles at this time.");
+    //for xdlFieldType, copy some similar options. Don't do docValues since it isn't needed here.
+    xdlFieldType = new FieldType(StringField.TYPE_NOT_STORED);
+    xdlFieldType.setStored(fieldType.stored());
+    xdlFieldType.setIndexOptions(fieldType.indexOptions());
+    xdlFieldType.freeze();
+  }
+
+  //---------------------------------
+  // Indexing
+  //---------------------------------
+
+  @Override
+  public Field[] createIndexableFields(Shape shape) {
+    return createIndexableFields(shape.getBoundingBox());
+  }
+
+  public Field[] createIndexableFields(Rectangle bbox) {
+    Field[] fields = new Field[5];
+    fields[0] = new ComboField(field_minX, bbox.getMinX(), fieldType);
+    fields[1] = new ComboField(field_maxX, bbox.getMaxX(), fieldType);
+    fields[2] = new ComboField(field_minY, bbox.getMinY(), fieldType);
+    fields[3] = new ComboField(field_maxY, bbox.getMaxY(), fieldType);
+    fields[4] = new ComboField(field_xdl, bbox.getCrossesDateLine()?"T":"F", xdlFieldType);
+    return fields;
+  }
+
+  /** Field subclass circumventing Field limitations. This one instance can have any combination of indexed, stored,
+   * and docValues.
+   */
+  private static class ComboField extends Field {
+    private ComboField(String name, Object value, FieldType type) {
+      super(name, type);//this expert constructor allows us to have a field that has docValues & indexed/stored
+      super.fieldsData = value;
+    }
+
+    //Is this a hack?  We assume that numericValue() is only called for DocValues purposes.
+    @Override
+    public Number numericValue() {
+      //Numeric DocValues only supports Long,
+      final Number number = super.numericValue();
+      if (number == null)
+        return null;
+      if (fieldType().numericType() == FieldType.LegacyNumericType.DOUBLE)
+        return Double.doubleToLongBits(number.doubleValue());
+      if (fieldType().numericType() == FieldType.LegacyNumericType.FLOAT)
+        return Float.floatToIntBits(number.floatValue());
+      return number.longValue();
+    }
+  }
+
+  //---------------------------------
+  // Value Source / Relevancy
+  //---------------------------------
+
+  /**
+   * Provides access to each rectangle per document as a ValueSource in which
+   * {@link org.apache.lucene.queries.function.FunctionValues#objectVal(int)} returns a {@link
+   * Shape}.
+   */ //TODO raise to SpatialStrategy
+  public ValueSource makeShapeValueSource() {
+    return new BBoxValueSource(this);
+  }
+
+  @Override
+  public ValueSource makeDistanceValueSource(Point queryPoint, double multiplier) {
+    //TODO if makeShapeValueSource gets lifted to the top; this could become a generic impl.
+    return new DistanceToShapeValueSource(makeShapeValueSource(), queryPoint, multiplier, ctx);
+  }
+
+  /** Returns a similarity based on {@link BBoxOverlapRatioValueSource}. This is just a
+   * convenience method. */
+  public ValueSource makeOverlapRatioValueSource(Rectangle queryBox, double queryTargetProportion) {
+    return new BBoxOverlapRatioValueSource(
+        makeShapeValueSource(), ctx.isGeo(), queryBox, queryTargetProportion, 0.0);
+  }
+
+  //---------------------------------
+  // Query Building
+  //---------------------------------
+
+  //  Utility on SpatialStrategy?
+//  public Query makeQueryWithValueSource(SpatialArgs args, ValueSource valueSource) {
+//    return new CustomScoreQuery(makeQuery(args), new FunctionQuery(valueSource));
+  //or...
+//  return new BooleanQuery.Builder()
+//      .add(new FunctionQuery(valueSource), BooleanClause.Occur.MUST)//matches everything and provides score
+//      .add(filterQuery, BooleanClause.Occur.FILTER)//filters (score isn't used)
+//  .build();
+//  }
+
+  @Override
+  public Query makeQuery(SpatialArgs args) {
+    Shape shape = args.getShape();
+    if (!(shape instanceof Rectangle))
+      throw new UnsupportedOperationException("Can only query by Rectangle, not " + shape);
+
+    Rectangle bbox = (Rectangle) shape;
+    Query spatial;
+
+    // Useful for understanding Relations:
+    // http://edndoc.esri.com/arcsde/9.1/general_topics/understand_spatial_relations.htm
+    SpatialOperation op = args.getOperation();
+         if( op == SpatialOperation.BBoxIntersects ) spatial = makeIntersects(bbox);
+    else if( op == SpatialOperation.BBoxWithin     ) spatial = makeWithin(bbox);
+    else if( op == SpatialOperation.Contains       ) spatial = makeContains(bbox);
+    else if( op == SpatialOperation.Intersects     ) spatial = makeIntersects(bbox);
+    else if( op == SpatialOperation.IsEqualTo      ) spatial = makeEquals(bbox);
+    else if( op == SpatialOperation.IsDisjointTo   ) spatial = makeDisjoint(bbox);
+    else if( op == SpatialOperation.IsWithin       ) spatial = makeWithin(bbox);
+    else { //no Overlaps support yet
+        throw new UnsupportedSpatialOperation(op);
+    }
+    return new ConstantScoreQuery(spatial);
+  }
+
+  /**
+   * Constructs a query to retrieve documents that fully contain the input envelope.
+   *
+   * @return the spatial query
+   */
+  Query makeContains(Rectangle bbox) {
+
+    // general case
+    // docMinX <= queryExtent.getMinX() AND docMinY <= queryExtent.getMinY() AND docMaxX >= queryExtent.getMaxX() AND docMaxY >= queryExtent.getMaxY()
+
+    // Y conditions
+    // docMinY <= queryExtent.getMinY() AND docMaxY >= queryExtent.getMaxY()
+    Query qMinY = LegacyNumericRangeQuery.newDoubleRange(field_minY, getPrecisionStep(), null, bbox.getMinY(), false, true);
+    Query qMaxY = LegacyNumericRangeQuery.newDoubleRange(field_maxY, getPrecisionStep(), bbox.getMaxY(), null, true, false);
+    Query yConditions = this.makeQuery(BooleanClause.Occur.MUST, qMinY, qMaxY);
+
+    // X conditions
+    Query xConditions;
+
+    // queries that do not cross the date line
+    if (!bbox.getCrossesDateLine()) {
+
+      // X Conditions for documents that do not cross the date line,
+      // documents that contain the min X and max X of the query envelope,
+      // docMinX <= queryExtent.getMinX() AND docMaxX >= queryExtent.getMaxX()
+      Query qMinX = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), null, bbox.getMinX(), false, true);
+      Query qMaxX = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), bbox.getMaxX(), null, true, false);
+      Query qMinMax = this.makeQuery(BooleanClause.Occur.MUST, qMinX, qMaxX);
+      Query qNonXDL = this.makeXDL(false, qMinMax);
+
+      if (!ctx.isGeo()) {
+        xConditions = qNonXDL;
+      } else {
+        // X Conditions for documents that cross the date line,
+        // the left portion of the document contains the min X of the query
+        // OR the right portion of the document contains the max X of the query,
+        // docMinXLeft <= queryExtent.getMinX() OR docMaxXRight >= queryExtent.getMaxX()
+        Query qXDLLeft = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), null, bbox.getMinX(), false, true);
+        Query qXDLRight = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), bbox.getMaxX(), null, true, false);
+        Query qXDLLeftRight = this.makeQuery(BooleanClause.Occur.SHOULD, qXDLLeft, qXDLRight);
+        Query qXDL = this.makeXDL(true, qXDLLeftRight);
+
+        Query qEdgeDL = null;
+        if (bbox.getMinX() == bbox.getMaxX() && Math.abs(bbox.getMinX()) == 180) {
+          double edge = bbox.getMinX() * -1;//opposite dateline edge
+          qEdgeDL = makeQuery(BooleanClause.Occur.SHOULD,
+              makeNumberTermQuery(field_minX, edge), makeNumberTermQuery(field_maxX, edge));
+        }
+
+        // apply the non-XDL and XDL conditions
+        xConditions = this.makeQuery(BooleanClause.Occur.SHOULD, qNonXDL, qXDL, qEdgeDL);
+      }
+    } else {
+      // queries that cross the date line
+
+      // No need to search for documents that do not cross the date line
+
+      // X Conditions for documents that cross the date line,
+      // the left portion of the document contains the min X of the query
+      // AND the right portion of the document contains the max X of the query,
+      // docMinXLeft <= queryExtent.getMinX() AND docMaxXRight >= queryExtent.getMaxX()
+      Query qXDLLeft = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), null, bbox.getMinX(), false, true);
+      Query qXDLRight = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), bbox.getMaxX(), null, true, false);
+      Query qXDLLeftRight = this.makeXDL(true, this.makeQuery(BooleanClause.Occur.MUST, qXDLLeft, qXDLRight));
+
+      Query qWorld = makeQuery(BooleanClause.Occur.MUST,
+          makeNumberTermQuery(field_minX, -180), makeNumberTermQuery(field_maxX, 180));
+
+      xConditions = makeQuery(BooleanClause.Occur.SHOULD, qXDLLeftRight, qWorld);
+    }
+
+    // both X and Y conditions must occur
+    return this.makeQuery(BooleanClause.Occur.MUST, xConditions, yConditions);
+  }
+
+  /**
+   * Constructs a query to retrieve documents that are disjoint to the input envelope.
+   *
+   * @return the spatial query
+   */
+  Query makeDisjoint(Rectangle bbox) {
+
+    // general case
+    // docMinX > queryExtent.getMaxX() OR docMaxX < queryExtent.getMinX() OR docMinY > queryExtent.getMaxY() OR docMaxY < queryExtent.getMinY()
+
+    // Y conditions
+    // docMinY > queryExtent.getMaxY() OR docMaxY < queryExtent.getMinY()
+    Query qMinY = LegacyNumericRangeQuery.newDoubleRange(field_minY, getPrecisionStep(), bbox.getMaxY(), null, false, false);
+    Query qMaxY = LegacyNumericRangeQuery.newDoubleRange(field_maxY, getPrecisionStep(), null, bbox.getMinY(), false, false);
+    Query yConditions = this.makeQuery(BooleanClause.Occur.SHOULD, qMinY, qMaxY);
+
+    // X conditions
+    Query xConditions;
+
+    // queries that do not cross the date line
+    if (!bbox.getCrossesDateLine()) {
+
+      // X Conditions for documents that do not cross the date line,
+      // docMinX > queryExtent.getMaxX() OR docMaxX < queryExtent.getMinX()
+      Query qMinX = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), bbox.getMaxX(), null, false, false);
+      if (bbox.getMinX() == -180.0 && ctx.isGeo()) {//touches dateline; -180 == 180
+        BooleanQuery.Builder bq = new BooleanQuery.Builder();
+        bq.add(qMinX, BooleanClause.Occur.MUST);
+        bq.add(makeNumberTermQuery(field_maxX, 180.0), BooleanClause.Occur.MUST_NOT);
+        qMinX = bq.build();
+      }
+      Query qMaxX = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, bbox.getMinX(), false, false);
+      if (bbox.getMaxX() == 180.0 && ctx.isGeo()) {//touches dateline; -180 == 180
+        BooleanQuery.Builder bq = new BooleanQuery.Builder();
+        bq.add(qMaxX, BooleanClause.Occur.MUST);
+        bq.add(makeNumberTermQuery(field_minX, -180.0), BooleanClause.Occur.MUST_NOT);
+        qMaxX = bq.build();
+      }
+      Query qMinMax = this.makeQuery(BooleanClause.Occur.SHOULD, qMinX, qMaxX);
+      Query qNonXDL = this.makeXDL(false, qMinMax);
+
+      if (!ctx.isGeo()) {
+        xConditions = qNonXDL;
+      } else {
+        // X Conditions for documents that cross the date line,
+
+        // both the left and right portions of the document must be disjoint to the query
+        // (docMinXLeft > queryExtent.getMaxX() OR docMaxXLeft < queryExtent.getMinX()) AND
+        // (docMinXRight > queryExtent.getMaxX() OR docMaxXRight < queryExtent.getMinX())
+        // where: docMaxXLeft = 180.0, docMinXRight = -180.0
+        // (docMaxXLeft  < queryExtent.getMinX()) equates to (180.0  < queryExtent.getMinX()) and is ignored
+        // (docMinXRight > queryExtent.getMaxX()) equates to (-180.0 > queryExtent.getMaxX()) and is ignored
+        Query qMinXLeft = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), bbox.getMaxX(), null, false, false);
+        Query qMaxXRight = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, bbox.getMinX(), false, false);
+        Query qLeftRight = this.makeQuery(BooleanClause.Occur.MUST, qMinXLeft, qMaxXRight);
+        Query qXDL = this.makeXDL(true, qLeftRight);
+
+        // apply the non-XDL and XDL conditions
+        xConditions = this.makeQuery(BooleanClause.Occur.SHOULD, qNonXDL, qXDL);
+      }
+      // queries that cross the date line
+    } else {
+
+      // X Conditions for documents that do not cross the date line,
+      // the document must be disjoint to both the left and right query portions
+      // (docMinX > queryExtent.getMaxX()Left OR docMaxX < queryExtent.getMinX()) AND (docMinX > queryExtent.getMaxX() OR docMaxX < queryExtent.getMinX()Left)
+      // where: queryExtent.getMaxX()Left = 180.0, queryExtent.getMinX()Left = -180.0
+      Query qMinXLeft = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), 180.0, null, false, false);
+      Query qMaxXLeft = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, bbox.getMinX(), false, false);
+      Query qMinXRight = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), bbox.getMaxX(), null, false, false);
+      Query qMaxXRight = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, -180.0, false, false);
+      Query qLeft = this.makeQuery(BooleanClause.Occur.SHOULD, qMinXLeft, qMaxXLeft);
+      Query qRight = this.makeQuery(BooleanClause.Occur.SHOULD, qMinXRight, qMaxXRight);
+      Query qLeftRight = this.makeQuery(BooleanClause.Occur.MUST, qLeft, qRight);
+
+      // No need to search for documents that do not cross the date line
+
+      xConditions = this.makeXDL(false, qLeftRight);
+    }
+
+    // either X or Y conditions should occur
+    return this.makeQuery(BooleanClause.Occur.SHOULD, xConditions, yConditions);
+  }
+
+  /**
+   * Constructs a query to retrieve documents that equal the input envelope.
+   *
+   * @return the spatial query
+   */
+  Query makeEquals(Rectangle bbox) {
+
+    // docMinX = queryExtent.getMinX() AND docMinY = queryExtent.getMinY() AND docMaxX = queryExtent.getMaxX() AND docMaxY = queryExtent.getMaxY()
+    Query qMinX = makeNumberTermQuery(field_minX, bbox.getMinX());
+    Query qMinY = makeNumberTermQuery(field_minY, bbox.getMinY());
+    Query qMaxX = makeNumberTermQuery(field_maxX, bbox.getMaxX());
+    Query qMaxY = makeNumberTermQuery(field_maxY, bbox.getMaxY());
+    return makeQuery(BooleanClause.Occur.MUST, qMinX, qMinY, qMaxX, qMaxY);
+  }
+
+  /**
+   * Constructs a query to retrieve documents that intersect the input envelope.
+   *
+   * @return the spatial query
+   */
+  Query makeIntersects(Rectangle bbox) {
+
+    // the original intersects query does not work for envelopes that cross the date line,
+    // switch to a NOT Disjoint query
+
+    // MUST_NOT causes a problem when it's the only clause type within a BooleanQuery,
+    // to get around it we add all documents as a SHOULD
+
+    // there must be an envelope, it must not be disjoint
+    Query qHasEnv;
+    if (ctx.isGeo()) {
+      Query qIsNonXDL = this.makeXDL(false);
+      Query qIsXDL = ctx.isGeo() ? this.makeXDL(true) : null;
+      qHasEnv = this.makeQuery(BooleanClause.Occur.SHOULD, qIsNonXDL, qIsXDL);
+    } else {
+      qHasEnv = this.makeXDL(false);
+    }
+
+    BooleanQuery.Builder qNotDisjoint = new BooleanQuery.Builder();
+    qNotDisjoint.add(qHasEnv, BooleanClause.Occur.MUST);
+    Query qDisjoint = makeDisjoint(bbox);
+    qNotDisjoint.add(qDisjoint, BooleanClause.Occur.MUST_NOT);
+
+    //Query qDisjoint = makeDisjoint();
+    //BooleanQuery qNotDisjoint = new BooleanQuery();
+    //qNotDisjoint.add(new MatchAllDocsQuery(),BooleanClause.Occur.SHOULD);
+    //qNotDisjoint.add(qDisjoint,BooleanClause.Occur.MUST_NOT);
+    return qNotDisjoint.build();
+  }
+
+  /**
+   * Makes a boolean query based upon a collection of queries and a logical operator.
+   *
+   * @param occur the logical operator
+   * @param queries the query collection
+   * @return the query
+   */
+  BooleanQuery makeQuery(BooleanClause.Occur occur, Query... queries) {
+    BooleanQuery.Builder bq = new BooleanQuery.Builder();
+    for (Query query : queries) {
+      if (query != null)
+        bq.add(query, occur);
+    }
+    return bq.build();
+  }
+
+  /**
+   * Constructs a query to retrieve documents are fully within the input envelope.
+   *
+   * @return the spatial query
+   */
+  Query makeWithin(Rectangle bbox) {
+
+    // general case
+    // docMinX >= queryExtent.getMinX() AND docMinY >= queryExtent.getMinY() AND docMaxX <= queryExtent.getMaxX() AND docMaxY <= queryExtent.getMaxY()
+
+    // Y conditions
+    // docMinY >= queryExtent.getMinY() AND docMaxY <= queryExtent.getMaxY()
+    Query qMinY = LegacyNumericRangeQuery.newDoubleRange(field_minY, getPrecisionStep(), bbox.getMinY(), null, true, false);
+    Query qMaxY = LegacyNumericRangeQuery.newDoubleRange(field_maxY, getPrecisionStep(), null, bbox.getMaxY(), false, true);
+    Query yConditions = this.makeQuery(BooleanClause.Occur.MUST, qMinY, qMaxY);
+
+    // X conditions
+    Query xConditions;
+
+    if (ctx.isGeo() && bbox.getMinX() == -180.0 && bbox.getMaxX() == 180.0) {
+      //if query world-wraps, only the y condition matters
+      return yConditions;
+
+    } else if (!bbox.getCrossesDateLine()) {
+      // queries that do not cross the date line
+
+      // docMinX >= queryExtent.getMinX() AND docMaxX <= queryExtent.getMaxX()
+      Query qMinX = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), bbox.getMinX(), null, true, false);
+      Query qMaxX = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, bbox.getMaxX(), false, true);
+      Query qMinMax = this.makeQuery(BooleanClause.Occur.MUST, qMinX, qMaxX);
+
+      double edge = 0;//none, otherwise opposite dateline of query
+      if (bbox.getMinX() == -180.0)
+        edge = 180;
+      else if (bbox.getMaxX() == 180.0)
+        edge = -180;
+      if (edge != 0 && ctx.isGeo()) {
+        Query edgeQ = makeQuery(BooleanClause.Occur.MUST,
+            makeNumberTermQuery(field_minX, edge), makeNumberTermQuery(field_maxX, edge));
+        qMinMax = makeQuery(BooleanClause.Occur.SHOULD, qMinMax, edgeQ);
+      }
+
+      xConditions = this.makeXDL(false, qMinMax);
+
+      // queries that cross the date line
+    } else {
+
+      // X Conditions for documents that do not cross the date line
+
+      // the document should be within the left portion of the query
+      // docMinX >= queryExtent.getMinX() AND docMaxX <= 180.0
+      Query qMinXLeft = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), bbox.getMinX(), null, true, false);
+      Query qMaxXLeft = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, 180.0, false, true);
+      Query qLeft = this.makeQuery(BooleanClause.Occur.MUST, qMinXLeft, qMaxXLeft);
+
+      // the document should be within the right portion of the query
+      // docMinX >= -180.0 AND docMaxX <= queryExtent.getMaxX()
+      Query qMinXRight = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), -180.0, null, true, false);
+      Query qMaxXRight = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, bbox.getMaxX(), false, true);
+      Query qRight = this.makeQuery(BooleanClause.Occur.MUST, qMinXRight, qMaxXRight);
+
+      // either left or right conditions should occur,
+      // apply the left and right conditions to documents that do not cross the date line
+      Query qLeftRight = this.makeQuery(BooleanClause.Occur.SHOULD, qLeft, qRight);
+      Query qNonXDL = this.makeXDL(false, qLeftRight);
+
+      // X Conditions for documents that cross the date line,
+      // the left portion of the document must be within the left portion of the query,
+      // AND the right portion of the document must be within the right portion of the query
+      // docMinXLeft >= queryExtent.getMinX() AND docMaxXLeft <= 180.0
+      // AND docMinXRight >= -180.0 AND docMaxXRight <= queryExtent.getMaxX()
+      Query qXDLLeft = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), bbox.getMinX(), null, true, false);
+      Query qXDLRight = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, bbox.getMaxX(), false, true);
+      Query qXDLLeftRight = this.makeQuery(BooleanClause.Occur.MUST, qXDLLeft, qXDLRight);
+      Query qXDL = this.makeXDL(true, qXDLLeftRight);
+
+      // apply the non-XDL and XDL conditions
+      xConditions = this.makeQuery(BooleanClause.Occur.SHOULD, qNonXDL, qXDL);
+    }
+
+    // both X and Y conditions must occur
+    return this.makeQuery(BooleanClause.Occur.MUST, xConditions, yConditions);
+  }
+
+  /**
+   * Constructs a query to retrieve documents that do or do not cross the date line.
+   *
+   * @param crossedDateLine <code>true</true> for documents that cross the date line
+   * @return the query
+   */
+  private Query makeXDL(boolean crossedDateLine) {
+    // The 'T' and 'F' values match solr fields
+    return new TermQuery(new Term(field_xdl, crossedDateLine ? "T" : "F"));
+  }
+
+  /**
+   * Constructs a query to retrieve documents that do or do not cross the date line
+   * and match the supplied spatial query.
+   *
+   * @param crossedDateLine <code>true</true> for documents that cross the date line
+   * @param query the spatial query
+   * @return the query
+   */
+  private Query makeXDL(boolean crossedDateLine, Query query) {
+    if (!ctx.isGeo()) {
+      assert !crossedDateLine;
+      return query;
+    }
+    BooleanQuery.Builder bq = new BooleanQuery.Builder();
+    bq.add(this.makeXDL(crossedDateLine), BooleanClause.Occur.MUST);
+    bq.add(query, BooleanClause.Occur.MUST);
+    return bq.build();
+  }
+
+  private Query makeNumberTermQuery(String field, double number) {
+    BytesRefBuilder bytes = new BytesRefBuilder();
+    LegacyNumericUtils.longToPrefixCoded(LegacyNumericUtils.doubleToSortableLong(number), 0, bytes);
+    return new TermQuery(new Term(field, bytes.get()));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxValueSource.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxValueSource.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxValueSource.java
new file mode 100644
index 0000000..5d95407
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxValueSource.java
@@ -0,0 +1,115 @@
+/*
+ * 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.bbox;
+
+import com.spatial4j.core.shape.Rectangle;
+import org.apache.lucene.index.LeafReader;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.DocValues;
+import org.apache.lucene.index.NumericDocValues;
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.search.Explanation;
+import org.apache.lucene.util.Bits;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * A ValueSource in which the indexed Rectangle is returned from
+ * {@link org.apache.lucene.queries.function.FunctionValues#objectVal(int)}.
+ *
+ * @lucene.internal
+ */
+class BBoxValueSource extends ValueSource {
+
+  private final BBoxStrategy strategy;
+
+  public BBoxValueSource(BBoxStrategy strategy) {
+    this.strategy = strategy;
+  }
+
+  @Override
+  public String description() {
+    return "bboxShape(" + strategy.getFieldName() + ")";
+  }
+
+  @Override
+  public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
+    LeafReader reader = readerContext.reader();
+    final NumericDocValues minX = DocValues.getNumeric(reader, strategy.field_minX);
+    final NumericDocValues minY = DocValues.getNumeric(reader, strategy.field_minY);
+    final NumericDocValues maxX = DocValues.getNumeric(reader, strategy.field_maxX);
+    final NumericDocValues maxY = DocValues.getNumeric(reader, strategy.field_maxY);
+
+    final Bits validBits = DocValues.getDocsWithField(reader, strategy.field_minX);//could have chosen any field
+    //reused
+    final Rectangle rect = strategy.getSpatialContext().makeRectangle(0,0,0,0);
+
+    return new FunctionValues() {
+      @Override
+      public Object objectVal(int doc) {
+        if (!validBits.get(doc)) {
+          return null;
+        } else {
+          rect.reset(
+              Double.longBitsToDouble(minX.get(doc)), Double.longBitsToDouble(maxX.get(doc)),
+              Double.longBitsToDouble(minY.get(doc)), Double.longBitsToDouble(maxY.get(doc)));
+          return rect;
+        }
+      }
+
+      @Override
+      public String strVal(int doc) {//TODO support WKT output once Spatial4j does
+        Object v = objectVal(doc);
+        return v == null ? null : v.toString();
+      }
+
+      @Override
+      public boolean exists(int doc) {
+        return validBits.get(doc);
+      }
+
+      @Override
+      public Explanation explain(int doc) {
+        return Explanation.match(Float.NaN, toString(doc));
+      }
+
+      @Override
+      public String toString(int doc) {
+        return description() + '=' + strVal(doc);
+      }
+    };
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    BBoxValueSource that = (BBoxValueSource) o;
+
+    if (!strategy.equals(that.strategy)) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    return strategy.hashCode();
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/package-info.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/package-info.java
new file mode 100644
index 0000000..518f447
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+/**
+ * Bounding Box Spatial Strategy
+ * <p>
+ * Index a shape extent using 4 numeric fields and a flag to say if it crosses the dateline
+ */
+package org.apache.lucene.spatial.bbox;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/CompositeSpatialStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/CompositeSpatialStrategy.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/CompositeSpatialStrategy.java
new file mode 100644
index 0000000..7dc2dfa
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/CompositeSpatialStrategy.java
@@ -0,0 +1,144 @@
+/*
+ * 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.composite;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.spatial.SpatialStrategy;
+import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.apache.lucene.spatial.query.UnsupportedSpatialOperation;
+import org.apache.lucene.spatial.serialized.SerializedDVStrategy;
+import org.apache.lucene.spatial.util.ShapePredicateValueSource;
+
+/**
+ * A composite {@link SpatialStrategy} based on {@link RecursivePrefixTreeStrategy} (RPT) and
+ * {@link SerializedDVStrategy} (SDV).
+ * RPT acts as an index to the precision available in SDV, and in some circumstances can avoid geometry lookups based
+ * on where a cell is in relation to the query shape.  Currently the only predicate optimized like this is Intersects.
+ * All predicates are supported except for the BBox* ones, and Disjoint.
+ *
+ * @lucene.experimental
+ */
+public class CompositeSpatialStrategy extends SpatialStrategy {
+
+  //TODO support others? (BBox)
+  private final RecursivePrefixTreeStrategy indexStrategy;
+
+  /** Has the geometry. */ // TODO support others?
+  private final SerializedDVStrategy geometryStrategy;
+  private boolean optimizePredicates = true;
+
+  public CompositeSpatialStrategy(String fieldName,
+                                  RecursivePrefixTreeStrategy indexStrategy, SerializedDVStrategy geometryStrategy) {
+    super(indexStrategy.getSpatialContext(), fieldName);//field name; unused
+    this.indexStrategy = indexStrategy;
+    this.geometryStrategy = geometryStrategy;
+  }
+
+  public RecursivePrefixTreeStrategy getIndexStrategy() {
+    return indexStrategy;
+  }
+
+  public SerializedDVStrategy getGeometryStrategy() {
+    return geometryStrategy;
+  }
+
+  public boolean isOptimizePredicates() {
+    return optimizePredicates;
+  }
+
+  /** Set to false to NOT use optimized search predicates that avoid checking the geometry sometimes. Only useful for
+   * benchmarking. */
+  public void setOptimizePredicates(boolean optimizePredicates) {
+    this.optimizePredicates = optimizePredicates;
+  }
+
+  @Override
+  public Field[] createIndexableFields(Shape shape) {
+    List<Field> fields = new ArrayList<>();
+    Collections.addAll(fields, indexStrategy.createIndexableFields(shape));
+    Collections.addAll(fields, geometryStrategy.createIndexableFields(shape));
+    return fields.toArray(new Field[fields.size()]);
+  }
+
+  @Override
+  public ValueSource makeDistanceValueSource(Point queryPoint, double multiplier) {
+    //TODO consider indexing center-point in DV?  Guarantee contained by the shape, which could then be used for
+    // other purposes like faster WITHIN predicate?
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public Query makeQuery(SpatialArgs args) {
+    final SpatialOperation pred = args.getOperation();
+
+    if (pred == SpatialOperation.BBoxIntersects || pred == SpatialOperation.BBoxWithin) {
+      throw new UnsupportedSpatialOperation(pred);
+    }
+
+    if (pred == SpatialOperation.IsDisjointTo) {
+//      final Query intersectQuery = makeQuery(new SpatialArgs(SpatialOperation.Intersects, args.getShape()));
+//      DocValues.getDocsWithField(reader, geometryStrategy.getFieldName());
+      //TODO resurrect Disjoint spatial query utility accepting a field name known to have DocValues.
+      // update class docs when it's added.
+      throw new UnsupportedSpatialOperation(pred);
+    }
+
+    final ShapePredicateValueSource predicateValueSource =
+        new ShapePredicateValueSource(geometryStrategy.makeShapeValueSource(), pred, args.getShape());
+    //System.out.println("PredOpt: " + optimizePredicates);
+    if (pred == SpatialOperation.Intersects && optimizePredicates) {
+      // We have a smart Intersects impl
+
+      final SpatialPrefixTree grid = indexStrategy.getGrid();
+      final int detailLevel = grid.getLevelForDistance(args.resolveDistErr(ctx, 0.0));//default to max precision
+      return new IntersectsRPTVerifyQuery(args.getShape(), indexStrategy.getFieldName(), grid,
+          detailLevel, indexStrategy.getPrefixGridScanLevel(), predicateValueSource);
+    } else {
+      //The general path; all index matches get verified
+
+      SpatialArgs indexArgs;
+      if (pred == SpatialOperation.Contains) {
+        // note: we could map IsWithin as well but it's pretty darned slow since it touches all world grids
+        indexArgs = args;
+      } else {
+        //TODO add args.clone method with new predicate? Or simply make non-final?
+        indexArgs = new SpatialArgs(SpatialOperation.Intersects, args.getShape());
+        indexArgs.setDistErr(args.getDistErr());
+        indexArgs.setDistErrPct(args.getDistErrPct());
+      }
+
+      if (indexArgs.getDistErr() == null && indexArgs.getDistErrPct() == null) {
+        indexArgs.setDistErrPct(0.10);
+      }
+
+      final Query indexQuery = indexStrategy.makeQuery(indexArgs);
+      return new CompositeVerifyQuery(indexQuery, predicateValueSource);
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/CompositeVerifyQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/CompositeVerifyQuery.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/CompositeVerifyQuery.java
new file mode 100644
index 0000000..0e6ea2c
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/CompositeVerifyQuery.java
@@ -0,0 +1,120 @@
+/*
+ * 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.composite;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.queries.function.ValueSource;
+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;
+
+/**
+ * A Query that considers an "indexQuery" to have approximate results, and a follow-on
+ * {@link ValueSource}/{@link FunctionValues#boolVal(int)} is called to verify each hit
+ * from {@link TwoPhaseIterator#matches()}.
+ *
+ * @lucene.experimental
+ */
+public class CompositeVerifyQuery extends Query {
+  final Query indexQuery;//approximation (matches more than needed)
+  final ValueSource predicateValueSource;//we call boolVal(doc)
+
+  public CompositeVerifyQuery(Query indexQuery, ValueSource predicateValueSource) {
+    this.indexQuery = indexQuery;
+    this.predicateValueSource = predicateValueSource;
+  }
+
+  @Override
+  public Query rewrite(IndexReader reader) throws IOException {
+    final Query rewritten = indexQuery.rewrite(reader);
+    if (rewritten != indexQuery) {
+      return new CompositeVerifyQuery(rewritten, predicateValueSource);
+    }
+    return super.rewrite(reader);
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+    if (!super.equals(o)) return false;
+
+    CompositeVerifyQuery that = (CompositeVerifyQuery) o;
+
+    if (!indexQuery.equals(that.indexQuery)) return false;
+    if (!predicateValueSource.equals(that.predicateValueSource)) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = super.hashCode();
+    result = 31 * result + indexQuery.hashCode();
+    result = 31 * result + predicateValueSource.hashCode();
+    return result;
+  }
+
+  @Override
+  public String toString(String field) {
+    //TODO verify this looks good
+    return getClass().getSimpleName() + "(" + indexQuery.toString(field) + ", " + predicateValueSource + ")";
+  }
+
+  @Override
+  public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
+    final Weight indexQueryWeight = indexQuery.createWeight(searcher, false);//scores aren't unsupported
+    final Map valueSourceContext = ValueSource.newContext(searcher);
+
+    return new ConstantScoreWeight(this) {
+
+      @Override
+      public Scorer scorer(LeafReaderContext context) throws IOException {
+
+        final Scorer indexQueryScorer = indexQueryWeight.scorer(context);
+        if (indexQueryScorer == null) {
+          return null;
+        }
+
+        final FunctionValues predFuncValues = predicateValueSource.getValues(valueSourceContext, context);
+
+        final TwoPhaseIterator twoPhaseIterator = new TwoPhaseIterator(indexQueryScorer.iterator()) {
+          @Override
+          public boolean matches() throws IOException {
+            return predFuncValues.boolVal(indexQueryScorer.docID());
+          }
+
+          @Override
+          public float matchCost() {
+            return 100; // TODO: use cost of predFuncValues.boolVal()
+          }
+        };
+
+        return new ConstantScoreScorer(this, score(), twoPhaseIterator);
+      }
+    };
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java
new file mode 100644
index 0000000..a963b6e
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java
@@ -0,0 +1,235 @@
+/*
+ * 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.composite;
+
+import java.io.IOException;
+import java.util.Map;
+
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.SpatialRelation;
+
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.search.ConstantScoreScorer;
+import org.apache.lucene.search.ConstantScoreWeight;
+import org.apache.lucene.search.DocIdSet;
+import org.apache.lucene.search.DocIdSetIterator;
+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;
+import org.apache.lucene.spatial.prefix.AbstractVisitingPrefixTreeQuery;
+import org.apache.lucene.spatial.prefix.tree.Cell;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.util.DocIdSetBuilder;
+
+/**
+ * A spatial Intersects predicate that distinguishes an approximated match from an exact match based on which cells
+ * are within the query shape. It exposes a {@link TwoPhaseIterator} that will verify a match with a provided
+ * predicate in the form of a {@link ValueSource} by calling {@link FunctionValues#boolVal(int)}.
+ *
+ * @lucene.internal
+ */
+public class IntersectsRPTVerifyQuery extends Query {
+
+  private final IntersectsDifferentiatingQuery intersectsDiffQuery;
+  private final ValueSource predicateValueSource; // we call FunctionValues.boolVal(doc)
+
+  public IntersectsRPTVerifyQuery(Shape queryShape, String fieldName, SpatialPrefixTree grid, int detailLevel,
+                                  int prefixGridScanLevel, ValueSource predicateValueSource) {
+    this.predicateValueSource = predicateValueSource;
+    this.intersectsDiffQuery = new IntersectsDifferentiatingQuery(queryShape, fieldName, grid, detailLevel,
+        prefixGridScanLevel);
+  }
+
+  @Override
+  public String toString(String field) {
+    return "IntersectsVerified(fieldName=" + field + ")";
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (!super.equals(o)) return false;
+
+    IntersectsRPTVerifyQuery that = (IntersectsRPTVerifyQuery) o;
+
+    if (!intersectsDiffQuery.equals(that.intersectsDiffQuery)) return false;
+    return predicateValueSource.equals(that.predicateValueSource);
+
+  }
+
+  @Override
+  public int hashCode() {
+    int result = super.hashCode();
+    result = 31 * result + intersectsDiffQuery.hashCode();
+    result = 31 * result + predicateValueSource.hashCode();
+    return result;
+  }
+
+  @Override
+  public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
+    final Map valueSourceContext = ValueSource.newContext(searcher);
+
+    return new ConstantScoreWeight(this) {
+      @Override
+      public Scorer scorer(LeafReaderContext context) throws IOException {
+        // Compute approx & exact
+        final IntersectsDifferentiatingQuery.IntersectsDifferentiatingVisitor result =
+            intersectsDiffQuery.compute(context);
+        if (result.approxDocIdSet == null) {
+          return null;
+        }
+        final DocIdSetIterator approxDISI = result.approxDocIdSet.iterator();
+        if (approxDISI == null) {
+          return null;
+        }
+        final DocIdSetIterator exactIterator;
+        if (result.exactDocIdSet != null) {
+          // If both sets are the same, there's nothing to verify; we needn't return a TwoPhaseIterator
+          if (result.approxDocIdSet == result.exactDocIdSet) {
+            return new ConstantScoreScorer(this, score(), approxDISI);
+          }
+          exactIterator = result.exactDocIdSet.iterator();
+          assert exactIterator != null;
+        } else {
+          exactIterator = null;
+        }
+
+        final FunctionValues predFuncValues = predicateValueSource.getValues(valueSourceContext, context);
+
+        final TwoPhaseIterator twoPhaseIterator = new TwoPhaseIterator(approxDISI) {
+          @Override
+          public boolean matches() throws IOException {
+            final int doc = approxDISI.docID();
+            if (exactIterator != null) {
+              if (exactIterator.docID() < doc) {
+                exactIterator.advance(doc);
+              }
+              if (exactIterator.docID() == doc) {
+                return true;
+              }
+            }
+
+            return predFuncValues.boolVal(doc);
+          }
+
+          @Override
+          public float matchCost() {
+            return 100; // TODO: use cost of exactIterator.advance() and predFuncValues.boolVal()
+          }
+        };
+
+        return new ConstantScoreScorer(this, score(), twoPhaseIterator);
+      }
+    };
+  }
+
+  //This may be a "Query" but we don't use it as-such; the caller calls the constructor and then compute() and examines
+  // the results which consists of two parts -- the approximated results, and a subset of exact matches. The
+  // difference needs to be verified.
+  // TODO refactor AVPTQ to not be a Query?
+  private static class IntersectsDifferentiatingQuery extends AbstractVisitingPrefixTreeQuery {
+
+    public IntersectsDifferentiatingQuery(Shape queryShape, String fieldName, SpatialPrefixTree grid,
+                                          int detailLevel, int prefixGridScanLevel) {
+      super(queryShape, fieldName, grid, detailLevel, prefixGridScanLevel);
+    }
+
+    IntersectsDifferentiatingQuery.IntersectsDifferentiatingVisitor compute(LeafReaderContext context)
+        throws IOException {
+      final IntersectsDifferentiatingQuery.IntersectsDifferentiatingVisitor result =
+          new IntersectsDifferentiatingQuery.IntersectsDifferentiatingVisitor(context);
+      result.getDocIdSet();//computes
+      return result;
+    }
+
+    // TODO consider if IntersectsPrefixTreeQuery should simply do this and provide both sets
+
+    class IntersectsDifferentiatingVisitor extends VisitorTemplate {
+      DocIdSetBuilder approxBuilder = new DocIdSetBuilder(maxDoc);
+      DocIdSetBuilder exactBuilder = new DocIdSetBuilder(maxDoc);
+      boolean approxIsEmpty = true;
+      boolean exactIsEmpty = true;
+      DocIdSet exactDocIdSet;
+      DocIdSet approxDocIdSet;
+
+      public IntersectsDifferentiatingVisitor(LeafReaderContext context) throws IOException {
+        super(context);
+      }
+
+      @Override
+      protected void start() throws IOException {
+      }
+
+      @Override
+      protected DocIdSet finish() throws IOException {
+        if (exactIsEmpty) {
+          exactDocIdSet = null;
+        } else {
+          exactDocIdSet = exactBuilder.build();
+        }
+        if (approxIsEmpty) {
+          approxDocIdSet = exactDocIdSet;//optimization
+        } else {
+          if (exactDocIdSet != null) {
+            approxBuilder.add(exactDocIdSet.iterator());
+          }
+          approxDocIdSet = approxBuilder.build();
+        }
+        return null;//unused in this weird re-use of AVPTQ
+      }
+
+      @Override
+      protected boolean visitPrefix(Cell cell) throws IOException {
+        if (cell.getShapeRel() == SpatialRelation.WITHIN) {
+          exactIsEmpty = false;
+          collectDocs(exactBuilder);//note: we'll add exact to approx on finish()
+          return false;
+        } else if (cell.getLevel() == detailLevel) {
+          approxIsEmpty = false;
+          collectDocs(approxBuilder);
+          return false;
+        }
+        return true;
+      }
+
+      @Override
+      protected void visitLeaf(Cell cell) throws IOException {
+        if (cell.getShapeRel() == SpatialRelation.WITHIN) {
+          exactIsEmpty = false;
+          collectDocs(exactBuilder);//note: we'll add exact to approx on finish()
+        } else {
+          approxIsEmpty = false;
+          collectDocs(approxBuilder);
+        }
+      }
+    }
+
+    @Override
+    public DocIdSet getDocIdSet(LeafReaderContext context) throws IOException {
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public String toString(String field) {
+      throw new IllegalStateException();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/package-info.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/package-info.java
new file mode 100644
index 0000000..c207ea6
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+/** Composite strategies. */
+package org.apache.lucene.spatial.composite;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/package-info.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/package-info.java
new file mode 100644
index 0000000..c86bc6e
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Lucene advanced spatial search
+ */
+package org.apache.lucene.spatial;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeQuery.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeQuery.java
new file mode 100644
index 0000000..127e689
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeQuery.java
@@ -0,0 +1,133 @@
+/*
+ * 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.prefix;
+
+import java.io.IOException;
+
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.index.LeafReader;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.PostingsEnum;
+import org.apache.lucene.index.Terms;
+import org.apache.lucene.index.TermsEnum;
+import org.apache.lucene.search.ConstantScoreScorer;
+import org.apache.lucene.search.ConstantScoreWeight;
+import org.apache.lucene.search.DocIdSet;
+import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.Weight;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.util.BitSet;
+import org.apache.lucene.util.DocIdSetBuilder;
+
+/**
+ * Base class for Lucene Queries on SpatialPrefixTree fields.
+ * @lucene.internal
+ */
+public abstract class AbstractPrefixTreeQuery extends Query {
+
+  protected final Shape queryShape;
+  protected final String fieldName;
+  protected final SpatialPrefixTree grid;//not in equals/hashCode since it's implied for a specific field
+  protected final int detailLevel;
+
+  public AbstractPrefixTreeQuery(Shape queryShape, String fieldName, SpatialPrefixTree grid, int detailLevel) {
+    this.queryShape = queryShape;
+    this.fieldName = fieldName;
+    this.grid = grid;
+    this.detailLevel = detailLevel;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (super.equals(o) == false) return false;
+
+    AbstractPrefixTreeQuery that = (AbstractPrefixTreeQuery) o;
+
+    if (detailLevel != that.detailLevel) return false;
+    if (!fieldName.equals(that.fieldName)) return false;
+    if (!queryShape.equals(that.queryShape)) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = super.hashCode();
+    result = 31 * result + queryShape.hashCode();
+    result = 31 * result + fieldName.hashCode();
+    result = 31 * result + detailLevel;
+    return result;
+  }
+
+  @Override
+  public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
+    return new ConstantScoreWeight(this) {
+      @Override
+      public Scorer scorer(LeafReaderContext context) throws IOException {
+        DocIdSet docSet = getDocIdSet(context);
+        if (docSet == null) {
+          return null;
+        }
+        DocIdSetIterator disi = docSet.iterator();
+        if (disi == null) {
+          return null;
+        }
+        return new ConstantScoreScorer(this, score(), disi);
+      }
+    };
+  }
+
+  protected abstract DocIdSet getDocIdSet(LeafReaderContext context) throws IOException;
+
+  /** Holds transient state and docid collecting utility methods as part of
+   * traversing a {@link TermsEnum} for a {@link org.apache.lucene.index.LeafReaderContext}. */
+  public abstract class BaseTermsEnumTraverser {//TODO rename to LeafTermsEnumTraverser ?
+    //note: only 'fieldName' (accessed in constructor) keeps this from being a static inner class
+
+    protected final LeafReaderContext context;
+    protected final int maxDoc;
+
+    protected TermsEnum termsEnum;//remember to check for null!
+    protected PostingsEnum postingsEnum;
+
+    public BaseTermsEnumTraverser(LeafReaderContext context) throws IOException {
+      this.context = context;
+      LeafReader reader = context.reader();
+      this.maxDoc = reader.maxDoc();
+      Terms terms = reader.terms(fieldName);
+      if (terms != null)
+        this.termsEnum = terms.iterator();
+    }
+
+    protected void collectDocs(BitSet bitSet) throws IOException {
+      assert termsEnum != null;
+      postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.NONE);
+      bitSet.or(postingsEnum);
+    }
+
+    protected void collectDocs(DocIdSetBuilder docSetBuilder) throws IOException {
+      assert termsEnum != null;
+      postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.NONE);
+      docSetBuilder.add(postingsEnum);
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/AbstractVisitingPrefixTreeQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/AbstractVisitingPrefixTreeQuery.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/AbstractVisitingPrefixTreeQuery.java
new file mode 100644
index 0000000..2237ca9
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/AbstractVisitingPrefixTreeQuery.java
@@ -0,0 +1,380 @@
+/*
+ * 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.prefix;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.SpatialRelation;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.TermsEnum;
+import org.apache.lucene.search.DocIdSet;
+import org.apache.lucene.spatial.prefix.tree.Cell;
+import org.apache.lucene.spatial.prefix.tree.CellIterator;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.util.BytesRef;
+
+/**
+ * Traverses a {@link SpatialPrefixTree} indexed field, using the template and
+ * visitor design patterns for subclasses to guide the traversal and collect
+ * matching documents.
+ * <p>
+ * Subclasses implement {@link #getDocIdSet(org.apache.lucene.index.LeafReaderContext)}
+ * by instantiating a custom {@link VisitorTemplate} subclass (i.e. an anonymous inner class)
+ * and implement the required methods.
+ *
+ * @lucene.internal
+ */
+public abstract class AbstractVisitingPrefixTreeQuery extends AbstractPrefixTreeQuery {
+
+  //Historical note: this code resulted from a refactoring of RecursivePrefixTreeQuery,
+  // which in turn came out of SOLR-2155
+
+  //This class perhaps could have been implemented in terms of FilteredTermsEnum & MultiTermQuery.
+  //  Maybe so for simple Intersects predicate but not for when we want to collect terms
+  //  differently depending on cell state like IsWithin and for fuzzy/accurate collection planned improvements.  At
+  //  least it would just make things more complicated.
+
+  protected final int prefixGridScanLevel;//at least one less than grid.getMaxLevels()
+
+  public AbstractVisitingPrefixTreeQuery(Shape queryShape, String fieldName, SpatialPrefixTree grid,
+                                         int detailLevel, int prefixGridScanLevel) {
+    super(queryShape, fieldName, grid, detailLevel);
+    this.prefixGridScanLevel = Math.max(0, Math.min(prefixGridScanLevel, grid.getMaxLevels() - 1));
+    assert detailLevel <= grid.getMaxLevels();
+  }
+
+  /**
+   * An abstract class designed to make it easy to implement predicates or
+   * other operations on a {@link SpatialPrefixTree} indexed field. An instance
+   * of this class is not designed to be re-used across LeafReaderContext
+   * instances so simply create a new one per-leaf.
+   * The {@link #getDocIdSet()} method here starts the work. It first checks
+   * that there are indexed terms; if not it quickly returns null. Then it calls
+   * {@link #start()} so a subclass can set up a return value, like an
+   * {@link org.apache.lucene.util.FixedBitSet}. Then it starts the traversal
+   * process, calling {@link #findSubCellsToVisit(org.apache.lucene.spatial.prefix.tree.Cell)}
+   * which by default finds the top cells that intersect {@code queryShape}. If
+   * there isn't an indexed cell for a corresponding cell returned for this
+   * method then it's short-circuited until it finds one, at which point
+   * {@link #visitPrefix(org.apache.lucene.spatial.prefix.tree.Cell)} is called. At
+   * some depths, of the tree, the algorithm switches to a scanning mode that
+   * calls {@link #visitScanned(org.apache.lucene.spatial.prefix.tree.Cell)}
+   * for each leaf cell found.
+   *
+   * @lucene.internal
+   */
+  public abstract class VisitorTemplate extends BaseTermsEnumTraverser {
+
+  /* Future potential optimizations:
+
+  * Can a polygon query shape be optimized / made-simpler at recursive depths
+    (e.g. intersection of shape + cell box)
+
+  * RE "scan" vs divide & conquer performance decision:
+    We should use termsEnum.docFreq() as an estimate on the number of places at
+    this depth.  It would be nice if termsEnum knew how many terms
+    start with the current term without having to repeatedly next() & test to find out.
+
+  * Perhaps don't do intermediate seek()'s to cells above detailLevel that have Intersects
+    relation because we won't be collecting those docs any way.  However seeking
+    does act as a short-circuit.  So maybe do some percent of the time or when the level
+    is above some threshold.
+
+  */
+
+    //
+    //  TODO MAJOR REFACTOR SIMPLIFICATION BASED ON TreeCellIterator  TODO
+    //
+
+    private VNode curVNode;//current pointer, derived from query shape
+    private BytesRef curVNodeTerm = new BytesRef();//curVNode.cell's term, without leaf. in main loop only
+
+    private BytesRef thisTerm;//the result of termsEnum.term()
+    private Cell indexedCell;//Cell wrapper of thisTerm. Always updated when thisTerm is.
+
+    public VisitorTemplate(LeafReaderContext context) throws IOException {
+      super(context);
+    }
+
+    public DocIdSet getDocIdSet() throws IOException {
+      assert curVNode == null : "Called more than once?";
+      if (termsEnum == null)
+        return null;
+      if (!nextTerm()) {//advances
+        return null;
+      }
+
+      curVNode = new VNode(null);
+      curVNode.reset(grid.getWorldCell());
+
+      start();
+
+      addIntersectingChildren();
+
+      main: while (thisTerm != null) {//terminates for other reasons too!
+
+        //Advance curVNode pointer
+        if (curVNode.children != null) {
+          //-- HAVE CHILDREN: DESCEND
+          assert curVNode.children.hasNext();//if we put it there then it has something
+          preSiblings(curVNode);
+          curVNode = curVNode.children.next();
+        } else {
+          //-- NO CHILDREN: ADVANCE TO NEXT SIBLING
+          VNode parentVNode = curVNode.parent;
+          while (true) {
+            if (parentVNode == null)
+              break main; // all done
+            if (parentVNode.children.hasNext()) {
+              //advance next sibling
+              curVNode = parentVNode.children.next();
+              break;
+            } else {
+              //reached end of siblings; pop up
+              postSiblings(parentVNode);
+              parentVNode.children = null;//GC
+              parentVNode = parentVNode.parent;
+            }
+          }
+        }
+
+        //Seek to curVNode's cell (or skip if termsEnum has moved beyond)
+        final int compare = indexedCell.compareToNoLeaf(curVNode.cell);
+        if (compare > 0) {
+          // The indexed cell is after; continue loop to next query cell
+          continue;
+        }
+        if (compare < 0) {
+          // The indexed cell is before; seek ahead to query cell:
+          //      Seek !
+          curVNode.cell.getTokenBytesNoLeaf(curVNodeTerm);
+          TermsEnum.SeekStatus seekStatus = termsEnum.seekCeil(curVNodeTerm);
+          if (seekStatus == TermsEnum.SeekStatus.END)
+            break; // all done
+          thisTerm = termsEnum.term();
+          indexedCell = grid.readCell(thisTerm, indexedCell);
+          if (seekStatus == TermsEnum.SeekStatus.NOT_FOUND) {
+            // Did we find a leaf of the cell we were looking for or something after?
+            if (!indexedCell.isLeaf() || indexedCell.compareToNoLeaf(curVNode.cell) != 0)
+              continue; // The indexed cell is after; continue loop to next query cell
+          }
+        }
+        // indexedCell == queryCell (disregarding leaf).
+
+        // If indexedCell is a leaf then there's no prefix (prefix sorts before) -- just visit and continue
+        if (indexedCell.isLeaf()) {
+          visitLeaf(indexedCell);//TODO or query cell? Though shouldn't matter.
+          if (!nextTerm()) break;
+          continue;
+        }
+        // If a prefix (non-leaf) then visit; see if we descend.
+        final boolean descend = visitPrefix(curVNode.cell);//need to use curVNode.cell not indexedCell
+        if (!nextTerm()) break;
+        // Check for adjacent leaf with the same prefix
+        if (indexedCell.isLeaf() && indexedCell.getLevel() == curVNode.cell.getLevel()) {
+          visitLeaf(indexedCell);//TODO or query cell? Though shouldn't matter.
+          if (!nextTerm()) break;
+        }
+
+
+        if (descend) {
+          addIntersectingChildren();
+        }
+
+      }//main loop
+
+      return finish();
+    }
+
+    /** Called initially, and whenever {@link #visitPrefix(org.apache.lucene.spatial.prefix.tree.Cell)}
+     * returns true. */
+    private void addIntersectingChildren() throws IOException {
+      assert thisTerm != null;
+      Cell cell = curVNode.cell;
+      if (cell.getLevel() >= detailLevel)
+        throw new IllegalStateException("Spatial logic error");
+
+      //Decide whether to continue to divide & conquer, or whether it's time to
+      // scan through terms beneath this cell.
+      // Scanning is a performance optimization trade-off.
+
+      //TODO use termsEnum.docFreq() as heuristic
+      boolean scan = cell.getLevel() >= prefixGridScanLevel;//simple heuristic
+
+      if (!scan) {
+        //Divide & conquer (ultimately termsEnum.seek())
+
+        Iterator<Cell> subCellsIter = findSubCellsToVisit(cell);
+        if (!subCellsIter.hasNext())//not expected
+          return;
+        curVNode.children = new VNodeCellIterator(subCellsIter, new VNode(curVNode));
+
+      } else {
+        //Scan (loop of termsEnum.next())
+
+        scan(detailLevel);
+      }
+    }
+
+    /**
+     * Called when doing a divide and conquer to find the next intersecting cells
+     * of the query shape that are beneath {@code cell}. {@code cell} is
+     * guaranteed to have an intersection and thus this must return some number
+     * of nodes.
+     */
+    protected CellIterator findSubCellsToVisit(Cell cell) {
+      return cell.getNextLevelCells(queryShape);
+    }
+
+    /**
+     * Scans ({@code termsEnum.next()}) terms until a term is found that does
+     * not start with curVNode's cell. If it finds a leaf cell or a cell at
+     * level {@code scanDetailLevel} then it calls {@link
+     * #visitScanned(org.apache.lucene.spatial.prefix.tree.Cell)}.
+     */
+    protected void scan(int scanDetailLevel) throws IOException {
+      //note: this can be a do-while instead in 6x; 5x has a back-compat with redundant leaves -- LUCENE-4942
+      while (curVNode.cell.isPrefixOf(indexedCell)) {
+        if (indexedCell.getLevel() == scanDetailLevel
+            || (indexedCell.getLevel() < scanDetailLevel && indexedCell.isLeaf())) {
+          visitScanned(indexedCell);
+        }
+        //advance
+        if (!nextTerm()) break;
+      }
+    }
+
+    private boolean nextTerm() throws IOException {
+      if ((thisTerm = termsEnum.next()) == null)
+        return false;
+      indexedCell = grid.readCell(thisTerm, indexedCell);
+      return true;
+    }
+
+    /** Used for {@link VNode#children}. */
+    private class VNodeCellIterator implements Iterator<VNode> {
+
+      final Iterator<Cell> cellIter;
+      private final VNode vNode;
+
+      VNodeCellIterator(Iterator<Cell> cellIter, VNode vNode) {
+        this.cellIter = cellIter;
+        this.vNode = vNode;
+      }
+
+      @Override
+      public boolean hasNext() {
+        return cellIter.hasNext();
+      }
+
+      @Override
+      public VNode next() {
+        assert hasNext();
+        vNode.reset(cellIter.next());
+        return vNode;
+      }
+
+      @Override
+      public void remove() {//it always removes
+      }
+    }
+
+    /** Called first to setup things. */
+    protected abstract void start() throws IOException;
+
+    /** Called last to return the result. */
+    protected abstract DocIdSet finish() throws IOException;
+
+    /**
+     * Visit an indexed non-leaf cell. The presence of a prefix cell implies
+     * there are leaf cells at further levels. The cell passed should have it's
+     * {@link org.apache.lucene.spatial.prefix.tree.Cell#getShapeRel()} set
+     * relative to the filtered shape.
+     *
+     * @param cell An intersecting cell; not a leaf.
+     * @return true to descend to more levels.
+     */
+    protected abstract boolean visitPrefix(Cell cell) throws IOException;
+
+    /**
+     * Called when an indexed leaf cell is found. An
+     * indexed leaf cell usually means associated documents won't be found at
+     * further detail levels.  However, if a document has
+     * multiple overlapping shapes at different resolutions, then this isn't true.
+     */
+    protected abstract void visitLeaf(Cell cell) throws IOException;
+
+    /**
+     * The cell is either indexed as a leaf or is the last level of detail. It
+     * might not even intersect the query shape, so be sure to check for that.
+     * The default implementation will check that and if passes then call
+     * {@link #visitLeaf(org.apache.lucene.spatial.prefix.tree.Cell)} or
+     * {@link #visitPrefix(org.apache.lucene.spatial.prefix.tree.Cell)}.
+     */
+    protected void visitScanned(Cell cell) throws IOException {
+      final SpatialRelation relate = cell.getShape().relate(queryShape);
+      if (relate.intersects()) {
+        cell.setShapeRel(relate);//just being pedantic
+        if (cell.isLeaf()) {
+          visitLeaf(cell);
+        } else {
+          visitPrefix(cell);
+        }
+      }
+    }
+
+    protected void preSiblings(VNode vNode) throws IOException {
+    }
+
+    protected void postSiblings(VNode vNode) throws IOException {
+    }
+  }//class VisitorTemplate
+
+  /**
+   * A visitor node/cell found via the query shape for {@link VisitorTemplate}.
+   * Sometimes these are reset(cell). It's like a LinkedList node but forms a
+   * tree.
+   *
+   * @lucene.internal
+   */
+  protected static class VNode {
+    //Note: The VNode tree adds more code to debug/maintain v.s. a flattened
+    // LinkedList that we used to have. There is more opportunity here for
+    // custom behavior (see preSiblings & postSiblings) but that's not
+    // leveraged yet. Maybe this is slightly more GC friendly.
+
+    final VNode parent;//only null at the root
+    Iterator<VNode> children;//null, then sometimes set, then null
+    Cell cell;//not null (except initially before reset())
+
+    /**
+     * call reset(cell) after to set the cell.
+     */
+    VNode(VNode parent) { // remember to call reset(cell) after
+      this.parent = parent;
+    }
+
+    void reset(Cell cell) {
+      assert cell != null;
+      this.cell = cell;
+      assert children == null;
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/BytesRefIteratorTokenStream.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/BytesRefIteratorTokenStream.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/BytesRefIteratorTokenStream.java
new file mode 100644
index 0000000..e724ab0
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/BytesRefIteratorTokenStream.java
@@ -0,0 +1,72 @@
+/*
+ * 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.prefix;
+
+import java.io.IOException;
+
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.tokenattributes.BytesTermAttribute;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.BytesRefIterator;
+
+/**
+ * A TokenStream used internally by {@link org.apache.lucene.spatial.prefix.PrefixTreeStrategy}.
+ *
+ * This is modelled after {@link org.apache.lucene.analysis.LegacyNumericTokenStream}.
+ *
+ * @lucene.internal
+ */
+class BytesRefIteratorTokenStream extends TokenStream {
+
+  public BytesRefIterator getBytesRefIterator() {
+    return bytesIter;
+  }
+
+  public BytesRefIteratorTokenStream setBytesRefIterator(BytesRefIterator iter) {
+    this.bytesIter = iter;
+    return this;
+  }
+
+  @Override
+  public void reset() throws IOException {
+    if (bytesIter == null)
+      throw new IllegalStateException("call setBytesRefIterator() before usage");
+  }
+
+  @Override
+  public final boolean incrementToken() throws IOException {
+    if (bytesIter == null)
+      throw new IllegalStateException("call setBytesRefIterator() before usage");
+
+    // get next
+    BytesRef bytes = bytesIter.next();
+    if (bytes == null) {
+      return false;
+    } else {
+      clearAttributes();
+      bytesAtt.setBytesRef(bytes);
+      //note: we don't bother setting posInc or type attributes.  There's no point to it.
+      return true;
+    }
+  }
+
+  //members
+  private final BytesTermAttribute bytesAtt = addAttribute(BytesTermAttribute.class);
+
+  private BytesRefIterator bytesIter = null; // null means not initialized
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/CellToBytesRefIterator.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/CellToBytesRefIterator.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/CellToBytesRefIterator.java
new file mode 100644
index 0000000..0b81b26
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/CellToBytesRefIterator.java
@@ -0,0 +1,49 @@
+/*
+ * 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.prefix;
+
+import java.util.Iterator;
+
+import org.apache.lucene.spatial.prefix.tree.Cell;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.BytesRefIterator;
+
+/**
+ * A reset'able {@link org.apache.lucene.util.BytesRefIterator} wrapper around
+ * an {@link java.util.Iterator} of {@link org.apache.lucene.spatial.prefix.tree.Cell}s.
+ *
+ * @see PrefixTreeStrategy#newCellToBytesRefIterator()
+ *
+ * @lucene.internal
+ */
+public class CellToBytesRefIterator implements BytesRefIterator {
+
+  protected Iterator<Cell> cellIter;
+  protected BytesRef bytesRef = new BytesRef();
+
+  public void reset(Iterator<Cell> cellIter) {
+    this.cellIter = cellIter;
+  }
+
+  @Override
+  public BytesRef next() {
+    if (!cellIter.hasNext()) {
+      return null;
+    }
+    return cellIter.next().getTokenBytesWithLeaf(bytesRef);
+  }
+}


[24/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test-files/data/simple-bbox.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test-files/data/simple-bbox.txt b/lucene/spatial-extras/src/test-files/data/simple-bbox.txt
new file mode 100644
index 0000000..fdbe163
--- /dev/null
+++ b/lucene/spatial-extras/src/test-files/data/simple-bbox.txt
@@ -0,0 +1,4 @@
+#id	name	shape
+C5	CenterAt5	ENVELOPE(-5, 5, 5, -5)
+C10	CenterAt10	ENVELOPE(-10, 10, 10, -10)
+NW15	NorthWest	ENVELOPE(15, 20, 20, 15)

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test-files/data/states-bbox.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test-files/data/states-bbox.txt b/lucene/spatial-extras/src/test-files/data/states-bbox.txt
new file mode 100644
index 0000000..6223192
--- /dev/null
+++ b/lucene/spatial-extras/src/test-files/data/states-bbox.txt
@@ -0,0 +1,52 @@
+#id	name	shape
+HI	Hawaii	ENVELOPE(-160.242406, -154.791096, 22.229120, 18.921786)
+WA	Washington	ENVELOPE(-124.732769, -116.919132, 48.999931, 45.543092)
+MT	Montana	ENVELOPE(-116.063531, -104.043072, 49.000026, 44.353639)
+ME	Maine	ENVELOPE(-71.087509, -66.969271, 47.453334, 43.091050)
+ND	North Dakota	ENVELOPE(-104.062991, -96.551931, 49.000026, 45.930822)
+SD	South Dakota	ENVELOPE(-104.061036, -96.439394, 45.943547, 42.488459)
+WY	Wyoming	ENVELOPE(-111.053428, -104.051705, 45.002793, 40.994289)
+WI	Wisconsin	ENVELOPE(-92.885397, -86.967712, 46.952479, 42.489152)
+ID	Idaho	ENVELOPE(-117.236921, -111.046771, 48.999950, 41.994599)
+VT	Vermont	ENVELOPE(-73.436000, -71.505372, 45.013351, 42.725852)
+MN	Minnesota	ENVELOPE(-97.229436, -89.530673, 49.371730, 43.498102)
+OR	Oregon	ENVELOPE(-124.559617, -116.470418, 46.236091, 41.987672)
+NH	New Hampshire	ENVELOPE(-72.553428, -70.734139, 45.301469, 42.698603)
+IA	Iowa	ENVELOPE(-96.640709, -90.142796, 43.501457, 40.371946)
+MA	Massachusetts	ENVELOPE(-73.498840, -69.917780, 42.886877, 41.238279)
+NE	Nebraska	ENVELOPE(-104.056219, -95.308697, 43.003062, 39.992595)
+NY	New York	ENVELOPE(-79.763235, -71.869986, 45.006138, 40.506003)
+PA	Pennsylvania	ENVELOPE(-80.526045, -74.700062, 42.267327, 39.719313)
+CT	Connecticut	ENVELOPE(-73.725237, -71.788249, 42.047428, 40.998392)
+RI	Rhode Island	ENVELOPE(-71.866678, -71.117132, 42.013713, 41.322769)
+NJ	New Jersey	ENVELOPE(-75.570234, -73.896148, 41.350573, 38.956682)
+IN	Indiana	ENVELOPE(-88.101490, -84.787446, 41.765540, 37.776224)
+NV	Nevada	ENVELOPE(-119.996324, -114.037392, 41.996637, 34.998914)
+UT	Utah	ENVELOPE(-114.047273, -109.043206, 42.002300, 36.991746)
+CA	California	ENVELOPE(-124.392638, -114.125230, 42.002191, 32.535781)
+OH	Ohio	ENVELOPE(-84.812070, -80.519996, 41.986872, 38.400511)
+IL	Illinois	ENVELOPE(-91.516284, -87.507909, 42.509363, 36.986822)
+DC	District of Columbia	ENVELOPE(-77.122328, -76.910904, 38.993541, 38.788234)
+DE	Delaware	ENVELOPE(-75.791094, -75.045623, 39.840119, 38.449602)
+WV	West Virginia	ENVELOPE(-82.647158, -77.727467, 40.637203, 37.204910)
+MD	Maryland	ENVELOPE(-79.489865, -75.045623, 39.725461, 37.970255)
+CO	Colorado	ENVELOPE(-109.055861, -102.037207, 41.003375, 36.988994)
+KY	Kentucky	ENVELOPE(-89.568231, -81.959575, 39.142063, 36.496570)
+KS	Kansas	ENVELOPE(-102.051535, -94.601224, 40.002987, 36.988875)
+VA	Virginia	ENVELOPE(-83.675177, -75.242219, 39.456998, 36.541623)
+MO	Missouri	ENVELOPE(-95.767479, -89.105034, 40.609784, 35.989656)
+AZ	Arizona	ENVELOPE(-114.821761, -109.045615, 37.003926, 31.335634)
+OK	Oklahoma	ENVELOPE(-102.997709, -94.428552, 37.001478, 33.621136)
+NC	North Carolina	ENVELOPE(-84.323773, -75.456580, 36.589767, 33.882164)
+TN	Tennessee	ENVELOPE(-90.305448, -81.652272, 36.679683, 34.988759)
+TX	Texas	ENVELOPE(-106.650062, -93.507389, 36.493912, 25.845557)
+NM	New Mexico	ENVELOPE(-109.051346, -102.997401, 36.999760, 31.343453)
+AL	Alabama	ENVELOPE(-88.472952, -84.894016, 35.016033, 30.233604)
+MS	Mississippi	ENVELOPE(-91.643682, -88.090468, 35.005041, 30.194935)
+GA	Georgia	ENVELOPE(-85.608960, -80.894753, 35.000366, 30.361291)
+SC	South Carolina	ENVELOPE(-83.350685, -78.579453, 35.208356, 32.068173)
+AR	Arkansas	ENVELOPE(-94.617257, -89.645479, 36.492811, 33.010151)
+LA	Louisiana	ENVELOPE(-94.041785, -89.021803, 33.023422, 28.939655)
+FL	Florida	ENVELOPE(-87.625711, -80.050911, 31.003157, 24.956376)
+MI	Michigan	ENVELOPE(-90.408200, -82.419836, 48.173795, 41.697494)
+AK	Alaska	ENVELOPE(-178.217598, -129.992235, 71.406235, 51.583032)


[47/50] [abbrv] lucene-solr git commit: make test less evil

Posted by ho...@apache.org.
make test less evil


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/2a7314b5
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/2a7314b5
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/2a7314b5

Branch: refs/heads/jira/SOLR-445
Commit: 2a7314b599e09d36e6fd9688306178d25c081256
Parents: 2264600
Author: Mike McCandless <mi...@apache.org>
Authored: Tue Mar 1 10:47:06 2016 -0500
Committer: Mike McCandless <mi...@apache.org>
Committed: Tue Mar 1 10:47:06 2016 -0500

----------------------------------------------------------------------
 .../core/src/test/org/apache/lucene/search/TestPointQueries.java   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2a7314b5/lucene/core/src/test/org/apache/lucene/search/TestPointQueries.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestPointQueries.java b/lucene/core/src/test/org/apache/lucene/search/TestPointQueries.java
index 9ce8cff..ef5af2b 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestPointQueries.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestPointQueries.java
@@ -498,7 +498,7 @@ public class TestPointQueries extends LuceneTestCase {
 
   @Nightly
   public void testRandomBinaryBig() throws Exception {
-    doTestRandomBinary(200000);
+    doTestRandomBinary(100000);
   }
 
   private void doTestRandomBinary(int count) throws Exception {


[35/50] [abbrv] lucene-solr git commit: SOLR-445: more deletion tests

Posted by ho...@apache.org.
SOLR-445: more deletion tests


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/546f142b
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/546f142b
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/546f142b

Branch: refs/heads/jira/SOLR-445
Commit: 546f142ba5980393c89f6a4eee53a2354b025745
Parents: cffca39
Author: Chris Hostetter <ho...@apache.org>
Authored: Mon Feb 29 16:45:45 2016 -0700
Committer: Chris Hostetter <ho...@apache.org>
Committed: Mon Feb 29 16:45:45 2016 -0700

----------------------------------------------------------------------
 .../cloud/TestTolerantUpdateProcessorCloud.java | 67 ++++++++++++++++----
 1 file changed, 53 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/546f142b/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java b/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
index 50afd33..38db3ac 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
@@ -58,6 +58,7 @@ import org.junit.ClassRule;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.rules.RuleChain;
 import org.junit.rules.TestRule;
@@ -73,12 +74,9 @@ import org.slf4j.LoggerFactory;
  * <p>
  * <b>NOTE:</b> This test sets up a static instance of MiniSolrCloud with a single collection 
  * and several clients pointed at specific nodes. These are all re-used across multiple test methods, 
- * and assumesthat the state of the cluster is healthy.
+ * and assumes that the state of the cluster is healthy.
  * </p>
  *
- * nocommit: test deletions that fail (and are ignored because of maxErrors) as well...
- *  - nocommit: DBQ with malformed query
- *  - nocommit: delete by id with incorrect version (optimistic concurrency fail)
  *
  * nocommit: what about shard splitting and "sub shard leaders" ? ...
  * (no idea if/how that affects things, but i notice lots of logic in DistributedUpdateProcessor along 
@@ -296,6 +294,7 @@ public class TestTolerantUpdateProcessorCloud extends LuceneTestCase {
   }
 
   //
+  @Ignore("nocommit: need to implement tolerante response merging in cloud client")
   public void testVariousDeletesViaCloudClient() throws Exception {
     testVariousDeletes(CLOUD_CLIENT);
   }
@@ -340,35 +339,74 @@ public class TestTolerantUpdateProcessorCloud extends LuceneTestCase {
                                  delIErr(id));
     }
     
-    // attempt to delete multiple doc ids that should all fail because of oportunistic concurrency constraints
+    // multiple failed deletes from the same shard (via oportunistic concurrent w/ bogus ids)
+    rsp = update(params("update.chain", "tolerant-chain-max-errors-10",
+                        "commit", "true")
+                 ).deleteById(S_ONE_PRE + "X", +1L).deleteById(S_ONE_PRE + "Y", +1L).process(client);
+    assertEquals(0, rsp.getStatus());
+    assertUpdateTolerantErrors("failed oportunistic concurrent delete by id for 2 bogus docs", rsp,
+                               delIErr(S_ONE_PRE + "X"), delIErr(S_ONE_PRE + "Y"));
+    assertQueryDocIds(client, true, docId1, docId2);
+    
+    // multiple failed deletes from the diff shards due to oportunistic concurrency constraints
     rsp = update(params("update.chain", "tolerant-chain-max-errors-10",
                         "commit", "true")).deleteById(docId2, -1L).deleteById(docId1, -1L).process(client);
     assertEquals(0, rsp.getStatus());
     assertUpdateTolerantErrors("failed oportunistic concurrent delete by id for 2 docs", rsp,
                                delIErr(docId1), delIErr(docId2));
-    
-    // nocommit: deleteByQuery using malformed query
+    assertQueryDocIds(client, true, docId1, docId2);
+
+    // deleteByQuery using malformed query (fail)
     rsp = update(params("update.chain", "tolerant-chain-max-errors-10",
                         "commit", "true")).deleteByQuery("bogus_field:foo").process(client);
     assertEquals(0, rsp.getStatus());
     assertUpdateTolerantErrors("failed oportunistic concurrent delete by query", rsp,
                                delQErr("bogus_field:foo"));
+    assertQueryDocIds(client, true, docId1, docId2);
 
-    // nocommit: mix 2 deleteByQuery, one malformed (fail) one not but doesn't match anything (ok)
-    
-    // nocommit: mix 2 deleteById using _version_=-1, one for real doc1 (fail), one for bogus id (ok)
+    // mix 2 deleteByQuery, one malformed (fail), one that doesn't match anything (ok)
+    rsp = update(params("update.chain", "tolerant-chain-max-errors-10",
+                        "commit", "true")
+                 ).deleteByQuery("bogus_field:foo").deleteByQuery("foo_i:23").process(client);
+    assertEquals(0, rsp.getStatus());
+    assertUpdateTolerantErrors("failed oportunistic concurrent delete by query", rsp,
+                               delQErr("bogus_field:foo"));
+    assertQueryDocIds(client, true, docId1, docId2);
     
-    // nocommit: mix 2 deleteById using _version_=1, one for real doc1 (ok, deleted), one for bogus id (fail)
-
-    // nocommit: assertQueryDocIds doc2 only doc left
+    // mix 2 deleteById using _version_=-1, one for real doc1 (fail), one for bogus id (ok)
+    rsp = update(params("update.chain", "tolerant-chain-max-errors-10",
+                        "commit", "true")
+                 ).deleteById(docId1, -1L).deleteById("bogus", -1L).process(client);
+    assertEquals(0, rsp.getStatus());
+    assertUpdateTolerantErrors("failed oportunistic concurrent delete by id: exists", rsp,
+                               delIErr(docId1));
+    assertQueryDocIds(client, true, docId1, docId2);
     
-    // nocommit: test multiple failed deletes from the same shard (bogus ids are fine)
+    // mix 2 deleteById using _version_=1, one for real doc1 (ok, deleted), one for bogus id (fail)
+    rsp = update(params("update.chain", "tolerant-chain-max-errors-10",
+                        "commit", "true")
+                 ).deleteById(docId1, +1L).deleteById("bogusId", +1L).process(client);
+    assertEquals(0, rsp.getStatus());
+    assertUpdateTolerantErrors("failed oportunistic concurrent delete by id: bogus", rsp,
+                               delIErr("bogusId"));
+    assertQueryDocIds(client, false, docId1);
+    assertQueryDocIds(client, true, docId2);
     
+    // mix 2 deleteByQuery, one malformed (fail), one that alctaully removes some docs (ok)
+    assertQueryDocIds(client, true, docId2);
+    rsp = update(params("update.chain", "tolerant-chain-max-errors-10",
+                        "commit", "true")
+                 ).deleteByQuery("bogus_field:foo").deleteByQuery("foo_i:1976").process(client);
+    assertEquals(0, rsp.getStatus());
+    assertUpdateTolerantErrors("failed oportunistic concurrent delete by query", rsp,
+                               delQErr("bogus_field:foo"));
+    assertQueryDocIds(client, false, docId2);
 
   }
 
   
   //
+  @Ignore("nocommit: need to implement tolerante response merging in cloud client")
   public void testVariousAddsViaCloudClient() throws Exception {
     testVariousAdds(CLOUD_CLIENT);
   }
@@ -595,6 +633,7 @@ public class TestTolerantUpdateProcessorCloud extends LuceneTestCase {
   }
 
   //
+  @Ignore("nocommit: need to implement tolerante response merging in cloud client")
   public void testAddsMixedWithDeletesViaCloudClient() throws Exception {
     testAddsMixedWithDeletes(CLOUD_CLIENT);
   }


[44/50] [abbrv] lucene-solr git commit: also test points in TestUtil.checkReader

Posted by ho...@apache.org.
also test points in TestUtil.checkReader


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/37cf2289
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/37cf2289
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/37cf2289

Branch: refs/heads/jira/SOLR-445
Commit: 37cf22895f1e6b0ecccd457f639bd3558814e58b
Parents: 502b880
Author: Mike McCandless <mi...@apache.org>
Authored: Tue Mar 1 05:01:19 2016 -0500
Committer: Mike McCandless <mi...@apache.org>
Committed: Tue Mar 1 05:01:19 2016 -0500

----------------------------------------------------------------------
 lucene/test-framework/src/java/org/apache/lucene/util/TestUtil.java | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/37cf2289/lucene/test-framework/src/java/org/apache/lucene/util/TestUtil.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/util/TestUtil.java b/lucene/test-framework/src/java/org/apache/lucene/util/TestUtil.java
index e969b4c..c1da780 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/util/TestUtil.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/util/TestUtil.java
@@ -338,6 +338,7 @@ public final class TestUtil {
     CheckIndex.testStoredFields(codecReader, infoStream, true);
     CheckIndex.testTermVectors(codecReader, infoStream, false, crossCheckTermVectors, true);
     CheckIndex.testDocValues(codecReader, infoStream, true);
+    CheckIndex.testPoints(codecReader, infoStream, true);
     
     // some checks really against the reader API
     checkReaderSanity(reader);


[17/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/CellToBytesRefIterator.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/CellToBytesRefIterator.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/CellToBytesRefIterator.java
deleted file mode 100644
index 0b81b26..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/CellToBytesRefIterator.java
+++ /dev/null
@@ -1,49 +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.prefix;
-
-import java.util.Iterator;
-
-import org.apache.lucene.spatial.prefix.tree.Cell;
-import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.BytesRefIterator;
-
-/**
- * A reset'able {@link org.apache.lucene.util.BytesRefIterator} wrapper around
- * an {@link java.util.Iterator} of {@link org.apache.lucene.spatial.prefix.tree.Cell}s.
- *
- * @see PrefixTreeStrategy#newCellToBytesRefIterator()
- *
- * @lucene.internal
- */
-public class CellToBytesRefIterator implements BytesRefIterator {
-
-  protected Iterator<Cell> cellIter;
-  protected BytesRef bytesRef = new BytesRef();
-
-  public void reset(Iterator<Cell> cellIter) {
-    this.cellIter = cellIter;
-  }
-
-  @Override
-  public BytesRef next() {
-    if (!cellIter.hasNext()) {
-      return null;
-    }
-    return cellIter.next().getTokenBytesWithLeaf(bytesRef);
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/ContainsPrefixTreeQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/ContainsPrefixTreeQuery.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/ContainsPrefixTreeQuery.java
deleted file mode 100644
index 0046378..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/ContainsPrefixTreeQuery.java
+++ /dev/null
@@ -1,362 +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.prefix;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.SpatialRelation;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.PostingsEnum;
-import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.DocIdSet;
-import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.spatial.prefix.tree.Cell;
-import org.apache.lucene.spatial.prefix.tree.CellIterator;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.util.Bits;
-import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.RamUsageEstimator;
-import org.apache.lucene.util.SentinelIntSet;
-
-/**
- * Finds docs where its indexed shape {@link org.apache.lucene.spatial.query.SpatialOperation#Contains
- * CONTAINS} the query shape. For use on {@link RecursivePrefixTreeStrategy}.
- *
- * @lucene.experimental
- */
-public class ContainsPrefixTreeQuery extends AbstractPrefixTreeQuery {
-
-  /**
-   * If the spatial data for a document is comprised of multiple overlapping or adjacent parts,
-   * it might fail to match a query shape when doing the CONTAINS predicate when the sum of
-   * those shapes contain the query shape but none do individually.  Set this to false to
-   * increase performance if you don't care about that circumstance (such as if your indexed
-   * data doesn't even have such conditions).  See LUCENE-5062.
-   */
-  protected final boolean multiOverlappingIndexedShapes;
-
-  public ContainsPrefixTreeQuery(Shape queryShape, String fieldName, SpatialPrefixTree grid, int detailLevel, boolean multiOverlappingIndexedShapes) {
-    super(queryShape, fieldName, grid, detailLevel);
-    this.multiOverlappingIndexedShapes = multiOverlappingIndexedShapes;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (!super.equals(o))
-      return false;
-    return multiOverlappingIndexedShapes == ((ContainsPrefixTreeQuery)o).multiOverlappingIndexedShapes;
-  }
-
-  @Override
-  public int hashCode() {
-    return super.hashCode() + (multiOverlappingIndexedShapes ? 1 : 0);
-  }
-
-  @Override
-  public String toString(String field) {
-    return getClass().getSimpleName() + "(" +
-        "fieldName=" + fieldName + "," +
-        "queryShape=" + queryShape + "," +
-        "detailLevel=" + detailLevel + "," +
-        "multiOverlappingIndexedShapes=" + multiOverlappingIndexedShapes +
-        ")";
-  }
-
-  @Override
-  protected DocIdSet getDocIdSet(LeafReaderContext context) throws IOException {
-    return new ContainsVisitor(context).visit(grid.getWorldCell(), null);
-  }
-
-  private class ContainsVisitor extends BaseTermsEnumTraverser {
-
-    public ContainsVisitor(LeafReaderContext context) throws IOException {
-      super(context);
-      if (termsEnum != null) {
-        nextTerm();//advance to first
-      }
-    }
-
-    BytesRef seekTerm = new BytesRef();//temp; see seek()
-    BytesRef thisTerm;//current term in termsEnum
-    Cell indexedCell;//the cell wrapper around thisTerm
-
-    /** This is the primary algorithm; recursive.  Returns null if finds none. */
-    private SmallDocSet visit(Cell cell, Bits acceptContains) throws IOException {
-
-      if (thisTerm == null)//signals all done
-        return null;
-
-      // Get the AND of all child results (into combinedSubResults)
-      SmallDocSet combinedSubResults = null;
-      //   Optimization: use null subCellsFilter when we know cell is within the query shape.
-      Shape subCellsFilter = queryShape;
-      if (cell.getLevel() != 0 && ((cell.getShapeRel() == null || cell.getShapeRel() == SpatialRelation.WITHIN))) {
-        subCellsFilter = null;
-        assert cell.getShape().relate(queryShape) == SpatialRelation.WITHIN;
-      }
-      CellIterator subCells = cell.getNextLevelCells(subCellsFilter);
-      while (subCells.hasNext()) {
-        Cell subCell = subCells.next();
-        if (!seek(subCell)) {
-          combinedSubResults = null;
-        } else if (subCell.getLevel() == detailLevel) {
-          combinedSubResults = getDocs(subCell, acceptContains);
-        } else if (!multiOverlappingIndexedShapes &&
-            subCell.getShapeRel() == SpatialRelation.WITHIN) {
-          combinedSubResults = getLeafDocs(subCell, acceptContains);
-        } else {
-          //OR the leaf docs with all child results
-          SmallDocSet leafDocs = getLeafDocs(subCell, acceptContains);
-          SmallDocSet subDocs = visit(subCell, acceptContains); //recursion
-          combinedSubResults = union(leafDocs, subDocs);
-        }
-
-        if (combinedSubResults == null)
-          break;
-        acceptContains = combinedSubResults;//has the 'AND' effect on next iteration
-      }
-
-      return combinedSubResults;
-    }
-
-    private boolean seek(Cell cell) throws IOException {
-      if (thisTerm == null)
-        return false;
-      final int compare = indexedCell.compareToNoLeaf(cell);
-      if (compare > 0) {
-        return false;//leap-frog effect
-      } else if (compare == 0) {
-        return true; // already there!
-      } else {//compare > 0
-        //seek!
-        seekTerm = cell.getTokenBytesNoLeaf(seekTerm);
-        final TermsEnum.SeekStatus seekStatus = termsEnum.seekCeil(seekTerm);
-        if (seekStatus == TermsEnum.SeekStatus.END) {
-          thisTerm = null;//all done
-          return false;
-        }
-        thisTerm = termsEnum.term();
-        indexedCell = grid.readCell(thisTerm, indexedCell);
-        if (seekStatus == TermsEnum.SeekStatus.FOUND) {
-          return true;
-        }
-        return indexedCell.isLeaf() && indexedCell.compareToNoLeaf(cell) == 0;
-      }
-    }
-
-    /** Get prefix & leaf docs at this cell. */
-    private SmallDocSet getDocs(Cell cell, Bits acceptContains) throws IOException {
-      assert indexedCell.compareToNoLeaf(cell) == 0;
-      //called when we've reached detailLevel.
-      if (indexedCell.isLeaf()) {//only a leaf
-        SmallDocSet result = collectDocs(acceptContains);
-        nextTerm();
-        return result;
-      } else {
-        SmallDocSet docsAtPrefix = collectDocs(acceptContains);
-        if (!nextTerm()) {
-          return docsAtPrefix;
-        }
-        //collect leaf too
-        if (indexedCell.isLeaf() && indexedCell.compareToNoLeaf(cell) == 0) {
-          SmallDocSet docsAtLeaf = collectDocs(acceptContains);
-          nextTerm();
-          return union(docsAtPrefix, docsAtLeaf);
-        } else {
-          return docsAtPrefix;
-        }
-      }
-    }
-
-    /** Gets docs on the leaf of the given cell, _if_ there is a leaf cell, otherwise null. */
-    private SmallDocSet getLeafDocs(Cell cell, Bits acceptContains) throws IOException {
-      assert indexedCell.compareToNoLeaf(cell) == 0;
-      //Advance past prefix if we're at a prefix; return null if no leaf
-      if (!indexedCell.isLeaf()) {
-        if (!nextTerm() || !indexedCell.isLeaf() || indexedCell.getLevel() != cell.getLevel()) {
-          return null;
-        }
-      }
-      SmallDocSet result = collectDocs(acceptContains);
-      nextTerm();
-      return result;
-    }
-
-    private boolean nextTerm() throws IOException {
-      if ((thisTerm = termsEnum.next()) == null)
-        return false;
-      indexedCell = grid.readCell(thisTerm, indexedCell);
-      return true;
-    }
-
-    private SmallDocSet union(SmallDocSet aSet, SmallDocSet bSet) {
-      if (bSet != null) {
-        if (aSet == null)
-          return bSet;
-        return aSet.union(bSet);//union is 'or'
-      }
-      return aSet;
-    }
-
-    private SmallDocSet collectDocs(Bits acceptContains) throws IOException {
-      SmallDocSet set = null;
-
-      postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.NONE);
-      int docid;
-      while ((docid = postingsEnum.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
-        if (acceptContains != null && acceptContains.get(docid) == false) {
-          continue;
-        }
-        if (set == null) {
-          int size = termsEnum.docFreq();
-          if (size <= 0)
-            size = 16;
-          set = new SmallDocSet(size);
-        }
-        set.set(docid);
-      }
-      return set;
-    }
-
-  }//class ContainsVisitor
-
-  /** A hash based mutable set of docIds. If this were Solr code then we might
-   * use a combination of HashDocSet and SortedIntDocSet instead. */
-  // TODO use DocIdSetBuilder?
-  private static class SmallDocSet extends DocIdSet implements Bits {
-
-    private final SentinelIntSet intSet;
-    private int maxInt = 0;
-
-    public SmallDocSet(int size) {
-      intSet = new SentinelIntSet(size, -1);
-    }
-
-    @Override
-    public boolean get(int index) {
-      return intSet.exists(index);
-    }
-
-    public void set(int index) {
-      intSet.put(index);
-      if (index > maxInt)
-        maxInt = index;
-    }
-
-    /** Largest docid. */
-    @Override
-    public int length() {
-      return maxInt;
-    }
-
-    /** Number of docids. */
-    public int size() {
-      return intSet.size();
-    }
-
-    /** NOTE: modifies and returns either "this" or "other" */
-    public SmallDocSet union(SmallDocSet other) {
-      SmallDocSet bigger;
-      SmallDocSet smaller;
-      if (other.intSet.size() > this.intSet.size()) {
-        bigger = other;
-        smaller = this;
-      } else {
-        bigger = this;
-        smaller = other;
-      }
-      //modify bigger
-      for (int v : smaller.intSet.keys) {
-        if (v == smaller.intSet.emptyVal)
-          continue;
-        bigger.set(v);
-      }
-      return bigger;
-    }
-
-    @Override
-    public Bits bits() throws IOException {
-      //if the # of docids is super small, return null since iteration is going
-      // to be faster
-      return size() > 4 ? this : null;
-    }
-
-    @Override
-    public DocIdSetIterator iterator() throws IOException {
-      if (size() == 0)
-        return null;
-      //copy the unsorted values to a new array then sort them
-      int d = 0;
-      final int[] docs = new int[intSet.size()];
-      for (int v : intSet.keys) {
-        if (v == intSet.emptyVal)
-          continue;
-        docs[d++] = v;
-      }
-      assert d == intSet.size();
-      final int size = d;
-
-      //sort them
-      Arrays.sort(docs, 0, size);
-
-      return new DocIdSetIterator() {
-        int idx = -1;
-        @Override
-        public int docID() {
-          if (idx < 0) {
-            return -1;
-          } else if (idx < size) {
-            return docs[idx];
-          } else {
-            return NO_MORE_DOCS;
-          }
-        }
-
-        @Override
-        public int nextDoc() throws IOException {
-          if (++idx < size)
-            return docs[idx];
-          return NO_MORE_DOCS;
-        }
-
-        @Override
-        public int advance(int target) throws IOException {
-          //for this small set this is likely faster vs. a binary search
-          // into the sorted array
-          return slowAdvance(target);
-        }
-
-        @Override
-        public long cost() {
-          return size;
-        }
-      };
-    }
-
-    @Override
-    public long ramBytesUsed() {
-      return RamUsageEstimator.alignObjectSize(
-            RamUsageEstimator.NUM_BYTES_OBJECT_REF
-          + Integer.BYTES)
-          + intSet.ramBytesUsed();
-    }
-
-  }//class SmallDocSet
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java
deleted file mode 100644
index c6700cd..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java
+++ /dev/null
@@ -1,310 +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.prefix;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.SpatialRelation;
-import org.apache.lucene.index.IndexReaderContext;
-import org.apache.lucene.spatial.prefix.tree.Cell;
-import org.apache.lucene.spatial.prefix.tree.CellIterator;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.util.ArrayUtil;
-import org.apache.lucene.util.Bits;
-
-/**
- * Computes spatial facets in two dimensions as a grid of numbers.  The data is often visualized as a so-called
- * "heatmap", hence the name.
- *
- * @lucene.experimental
- */
-public class HeatmapFacetCounter {
-  //TODO where should this code live? It could go to PrefixTreeFacetCounter, or maybe here in its own class is fine.
-
-  /** Maximum number of supported rows (or columns). */
-  public static final int MAX_ROWS_OR_COLUMNS = (int) Math.sqrt(ArrayUtil.MAX_ARRAY_LENGTH);
-  static {
-    Math.multiplyExact(MAX_ROWS_OR_COLUMNS, MAX_ROWS_OR_COLUMNS);//will throw if doesn't stay within integer
-  }
-
-  /** Response structure */
-  public static class Heatmap {
-    public final int columns;
-    public final int rows;
-    public final int[] counts;//in order of 1st column (all rows) then 2nd column (all rows) etc.
-    public final Rectangle region;
-
-    public Heatmap(int columns, int rows, Rectangle region) {
-      this.columns = columns;
-      this.rows = rows;
-      this.counts = new int[columns * rows];
-      this.region = region;
-    }
-
-    public int getCount(int x, int y) {
-      return counts[x * rows + y];
-    }
-
-    @Override
-    public String toString() {
-      return "Heatmap{" + columns + "x" + rows + " " + region + '}';
-    }
-  }
-
-  /**
-   * Calculates spatial 2D facets (aggregated counts) in a grid, sometimes called a heatmap.
-   * Facet computation is implemented by navigating the underlying indexed terms efficiently. If you don't know exactly
-   * what facetLevel to go to for a given input box but you have some sense of how many cells there should be relative
-   * to the size of the shape, then consider using the logic that {@link org.apache.lucene.spatial.prefix.PrefixTreeStrategy}
-   * uses when approximating what level to go to when indexing a shape given a distErrPct.
-   *
-   * @param context the IndexReader's context
-   * @param topAcceptDocs a Bits to limit counted docs.  If null, live docs are counted.
-   * @param inputShape the shape to gather grid squares for; typically a {@link Rectangle}.
-   *                   The <em>actual</em> heatmap area will usually be larger since the cells on the edge that overlap
-   *                   are returned. We always return a rectangle of integers even if the inputShape isn't a rectangle
-   *                   -- the non-intersecting cells will all be 0.
-   *                   If null is given, the entire world is assumed.
-   * @param facetLevel the target depth (detail) of cells.
-   * @param maxCells the maximum number of cells to return. If the cells exceed this count, an
-   */
-  public static Heatmap calcFacets(PrefixTreeStrategy strategy, IndexReaderContext context, Bits topAcceptDocs,
-                                   Shape inputShape, final int facetLevel, int maxCells) throws IOException {
-    if (maxCells > (MAX_ROWS_OR_COLUMNS * MAX_ROWS_OR_COLUMNS)) {
-      throw new IllegalArgumentException("maxCells (" + maxCells + ") should be <= " + MAX_ROWS_OR_COLUMNS);
-    }
-    if (inputShape == null) {
-      inputShape = strategy.getSpatialContext().getWorldBounds();
-    }
-    final Rectangle inputRect = inputShape.getBoundingBox();
-    //First get the rect of the cell at the bottom-left at depth facetLevel
-    final SpatialPrefixTree grid = strategy.getGrid();
-    final SpatialContext ctx = grid.getSpatialContext();
-    final Point cornerPt = ctx.makePoint(inputRect.getMinX(), inputRect.getMinY());
-    final CellIterator cellIterator = grid.getTreeCellIterator(cornerPt, facetLevel);
-    Cell cornerCell = null;
-    while (cellIterator.hasNext()) {
-      cornerCell = cellIterator.next();
-    }
-    assert cornerCell != null && cornerCell.getLevel() == facetLevel : "Cell not at target level: " + cornerCell;
-    final Rectangle cornerRect = (Rectangle) cornerCell.getShape();
-    assert cornerRect.hasArea();
-    //Now calculate the number of columns and rows necessary to cover the inputRect
-    double heatMinX = cornerRect.getMinX();//note: we might change this below...
-    final double cellWidth = cornerRect.getWidth();
-    final Rectangle worldRect = ctx.getWorldBounds();
-    final int columns = calcRowsOrCols(cellWidth, heatMinX, inputRect.getWidth(), inputRect.getMinX(), worldRect.getWidth());
-    final double heatMinY = cornerRect.getMinY();
-    final double cellHeight = cornerRect.getHeight();
-    final int rows = calcRowsOrCols(cellHeight, heatMinY, inputRect.getHeight(), inputRect.getMinY(), worldRect.getHeight());
-    assert rows > 0 && columns > 0;
-    if (columns > MAX_ROWS_OR_COLUMNS || rows > MAX_ROWS_OR_COLUMNS || columns * rows > maxCells) {
-      throw new IllegalArgumentException(
-          "Too many cells (" + columns + " x " + rows + ") for level " + facetLevel + " shape " + inputRect);
-    }
-
-    //Create resulting heatmap bounding rectangle & Heatmap object.
-    final double halfCellWidth = cellWidth / 2.0;
-    // if X world-wraps, use world bounds' range
-    if (columns * cellWidth + halfCellWidth > worldRect.getWidth()) {
-      heatMinX = worldRect.getMinX();
-    }
-    double heatMaxX = heatMinX + columns * cellWidth;
-    if (Math.abs(heatMaxX - worldRect.getMaxX()) < halfCellWidth) {//numeric conditioning issue
-      heatMaxX = worldRect.getMaxX();
-    } else if (heatMaxX > worldRect.getMaxX()) {//wraps dateline (won't happen if !geo)
-      heatMaxX = heatMaxX - worldRect.getMaxX() +  worldRect.getMinX();
-    }
-    final double halfCellHeight = cellHeight / 2.0;
-    double heatMaxY = heatMinY + rows * cellHeight;
-    if (Math.abs(heatMaxY - worldRect.getMaxY()) < halfCellHeight) {//numeric conditioning issue
-      heatMaxY = worldRect.getMaxY();
-    }
-
-    final Heatmap heatmap = new Heatmap(columns, rows, ctx.makeRectangle(heatMinX, heatMaxX, heatMinY, heatMaxY));
-
-    //All ancestor cell counts (of facetLevel) will be captured during facet visiting and applied later. If the data is
-    // just points then there won't be any ancestors.
-    //Facet count of ancestors covering all of the heatmap:
-    int[] allCellsAncestorCount = new int[1]; // single-element array so it can be accumulated in the inner class
-    //All other ancestors:
-    Map<Rectangle,Integer> ancestors = new HashMap<>();
-
-    //Now lets count some facets!
-    PrefixTreeFacetCounter.compute(strategy, context, topAcceptDocs, inputShape, facetLevel,
-        new PrefixTreeFacetCounter.FacetVisitor() {
-      @Override
-      public void visit(Cell cell, int count) {
-        final double heatMinX = heatmap.region.getMinX();
-        final Rectangle rect = (Rectangle) cell.getShape();
-        if (cell.getLevel() == facetLevel) {//heatmap level; count it directly
-          //convert to col & row
-          int column;
-          if (rect.getMinX() >= heatMinX) {
-            column = (int) Math.round((rect.getMinX() - heatMinX) / cellWidth);
-          } else { // due to dateline wrap
-            column = (int) Math.round((rect.getMinX() + 360 - heatMinX) / cellWidth);
-          }
-          int row = (int) Math.round((rect.getMinY() - heatMinY) / cellHeight);
-          //note: unfortunately, it's possible for us to visit adjacent cells to the heatmap (if the SpatialPrefixTree
-          // allows adjacent cells to overlap on the seam), so we need to skip them
-          if (column < 0 || column >= heatmap.columns || row < 0 || row >= heatmap.rows) {
-            return;
-          }
-          // increment
-          heatmap.counts[column * heatmap.rows + row] += count;
-
-        } else if (rect.relate(heatmap.region) == SpatialRelation.CONTAINS) {//containing ancestor
-          allCellsAncestorCount[0] += count;
-
-        } else { // ancestor
-          // note: not particularly efficient (possible put twice, and Integer wrapper); oh well
-          Integer existingCount = ancestors.put(rect, count);
-          if (existingCount != null) {
-            ancestors.put(rect, count + existingCount);
-          }
-        }
-      }
-    });
-
-    //Update the heatmap counts with ancestor counts
-
-    // Apply allCellsAncestorCount
-    if (allCellsAncestorCount[0] > 0) {
-      for (int i = 0; i < heatmap.counts.length; i++) {
-        heatmap.counts[i] += allCellsAncestorCount[0];
-      }
-    }
-
-    // Apply ancestors
-    //  note: This approach isn't optimized for a ton of ancestor cells. We'll potentially increment the same cells
-    //    multiple times in separate passes if any ancestors overlap. IF this poses a problem, we could optimize it
-    //    with additional complication by keeping track of intervals in a sorted tree structure (possible TreeMap/Set)
-    //    and iterate them cleverly such that we just make one pass at this stage.
-
-    int[] pair = new int[2];//output of intersectInterval
-    for (Map.Entry<Rectangle, Integer> entry : ancestors.entrySet()) {
-      Rectangle rect = entry.getKey();
-      final int count = entry.getValue();
-      //note: we approach this in a way that eliminates int overflow/underflow (think huge cell, tiny heatmap)
-      intersectInterval(heatMinY, heatMaxY, cellHeight, rows, rect.getMinY(), rect.getMaxY(), pair);
-      final int startRow = pair[0];
-      final int endRow = pair[1];
-
-      if (!heatmap.region.getCrossesDateLine()) {
-        intersectInterval(heatMinX, heatMaxX, cellWidth, columns, rect.getMinX(), rect.getMaxX(), pair);
-        final int startCol = pair[0];
-        final int endCol = pair[1];
-        incrementRange(heatmap, startCol, endCol, startRow, endRow, count);
-
-      } else {
-        //left half of dateline:
-        if (rect.getMaxX() >= heatMinX) {
-          final int leftColumns = (int) Math.round((180 - heatMinX) / cellWidth) + 1;
-          intersectInterval(heatMinX, 180, cellWidth, leftColumns, rect.getMinX(), rect.getMaxX(), pair);
-          final int startCol = pair[0];
-          final int endCol = pair[1];
-          incrementRange(heatmap, startCol, endCol, startRow, endRow, count);
-        }
-        //right half of dateline
-        if (rect.getMinY() <= heatMaxX) {
-          final int rightColumns = (int) Math.round(heatMaxX / cellWidth) + 1;
-          intersectInterval(0, heatMaxX, cellWidth, rightColumns, rect.getMinX(), rect.getMaxX(), pair);
-          final int startCol = pair[0];
-          final int endCol = pair[1];
-          incrementRange(heatmap, startCol, endCol, startRow, endRow, count);
-        }
-      }
-
-    }
-
-    return heatmap;
-  }
-
-  private static void intersectInterval(double heatMin, double heatMax, double heatCellLen, int heatLen,
-                                        double cellMin, double cellMax,
-                                        int[] out) {
-    //precondition: we know there's an intersection
-    if (heatMin >= cellMin) {
-      out[0] = 0;
-    } else {
-      out[0] = (int) Math.round((cellMin - heatMin) / heatCellLen);
-    }
-    if (heatMax <= cellMax) {
-      out[1] = heatLen - 1;
-    } else {
-      out[1] = (int) Math.round((cellMax - heatMin) / heatCellLen) - 1;
-    }
-  }
-
-  private static void incrementRange(Heatmap heatmap, int startColumn, int endColumn, int startRow, int endRow,
-                                     int count) {
-    //startColumn & startRow are not necessarily within the heatmap range; likewise numRows/columns may overlap.
-    if (startColumn < 0) {
-      endColumn += startColumn;
-      startColumn = 0;
-    }
-    endColumn = Math.min(heatmap.columns-1, endColumn);
-
-    if (startRow < 0) {
-      endRow += startRow;
-      startRow = 0;
-    }
-    endRow = Math.min(heatmap.rows-1, endRow);
-
-    if (startRow > endRow) {
-      return;//short-circuit
-    }
-    for (int c = startColumn; c <= endColumn; c++) {
-      int cBase = c * heatmap.rows;
-      for (int r = startRow; r <= endRow; r++) {
-        heatmap.counts[cBase + r] += count;
-      }
-    }
-  }
-
-  /** Computes the number of intervals (rows or columns) to cover a range given the sizes. */
-  private static int calcRowsOrCols(double cellRange, double cellMin, double requestRange, double requestMin,
-                                    double worldRange) {
-    assert requestMin >= cellMin;
-    //Idealistically this wouldn't be so complicated but we concern ourselves with overflow and edge cases
-    double range = (requestRange + (requestMin - cellMin));
-    if (range == 0) {
-      return 1;
-    }
-    final double intervals = Math.ceil(range / cellRange);
-    if (intervals > Integer.MAX_VALUE) {
-      return Integer.MAX_VALUE;//should result in an error soon (exceed thresholds)
-    }
-    // ensures we don't have more intervals than world bounds (possibly due to rounding/edge issue)
-    final long intervalsMax = Math.round(worldRange / cellRange);
-    if (intervalsMax > Integer.MAX_VALUE) {
-      //just return intervals
-      return (int) intervals;
-    }
-    return Math.min((int)intervalsMax, (int)intervals);
-  }
-
-  private HeatmapFacetCounter() {
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/IntersectsPrefixTreeQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/IntersectsPrefixTreeQuery.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/IntersectsPrefixTreeQuery.java
deleted file mode 100644
index ccb0f89..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/IntersectsPrefixTreeQuery.java
+++ /dev/null
@@ -1,95 +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.prefix;
-
-import java.io.IOException;
-
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.SpatialRelation;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.DocIdSet;
-import org.apache.lucene.spatial.prefix.tree.Cell;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.util.BitDocIdSet;
-import org.apache.lucene.util.FixedBitSet;
-
-/**
- * A Query matching documents that have an {@link SpatialRelation#INTERSECTS}
- * (i.e. not DISTINCT) relationship with a provided query shape.
- *
- * @lucene.internal
- */
-public class IntersectsPrefixTreeQuery extends AbstractVisitingPrefixTreeQuery {
-
-  public IntersectsPrefixTreeQuery(Shape queryShape, String fieldName,
-                                   SpatialPrefixTree grid, int detailLevel,
-                                   int prefixGridScanLevel) {
-    super(queryShape, fieldName, grid, detailLevel, prefixGridScanLevel);
-  }
-
-  @Override
-  protected DocIdSet getDocIdSet(LeafReaderContext context) throws IOException {
-    /* Possible optimizations (in IN ADDITION TO THOSE LISTED IN VISITORTEMPLATE):
-
-    * If docFreq is 1 (or < than some small threshold), then check to see if we've already
-      collected it; if so short-circuit. Don't do this just for point data, as there is
-      no benefit, or only marginal benefit when multi-valued.
-
-    * Point query shape optimization when the only indexed data is a point (no leaves).  Result is a term query.
-
-     */
-    return new VisitorTemplate(context) {
-      private FixedBitSet results;
-
-      @Override
-      protected void start() {
-        results = new FixedBitSet(maxDoc);
-      }
-
-      @Override
-      protected DocIdSet finish() {
-        return new BitDocIdSet(results);
-      }
-
-      @Override
-      protected boolean visitPrefix(Cell cell) throws IOException {
-        if (cell.getShapeRel() == SpatialRelation.WITHIN || cell.getLevel() == detailLevel) {
-          collectDocs(results);
-          return false;
-        }
-        return true;
-      }
-
-      @Override
-      protected void visitLeaf(Cell cell) throws IOException {
-        collectDocs(results);
-      }
-
-    }.getDocIdSet();
-  }
-
-  @Override
-  public String toString(String field) {
-    return getClass().getSimpleName() + "(" +
-        "fieldName=" + fieldName + "," +
-        "queryShape=" + queryShape + "," +
-        "detailLevel=" + detailLevel + "," +
-        "prefixGridScanLevel=" + prefixGridScanLevel +
-        ")";
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/NumberRangePrefixTreeStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/NumberRangePrefixTreeStrategy.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/NumberRangePrefixTreeStrategy.java
deleted file mode 100644
index 8001c82..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/NumberRangePrefixTreeStrategy.java
+++ /dev/null
@@ -1,199 +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.prefix;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.index.IndexReaderContext;
-import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.spatial.prefix.tree.Cell;
-import org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree;
-import org.apache.lucene.util.Bits;
-
-import static org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape;
-
-/** A PrefixTree based on Number/Date ranges. This isn't very "spatial" on the surface (to the user) but
- * it's implemented using spatial so that's why it's here extending a SpatialStrategy. When using this class, you will
- * use various utility methods on the prefix tree implementation to convert objects/strings to/from shapes.
- *
- * To use with dates, pass in {@link org.apache.lucene.spatial.prefix.tree.DateRangePrefixTree}.
- *
- * @lucene.experimental
- */
-public class NumberRangePrefixTreeStrategy extends RecursivePrefixTreeStrategy {
-
-  public NumberRangePrefixTreeStrategy(NumberRangePrefixTree prefixTree, String fieldName) {
-    super(prefixTree, fieldName);
-    setPruneLeafyBranches(false);
-    setPrefixGridScanLevel(prefixTree.getMaxLevels()-2);//user might want to change, however
-    setPointsOnly(false);
-    setDistErrPct(0);
-  }
-
-  @Override
-  public NumberRangePrefixTree getGrid() {
-    return (NumberRangePrefixTree) super.getGrid();
-  }
-
-  @Override
-  protected Iterator<Cell> createCellIteratorToIndex(Shape shape, int detailLevel, Iterator<Cell> reuse) {
-    //levels doesn't actually matter; NumberRange based Shapes have their own "level".
-    return super.createCellIteratorToIndex(shape, grid.getMaxLevels(), reuse);
-  }
-
-  /** Unsupported. */
-  @Override
-  public ValueSource makeDistanceValueSource(Point queryPoint, double multiplier) {
-    throw new UnsupportedOperationException();
-  }
-
-  /** Calculates facets between {@code start} and {@code end} to a detail level one greater than that provided by the
-   * arguments. For example providing March to October of 2014 would return facets to the day level of those months.
-   * This is just a convenience method.
-   * @see #calcFacets(IndexReaderContext, Bits, Shape, int)
-   */
-  public Facets calcFacets(IndexReaderContext context, Bits topAcceptDocs, UnitNRShape start, UnitNRShape end)
-      throws IOException {
-    Shape facetRange = getGrid().toRangeShape(start, end);
-    int detailLevel = Math.max(start.getLevel(), end.getLevel()) + 1;
-    return calcFacets(context, topAcceptDocs, facetRange, detailLevel);
-  }
-
-  /**
-   * Calculates facets (aggregated counts) given a range shape (start-end span) and a level, which specifies the detail.
-   * To get the level of an existing shape, say a Calendar, call
-   * {@link org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree#toUnitShape(Object)} then call
-   * {@link org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape#getLevel()}.
-   * Facet computation is implemented by navigating the underlying indexed terms efficiently.
-   */
-  public Facets calcFacets(IndexReaderContext context, Bits topAcceptDocs, Shape facetRange, final int level)
-      throws IOException {
-    final Facets facets = new Facets(level);
-    PrefixTreeFacetCounter.compute(this, context, topAcceptDocs, facetRange, level,
-        new PrefixTreeFacetCounter.FacetVisitor() {
-          Facets.FacetParentVal parentFacet;
-          UnitNRShape parentShape;
-
-          @Override
-          public void visit(Cell cell, int count) {
-            if (cell.getLevel() < level - 1) {//some ancestor of parent facet level, direct or distant
-              parentFacet = null;//reset
-              parentShape = null;//reset
-              facets.topLeaves += count;
-            } else if (cell.getLevel() == level - 1) {//parent
-              //set up FacetParentVal
-              setupParent((UnitNRShape) cell.getShape());
-              parentFacet.parentLeaves += count;
-            } else {//at facet level
-              UnitNRShape unitShape = (UnitNRShape) cell.getShape();
-              UnitNRShape unitShapeParent = unitShape.getShapeAtLevel(unitShape.getLevel() - 1);
-              if (parentFacet == null || !parentShape.equals(unitShapeParent)) {
-                setupParent(unitShapeParent);
-              }
-              //lazy init childCounts
-              if (parentFacet.childCounts == null) {
-                parentFacet.childCounts = new int[parentFacet.childCountsLen];
-              }
-              parentFacet.childCounts[unitShape.getValAtLevel(cell.getLevel())] += count;
-            }
-          }
-
-          private void setupParent(UnitNRShape unitShape) {
-            parentShape = unitShape.clone();
-            //Look for existing parentFacet (from previous segment), or create anew if needed
-            parentFacet = facets.parents.get(parentShape);
-            if (parentFacet == null) {//didn't find one; make a new one
-              parentFacet = new Facets.FacetParentVal();
-              parentFacet.childCountsLen = getGrid().getNumSubCells(parentShape);
-              facets.parents.put(parentShape, parentFacet);
-            }
-          }
-        });
-    return facets;
-  }
-
-  /** Facet response information */
-  public static class Facets {
-    //TODO consider a variable-level structure -- more general purpose.
-
-    public Facets(int detailLevel) {
-      this.detailLevel = detailLevel;
-    }
-
-    /** The bottom-most detail-level counted, as requested. */
-    public final int detailLevel;
-
-    /**
-     * The count of documents with ranges that completely spanned the parents of the detail level. In more technical
-     * terms, this is the count of leaf cells 2 up and higher from the bottom. Usually you only care about counts at
-     * detailLevel, and so you will add this number to all other counts below, including to omitted/implied children
-     * counts of 0. If there are no indexed ranges (just instances, i.e. fully specified dates) then this value will
-     * always be 0.
-     */
-    public int topLeaves;
-
-    /** Holds all the {@link FacetParentVal} instances in order of the key. This is sparse; there won't be an
-     * instance if it's count and children are all 0. The keys are {@link org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape} shapes, which can be
-     * converted back to the original Object (i.e. a Calendar) via
-     * {@link NumberRangePrefixTree#toObject(org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape)}. */
-    public final SortedMap<UnitNRShape,FacetParentVal> parents = new TreeMap<>();
-
-    /** Holds a block of detailLevel counts aggregated to their parent level. */
-    public static class FacetParentVal {
-
-      /** The count of ranges that span all of the childCounts.  In more technical terms, this is the number of leaf
-       * cells found at this parent.  Treat this like {@link Facets#topLeaves}. */
-      public int parentLeaves;
-
-      /** The length of {@link #childCounts}. If childCounts is not null then this is childCounts.length, otherwise it
-       * says how long it would have been if it weren't null. */
-      public int childCountsLen;
-
-      /** The detail level counts. It will be null if there are none, and thus they are assumed 0. Most apps, when
-       * presenting the information, will add {@link #topLeaves} and {@link #parentLeaves} to each count. */
-      public int[] childCounts;
-      //assert childCountsLen == childCounts.length
-    }
-
-    @Override
-    public String toString() {
-      StringBuilder buf = new StringBuilder(2048);
-      buf.append("Facets: level=" + detailLevel + " topLeaves=" + topLeaves + " parentCount=" + parents.size());
-      for (Map.Entry<UnitNRShape, FacetParentVal> entry : parents.entrySet()) {
-        buf.append('\n');
-        if (buf.length() > 1000) {
-          buf.append("...");
-          break;
-        }
-        final FacetParentVal pVal = entry.getValue();
-        buf.append(' ').append(entry.getKey()+" leafCount=" + pVal.parentLeaves);
-        if (pVal.childCounts != null) {
-          buf.append(' ').append(Arrays.toString(pVal.childCounts));
-        }
-      }
-      return buf.toString();
-    }
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PointPrefixTreeFieldCacheProvider.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PointPrefixTreeFieldCacheProvider.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PointPrefixTreeFieldCacheProvider.java
deleted file mode 100644
index 165c418..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PointPrefixTreeFieldCacheProvider.java
+++ /dev/null
@@ -1,48 +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.prefix;
-
-import com.spatial4j.core.shape.Point;
-import org.apache.lucene.spatial.prefix.tree.Cell;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.spatial.util.ShapeFieldCacheProvider;
-import org.apache.lucene.util.BytesRef;
-
-/**
- * Implementation of {@link ShapeFieldCacheProvider} designed for {@link PrefixTreeStrategy}s that index points
- * (AND ONLY POINTS!).
- *
- * @lucene.internal
- */
-public class PointPrefixTreeFieldCacheProvider extends ShapeFieldCacheProvider<Point> {
-
-  private final SpatialPrefixTree grid;
-  private Cell scanCell;//re-used in readShape to save GC
-
-  public PointPrefixTreeFieldCacheProvider(SpatialPrefixTree grid, String shapeField, int defaultSize) {
-    super( shapeField, defaultSize );
-    this.grid = grid;
-  }
-
-  @Override
-  protected Point readShape(BytesRef term) {
-    scanCell = grid.readCell(term, scanCell);
-    if (scanCell.getLevel() == grid.getMaxLevels())
-      return scanCell.getShape().getCenter();
-    return null;
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeFacetCounter.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeFacetCounter.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeFacetCounter.java
deleted file mode 100644
index 59f43e0..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeFacetCounter.java
+++ /dev/null
@@ -1,201 +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.prefix;
-
-import java.io.IOException;
-
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.index.IndexReaderContext;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.PostingsEnum;
-import org.apache.lucene.search.DocIdSet;
-import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.spatial.prefix.tree.Cell;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.util.Bits;
-
-/**
- * Computes facets on cells for {@link org.apache.lucene.spatial.prefix.PrefixTreeStrategy}.
- * <p>
- * <em>NOTE:</em> If for a given document and a given field using
- * {@link org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy}
- * multiple values are indexed (i.e. multi-valued) and at least one of them is a non-point, then there is a possibility
- * of double-counting the document in the facet results.  Since each shape is independently turned into grid cells at
- * a resolution chosen by the shape's size, it's possible they will be indexed at different resolutions.  This means
- * the document could be present in BOTH the postings for a cell in both its prefix and leaf variants.  To avoid this,
- * use a single valued field with a {@link com.spatial4j.core.shape.ShapeCollection} (or WKT equivalent).  Or
- * calculate a suitable level/distErr to index both and call
- * {@link org.apache.lucene.spatial.prefix.PrefixTreeStrategy#createIndexableFields(com.spatial4j.core.shape.Shape, int)}
- * with the same value for all shapes for a given document/field.
- *
- * @lucene.experimental
- */
-public class PrefixTreeFacetCounter {
-
-  /** A callback/visitor of facet counts. */
-  public static abstract class FacetVisitor {
-    /** Called at the start of the segment, if there is indexed data. */
-    public void startOfSegment() {}
-
-    /** Called for cells with a leaf, or cells at the target facet level.  {@code count} is greater than zero.
-     * When an ancestor cell is given with non-zero count, the count can be considered to be added to all cells
-     * below. You won't necessarily get a cell at level {@code facetLevel} if the indexed data is courser (bigger).
-     */
-    public abstract void visit(Cell cell, int count);
-  }
-
-  private PrefixTreeFacetCounter() {
-  }
-
-  /**
-   * Computes facets using a callback/visitor style design, allowing flexibility for the caller to determine what to do
-   * with each underlying count.
-   * @param strategy the prefix tree strategy (contains the field reference, grid, max levels)
-   * @param context the IndexReader's context
-   * @param topAcceptDocs a Bits to limit counted docs. If null, live docs are counted.
-   * @param queryShape the shape to limit the range of facet counts to
-   * @param facetLevel the maximum depth (detail) of faceted cells
-   * @param facetVisitor the visitor/callback to receive the counts
-   */
-  public static void compute(PrefixTreeStrategy strategy, IndexReaderContext context, Bits topAcceptDocs,
-                             Shape queryShape, int facetLevel, FacetVisitor facetVisitor)
-      throws IOException {
-    //We collect per-leaf
-    for (final LeafReaderContext leafCtx : context.leaves()) {
-      //determine leaf acceptDocs Bits
-      Bits leafAcceptDocs;
-      if (topAcceptDocs == null) {
-        leafAcceptDocs = leafCtx.reader().getLiveDocs();//filter deleted
-      } else {
-        leafAcceptDocs = new Bits() {
-          @Override
-          public boolean get(int index) {
-            return topAcceptDocs.get(leafCtx.docBase + index);
-          }
-
-          @Override
-          public int length() {
-            return leafCtx.reader().maxDoc();
-          }
-        };
-      }
-
-      compute(strategy, leafCtx, leafAcceptDocs, queryShape, facetLevel, facetVisitor);
-    }
-  }
-
-  /** Lower-level per-leaf segment method. */
-  public static void compute(final PrefixTreeStrategy strategy, final LeafReaderContext context, final Bits acceptDocs,
-                             final Shape queryShape, final int facetLevel, final FacetVisitor facetVisitor)
-      throws IOException {
-    if (acceptDocs != null && acceptDocs.length() != context.reader().maxDoc()) {
-      throw new IllegalArgumentException(
-          "acceptDocs bits length " + acceptDocs.length() +" != leaf maxdoc " + context.reader().maxDoc());
-    }
-    final SpatialPrefixTree tree = strategy.getGrid();
-
-    //scanLevel is an optimization knob of AbstractVisitingPrefixTreeFilter. It's unlikely
-    // another scanLevel would be much faster and it tends to be a risky knob (can help a little, can hurt a ton).
-    // TODO use RPT's configured scan level?  Do we know better here?  Hard to say.
-    final int scanLevel = tree.getMaxLevels();
-    //AbstractVisitingPrefixTreeFilter is a Lucene Filter.  We don't need a filter; we use it for its great prefix-tree
-    // traversal code.  TODO consider refactoring if/when it makes sense (more use cases than this)
-    new AbstractVisitingPrefixTreeQuery(queryShape, strategy.getFieldName(), tree, facetLevel, scanLevel) {
-      
-      @Override
-      public String toString(String field) {
-        return "anonPrefixTreeQuery";//un-used
-      }
-
-      @Override
-      public DocIdSet getDocIdSet(LeafReaderContext contexts) throws IOException {
-        assert facetLevel == super.detailLevel;//same thing, FYI. (constant)
-
-        return new VisitorTemplate(context) {
-
-          @Override
-          protected void start() throws IOException {
-            facetVisitor.startOfSegment();
-          }
-
-          @Override
-          protected DocIdSet finish() throws IOException {
-            return null;//unused;
-          }
-
-          @Override
-          protected boolean visitPrefix(Cell cell) throws IOException {
-            // At facetLevel...
-            if (cell.getLevel() == facetLevel) {
-              // Count docs
-              visitLeaf(cell);//we're not a leaf but we treat it as such at facet level
-              return false;//don't descend further; this is enough detail
-            }
-
-            // We optimize for discriminating filters (reflected in acceptDocs) and short-circuit if no
-            // matching docs. We could do this at all levels or never but the closer we get to the facet level, the
-            // higher the probability this is worthwhile. We do when docFreq == 1 because it's a cheap check, especially
-            // due to "pulsing" in the codec.
-            //TODO this opt should move to VisitorTemplate (which contains an optimization TODO to this effect)
-            if (cell.getLevel() == facetLevel - 1 || termsEnum.docFreq() == 1) {
-              if (!hasDocsAtThisTerm()) {
-                return false;
-              }
-            }
-            return true;
-          }
-
-          @Override
-          protected void visitLeaf(Cell cell) throws IOException {
-            final int count = countDocsAtThisTerm();
-            if (count > 0) {
-              facetVisitor.visit(cell, count);
-            }
-          }
-
-          private int countDocsAtThisTerm() throws IOException {
-            if (acceptDocs == null) {
-              return termsEnum.docFreq();
-            }
-            int count = 0;
-            postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.NONE);
-            while (postingsEnum.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
-              if (acceptDocs.get(postingsEnum.docID()) == false) {
-                continue;
-              }
-              count++;
-            }
-            return count;
-          }
-
-          private boolean hasDocsAtThisTerm() throws IOException {
-            if (acceptDocs == null) {
-              return true;
-            }
-            postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.NONE);
-            int nextDoc = postingsEnum.nextDoc();
-            while (nextDoc != DocIdSetIterator.NO_MORE_DOCS && acceptDocs.get(nextDoc) == false) {
-              nextDoc = postingsEnum.nextDoc();
-            }
-            return nextDoc != DocIdSetIterator.NO_MORE_DOCS;
-          }
-
-        }.getDocIdSet();
-      }
-    }.getDocIdSet(context);
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java
deleted file mode 100644
index 608879b..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java
+++ /dev/null
@@ -1,208 +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.prefix;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.FieldType;
-import org.apache.lucene.index.IndexOptions;
-import org.apache.lucene.index.IndexReaderContext;
-import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.spatial.SpatialStrategy;
-import org.apache.lucene.spatial.prefix.tree.Cell;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.util.ShapeFieldCacheDistanceValueSource;
-import org.apache.lucene.util.Bits;
-
-/**
- * An abstract SpatialStrategy based on {@link SpatialPrefixTree}. The two
- * subclasses are {@link RecursivePrefixTreeStrategy} and {@link
- * TermQueryPrefixTreeStrategy}.  This strategy is most effective as a fast
- * approximate spatial search filter.
- * <p>
- * <b>Characteristics:</b>
- * <br>
- * <ul>
- * <li>Can index any shape; however only {@link RecursivePrefixTreeStrategy}
- * can effectively search non-point shapes.</li>
- * <li>Can index a variable number of shapes per field value. This strategy
- * can do it via multiple calls to {@link #createIndexableFields(com.spatial4j.core.shape.Shape)}
- * for a document or by giving it some sort of Shape aggregate (e.g. JTS
- * WKT MultiPoint).  The shape's boundary is approximated to a grid precision.
- * </li>
- * <li>Can query with any shape.  The shape's boundary is approximated to a grid
- * precision.</li>
- * <li>Only {@link org.apache.lucene.spatial.query.SpatialOperation#Intersects}
- * is supported.  If only points are indexed then this is effectively equivalent
- * to IsWithin.</li>
- * <li>The strategy supports {@link #makeDistanceValueSource(com.spatial4j.core.shape.Point,double)}
- * even for multi-valued data, so long as the indexed data is all points; the
- * behavior is undefined otherwise.  However, <em>it will likely be removed in
- * the future</em> in lieu of using another strategy with a more scalable
- * implementation.  Use of this call is the only
- * circumstance in which a cache is used.  The cache is simple but as such
- * it doesn't scale to large numbers of points nor is it real-time-search
- * friendly.</li>
- * </ul>
- * <p>
- * <b>Implementation:</b>
- * <p>
- * The {@link SpatialPrefixTree} does most of the work, for example returning
- * a list of terms representing grids of various sizes for a supplied shape.
- * An important
- * configuration item is {@link #setDistErrPct(double)} which balances
- * shape precision against scalability.  See those javadocs.
- *
- * @lucene.experimental
- */
-public abstract class PrefixTreeStrategy extends SpatialStrategy {
-  protected final SpatialPrefixTree grid;
-  private final Map<String, PointPrefixTreeFieldCacheProvider> provider = new ConcurrentHashMap<>();
-  protected int defaultFieldValuesArrayLen = 2;
-  protected double distErrPct = SpatialArgs.DEFAULT_DISTERRPCT;// [ 0 TO 0.5 ]
-  protected boolean pointsOnly = false;//if true, there are no leaves
-
-  public PrefixTreeStrategy(SpatialPrefixTree grid, String fieldName) {
-    super(grid.getSpatialContext(), fieldName);
-    this.grid = grid;
-  }
-
-  public SpatialPrefixTree getGrid() {
-    return grid;
-  }
-
-  /**
-   * A memory hint used by {@link #makeDistanceValueSource(com.spatial4j.core.shape.Point)}
-   * for how big the initial size of each Document's array should be. The
-   * default is 2.  Set this to slightly more than the default expected number
-   * of points per document.
-   */
-  public void setDefaultFieldValuesArrayLen(int defaultFieldValuesArrayLen) {
-    this.defaultFieldValuesArrayLen = defaultFieldValuesArrayLen;
-  }
-
-  public double getDistErrPct() {
-    return distErrPct;
-  }
-
-  /**
-   * The default measure of shape precision affecting shapes at index and query
-   * times. Points don't use this as they are always indexed at the configured
-   * maximum precision ({@link org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree#getMaxLevels()});
-   * this applies to all other shapes. Specific shapes at index and query time
-   * can use something different than this default value.  If you don't set a
-   * default then the default is {@link SpatialArgs#DEFAULT_DISTERRPCT} --
-   * 2.5%.
-   *
-   * @see org.apache.lucene.spatial.query.SpatialArgs#getDistErrPct()
-   */
-  public void setDistErrPct(double distErrPct) {
-    this.distErrPct = distErrPct;
-  }
-
-  public boolean isPointsOnly() {
-    return pointsOnly;
-  }
-
-  /** True if only indexed points shall be supported. There are no "leafs" in such a case, except those
-   * at maximum precision. */
-  public void setPointsOnly(boolean pointsOnly) {
-    this.pointsOnly = pointsOnly;
-  }
-
-  @Override
-  public Field[] createIndexableFields(Shape shape) {
-    double distErr = SpatialArgs.calcDistanceFromErrPct(shape, distErrPct, ctx);
-    return createIndexableFields(shape, distErr);
-  }
-
-  /**
-   * Turns {@link SpatialPrefixTree#getTreeCellIterator(Shape, int)} into a
-   * {@link org.apache.lucene.analysis.TokenStream}.
-   */
-  public Field[] createIndexableFields(Shape shape, double distErr) {
-    int detailLevel = grid.getLevelForDistance(distErr);
-    return createIndexableFields(shape, detailLevel);
-  }
-
-  public Field[] createIndexableFields(Shape shape, int detailLevel) {
-    //TODO re-use TokenStream LUCENE-5776: Subclass Field, put cell iterator there, override tokenStream()
-    Iterator<Cell> cells = createCellIteratorToIndex(shape, detailLevel, null);
-    CellToBytesRefIterator cellToBytesRefIterator = newCellToBytesRefIterator();
-    cellToBytesRefIterator.reset(cells);
-    BytesRefIteratorTokenStream tokenStream = new BytesRefIteratorTokenStream();
-    tokenStream.setBytesRefIterator(cellToBytesRefIterator);
-    Field field = new Field(getFieldName(), tokenStream, FIELD_TYPE);
-    return new Field[]{field};
-  }
-
-  protected CellToBytesRefIterator newCellToBytesRefIterator() {
-    //subclasses could return one that never emits leaves, or does both, or who knows.
-    return new CellToBytesRefIterator();
-  }
-
-  protected Iterator<Cell> createCellIteratorToIndex(Shape shape, int detailLevel, Iterator<Cell> reuse) {
-    if (pointsOnly && !(shape instanceof Point)) {
-      throw new IllegalArgumentException("pointsOnly is true yet a " + shape.getClass() + " is given for indexing");
-    }
-    return grid.getTreeCellIterator(shape, detailLevel);//TODO should take a re-use iterator
-  }
-
-  /* Indexed, tokenized, not stored. */
-  public static final FieldType FIELD_TYPE = new FieldType();
-
-  static {
-    FIELD_TYPE.setTokenized(true);
-    FIELD_TYPE.setOmitNorms(true);
-    FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
-    FIELD_TYPE.freeze();
-  }
-
-  @Override
-  public ValueSource makeDistanceValueSource(Point queryPoint, double multiplier) {
-    PointPrefixTreeFieldCacheProvider p = provider.get( getFieldName() );
-    if( p == null ) {
-      synchronized (this) {//double checked locking idiom is okay since provider is threadsafe
-        p = provider.get( getFieldName() );
-        if (p == null) {
-          p = new PointPrefixTreeFieldCacheProvider(grid, getFieldName(), defaultFieldValuesArrayLen);
-          provider.put(getFieldName(),p);
-        }
-      }
-    }
-
-    return new ShapeFieldCacheDistanceValueSource(ctx, p, queryPoint, multiplier);
-  }
-
-  /**
-   * Computes spatial facets in two dimensions as a grid of numbers.  The data is often visualized as a so-called
-   * "heatmap".
-   *
-   * @see HeatmapFacetCounter#calcFacets(PrefixTreeStrategy, IndexReaderContext, Bits, Shape, int, int)
-   */
-  public HeatmapFacetCounter.Heatmap calcFacets(IndexReaderContext context, Bits topAcceptDocs,
-                                   Shape inputShape, final int facetLevel, int maxCells) throws IOException {
-    return HeatmapFacetCounter.calcFacets(this, context, topAcceptDocs, inputShape, facetLevel, maxCells);
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeStrategy.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeStrategy.java
deleted file mode 100644
index 575b6c9..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeStrategy.java
+++ /dev/null
@@ -1,196 +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.prefix;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.spatial.prefix.tree.Cell;
-import org.apache.lucene.spatial.prefix.tree.CellIterator;
-import org.apache.lucene.spatial.prefix.tree.LegacyCell;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.query.SpatialOperation;
-import org.apache.lucene.spatial.query.UnsupportedSpatialOperation;
-
-/**
- * A {@link PrefixTreeStrategy} which uses {@link AbstractVisitingPrefixTreeQuery}.
- * This strategy has support for searching non-point shapes (note: not tested).
- * Even a query shape with distErrPct=0 (fully precise to the grid) should have
- * good performance for typical data, unless there is a lot of indexed data
- * coincident with the shape's edge.
- *
- * @lucene.experimental
- */
-public class RecursivePrefixTreeStrategy extends PrefixTreeStrategy {
-  /* Future potential optimizations:
-
-    Each shape.relate(otherShape) result could be cached since much of the same relations will be invoked when
-    multiple segments are involved. Do this for "complex" shapes, not cheap ones, and don't cache when disjoint to
-    bbox because it's a cheap calc. This is one advantage TermQueryPrefixTreeStrategy has over RPT.
-
-   */
-
-  protected int prefixGridScanLevel;
-
-  //Formerly known as simplifyIndexedCells. Eventually will be removed. Only compatible with RPT
-  // and a LegacyPrefixTree.
-  protected boolean pruneLeafyBranches = true;
-
-  protected boolean multiOverlappingIndexedShapes = true;
-
-  public RecursivePrefixTreeStrategy(SpatialPrefixTree grid, String fieldName) {
-    super(grid, fieldName);
-    prefixGridScanLevel = grid.getMaxLevels() - 4;//TODO this default constant is dependent on the prefix grid size
-  }
-
-  public int getPrefixGridScanLevel() {
-    return prefixGridScanLevel;
-  }
-
-  /**
-   * Sets the grid level [1-maxLevels] at which indexed terms are scanned brute-force
-   * instead of by grid decomposition.  By default this is maxLevels - 4.  The
-   * final level, maxLevels, is always scanned.
-   *
-   * @param prefixGridScanLevel 1 to maxLevels
-   */
-  public void setPrefixGridScanLevel(int prefixGridScanLevel) {
-    //TODO if negative then subtract from maxlevels
-    this.prefixGridScanLevel = prefixGridScanLevel;
-  }
-
-  public boolean isMultiOverlappingIndexedShapes() {
-    return multiOverlappingIndexedShapes;
-  }
-
-  /** See {@link ContainsPrefixTreeQuery#multiOverlappingIndexedShapes}. */
-  public void setMultiOverlappingIndexedShapes(boolean multiOverlappingIndexedShapes) {
-    this.multiOverlappingIndexedShapes = multiOverlappingIndexedShapes;
-  }
-
-  public boolean isPruneLeafyBranches() {
-    return pruneLeafyBranches;
-  }
-
-  /**
-   * An optional hint affecting non-point shapes: it will
-   * prune away a complete set sibling leaves to their parent (recursively), resulting in ~20-50%
-   * fewer indexed cells, and consequently that much less disk and that much faster indexing.
-   * So if it's a quad tree and all 4 sub-cells are there marked as a leaf, then they will be
-   * removed (pruned) and the parent is marked as a leaf instead.  This occurs recursively on up.  Unfortunately, the
-   * current implementation will buffer all cells to do this, so consider disabling for high precision (low distErrPct)
-   * shapes. (default=true)
-   */
-  public void setPruneLeafyBranches(boolean pruneLeafyBranches) {
-    this.pruneLeafyBranches = pruneLeafyBranches;
-  }
-
-  @Override
-  public String toString() {
-    StringBuilder str = new StringBuilder(getClass().getSimpleName()).append('(');
-    str.append("SPG:(").append(grid.toString()).append(')');
-    if (pointsOnly)
-      str.append(",pointsOnly");
-    if (pruneLeafyBranches)
-      str.append(",pruneLeafyBranches");
-    if (prefixGridScanLevel != grid.getMaxLevels() - 4)
-      str.append(",prefixGridScanLevel:").append(""+prefixGridScanLevel);
-    if (!multiOverlappingIndexedShapes)
-      str.append(",!multiOverlappingIndexedShapes");
-    return str.append(')').toString();
-  }
-
-  @Override
-  protected Iterator<Cell> createCellIteratorToIndex(Shape shape, int detailLevel, Iterator<Cell> reuse) {
-    if (shape instanceof Point || !pruneLeafyBranches)
-      return super.createCellIteratorToIndex(shape, detailLevel, reuse);
-
-    List<Cell> cells = new ArrayList<>(4096);
-    recursiveTraverseAndPrune(grid.getWorldCell(), shape, detailLevel, cells);
-    return cells.iterator();
-  }
-
-  /** Returns true if cell was added as a leaf. If it wasn't it recursively descends. */
-  private boolean recursiveTraverseAndPrune(Cell cell, Shape shape, int detailLevel, List<Cell> result) {
-    // Important: this logic assumes Cells don't share anything with other cells when
-    // calling cell.getNextLevelCells(). This is only true for LegacyCell.
-    if (!(cell instanceof LegacyCell))
-      throw new IllegalStateException("pruneLeafyBranches must be disabled for use with grid "+grid);
-
-    if (cell.getLevel() == detailLevel) {
-      cell.setLeaf();//FYI might already be a leaf
-    }
-    if (cell.isLeaf()) {
-      result.add(cell);
-      return true;
-    }
-    if (cell.getLevel() != 0)
-      result.add(cell);
-
-    int leaves = 0;
-    CellIterator subCells = cell.getNextLevelCells(shape);
-    while (subCells.hasNext()) {
-      Cell subCell = subCells.next();
-      if (recursiveTraverseAndPrune(subCell, shape, detailLevel, result))
-        leaves++;
-    }
-    //can we prune?
-    if (leaves == ((LegacyCell)cell).getSubCellsSize() && cell.getLevel() != 0) {
-      //Optimization: substitute the parent as a leaf instead of adding all
-      // children as leaves
-
-      //remove the leaves
-      do {
-        result.remove(result.size() - 1);//remove last
-      } while (--leaves > 0);
-      //add cell as the leaf
-      cell.setLeaf();
-      return true;
-    }
-    return false;
-  }
-
-  @Override
-  public Query makeQuery(SpatialArgs args) {
-    final SpatialOperation op = args.getOperation();
-
-    Shape shape = args.getShape();
-    int detailLevel = grid.getLevelForDistance(args.resolveDistErr(ctx, distErrPct));
-
-    if (op == SpatialOperation.Intersects) {
-      return new IntersectsPrefixTreeQuery(
-          shape, getFieldName(), grid, detailLevel, prefixGridScanLevel);
-    } else if (op == SpatialOperation.IsWithin) {
-      return new WithinPrefixTreeQuery(
-          shape, getFieldName(), grid, detailLevel, prefixGridScanLevel,
-          -1);//-1 flag is slower but ensures correct results
-    } else if (op == SpatialOperation.Contains) {
-      return new ContainsPrefixTreeQuery(shape, getFieldName(), grid, detailLevel,
-          multiOverlappingIndexedShapes);
-    }
-    throw new UnsupportedSpatialOperation(op);
-  }
-}
-
-
-
-

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/TermQueryPrefixTreeStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/TermQueryPrefixTreeStrategy.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/TermQueryPrefixTreeStrategy.java
deleted file mode 100644
index a74786b..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/TermQueryPrefixTreeStrategy.java
+++ /dev/null
@@ -1,111 +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.prefix;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.queries.TermsQuery;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.spatial.prefix.tree.Cell;
-import org.apache.lucene.spatial.prefix.tree.CellIterator;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.query.SpatialOperation;
-import org.apache.lucene.spatial.query.UnsupportedSpatialOperation;
-import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.BytesRefBuilder;
-
-/**
- * A basic implementation of {@link PrefixTreeStrategy} using a large
- * {@link TermsQuery} of all the cells from
- * {@link SpatialPrefixTree#getTreeCellIterator(com.spatial4j.core.shape.Shape, int)}.
- * It only supports the search of indexed Point shapes.
- * <p>
- * The precision of query shapes (distErrPct) is an important factor in using
- * this Strategy. If the precision is too precise then it will result in many
- * terms which will amount to a slower query.
- *
- * @lucene.experimental
- */
-public class TermQueryPrefixTreeStrategy extends PrefixTreeStrategy {
-
-  protected boolean simplifyIndexedCells = false;
-
-  public TermQueryPrefixTreeStrategy(SpatialPrefixTree grid, String fieldName) {
-    super(grid, fieldName);
-  }
-
-  @Override
-  protected CellToBytesRefIterator newCellToBytesRefIterator() {
-    //Ensure we don't have leaves, as this strategy doesn't handle them.
-    return new CellToBytesRefIterator() {
-      @Override
-      public BytesRef next() {
-        if (!cellIter.hasNext()) {
-          return null;
-        }
-        return cellIter.next().getTokenBytesNoLeaf(bytesRef);
-      }
-    };
-  }
-
-  @Override
-  public Query makeQuery(SpatialArgs args) {
-    final SpatialOperation op = args.getOperation();
-    if (op != SpatialOperation.Intersects)
-      throw new UnsupportedSpatialOperation(op);
-
-    Shape shape = args.getShape();
-    int detailLevel = grid.getLevelForDistance(args.resolveDistErr(ctx, distErrPct));
-
-    //--get a List of BytesRef for each term we want (no parents, no leaf bytes))
-    final int GUESS_NUM_TERMS;
-    if (shape instanceof Point)
-      GUESS_NUM_TERMS = detailLevel;//perfect guess
-    else
-      GUESS_NUM_TERMS = 4096;//should this be a method on SpatialPrefixTree?
-
-    BytesRefBuilder masterBytes = new BytesRefBuilder();//shared byte array for all terms
-    List<BytesRef> terms = new ArrayList<>(GUESS_NUM_TERMS);
-
-    CellIterator cells = grid.getTreeCellIterator(shape, detailLevel);
-    while (cells.hasNext()) {
-      Cell cell = cells.next();
-      if (!cell.isLeaf())
-        continue;
-      BytesRef term = cell.getTokenBytesNoLeaf(null);//null because we want a new BytesRef
-      //We copy out the bytes because it may be re-used across the iteration. This also gives us the opportunity
-      // to use one contiguous block of memory for the bytes of all terms we need.
-      masterBytes.grow(masterBytes.length() + term.length);
-      masterBytes.append(term);
-      term.bytes = null;//don't need; will reset later
-      term.offset = masterBytes.length() - term.length;
-      terms.add(term);
-    }
-    //doing this now because if we did earlier, it's possible the bytes needed to grow()
-    for (BytesRef byteRef : terms) {
-      byteRef.bytes = masterBytes.bytes();
-    }
-    //unfortunately TermsQuery will needlessly sort & dedupe
-    //TODO an automatonQuery might be faster?
-    return new TermsQuery(getFieldName(), terms);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/WithinPrefixTreeQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/WithinPrefixTreeQuery.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/WithinPrefixTreeQuery.java
deleted file mode 100644
index c534a5b..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/WithinPrefixTreeQuery.java
+++ /dev/null
@@ -1,233 +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.prefix;
-
-import java.io.IOException;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.distance.DistanceUtils;
-import com.spatial4j.core.shape.Circle;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.SpatialRelation;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.DocIdSet;
-import org.apache.lucene.spatial.prefix.tree.Cell;
-import org.apache.lucene.spatial.prefix.tree.CellIterator;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.util.BitDocIdSet;
-import org.apache.lucene.util.Bits;
-import org.apache.lucene.util.FixedBitSet;
-
-/**
- * Finds docs where its indexed shape is {@link org.apache.lucene.spatial.query.SpatialOperation#IsWithin
- * WITHIN} the query shape.  It works by looking at cells outside of the query
- * shape to ensure documents there are excluded. By default, it will
- * examine all cells, and it's fairly slow.  If you know that the indexed shapes
- * are never comprised of multiple disjoint parts (which also means it is not multi-valued),
- * then you can pass {@code SpatialPrefixTree.getDistanceForLevel(maxLevels)} as
- * the {@code queryBuffer} constructor parameter to minimally look this distance
- * beyond the query shape's edge.  Even if the indexed shapes are sometimes
- * comprised of multiple disjoint parts, you might want to use this option with
- * a large buffer as a faster approximation with minimal false-positives.
- *
- * @lucene.experimental
- */
-public class WithinPrefixTreeQuery extends AbstractVisitingPrefixTreeQuery {
-  //TODO LUCENE-4869: implement faster algorithm based on filtering out false-positives of a
-  //  minimal query buffer by looking in a DocValues cache holding a representative
-  //  point of each disjoint component of a document's shape(s).
-
-  //TODO Could the recursion in allCellsIntersectQuery() be eliminated when non-fuzzy or other
-  //  circumstances?
-
-  private final Shape bufferedQueryShape;//if null then the whole world
-
-  /**
-   * See {@link AbstractVisitingPrefixTreeQuery#AbstractVisitingPrefixTreeQuery(com.spatial4j.core.shape.Shape, String, org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree, int, int)}.
-   * {@code queryBuffer} is the (minimum) distance beyond the query shape edge
-   * where non-matching documents are looked for so they can be excluded. If
-   * -1 is used then the whole world is examined (a good default for correctness).
-   */
-  public WithinPrefixTreeQuery(Shape queryShape, String fieldName, SpatialPrefixTree grid,
-                               int detailLevel, int prefixGridScanLevel,
-                               double queryBuffer) {
-    super(queryShape, fieldName, grid, detailLevel, prefixGridScanLevel);
-    this.bufferedQueryShape = queryBuffer == -1 ? null : bufferShape(queryShape, queryBuffer);
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (!super.equals(o)) return false;//checks getClass == o.getClass & instanceof
-
-    WithinPrefixTreeQuery that = (WithinPrefixTreeQuery) o;
-
-    if (bufferedQueryShape != null ? !bufferedQueryShape.equals(that.bufferedQueryShape) : that.bufferedQueryShape != null)
-      return false;
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = super.hashCode();
-    result = 31 * result + (bufferedQueryShape != null ? bufferedQueryShape.hashCode() : 0);
-    return result;
-  }
-  
-  @Override
-  public String toString(String field) {
-    return getClass().getSimpleName() + "(" +
-             "fieldName=" + fieldName + "," +
-             "queryShape=" + queryShape + "," +
-             "detailLevel=" + detailLevel + "," +
-             "prefixGridScanLevel=" + prefixGridScanLevel +
-           ")";
-  }
-
-  /** Returns a new shape that is larger than shape by at distErr.
-   */
-  //TODO move this generic code elsewhere?  Spatial4j?
-  protected Shape bufferShape(Shape shape, double distErr) {
-    if (distErr <= 0)
-      throw new IllegalArgumentException("distErr must be > 0");
-    SpatialContext ctx = grid.getSpatialContext();
-    if (shape instanceof Point) {
-      return ctx.makeCircle((Point)shape, distErr);
-    } else if (shape instanceof Circle) {
-      Circle circle = (Circle) shape;
-      double newDist = circle.getRadius() + distErr;
-      if (ctx.isGeo() && newDist > 180)
-        newDist = 180;
-      return ctx.makeCircle(circle.getCenter(), newDist);
-    } else {
-      Rectangle bbox = shape.getBoundingBox();
-      double newMinX = bbox.getMinX() - distErr;
-      double newMaxX = bbox.getMaxX() + distErr;
-      double newMinY = bbox.getMinY() - distErr;
-      double newMaxY = bbox.getMaxY() + distErr;
-      if (ctx.isGeo()) {
-        if (newMinY < -90)
-          newMinY = -90;
-        if (newMaxY > 90)
-          newMaxY = 90;
-        if (newMinY == -90 || newMaxY == 90 || bbox.getWidth() + 2*distErr > 360) {
-          newMinX = -180;
-          newMaxX = 180;
-        } else {
-          newMinX = DistanceUtils.normLonDEG(newMinX);
-          newMaxX = DistanceUtils.normLonDEG(newMaxX);
-        }
-      } else {
-        //restrict to world bounds
-        newMinX = Math.max(newMinX, ctx.getWorldBounds().getMinX());
-        newMaxX = Math.min(newMaxX, ctx.getWorldBounds().getMaxX());
-        newMinY = Math.max(newMinY, ctx.getWorldBounds().getMinY());
-        newMaxY = Math.min(newMaxY, ctx.getWorldBounds().getMaxY());
-      }
-      return ctx.makeRectangle(newMinX, newMaxX, newMinY, newMaxY);
-    }
-  }
-
-
-  @Override
-  protected DocIdSet getDocIdSet(LeafReaderContext context) throws IOException {
-    return new VisitorTemplate(context) {
-      private FixedBitSet inside;
-      private FixedBitSet outside;
-
-      @Override
-      protected void start() {
-        inside = new FixedBitSet(maxDoc);
-        outside = new FixedBitSet(maxDoc);
-      }
-
-      @Override
-      protected DocIdSet finish() {
-        inside.andNot(outside);
-        return new BitDocIdSet(inside);
-      }
-
-      @Override
-      protected CellIterator findSubCellsToVisit(Cell cell) {
-        //use buffered query shape instead of orig.  Works with null too.
-        return cell.getNextLevelCells(bufferedQueryShape);
-      }
-
-      @Override
-      protected boolean visitPrefix(Cell cell) throws IOException {
-        //cell.relate is based on the bufferedQueryShape; we need to examine what
-        // the relation is against the queryShape
-        SpatialRelation visitRelation = cell.getShape().relate(queryShape);
-        if (cell.getLevel() == detailLevel) {
-          collectDocs(visitRelation.intersects() ? inside : outside);
-          return false;
-        } else if (visitRelation == SpatialRelation.WITHIN) {
-          collectDocs(inside);
-          return false;
-        } else if (visitRelation == SpatialRelation.DISJOINT) {
-          collectDocs(outside);
-          return false;
-        }
-        return true;
-      }
-
-      @Override
-      protected void visitLeaf(Cell cell) throws IOException {
-        if (allCellsIntersectQuery(cell))
-          collectDocs(inside);
-        else
-          collectDocs(outside);
-      }
-
-      /** Returns true if the provided cell, and all its sub-cells down to
-       * detailLevel all intersect the queryShape.
-       */
-      private boolean allCellsIntersectQuery(Cell cell) {
-        SpatialRelation relate = cell.getShape().relate(queryShape);
-        if (cell.getLevel() == detailLevel)
-          return relate.intersects();
-        if (relate == SpatialRelation.WITHIN)
-          return true;
-        if (relate == SpatialRelation.DISJOINT)
-          return false;
-        // Note: Generating all these cells just to determine intersection is not ideal.
-        // The real solution is LUCENE-4869.
-        CellIterator subCells = cell.getNextLevelCells(null);
-        while (subCells.hasNext()) {
-          Cell subCell = subCells.next();
-          if (!allCellsIntersectQuery(subCell))//recursion
-            return false;
-        }
-        return true;
-      }
-
-      @Override
-      protected void visitScanned(Cell cell) throws IOException {
-        visitLeaf(cell);//collects as we want, even if not a leaf
-//        if (cell.isLeaf()) {
-//          visitLeaf(cell);
-//        } else {
-//          visitPrefix(cell);
-//        }
-      }
-
-    }.getDocIdSet();
-  }
-
-}


[26/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test-files/data/countries-poly.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test-files/data/countries-poly.txt b/lucene/spatial-extras/src/test-files/data/countries-poly.txt
new file mode 100644
index 0000000..862a39a
--- /dev/null
+++ b/lucene/spatial-extras/src/test-files/data/countries-poly.txt
@@ -0,0 +1,249 @@
+#id	name	shape
+FLK	Falkland Is.	MULTIPOLYGON (((-59.348063887634126 -52.34305496492924, -59.37944588766335 -52.32778196491501, -59.57444588784496 -52.21528196481024, -59.71611788797689 -52.11737296471905, -59.56667288783771 -51.91749996453291, -59.51805488779243 -51.87528196449359, -59.2883358875785 -51.746944964374066, -59.221254887516025 -51.71709096434626, -59.13306388743389 -51.69444496432517, -59.055554887361694 -51.691672964322585, -59.03087288733872 -51.7643819643903, -59.04139088734851 -51.81520896443764, -59.00083588731074 -51.8100089644328, -58.99472688730505 -51.80667296442969, -58.9826458872938 -51.79534496441914, -59.02389988733222 -51.67694496430887, -59.07833588738292 -51.631954964266974, -59.168263887466665 -51.585281964223505, -59.10860888741111 -51.513890964157014, -59.08416388738834 -51.53722696417875, -59.06986388737502 -51.557363964197506, -59.039308887346564 -51.58396396422228, -59.01430888732328 -51.575835964214704, -58.989445887300135 -51.50417296414796, -59.0461088873529 -
 51.47889096412442, -59.074726887379555 -51.469863964116016, -59.08472688738887 -51.41166396406181, -58.99110888730168 -51.40555496405612, -58.868754887187734 -51.37007296402307, -58.88430888720221 -51.33083596398653, -58.84861788716897 -51.291390963949794, -58.75403588708089 -51.32639096398239, -58.69667288702746 -51.336672963991965, -58.614508886950944 -51.3294089639852, -58.57972688691855 -51.30944496396661, -58.5444458868857 -51.30569996396312, -58.4673638868139 -51.307363963964676, -58.41250888676282 -51.32340896397962, -58.34361788669865 -51.36903596402211, -58.32459088668094 -51.416081964065924, -58.36194588671573 -51.44445496409235, -58.44389088679205 -51.45361796410088, -58.45917288680627 -51.43020896407908, -58.47597288682192 -51.39999996405095, -58.49610888684067 -51.39631796404752, -58.55028188689113 -51.43361796408225, -58.51833588686138 -51.47610896412183, -58.49889088684327 -51.50028196414434, -58.420563886770324 -51.556672964196856, -58.36249988671625 -51.567217964206
 684, -58.33583588669141 -51.56667296420617, -58.28167288664096 -51.606808964243555, -58.241390886603455 -51.65014496428391, -58.21743588658114 -51.65069996428443, -58.18278188654887 -51.60917296424575, -58.188899886554566 -51.585281964223505, -58.2572268866182 -51.53055496417254, -58.31409988667117 -51.50041796414447, -58.345554886700455 -51.509099964152554, -58.27479988663457 -51.413754964063756, -58.25028188661173 -51.40097296405185, -58.21736388658107 -51.39528196404655, -57.94445488632691 -51.371808964024694, -57.91541788629986 -51.37528196402793, -57.89680888628253 -51.3841729640362, -57.873890886261194 -51.4016729640525, -57.768054886162616 -51.50403596414784, -57.77291788616715 -51.54375496418483, -57.81389988620532 -51.54972696419039, -57.87861788626559 -51.54610896418702, -57.90472688628991 -51.543335964184436, -57.93028188631371 -51.539999964181334, -57.95360888633543 -51.53486396417655, -57.9794458863595 -51.52389096416633, -58.00417288638252 -51.50778196415133, -58.03541
 788641162 -51.50209096414603, -58.138963886508066 -51.54986396419052, -58.109308886480434 -51.570563964209796, -58.039235886415184 -51.59014496422803, -58.0087548863868 -51.59319996423088, -57.983545886363316 -51.58805496422609, -57.87694588626404 -51.60000896423722, -57.79764588619018 -51.61180896424821, -57.77528188616935 -51.621735964257454, -57.733199886130166 -51.69444496432517, -57.83444588622446 -51.723617964352336, -57.973890886354326 -51.74860896437561, -58.0324998864089 -51.7575089643839, -58.1119458864829 -51.76333596438933, -58.19778188656284 -51.761944964388036, -58.249172886610694 -51.7573999643838, -58.21389088657784 -51.78110896440588, -58.17361788654033 -51.796672964420374, -58.200008886564916 -51.793890964417784, -58.24680888660849 -51.79333596441727, -58.35833588671237 -51.82666396444831, -58.33778188669322 -51.83278196445401, -58.31514588667214 -51.83444496445556, -58.28528188664433 -51.82722696444883, -58.234726886597244 -51.83278196445401, -58.39291788674457 -5
 1.89583596451273, -58.4199998867698 -51.90069996451726, -58.60639088694339 -51.90028196451687, -58.76812688709401 -51.89125496450846, -58.88945488720701 -51.84472696446513, -58.90917288722537 -51.83583596445685, -58.92347288723869 -51.820281964442366, -58.935554887249936 -51.80125496442464, -58.96243588727498 -51.81764496443991, -58.97382688728558 -51.85146396447141, -58.926672887241665 -51.87806396449618, -58.82389088714595 -51.91528196453084, -58.720626887049775 -51.94784496456116, -58.63396388696907 -51.96451796457669, -58.60389088694106 -52.001399964611046, -58.64694588698116 -52.067217964672345, -58.6802818870122 -52.090835964694335, -58.734726887062905 -52.046672964653204, -58.78791788711244 -52.03417296464156, -58.82500888714699 -52.047226964653724, -58.856526887176344 -52.0688909646739, -58.918890887234426 -52.099999964702874, -58.981108887292365 -52.06958196467454, -59.03333588734101 -52.02444496463251, -59.14236388744254 -51.985281964596034, -59.251672887544345 -51.9911089
 6460146, -59.29430888758405 -52.0097269646188, -59.279654887570416 -52.02493596463297, -59.24444588753762 -52.01944496462785, -59.21959088751447 -52.0234729646316, -59.19180888748859 -52.029444964637165, -59.12222688742379 -52.063335964668724, -59.03625488734373 -52.1408359647409, -59.05069988735718 -52.217499964812305, -59.0720908873771 -52.231535964825376, -59.19389088749054 -52.206672964802216, -59.24083588753426 -52.18639096478333, -59.29249988758238 -52.157499964756425, -59.37951788766341 -52.11923596472079, -59.44979088772887 -52.1467359647464, -59.428408887708954 -52.21389096480894, -59.38444588766801 -52.22722696482136, -59.343472887629844 -52.25215496484458, -59.33805488762479 -52.324444964911905, -59.348063887634126 -52.34305496492924)), ((-60.34528188856285 -51.86083596448013, -60.310835888530775 -51.81139096443408, -60.25749988848111 -51.77486396440007, -60.222781888448765 -51.7877819644121, -60.18284588841158 -51.75785496438422, -60.178481888407504 -51.71222696434173, -
 60.201117888428584 -51.70333596433345, -60.22749988845317 -51.70028196433061, -60.35610888857293 -51.711317964340886, -60.38556388860037 -51.744726964372, -60.445281888655984 -51.76249996438855, -60.5561178887592 -51.77555496440071, -60.63437288883209 -51.72499996435363, -60.638408888835855 -51.67972696431146, -60.61389088881302 -51.671108964303436, -60.57722688877887 -51.68528196431664, -60.55722688876024 -51.69306396432388, -60.52472688872997 -51.69944496432983, -60.48861788869634 -51.702781964332935, -60.45722688866711 -51.70222696433242, -60.43625488864758 -51.697090964327636, -60.39939088861324 -51.67999996431172, -60.36472688858096 -51.66749996430008, -60.34389088856156 -51.66528196429801, -60.248890888473085 -51.665554964298266, -60.163608888393654 -51.67111796430344, -60.29444588851551 -51.59861796423592, -60.40444588861796 -51.55139096419194, -60.390626888605084 -51.4922909641369, -60.40391788861746 -51.46865496411488, -60.448126888658635 -51.44507296409292, -60.50555488871
 211 -51.43652696408496, -60.55500888875818 -51.437435964085815, -60.62201788882058 -51.41152696406168, -60.643617888840694 -51.358054964011885, -60.60694588880655 -51.34861796400309, -60.48360888869168 -51.38528196403724, -60.39744588861143 -51.42349996407283, -60.333617888551984 -51.45555496410269, -60.3133358885331 -51.46333596410993, -60.25583588847955 -51.48111796412649, -60.22264588844864 -51.486672964131664, -60.12722688835977 -51.49472696413917, -59.992363888234166 -51.46562696411207, -60.04291788828125 -51.45069996409816, -60.0624998882995 -51.42083596407035, -60.023199888262894 -51.38125496403349, -59.89417288814272 -51.37236396402521, -59.87028188812047 -51.38110896403335, -59.825835888079084 -51.40722696405768, -59.82389088807727 -51.43322696408189, -59.777781888034326 -51.44694496409467, -59.750835888009235 -51.44917296409674, -59.5136178877883 -51.46194496410864, -59.45861788773708 -51.45806396410502, -59.39535488767817 -51.43104496407986, -59.41667288769801 -51.4141729
 6406414, -59.442154887721756 -51.40479096405541, -59.44889088772803 -51.35833596401214, -59.399799887682306 -51.33764496399287, -59.21167288750709 -51.40819996405858, -59.39833588768094 -51.60264496423967, -59.431945887712246 -51.62333596425894, -59.454235887733006 -51.62104496425681, -59.57778188784806 -51.68833596431948, -59.67361788793731 -51.771663964397085, -59.83167288808451 -51.8933359645104, -59.93194588817791 -51.968608964580504, -59.953054888197556 -51.98306396459397, -60.06486388830169 -51.940563964554386, -60.18999988841824 -51.97833596458956, -60.27250888849508 -52.04361796465036, -60.26451788848763 -52.07089996467577, -60.280554888502564 -52.09611796469925, -60.31444588853414 -52.1294449647303, -60.368054888584055 -52.15917296475798, -60.598617888798785 -52.24222696483533, -60.62458188882297 -52.243199964836236, -60.657363888853496 -52.22778196482188, -60.73528188892607 -52.17778196477531, -60.86278188904481 -52.119444964720984, -60.98083588915476 -52.06195496466744, -
 60.91111788908982 -52.03110896463871, -60.82020888900516 -52.033754964641176, -60.75041788894016 -52.00659996461589, -60.813408888998836 -51.99264496460289, -60.84403588902735 -51.9619449645743, -60.76611788895478 -51.95583596456861, -60.70722688889994 -51.96167296457404, -60.67583588887071 -51.968890964580766, -60.64110888883836 -51.975008964586465, -60.53389088873851 -51.97749996458879, -60.45972688866944 -51.97083596458258, -60.43972688865081 -51.96208196457442, -60.40649988861986 -51.92409996453905, -60.42444588863658 -51.911944964527734, -60.44944588865987 -51.88305496450083, -60.45403588866414 -51.80583596442891, -60.44034588865139 -51.782844964407495, -60.38125488859636 -51.76653596439231, -60.363199888579544 -51.8064639644295, -60.37610888859156 -51.83459096445569, -60.34528188856285 -51.86083596448013)), ((-60.99305488916613 -51.96583596457792, -61.02944588920003 -51.94722696456059, -61.112154889277065 -51.89541796451234, -61.14805488931049 -51.84639096446668, -61.139163889
 30221 -51.835281964456335, -61.12264588928683 -51.821390964443395, -61.01306388918478 -51.779726964404595, -60.99917288917183 -51.77847296440343, -60.96805488914285 -51.78110896440588, -60.938545889115375 -51.80680896442982, -60.945554889121894 -51.81917296444133, -60.95667288913225 -51.826117964447796, -60.994172889167174 -51.83861796445944, -61.01389088918555 -51.84806396446824, -61.03076388920125 -51.86590896448486, -61.01639988918788 -51.869726964488414, -60.97278188914726 -51.86028196447962, -60.94944588912553 -51.853335964473146, -60.92694588910457 -51.84528196446565, -60.9072268890862 -51.836390964457365, -60.89083588907094 -51.825835964447535, -60.87528188905645 -51.83999996446073, -60.86847288905011 -51.906108964522296, -60.88110888906188 -51.93444496454869, -60.91222688909086 -51.94389096455748, -60.96805488914285 -51.95972696457223, -60.99305488916613 -51.96583596457792)), ((-60.28526388850696 -51.37564496402826, -60.27944588850154 -51.36361796401706, -60.28917288851059 -
 51.28583596394462, -60.299172888519905 -51.274444963934016, -60.29097288851227 -51.26652696392664, -60.273199888495725 -51.26514496392535, -60.07944588831528 -51.30083596395859, -60.06806388830468 -51.3074999639648, -60.0483358882863 -51.33333596398886, -60.05278188829044 -51.34667296400128, -60.11360888834709 -51.40680896405729, -60.24986388847398 -51.403199964053925, -60.268335888491194 -51.39805496404914, -60.285135888506844 -51.38403596403608, -60.28526388850696 -51.37564496402826)), ((-59.791390888047005 -51.24945496391074, -59.73194588799164 -51.2530639639141, -59.58361788785349 -51.25750896391824, -59.48319988775998 -51.26389096392418, -59.47306388775054 -51.26778196392781, -59.45083588772984 -51.30555496396299, -59.44555488772491 -51.320281963976704, -59.467781887745616 -51.335281963990674, -59.50833588778339 -51.33749996399274, -59.53833588781133 -51.33749996399274, -59.55749988782918 -51.336672963991965, -59.57361788784418 -51.33361796398912, -59.802363888057215 -51.274590
 96393415, -59.81110888806536 -51.26972696392962, -59.80514588805981 -51.25499996391591, -59.791390888047005 -51.24945496391074)))
+GUF	French Guiana	MULTIPOLYGON (((-54.60378188321566 2.3291910859882705, -54.499172883118234 2.3650000860216096, -54.420563883045034 2.434718086086548, -54.365908882994134 2.49660008614417, -54.35195488298113 2.5238910861695985, -54.32180888295305 2.5984730862390535, -54.31513588294685 2.629164086267636, -54.25695488289266 2.7188910863512064, -54.222917882860955 2.755554086385345, -54.20459088284389 2.775000086403452, -54.19528188283522 2.796245086423241, -54.16083588280314 2.9536090865697986, -54.176117882817366 3.043891086653886, -54.19574588283565 3.096200086702595, -54.2084728828475 3.124309086728772, -54.206117882845305 3.14528208674831, -54.187226882827716 3.1948640867944818, -54.11875488276395 3.27778208687171, -54.09445488274132 3.2950000868877396, -54.07110888271957 3.3127820869043063, -54.00110888265438 3.4483360870305546, -53.986117882640414 3.601527087173224, -53.99778188265128 3.626945087196887, -54.12764588277223 3.788609087347453, -54.14639088278969 3.7977820873559978
 , -54.18868188282907 3.808745087366205, -54.29028188292369 3.9338910874827633, -54.36076388298933 4.042427087583846, -54.365008882993294 4.163609087696699, -54.39389088302019 4.237218087765257, -54.43139988305512 4.369164087888137, -54.44023588306335 4.410645087926767, -54.45180888307412 4.512364088021499, -54.442917883065846 4.530691088038566, -54.42326388304754 4.5643090880698765, -54.42209088304645 4.601527088104547, -54.439726883062875 4.669164088167534, -54.47333588309418 4.734582088228464, -54.47778188309832 4.7541640882466965, -54.47610888309676 4.867773088352507, -54.45528188307736 5.004027088479404, -54.448063883070645 5.0241640884981535, -54.4086178830339 5.08055408855067, -54.37889088300622 5.112218088580164, -54.347781882977245 5.148336088613803, -54.317326882948876 5.208627088669942, -54.28348188291736 5.254864088713006, -54.244999882881515 5.2850000887410715, -54.19333588283341 5.315273088769274, -54.17069988281233 5.342218088794368, -54.16668188280859 5.34740008879919
 1, -54.1398638827836 5.357782088808861, -54.091663882738715 5.3919450888406715, -54.06959088271816 5.4180540888649915, -54.058199882707555 5.437364088882973, -54.006735882659626 5.5447910889830325, -54.003890882656975 5.575691089011798, -54.0111178826637 5.605973089040006, -54.00569988265866 5.641527089073122, -53.99222688264611 5.673054089102479, -53.981672882636275 5.690554089118777, -53.93972688259721 5.7447180891692255, -53.91139088257083 5.750282089174405, -53.858608882521665 5.755418089179187, -53.7508358824213 5.731391089156816, -53.63667288231497 5.673054089102479, -53.52236388220851 5.60471808903884, -53.49917288218691 5.58028208901608, -53.49433588218241 5.572345089008692, -53.48360888217242 5.56805408900469, -53.40833588210232 5.548891088986849, -53.30278188200401 5.52305408896278, -53.18639088189562 5.499164088940532, -53.084445881800676 5.483336088925796, -52.97319988169707 5.473054088916214, -52.93778188166408 5.458336088902513, -52.88652688161635 5.420282088867069, -5
 2.799726881535506 5.341945088794105, -52.78750888152413 5.321945088775479, -52.736390881476524 5.260554088718308, -52.611117881359846 5.129445088596199, -52.56750888131924 5.096664088565674, -52.42222688118393 4.99250008846866, -52.330699881098695 4.948891088428056, -52.28972688106053 4.938400088418277, -52.06444588085073 4.733891088227821, -52.02347288081256 4.685691088182921, -51.99694588078785 4.6430540881432165, -51.985281880776995 4.613609088115794, -51.97805488077026 4.586945088090957, -51.95625488074995 4.492364088002873, -51.950835880744904 4.456664087969628, -51.950835880744904 4.423891087939111, -51.96041788075385 4.400136087916977, -52.001254880791876 4.368891087887889, -52.029035880817744 4.352364087872488, -52.04069988082861 4.334582087855935, -51.99194588078319 4.348191087868599, -51.951181880745224 4.372636087891365, -51.92819988072384 4.400836087917639, -51.923617880719576 4.4270820879420825, -51.92639088072215 4.465282087977656, -51.929308880724875 4.486809087997699
 , -51.931399880726815 4.529164088037149, -51.931399880726815 4.570000088075176, -51.92444588072033 4.620973088122653, -51.91555488071205 4.646527088146456, -51.900008880697584 4.66180908816068, -51.8615998806618 4.659309088158352, -51.794445880599255 4.605554088108292, -51.76701788057372 4.5376360880450335, -51.75917288056641 4.500282088010252, -51.75639088056383 4.477218087988774, -51.75249988056021 4.455282087968342, -51.74417288055244 4.4211090879365145, -51.71389088052425 4.3129180878357545, -51.70249988051364 4.287082087811697, -51.6744458804875 4.253336087780269, -51.65569988047005 4.225418087754264, -51.648472880463316 4.200282087730855, -51.64805488046292 4.167218087700064, -51.65222688046683 4.1372180876721245, -51.66104588047503 4.081109087619865, -51.6744458804875 4.049445087590371, -51.68406388049647 4.034164087576144, -51.70417288051519 4.026109087568642, -51.728335880537685 4.01583608755908, -51.7538908805615 4.000554087544842, -51.77180888057819 3.9834730875289353, -5
 1.78361788058919 3.961109087508106, -51.79389088059875 3.916664087466714, -51.81232688061593 3.876818087429612, -51.906390880703526 3.7908360873495326, -51.927081880722795 3.7769450873365855, -51.98104588077305 3.7000000872649252, -51.9900088807814 3.657500087225344, -51.995835880786814 3.6258360871958644, -52.1002818808841 3.448891087031072, -52.16528188094463 3.342218086931723, -52.226745881001875 3.253054086848678, -52.24965488102322 3.2437450868400077, -52.27360888104552 3.2410450868375023, -52.34493588111195 3.157400086759594, -52.353054881119505 3.1316640867356256, -52.34486388111188 3.0884730866954015, -52.35195488111849 3.0400000866502523, -52.37917288114383 2.9741640865889423, -52.40861788117125 2.9222180865405676, -52.46417288122299 2.8133360864391648, -52.519726881274735 2.697782086331543, -52.55278188130552 2.6212450862602594, -52.539863881293485 2.586391086227806, -52.54222688129569 2.565554086208394, -52.563754881315745 2.522082086167913, -52.59445488134433 2.473891086
 1230323, -52.67562688141993 2.3741640860301487, -52.78945488152594 2.3033360859641903, -52.88278188161286 2.22471808589097, -52.89646388162561 2.2068090858742835, -52.95472688167986 2.176182085845767, -52.99430888171672 2.175691085845301, -53.054863881773116 2.1869450858557826, -53.06959088178684 2.2030540858707894, -53.087363881803384 2.2194450858860506, -53.11180888182615 2.222500085888896, -53.196108881904664 2.21360908588062, -53.23917288194477 2.2083360858757146, -53.2261088819326 2.26444508592796, -53.296535881998196 2.3190090859787773, -53.319863882019916 2.3479820860057714, -53.340563882039206 2.3496540860073196, -53.34833588204644 2.3227090859822255, -53.45861788214914 2.2575000859214924, -53.52778188221356 2.249509085914056, -53.7016638823755 2.3102820859706554, -53.72153588239401 2.3417360859999548, -53.74610888241689 2.3709730860271776, -53.77680888244548 2.3645820860212297, -53.79944588246657 2.3523640860098425, -53.91028188256979 2.2772180859398645, -53.92806388258636 
 2.2527820859171044, -53.93263588259062 2.2280540858940725, -54.10965488275548 2.113473085787362, -54.32055488295188 2.1615270858321196, -54.4646548830861 2.211736085878883, -54.51861788313634 2.2575000859214924, -54.527226883144365 2.2893090859511176, -54.541326883157495 2.3152090859752406, -54.57389088318783 2.3252820859846253, -54.59361788320619 2.329718085988759, -54.60378188321566 2.3291910859882705)))
+GUY	Guyana	MULTIPOLYGON (((-58.1726178865394 6.812218090163412, -58.154935886522935 6.828191090178279, -58.03889088641486 6.815554090166515, -57.98639088636597 6.790554090143232, -57.966672886347595 6.775418090129136, -57.94333588632587 6.750554090105979, -57.92778188631138 6.731664090088387, -57.91445488629897 6.711109090069243, -57.897917886283565 6.689864090049454, -57.88250888626922 6.674164090034836, -57.757781886153055 6.570000089937821, -57.64069988604402 6.485136089858784, -57.5943088860008 6.4345820898117125, -57.5213908859329 6.290345089677373, -57.519190885930854 6.270764089659139, -57.498617885911685 6.338682089722397, -57.469717885884776 6.34027308972388, -57.363617885785956 6.290000089677051, -57.33667288576086 6.2747180896628265, -57.261117885690496 6.2113910896038504, -57.22028188565247 6.169164089564518, -57.194308885628274 6.1393090895367095, -57.17778188561289 6.108336089507873, -57.16236388559852 6.056945089460001, -57.13576388557375 5.954100089364232, -57.175281
 88561056 5.637500089069363, -57.182781885617544 5.600691089035081, -57.195563885629454 5.568891089005476, -57.24850888567876 5.486109088928373, -57.27159988570027 5.384864088834078, -57.2994458857262 5.359718088810666, -57.32444588574948 5.303609088758407, -57.282781885710676 5.226391088686498, -57.26222688569153 5.22166408868209, -57.23520888566637 5.259945088717743, -57.20750888564058 5.223609088683901, -57.19104588562524 5.172009088635846, -57.231526885662944 5.146454088612046, -57.25055488568066 5.172636088636423, -57.27209088570072 5.177082088640574, -57.292363885719595 5.166245088630475, -57.321945885747155 5.075973088546405, -57.32722688575207 5.026109088499965, -57.41709088583576 4.989445088465814, -57.4736178858884 4.989164088465557, -57.61098188601633 4.992218088468405, -57.63417288603793 5.000282088475913, -57.67625488607713 5.011527088486389, -57.84111788623066 4.927782088408392, -57.901390886286805 4.855554088341123, -57.92333588630724 4.821945088309818, -57.92486388630
 866 4.796391088286029, -57.909026886293915 4.777782088268694, -57.88778188627413 4.7683360882599, -57.84035488622996 4.669027088167411, -57.8469458862361 4.6288910881300325, -57.902781886288096 4.503609088013349, -57.94861788633078 4.349164087869511, -57.9491728863313 4.317218087839763, -57.954517886336276 4.288336087812866, -58.00278188638123 4.239718087767585, -58.039172886415116 4.211391087741205, -58.0618088864362 4.180136087712086, -58.071399886445136 4.15569108768932, -58.04375488641939 4.001527087545753, -58.01639988639391 3.9636090875104344, -57.96889088634967 3.9291640874783553, -57.95041788633246 3.913191087463474, -57.93194588631526 3.8906910874425193, -57.876672886263776 3.8091640873665966, -57.86749988625523 3.7908360873495326, -57.85945488624775 3.771664087331672, -57.84930888623829 3.7388910873011554, -57.84597288623519 3.692636087258066, -57.83848188622821 3.6693090872363427, -57.8166728862079 3.6502820872186277, -57.76056388615565 3.624164087194302, -57.740835886137
 276 3.613745087184597, -57.66861788607001 3.5383360871143736, -57.65444588605682 3.518609087095996, -57.63840888604189 3.457009087038628, -57.65778188605992 3.4138910869984755, -57.642226886045435 3.3563910869449245, -57.61041788601581 3.3600000869482756, -57.53055488594143 3.3463910869356113, -57.42945488584728 3.3472180869363797, -57.304172885730594 3.380418086967296, -57.28354588571139 3.318682086909803, -57.29249988571972 3.2673640868620026, -57.28999988571739 3.181391086781943, -57.28361788571145 3.140973086744296, -57.255008885684816 3.103609086709497, -57.22028188565247 3.0650000866735354, -57.210281885643155 3.035836086646384, -57.207217885640304 3.004236086616956, -57.213335885646 2.878891086500218, -57.20083588563436 2.8228450864480124, -57.11688188555617 2.757191086386868, -56.94472688539584 2.4830540861315598, -56.917781885370744 2.428054086080337, -56.853890885311245 2.283336085945564, -56.810563885270895 2.1933360858617448, -56.77499988523776 2.1408360858128503, -56.68
 209088515124 2.0267640857066027, -56.64611788511773 2.028054085707808, -56.579726885055905 2.0273640857071626, -56.55597288503378 2.020554085700823, -56.47736388496057 1.9620820856463723, -56.470635884954305 1.944500085629997, -56.52555488500545 1.9225000856094994, -56.57791788505422 1.9216640856087253, -56.59499988507012 1.9322180856185582, -56.628199885101054 1.9394450856252803, -56.73500888520053 1.9141000856016746, -56.75209088521643 1.896945085585699, -56.77069088523376 1.8756270855658528, -56.87389088532987 1.8916640855807856, -57.00389088545094 1.9229180856098935, -57.050835885494664 1.9522180856371847, -57.06083588550398 1.984164085666933, -57.07423588551646 2.015764085696361, -57.10020888554064 2.0227820857029, -57.163063885599186 1.9966640856785745, -57.199172885632805 1.9711090856547742, -57.235345885666504 1.9497910856349279, -57.27667288570498 1.979509085662599, -57.298190885725035 1.9819450856648615, -57.33194588575647 1.9722180856558111, -57.42549088584359 1.901391085
 5898501, -57.42805488584597 1.8712450855617675, -57.450908885867264 1.8111090855057626, -57.512363885924486 1.730836085431008, -57.52806388593912 1.7158360854170382, -57.55930888596821 1.6997180854020257, -57.63333588603716 1.6927820853955637, -57.65361788605604 1.6966640853991777, -57.68749988608759 1.707500085409265, -57.72249988612019 1.7175000854185782, -57.75944588615461 1.717845085418901, -57.87610888626325 1.6650000853696838, -57.97249988635302 1.6134730853217008, -57.98291788636273 1.5723640852834109, -58.00715488638531 1.5156910852306282, -58.127781886497644 1.5177820852325823, -58.26833588662855 1.570554085281728, -58.29722688665545 1.5827820852931183, -58.387290886739336 1.4778450851953835, -58.50229088684644 1.454673085173809, -58.46930888681571 1.3584730850842135, -58.46764588681417 1.3376360850648013, -58.47514588682115 1.3140270850428237, -58.51961788686258 1.2696180850014542, -58.57249988691183 1.2752820850067366, -58.69299088702404 1.2847180850155269, -58.7088908870
 3885 1.2629180849952206, -58.722917887051906 1.2323640849667612, -58.751945887078946 1.209582084945552, -58.810699887133666 1.1868730849244002, -58.8363998871576 1.1902820849275741, -58.86959088718851 1.2050000849412754, -58.89840888721535 1.2311090849655955, -58.89736388721437 1.261836084994215, -58.92486388723998 1.2993090850291082, -58.95750888727039 1.3144450850432037, -58.97278188728461 1.3197180850481232, -59.104726887407494 1.3447180850714062, -59.24396388753718 1.3865270851103446, -59.41445488769595 1.5633360852750116, -59.48361788776036 1.6505540853562337, -59.50750888778262 1.6875000853906386, -59.6054178878738 1.7194450854203893, -59.64576388791137 1.735136085435002, -59.675281887938866 1.7670820854647644, -59.653617887918685 1.8022180854974863, -59.632472887899 1.8422360855347506, -59.7263178879864 1.854164085545861, -59.74902688800755 1.8613910855525972, -59.75625488801428 1.908891085596835, -59.743617888002504 2.0727820857494663, -59.727017887987046 2.241245085906357, 
 -59.73549088799494 2.2847180859468494, -59.79319988804869 2.297782085959014, -59.84972688810133 2.330554085989533, -59.893263888141874 2.3641000860207697, -59.901672888149704 2.384445086039719, -59.88889088813781 2.407082086060811, -59.89278188814143 2.4544450861049114, -59.925563888171965 2.567782086210471, -59.9541728881986 2.616391086255746, -59.98847288823055 2.688191086322604, -59.98278188822525 2.860282086482883, -59.97889088822163 2.899164086519093, -59.96278188820662 3.025836086637071, -59.949717888194456 3.071945086680003, -59.90472688815255 3.2041640868031465, -59.869726888119956 3.2763910868704187, -59.85611788810728 3.2977820868903365, -59.83569988808827 3.322082086912971, -59.810835888065114 3.3595820869478956, -59.81444588806848 3.498745087077495, -59.831945888084775 3.5241640871011697, -59.786117888042085 3.620554087190939, -59.6655548879298 3.711391087275544, -59.56860888783952 3.8994450874506725, -59.58167288785168 3.9988910875432992, -59.70861788796991 4.1706910877
 0329, -59.722226887982586 4.191391087722579, -59.73110888799086 4.219164087748439, -59.73083588799061 4.293336087817522, -59.675281887938866 4.373336087892028, -59.67444588793809 4.385136087903007, -59.71722688797793 4.414164087930047, -59.79111788804674 4.456109087969111, -59.94180888818708 4.508054088017488, -59.96778188821128 4.501945088011794, -60.045281888283455 4.4940270880044295, -60.13069988836301 4.509718088019042, -60.14847288837956 4.52000008802861, -60.152226888383055 4.5733360880782925, -60.12389088835667 4.596664088100013, -60.09152688832653 4.600691088103758, -60.07209088830842 4.618473088120325, -60.02583588826535 4.707218088202978, -60.02056388826044 4.734445088228327, -60.00583588824672 4.8369450883237874, -59.983063888225516 5.022500088496599, -60.013890888254224 5.11000008857809, -60.080872888316605 5.161509088626062, -60.081945888317605 5.1730540886368175, -60.09833588833287 5.217218088677953, -60.114581888348 5.245691088704461, -60.202363888429744 5.27270908872
 9627, -60.24999988847412 5.2584730887163715, -60.268408888491265 5.235282088694774, -60.317845888537306 5.197636088659706, -60.54639088875015 5.191391088653901, -60.5738268887757 5.197154088659261, -60.597426888797685 5.211945088673033, -60.689445888883384 5.216109088676916, -60.730372888921494 5.2048000886663885, -60.748890888938746 5.222500088682864, -60.781108888968745 5.2583360887162485, -60.86028188904248 5.348054088799799, -61.11610888928074 5.63471808906678, -61.38972688953557 5.940000089351088, -61.37345488952042 5.960973089370626, -61.3378908894873 5.972782089381624, -61.32306388947349 5.992500089399982, -61.282817889436004 6.056336089459435, -61.270281889424325 6.086391089487435, -61.26278188941734 6.107782089507353, -61.160145889321754 6.1825000895769335, -61.1386178893017 6.29916408968559, -61.140008889303004 6.408609089787518, -61.19652688935564 6.533682089904005, -61.20472688936327 6.5779180899452, -61.174445889335075 6.658745090020474, -61.12510888928912 6.71477309007
 2654, -61.05472688922357 6.72889109008581, -61.03597288920611 6.719718090077265, -60.93965488911641 6.724582090081796, -60.89368188907359 6.765000090119429, -60.81611788900135 6.788336090141172, -60.71917288891106 6.759027090113875, -60.69778188889114 6.766664090120983, -60.676390888871225 6.790000090142712, -60.66499988886062 6.80750009015901, -60.63778188883526 6.834927090184564, -60.590835888791545 6.85083609019938, -60.526945888732044 6.87471809022162, -60.498890888705915 6.8877820902337845, -60.463617888673056 6.906664090251368, -60.40833588862158 6.947500090289395, -60.29125488851254 7.056600090391015, -60.28139088850335 7.090000090422109, -60.278054888500236 7.118745090448883, -60.309035888529095 7.143473090471915, -60.33667288855483 7.155282090482913, -60.36049088857702 7.176245090502434, -60.45611788866607 7.195836090520686, -60.50576388871231 7.17270909049914, -60.51499988872092 7.142982090471463, -60.5380638887424 7.124445090454188, -60.61749988881638 7.19444509051938, -6
 0.6308358888288 7.221945090544992, -60.63423588883197 7.254309090575134, -60.61861788881741 7.2840270906028195, -60.595354888795754 7.30610909062338, -60.59139088879206 7.336391090651588, -60.6099998888094 7.381945090694003, -60.66083588885674 7.447218090754802, -60.688263888882275 7.453473090760625, -60.714026888906275 7.500973090804862, -60.71666388890873 7.540000090841204, -60.691108888884926 7.567082090866435, -60.662090888857904 7.566527090865918, -60.58875488878961 7.639309090933693, -60.57458188877641 7.7152090910043825, -60.533335888737994 7.803891091086982, -60.51319988871924 7.818191091100289, -60.31972688853905 7.877500091155525, -60.25754588848115 7.921573091196578, -60.23722688846222 7.946391091219695, -60.12486388835757 8.028327091296006, -60.09360888832846 8.041245091308028, -60.03778188827647 8.037009091304085, -60.0111818882517 8.059236091324792, -59.98701788822919 8.1469820914065, -59.9797268882224 8.174864091432468, -59.94618188819116 8.199991091455871, -59.922226
 88816885 8.211109091466227, -59.88889088813781 8.218609091473212, -59.83285488808562 8.231527091485248, -59.80305488805786 8.2833360915335, -59.81209088806628 8.306109091554703, -59.88611788813522 8.40083609164293, -59.98111788822369 8.518327091752354, -59.99028188823223 8.535273091768133, -59.95819988820236 8.514027091748346, -59.92930888817544 8.48416409172053, -59.902572888150544 8.445764091684765, -59.88945488813833 8.421664091662322, -59.87250888812255 8.397218091639559, -59.85583588810702 8.379445091622998, -59.83167288808451 8.361664091606443, -59.78625488804222 8.340973091587173, -59.76472688802217 8.349027091594678, -59.77930888803574 8.380973091624426, -59.764208888021685 8.407364091649, -59.6683358879324 8.360000091604888, -59.6508358879161 8.349445091595058, -59.35583588764136 8.173891091431571, -59.15472688745406 8.05639109132214, -59.12930888743038 8.040000091306865, -59.109445887411894 8.018473091286822, -59.09347288739701 7.987009091257519, -59.07583588738059 7.96916
 40912408985, -58.94389088725771 7.851109091130951, -58.80694588713017 7.730554091018675, -58.76889088709473 7.679718090971335, -58.751399887078435 7.6361090909307165, -58.71736388704673 7.59437309089185, -58.6419458869765 7.569445090868626, -58.48528188683059 7.368609090681588, -58.46854588681501 7.337573090652683, -58.465563886812234 7.135836090464807, -58.46666388681325 7.115000090445392, -58.4815268868271 7.009927090347546, -58.497508886841985 6.989445090328459, -58.51074588685431 6.980254090319903, -58.53709088687884 6.96069109030168, -58.55569988689618 6.937500090280082, -58.56305488690302 6.916391090260433, -58.59403588693188 6.801809090153711, -58.598608886936134 6.774309090128099, -58.60917288694597 6.656664090018538, -58.619090886955206 6.489491089862852, -58.637090886971976 6.421945089799934, -58.600726886938105 6.413945089792492, -58.59333588693123 6.420000089798123, -58.58132688692004 6.464973089840015, -58.574026886913245 6.509864089881816, -58.57278188691208 6.53250008
 9902896, -58.576117886915185 6.562218089930582, -58.57319988691248 6.602636089968215, -58.54972688689061 6.6782640900386525, -58.47944588682516 6.794445090146851, -58.45695488680421 6.827782090177905, -58.41972688676954 6.870282090217486, -58.39833588674962 6.879309090225888, -58.3165998866735 6.894236090239801, -58.25569988661678 6.876109090222911, -58.208617886572924 6.843054090192126, -58.1726178865394 6.812218090163412)))
+PCN	Pitcairn Is.	MULTIPOLYGON (((-128.33221795188064 -24.32726393883749, -128.3269359518757 -24.326117938836433, -128.31042695186034 -24.325835938836164, -128.30168195185217 -24.334445938844183, -128.29388195184492 -24.352499938861, -128.2866819518382 -24.38639093889256, -128.2861179518377 -24.40166393890678, -128.29111795184235 -24.411390938915844, -128.30156395185207 -24.411672938916112, -128.3130819518628 -24.404717938909627, -128.3278179518765 -24.390554938896443, -128.34308195189075 -24.367217938874703, -128.34695495189436 -24.353617938862044, -128.34600895189345 -24.33819993884768, -128.336945951885 -24.329163938839258, -128.33221795188064 -24.32726393883749)), ((-130.08139095350967 -25.082226939540604, -130.09068195351833 -25.080699939539187, -130.10262695352944 -25.074445939533362, -130.1050549535317 -25.061463939521275, -130.0905639535182 -25.055699939515904, -130.06384595349334 -25.06826393952761, -130.0769359535055 -25.079726939538276, -130.08139095350967 -25.082226939540
 604)))
+SGS	South Georgia & the South Sandwich Is.	MULTIPOLYGON (((-36.99139086681285 -54.35056396679887, -36.99972686682062 -54.348617966797065, -37.05944586687622 -54.329999966779724, -37.08375486689886 -54.31881796676931, -37.08222686689746 -54.29389096674609, -37.146117866956956 -54.26139096671582, -37.241808867046075 -54.247363966702764, -37.266254867068824 -54.25875496671337, -37.365835867161564 -54.271944966725655, -37.408335867201146 -54.26493596671913, -37.403472867196626 -54.18500896664469, -37.367226867162884 -54.17556396663589, -37.33555486713337 -54.17361796663408, -37.25208186705564 -54.15229096661422, -37.48986386727708 -54.12944496659294, -37.56118186734349 -54.14607296660843, -37.52944586731394 -54.16250896662373, -37.56222686734449 -54.170563966631235, -37.58944586736982 -54.17528196663563, -37.650417867426626 -54.18167296664158, -37.68528186745908 -54.17528196663563, -37.71917286749064 -54.140563966603295, -37.71757286748917 -54.09416396656008, -37.676390867450806 -54.074
 717966541975, -37.653826867429785 -54.072154966539586, -37.61979086739808 -54.04611796651534, -37.69221786746553 -54.034999966504984, -37.89778186765699 -54.04722696651637, -38.02257286777322 -54.054726966523354, -38.0237548677743 -54.00743596647931, -37.93361786769037 -53.99222696646515, -37.91028186766863 -53.98972696646282, -37.74721786751675 -53.99499996646773, -37.49499986728188 -54.01056396648222, -37.46139986725058 -54.036117966506026, -37.37389086716908 -54.04805496651714, -37.27028186707258 -54.050281966519215, -37.162781866972466 -54.03139096650162, -37.02778186684674 -54.05611796652465, -36.80944586664339 -54.08833596655465, -36.65639086650086 -54.107781966572766, -36.62375486647045 -54.120699966584795, -36.584163866433585 -54.20889096666693, -36.66757286651128 -54.24409996669972, -36.662645866506665 -54.27514496672863, -36.62667286647317 -54.28361796673653, -36.604026866452074 -54.26611796672023, -36.55680886640812 -54.245563966701084, -36.517081866371115 -54.23445496669
 074, -36.47889086633555 -54.23889096669487, -36.47263586632971 -54.26513596671931, -36.456117866314344 -54.3275089667774, -36.36999986623414 -54.35499996680301, -36.33667286620309 -54.35229096680048, -36.362090866226765 -54.293054966745316, -36.38368186624686 -54.27826396673154, -36.394799866257216 -54.24917296670444, -36.290208866159816 -54.26583596671996, -36.257226866129116 -54.28666396673936, -36.22917286610297 -54.33778196678697, -36.25610886612807 -54.36847296681555, -36.15999986603856 -54.44472696688657, -36.09680886597971 -54.54959096698423, -36.06389086594905 -54.57153596700467, -35.979726865870674 -54.57889096701152, -35.93471786582873 -54.62306396705266, -35.933890865827976 -54.700563967124836, -35.917363865812575 -54.715144967138414, -35.85667286575605 -54.74305496716441, -35.8280548657294 -54.75083596717165, -35.79396386569766 -54.76020896718038, -35.82778186572915 -54.79278196721072, -35.914172865809604 -54.81347296722999, -35.95944586585176 -54.81110896722779, -35.979
 726865870674 -54.80917296722598, -36.0006998658902 -54.80083596721822, -36.02528186591309 -54.787781967206065, -36.04583586593222 -54.77889096719778, -36.074717865959116 -54.768054967187695, -36.095308865978296 -54.76993596718945, -36.02111786590922 -54.81721796723348, -35.98972686587999 -54.8305549672459, -35.96430886585631 -54.83167296724694, -35.923617865818414 -54.8504179672644, -35.96139986585359 -54.86944496728212, -36.07639086596069 -54.890281967301526, -36.10472686598709 -54.88923596730055, -36.131463866011984 -54.8688909672816, -36.19917286607503 -54.80917296722598, -36.29749986616662 -54.733335967155355, -36.30250886617128 -54.71305496713647, -36.31721786618496 -54.686954967112165, -36.46860886632598 -54.52889096696495, -36.525908866379325 -54.497081966935326, -36.582226866431796 -54.49986396693792, -36.65555486650007 -54.491108966929765, -36.736945866575866 -54.47028196691037, -36.809799866643715 -54.44541796688721, -36.801108866635644 -54.41118196685533, -36.864935866695
 08 -54.34652696679511, -36.92528186675128 -54.337917966787096, -36.99139086681285 -54.35056396679887)), ((-26.248890856808117 -58.49860897066204, -26.264163856822336 -58.48806397065222, -26.290972856847304 -58.47861797064343, -26.37167285692246 -58.46305497062893, -26.389726856939262 -58.45972697062583, -26.406526856954912 -58.45944497062557, -26.41999985696748 -58.45667297062299, -26.458199857003052 -58.430699970598795, -26.433608856980157 -58.38916397056011, -26.416663856964362 -58.38360897055494, -26.403890856952472 -58.382508970553914, -26.39305485694237 -58.38278197055417, -26.317781856872273 -58.38639097055753, -26.29152685684781 -58.38806397055909, -26.265699856823773 -58.39417297056478, -26.246672856806043 -58.404444970574346, -26.241390856801132 -58.47167297063696, -26.243617856803212 -58.49472697065843, -26.248890856808117 -58.49860897066204)))
+SHN	St. Helena	MULTIPOLYGON (((-5.712972837682543 -15.992863931075476, -5.729163837697627 -16.005490931087238, -5.768472837734237 -16.021945931102564, -5.787217837751683 -16.009163931090654, -5.792781837756877 -15.991108931073839, -5.768890837734631 -15.94736393103311, -5.748608837715722 -15.929163931016149, -5.728890837697378 -15.91389093100193, -5.716390837685736 -15.905281930993908, -5.699517837670015 -15.903754930992491, -5.671390837643827 -15.90944593099779, -5.645281837619507 -15.93999993102625, -5.646390837620544 -15.958335931043322, -5.660417837633588 -15.985690931068802, -5.700417837670841 -16.003754931085624, -5.7105548376802915 -15.996390931078764, -5.712972837682543 -15.992863931075476)))
+SUR	Suriname	MULTIPOLYGON (((-55.12796388370384 5.82217308924136, -55.10444588368195 5.839445089257438, -55.01610888359967 5.850418089267663, -54.946672883535 5.846109089263649, -54.86444588345843 5.855136089272051, -54.88729088347971 5.879545089294794, -54.9688908835557 5.873336089289012, -54.99534588358034 5.865764089281953, -55.10625488368363 5.904582089318112, -55.14472688371946 5.934164089345657, -55.15944588373317 5.9634000893728825, -55.047363883628776 6.001809089408653, -54.97028188355699 5.988054089395845, -54.87694588347007 5.985282089393266, -54.77944588337927 5.982500089390669, -54.70994588331453 5.962436089371991, -54.639163883248614 5.954718089364803, -54.34445488297415 5.906945089320303, -54.29861788293145 5.898054089312026, -54.204726882844014 5.879718089294954, -54.17860888281969 5.871391089287201, -54.02556388267716 5.818609089238038, -53.990208882644225 5.746945089171291, -54.00652688265943 5.721245089147359, -54.04646388269663 5.653536089084298, -54.0515358827013
 44 5.590209089025322, -54.05180888270159 5.527082088966537, -54.067781882716474 5.491527088933424, -54.095835882742605 5.458054088902244, -54.120490882765566 5.431600088877616, -54.142226882785806 5.39527308884378, -54.16668188280859 5.347400088799191, -54.17069988281233 5.342218088794368, -54.19333588283341 5.315273088769274, -54.244999882881515 5.2850000887410715, -54.28348188291736 5.254864088713006, -54.317326882948876 5.208627088669942, -54.347781882977245 5.148336088613803, -54.37889088300622 5.112218088580164, -54.4086178830339 5.08055408855067, -54.448063883070645 5.0241640884981535, -54.45528188307736 5.004027088479404, -54.47610888309676 4.867773088352507, -54.47778188309832 4.7541640882466965, -54.47333588309418 4.734582088228464, -54.439726883062875 4.669164088167534, -54.42209088304645 4.601527088104547, -54.42326388304754 4.5643090880698765, -54.442917883065846 4.530691088038566, -54.45180888307412 4.512364088021499, -54.44023588306335 4.410645087926767, -54.4313998830
 5512 4.369164087888137, -54.39389088302019 4.237218087765257, -54.365008882993294 4.163609087696699, -54.36076388298933 4.042427087583846, -54.29028188292369 3.9338910874827633, -54.18868188282907 3.808745087366205, -54.14639088278969 3.7977820873559978, -54.12764588277223 3.788609087347453, -53.99778188265128 3.626945087196887, -53.986117882640414 3.601527087173224, -54.00110888265438 3.4483360870305546, -54.07110888271957 3.3127820869043063, -54.09445488274132 3.2950000868877396, -54.11875488276395 3.27778208687171, -54.187226882827716 3.1948640867944818, -54.206117882845305 3.14528208674831, -54.2084728828475 3.124309086728772, -54.19574588283565 3.096200086702595, -54.176117882817366 3.043891086653886, -54.16083588280314 2.9536090865697986, -54.19528188283522 2.796245086423241, -54.20459088284389 2.775000086403452, -54.222917882860955 2.755554086385345, -54.25695488289266 2.7188910863512064, -54.31513588294685 2.629164086267636, -54.32180888295305 2.5984730862390535, -54.3519548
 8298113 2.5238910861695985, -54.365908882994134 2.49660008614417, -54.420563883045034 2.434718086086548, -54.499172883118234 2.3650000860216096, -54.60378188321566 2.3291910859882705, -54.63472688324448 2.3200730859797716, -54.687499883293626 2.3255540859848765, -54.709099883313755 2.3879180860429585, -54.69020888329615 2.3995090860537545, -54.68986388329583 2.4516000861022604, -54.75312688335475 2.4706270861199897, -54.77538188337547 2.456845086107151, -54.80375488340191 2.4380540860896502, -54.84749988344264 2.436109086087839, -54.86916388346282 2.44194508609327, -54.96944588355622 2.550554086194424, -55.091945883670306 2.53471808617968, -55.11194588368893 2.527218086172695, -55.50333588405344 2.438891086090436, -55.71368188424934 2.4001360860543315, -55.86409988438943 2.471454086120758, -55.88639088441019 2.49708208614463, -55.91750888443917 2.5206910861666074, -55.94180888446179 2.5305540861757976, -55.96278188448133 2.533054086178126, -55.98249988449969 2.522082086167913, -56.0
 0041788451638 2.4508360861015603, -56.08444588459464 2.3575000860146247, -56.11583588462388 2.2491640859137334, -56.03639088454989 2.208891085876232, -55.90396388442656 2.0477820857261833, -55.90173588442448 1.90104508558953, -55.94264588446258 1.856109085547672, -55.96583588448418 1.8452820855375904, -55.99597288451224 1.8376360855304625, -56.0274998845416 1.8362450855291712, -56.06806388457939 1.8455540855378416, -56.11333588462155 1.863609085554657, -56.201663884703805 1.8916640855807856, -56.326954884820495 1.9252820856120962, -56.426390884913104 1.9341640856203668, -56.470635884954305 1.944500085629997, -56.47736388496057 1.9620820856463723, -56.55597288503378 2.020554085700823, -56.579726885055905 2.0273640857071626, -56.64611788511773 2.028054085707808, -56.68209088515124 2.0267640857066027, -56.77499988523776 2.1408360858128503, -56.810563885270895 2.1933360858617448, -56.853890885311245 2.283336085945564, -56.917781885370744 2.428054086080337, -56.94472688539584 2.483054086
 1315598, -57.11688188555617 2.757191086386868, -57.20083588563436 2.8228450864480124, -57.213335885646 2.878891086500218, -57.207217885640304 3.004236086616956, -57.210281885643155 3.035836086646384, -57.22028188565247 3.0650000866735354, -57.255008885684816 3.103609086709497, -57.28361788571145 3.140973086744296, -57.28999988571739 3.181391086781943, -57.29249988571972 3.2673640868620026, -57.28354588571139 3.318682086909803, -57.304172885730594 3.380418086967296, -57.42945488584728 3.3472180869363797, -57.53055488594143 3.3463910869356113, -57.61041788601581 3.3600000869482756, -57.642226886045435 3.3563910869449245, -57.65778188605992 3.4138910869984755, -57.63840888604189 3.457009087038628, -57.65444588605682 3.518609087095996, -57.66861788607001 3.5383360871143736, -57.740835886137276 3.613745087184597, -57.76056388615565 3.624164087194302, -57.8166728862079 3.6502820872186277, -57.83848188622821 3.6693090872363427, -57.84597288623519 3.692636087258066, -57.84930888623829 3.738
 8910873011554, -57.85945488624775 3.771664087331672, -57.86749988625523 3.7908360873495326, -57.876672886263776 3.8091640873665966, -57.93194588631526 3.8906910874425193, -57.95041788633246 3.913191087463474, -57.96889088634967 3.9291640874783553, -58.01639988639391 3.9636090875104344, -58.04375488641939 4.001527087545753, -58.071399886445136 4.15569108768932, -58.0618088864362 4.180136087712086, -58.039172886415116 4.211391087741205, -58.00278188638123 4.239718087767585, -57.954517886336276 4.288336087812866, -57.9491728863313 4.317218087839763, -57.94861788633078 4.349164087869511, -57.902781886288096 4.503609088013349, -57.8469458862361 4.6288910881300325, -57.84035488622996 4.669027088167411, -57.88778188627413 4.7683360882599, -57.909026886293915 4.777782088268694, -57.92486388630866 4.796391088286029, -57.92333588630724 4.821945088309818, -57.901390886286805 4.855554088341123, -57.84111788623066 4.927782088408392, -57.67625488607713 5.011527088486389, -57.63417288603793 5.0002
 82088475913, -57.61098188601633 4.992218088468405, -57.4736178858884 4.989164088465557, -57.41709088583576 4.989445088465814, -57.32722688575207 5.026109088499965, -57.321945885747155 5.075973088546405, -57.292363885719595 5.166245088630475, -57.27209088570072 5.177082088640574, -57.25055488568066 5.172636088636423, -57.231526885662944 5.146454088612046, -57.19104588562524 5.172009088635846, -57.20750888564058 5.223609088683901, -57.23520888566637 5.259945088717743, -57.26222688569153 5.22166408868209, -57.282781885710676 5.226391088686498, -57.32444588574948 5.303609088758407, -57.2994458857262 5.359718088810666, -57.27159988570027 5.384864088834078, -57.24850888567876 5.486109088928373, -57.18430888561896 5.51889108895891, -57.16742688560325 5.541391088979864, -57.13889088557667 5.671664089101185, -57.13597288557395 5.6925000891205855, -57.13249988557071 5.767500089190435, -57.06791788551057 5.941736089352716, -56.992499885440324 5.989445089397137, -56.96444588541421 5.99708208940
 4259, -56.70056388516845 5.965554089374891, -56.60361788507815 5.940500089351559, -56.55445488503237 5.948336089358861, -56.48000888496304 5.945418089356139, -56.26056388475867 5.889164089303748, -56.01778188453255 5.818336089237789, -55.910554884432685 5.778364089200565, -55.89444588441769 5.730273089155773, -55.89860888442156 5.67444508910377, -55.89955488442244 5.671909089101419, -55.885972884409796 5.683054089111792, -55.87778188440217 5.717636089143994, -55.89110888441458 5.775836089198208, -55.922717884444026 5.876073089291552, -55.85583588438173 5.948891089359378, -55.8277818843556 5.958336089368174, -55.76806388429999 5.967218089376445, -55.62028188416235 5.974445089383167, -55.548617884095606 5.977782089386281, -55.4127818839691 5.964164089373597, -55.37722688393599 5.960000089369714, -55.33902688390042 5.950136089360527, -55.266672883833024 5.923609089335827, -55.25389088382113 5.915836089328593, -55.230563883799405 5.898054089312026, -55.174999883747645 5.9072180893205655
 , -55.11555488369228 5.876982089292397, -55.11402688369087 5.8400000892579556, -55.12796388370384 5.82217308924136)))
+TTO	Trinidad & Tobago	MULTIPOLYGON (((-61.0794458892466 10.824164093899824, -61.075563889242986 10.826109093901636, -61.02541788919628 10.840273093914831, -60.92833588910587 10.838609093913277, -60.90923588908808 10.827009093902475, -60.92305488910094 10.797218093874733, -60.94445488912088 10.762218093842137, -60.96305488913819 10.739164093820662, -60.98722688916071 10.714718093797899, -61.01791788918929 10.698473093782766, -61.03417288920443 10.678191093763871, -61.0454178892149 10.489164093587831, -61.02097288919214 10.392218093497547, -60.99860888917131 10.351600093459723, -61.00444588917675 10.149582093271576, -61.083617889250476 10.102773093227981, -61.10722688927247 10.091945093217888, -61.15222688931438 10.075554093202626, -61.202917889361586 10.069164093196676, -61.405281889550054 10.066945093194605, -61.526672889663104 10.06833609319591, -61.67708188980319 10.076109093203144, -61.7055548898297 10.07889109320574, -61.80611788992336 10.0811090932078, -61.83361788994897 10.071
 391093198756, -61.858335889972 10.06221809319021, -61.88028188999243 10.042500093171839, -61.90951789001966 10.040345093169833, -61.92159989003092 10.064864093192668, -61.817781889934224 10.127773093251264, -61.6477818897759 10.19721809331594, -61.50409988964209 10.237636093353572, -61.46139088960231 10.274309093387728, -61.4537548895952 10.294164093406224, -61.46305488960385 10.571245093664274, -61.47361788961369 10.597773093688986, -61.49583588963439 10.63527309372391, -61.54625488968135 10.669445093755726, -61.60125488973257 10.684582093769833, -61.62291788975274 10.678891093764534, -61.65778188978521 10.680064093765623, -61.662017889789155 10.708400093792008, -61.60278188973399 10.74221809382351, -61.47999988961965 10.75055409383127, -61.42854588957172 10.753954093834437, -61.384590889530784 10.779718093858435, -61.24249988939846 10.790273093868265, -61.19639988935552 10.789445093867485, -61.17180888933261 10.79910009387649, -61.1433358893061 10.815273093891548, -61.079445889246
 6 10.824164093899824)), ((-60.79749988898402 11.14166409419552, -60.84493588902819 11.157218094210009, -60.847226889030324 11.176945094228373, -60.756672888945985 11.242218094289171, -60.70083588889399 11.275836094320482, -60.65778188885389 11.301391094344282, -60.5295908887345 11.345554094385406, -60.52083588872635 11.330554094371436, -60.52472688872997 11.273891094318671, -60.53180888873656 11.259027094304827, -60.64180888883901 11.202218094251919, -60.66889088886424 11.198891094248822, -60.68778188888183 11.201945094251656, -60.73875488892931 11.182636094233672, -60.758199888947416 11.171245094223067, -60.79749988898402 11.14166409419552)))
+VEN	Venezuela	MULTIPOLYGON (((-66.3102908941182 10.626018093715288, -66.28309089409287 10.64465409373264, -66.22987289404331 10.640554093728824, -66.0816818939053 10.576664093669322, -66.11972689394072 10.500000093597919, -65.95861789379067 10.356664093464431, -65.93573589376938 10.298300093410077, -65.81445489365642 10.228336093344922, -65.0813908929737 10.060554093188657, -64.76445489267853 10.097218093222807, -64.73279089264904 10.113473093237943, -64.71473589263222 10.179718093299641, -64.62597289254956 10.246664093361986, -64.57972689250649 10.25860909337311, -64.48250889241595 10.238054093353966, -64.37854589231912 10.301109093412691, -64.39584589233523 10.337218093446324, -64.36805489230936 10.384164093490043, -64.18205489213612 10.456545093557452, -63.80944589178911 10.442218093544113, -63.697499891684856 10.485554093584469, -63.83889089181653 10.551664093646039, -63.966390891935276 10.578473093671008, -64.14868189210505 10.570000093663111, -64.20098189215375 10.550273093644
 748, -64.23569089218608 10.514373093611312, -64.29959089224559 10.626527093715765, -64.264590892213 10.657773093744865, -64.1468088921033 10.617918093707743, -63.84278189182015 10.645827093733743, -63.534445891533 10.627082093716282, -63.25306389127094 10.678336093764017, -63.17222689119565 10.719718093802555, -62.99375489102944 10.716391093799459, -62.90667289094833 10.695836093780315, -62.697499890753534 10.747773093828684, -62.19250889028322 10.694164093778753, -61.87959088999179 10.728327093810577, -61.88333588999528 10.694718093779272, -61.9530548900602 10.648891093736594, -62.0855548901836 10.627218093716408, -62.249172890335984 10.627009093716211, -62.331108890412295 10.531664093627413, -62.527226890594946 10.540418093635566, -62.64972689070903 10.568191093661426, -62.91229989095358 10.528745093624693, -63.0042358910392 10.45298209355414, -62.87250889091652 10.524445093620685, -62.83860889088494 10.511664093608786, -62.8377088908841 10.397291093502275, -62.87180889091586 10.3
 89864093495348, -62.934308890974066 10.418473093521996, -63.00368189103868 10.394164093499356, -62.998408891033776 10.271600093385217, -62.93417289097394 10.279309093392385, -62.946663890985576 10.400900093505626, -62.8847358909279 10.374391093480938, -62.790090890839764 10.401336093506032, -62.73639089078975 10.37381809348041, -62.66639089072456 10.280554093393548, -62.630626890691246 10.107154093232054, -62.669308890727265 10.075000093202107, -62.82917289087615 10.053609093182189, -62.95694589099516 10.104309093229404, -63.015972891050126 10.095691093221376, -62.983854891020215 10.068918093196444, -62.91056389095196 10.076945093203918, -62.805281890853905 10.00860909314028, -62.66278189072119 10.059164093187363, -62.6157638906774 10.093191093219048, -62.605417890667766 10.127218093250747, -62.62333589068446 10.188609093307917, -62.60944589067152 10.223954093340836, -62.577499890641775 10.22513609334193, -62.48889089055925 10.153054093274804, -62.42694589050156 9.979164093112857, -
 62.31518189039747 9.752845092902078, -62.32264589040442 9.712082092864122, -62.277226890362115 9.747500092897099, -62.23680889032447 9.855000092997216, -62.25049089033722 9.967009093101538, -62.205699890295506 9.914027093052198, -62.165345890257925 9.715282092867099, -62.19610889028657 9.641664092798536, -62.17076389026296 9.657427092813222, -62.130008890225014 9.752109092901392, -62.133499890228265 9.82644509297063, -62.02743589012948 9.866418093007852, -62.11222689020845 9.929445093066548, -62.20153589029162 9.938336093074838, -62.231735890319754 9.964718093099407, -62.2092358902988 10.011036093142536, -62.17889089027054 10.014718093145973, -62.05389089015412 9.977500093111303, -61.96222689006875 9.91194509305025, -61.81167288992853 9.757891092906789, -61.73583588985791 9.600936092760605, -61.73333588985558 9.698745092851695, -61.80091788991852 9.812273092957426, -61.79278188991094 9.83110909297497, -61.77194588989154 9.830273092974195, -61.59770888972926 9.782773092929958, -61.57
 458188970773 9.800691092946636, -61.64805488977615 9.897364093036671, -61.619863889749894 9.90528209304405, -61.48056388962017 9.823609092967985, -61.407226889551865 9.704718092857263, -61.255981889411004 9.588891092749392, -61.04333588921297 9.575554092736965, -60.98757288916103 9.551809092714848, -60.85361788903627 9.444445092614856, -60.79819988898467 9.379309092554195, -60.78361788897108 9.305000092484988, -60.81889088900394 9.26889109245137, -60.987781889161226 9.188609092376595, -61.08459088925139 9.097500092291739, -61.098126889263995 9.043954092241876, -60.972708889147185 9.175209092364113, -60.9504908891265 9.175136092364042, -61.031535889201976 9.032082092230823, -61.09778188926367 8.963336092166799, -61.183335889343354 8.727782091947418, -61.210208889368374 8.595136091823875, -61.25090888940629 8.581454091811139, -61.436672889579285 8.60166409182996, -61.51972688965664 8.590418091819487, -61.59541788972713 8.616945091844187, -61.59889088973037 8.555000091786496, -61.39389
 088953945 8.474445091711473, -61.32917288947917 8.430827091670864, -61.16847288932951 8.495764091731331, -61.0775088892448 8.493054091728808, -61.0861088892528 8.421391091662073, -61.0735458892411 8.402918091644864, -61.017781889189166 8.46916409170656, -60.98125488915515 8.564445091795292, -60.71583588890796 8.604582091832683, -60.62716388882538 8.551182091782948, -60.46583588867513 8.5282640917616, -60.40875488862197 8.621600091848535, -60.23611788846118 8.627500091854017, -59.99028188823223 8.535273091768133, -59.80305488805786 8.2833360915335, -59.83285488808562 8.231527091485248, -59.92222688816885 8.211109091466227, -59.9797268882224 8.174864091432468, -60.0111818882517 8.059236091324792, -60.03778188827647 8.037009091304085, -60.12486388835757 8.028327091296006, -60.31972688853905 7.877500091155525, -60.533335888737994 7.803891091086982, -60.58875488878961 7.639309090933693, -60.662090888857904 7.566527090865918, -60.691108888884926 7.567082090866435, -60.71666388890873 7.540
 000090841204, -60.688263888882275 7.453473090760625, -60.66083588885674 7.447218090754802, -60.59139088879206 7.336391090651588, -60.63423588883197 7.254309090575134, -60.61749988881638 7.19444509051938, -60.5380638887424 7.124445090454188, -60.50576388871231 7.17270909049914, -60.45611788866607 7.195836090520686, -60.36049088857702 7.176245090502434, -60.278054888500236 7.118745090448883, -60.29125488851254 7.056600090391015, -60.463617888673056 6.906664090251368, -60.63778188883526 6.834927090184564, -60.69778188889114 6.766664090120983, -60.81611788900135 6.788336090141172, -60.89368188907359 6.765000090119429, -60.93965488911641 6.724582090081796, -61.12510888928912 6.714773090072654, -61.174445889335075 6.658745090020474, -61.20472688936327 6.5779180899452, -61.140008889303004 6.408609089787518, -61.160145889321754 6.1825000895769335, -61.26278188941734 6.107782089507353, -61.3378908894873 5.972782089381624, -61.38972688953557 5.940000089351088, -60.748890888938746 5.2225000886
 82864, -60.65520888885149 5.181318088644517, -60.5785458887801 4.952636088431532, -60.649308888845994 4.842918088329355, -60.7202818889121 4.776109088267134, -60.88652688906693 4.709718088205307, -60.92986388910728 4.591873088095554, -60.987090889160584 4.519309088027967, -61.163890889325245 4.494309088004684, -61.313608889464675 4.506664088016194, -61.50736388964512 4.390554087908058, -61.51069988964824 4.3034730878269585, -61.55438188968891 4.248818087776058, -61.69917288982376 4.259027087785569, -61.76291788988313 4.2430540877706875, -61.8488908899632 4.160554087693853, -61.914863890024634 4.146945087681175, -61.987499890092295 4.169582087702267, -62.05319989015348 4.150136087684146, -62.14264589023678 4.093191087631112, -62.440135890513844 4.1826730877144485, -62.539935890606785 4.112291087648913, -62.6041638906666 4.041945087583386, -62.72833589078225 4.038609087580284, -62.75778189080967 4.020273087563211, -62.78041789083075 3.9087450874593372, -62.72749989078147 3.73110908729
 3902, -62.73402689078755 3.6765270872430733, -62.78125489083153 3.604309087175807, -62.878054890921675 3.5601360871346657, -62.99056389102647 3.604309087175807, -63.24229089126091 3.8981270874494527, -63.335554891347755 3.9580540875052606, -63.419099891425574 3.967082087513674, -63.45819989146199 3.866454087419953, -63.491526891493024 3.857782087411877, -63.530135891528985 3.8672180874206674, -63.61417289160724 3.9448640874929737, -63.64445489163545 3.9486090874964646, -63.84806389182508 3.9588910875060463, -63.95625489192584 3.891245087443039, -64.01779089198314 3.886109087438257, -64.05270889201566 3.9084360874590516, -64.12639089208429 4.1095820876463875, -64.24889989219838 4.148054087682212, -64.33555489227909 4.154164087687903, -64.59201789251793 4.1277730876633285, -64.67472689259496 4.257500087784138, -64.74626389266159 4.287218087811823, -64.78167289269456 4.2863910878110545, -64.80000889271165 4.265073087791194, -64.80195489271345 4.210836087740688, -64.71313589263073 4.144
 027087678467, -64.62668189255022 3.9655540875122455, -64.44632689238225 3.7870090873459645, -64.30806389225349 3.7183360872820117, -64.19021789214374 3.5896540871621596, -64.18471789213861 3.5277820871045407, -64.23569989218609 3.432782087016065, -64.20529089215776 3.1933360867930674, -64.15889089211456 3.060836086669667, -63.987854891955266 2.718609086350938, -63.995417891962305 2.623054086261945, -64.04646389200985 2.509445086156134, -64.03403589199827 2.4713180861206325, -63.821808891800615 2.4258360860782773, -63.58167289157697 2.434718086086548, -63.36541789137557 2.4200000860728323, -63.346390891357856 2.4061090860598995, -63.360763891371235 2.259100085922981, -63.39944589140727 2.149509085820924, -63.60709089160065 2.105973085780377, -63.739172891723655 2.003054085684525, -63.825008891803606 1.9777820856609907, -63.93652689190746 1.9768090856600793, -64.00236389196877 1.9498640856349851, -64.0518908920149 1.8904820855796913, -64.07799089203921 1.6354180853421383, -64.11320889
 207201 1.5829180852932438, -64.26445489221287 1.4761090851937695, -64.3943088923338 1.5118090852270143, -64.52972689245992 1.4336090851541883, -64.59529089252098 1.3300000850576907, -64.69750889261618 1.262782084995095, -64.7572358926718 1.2443090849778855, -64.8190728927294 1.2794820850106419, -65.00695489290437 1.1658360849048108, -65.1362638930248 1.118473084860696, -65.16584589305235 0.9694450847218974, -65.19250889307719 0.9266640846820593, -65.32167289319747 0.9119450846683463, -65.38584589325724 0.8370820845986344, -65.40028189327069 0.7539540845212116, -65.43610889330405 0.6952820844665695, -65.52166389338373 0.6491640844236173, -65.55861789341814 0.6661090844393982, -65.58257289344046 0.7297910844987143, -65.5111178933739 0.8388910846003199, -65.510135893373 0.9019450846590331, -65.55944589341892 0.9711090847234516, -65.59542689345243 0.9904180847414352, -65.73529089358269 0.9827820847343247, -65.87083589370893 0.9083360846649953, -65.97959089381021 0.798745084562924, -66.1
 2709089394758 0.7341640845027797, -66.31472689412233 0.7513910845188292, -66.87045489463989 1.2209270849561165, -66.89168189465967 1.2513910849844905, -66.92639089469199 1.4597180851785083, -66.99167289475278 1.6958360853984118, -67.21153589495755 2.2436090859085596, -67.21694589496259 2.275282085938059, -67.17418189492277 2.336527085995101, -67.19250889493983 2.392500086047221, -67.32520889506341 2.474027086123158, -67.48556389521276 2.653336086290153, -67.53528189525906 2.680000086314976, -67.60583589532477 2.7933360864205383, -67.76583589547378 2.832500086457003, -67.82361789552759 2.8270820864519663, -67.8330728955364 2.8766640864981383, -67.4355638951662 3.253891086849464, -67.34639989508315 3.313682086905146, -67.29285489503329 3.3960450869818573, -67.30659989504609 3.4527820870346915, -67.38111789511548 3.4859730870656023, -67.43709089516761 3.648336087216819, -67.49104589521787 3.7243090872875655, -67.59987289531922 3.740691087302821, -67.63514589535207 3.797636087355855, -6
 7.7085088954204 4.0469540875880625, -67.78667289549318 4.166527087699421, -67.80625489551143 4.231809087760212, -67.78479989549145 4.334754087856098, -67.85875489556032 4.561245088067025, -67.80158189550707 4.973236088450719, -67.8486358955509 5.306518088761123, -67.80389089550923 5.38326408883259, -67.64944589536539 5.478336088921139, -67.61590889533416 5.5481910889861865, -67.65167289536745 5.683191089111915, -67.61999989533797 5.792218089213463, -67.4139818951461 5.995536089402819, -67.49252689521924 6.121409089520043, -67.48924589521619 6.153745089550156, -67.45445489518379 6.1930540895867665, -67.49626389522273 6.2054180895982824, -67.56361789528545 6.262500089651439, -67.6352818953522 6.28513608967252, -67.83118189553464 6.30757308969342, -67.91812689561561 6.238191089628799, -67.99792689568993 6.207218089599962, -68.15515489583636 6.222773089614449, -68.31945489598938 6.1680540895634834, -68.45389989611459 6.190554089584438, -68.63840889628644 6.135482089533156, -68.827790896
 4628 6.186391089580567, -69.05639989667571 6.2161090896082385, -69.19520889680498 6.100418089500494, -69.24174589684833 6.084100089485304, -69.2707088968753 6.090973089491698, -69.31611789691759 6.148609089545374, -69.42945489702315 6.1186090895174345, -70.11917289766549 6.975836090315795, -70.2218178977611 6.9740270903141095, -70.294726897829 6.9384730902809935, -70.55250889806908 7.058336090392629, -70.7197268982248 7.098054090429613, -70.88653589838016 7.07507309040821, -71.02500889850913 6.984445090323803, -71.18126389865465 6.9634730903042765, -71.33250889879551 7.022364090359119, -71.46389989891787 7.023336090360033, -71.60139089904592 7.057918090392235, -71.70195489913958 7.046391090381505, -71.83278189926142 6.987218090326394, -71.99236389941004 7.016245090353422, -72.06609989947871 7.06241809039642, -72.13292689954095 7.173336090499731, -72.16459989957045 7.262500090582762, -72.15472689956125 7.325282090641238, -72.26250889966164 7.389445090700988, -72.40167289979124 7.4072
 18090717549, -72.47244589985715 7.497982090802083, -72.45972689984531 7.920554091195626, -72.38938189977979 8.047564091313916, -72.3286178997232 8.061809091327177, -72.3366728997307 8.151945091411122, -72.3881998997787 8.369445091613684, -72.66446390003598 8.641109091866696, -72.77972690014333 9.080273092275704, -72.8855639002419 9.11916409231192, -72.96250890031357 9.178054092366764, -72.9811269003309 9.260827092443861, -73.0099999003578 9.302009092482209, -73.22195490055519 9.171109092360297, -73.37806390070058 9.171391092360565, -73.36389090068738 9.225827092411265, -73.24514590057679 9.40847309258136, -73.08168190042456 9.609445092768524, -73.00472690035288 9.768327092916508, -72.97750890032754 10.001945093134069, -72.93889990029157 10.11645409324072, -72.90354590025865 10.444445093546179, -72.49125489987468 11.12277309417793, -72.31764589971299 11.164509094216797, -72.20935489961214 11.25000009429641, -71.9684818993878 11.666245094684072, -71.7697268992027 11.700836094716294, -
 71.40333589886147 11.812773094820542, -71.32471789878825 11.853054094858052, -71.37861789883844 11.753336094765189, -71.44584589890106 11.723891094737766, -71.76583589919908 11.662364094680456, -71.95417289937447 11.594718094617463, -71.96639989938586 11.506391094535203, -71.93278189935455 11.363054094401704, -71.7408458991758 11.034164094095402, -71.763617899197 11.013745094076384, -71.69111789912948 10.834164093909138, -71.6618088991022 10.77750009385636, -71.57792689902406 10.71610909379919, -71.58168189902757 10.674718093760646, -71.64889989909017 10.442500093544368, -71.75569989918964 10.369718093476592, -71.79444589922572 10.321809093431966, -71.8411268992692 10.218891093336126, -72.1253548995339 9.818191092962934, -72.07792689948973 9.735554092885977, -71.97917289939775 9.623336092781472, -71.91084589933412 9.493609092660648, -71.73319989916868 9.375691092550824, -71.72361789915975 9.345000092522241, -71.75945489919313 9.118327092311148, -71.7148638991516 9.077918092273507, -
 71.62389089906688 9.043054092241036, -71.55278189900065 9.040836092238976, -71.3136088987779 9.1105540923039, -71.24139089871065 9.155418092345684, -71.16541789863989 9.273745092455883, -71.07486389855555 9.312500092491973, -71.05597289853796 9.338745092516419, -71.08917289856888 9.536600092700695, -71.05334589853551 9.703609092856226, -71.07339989855419 9.851109092993596, -71.26945489873678 10.150136093272081, -71.38556389884492 10.282773093395619, -71.43667289889251 10.36944509347633, -71.45861789891295 10.460000093560666, -71.54570889899406 10.568327093661566, -71.52639989897608 10.726945093809277, -71.44667289890182 10.795554093873179, -71.45167289890648 10.916391093985723, -71.49285489894484 10.961036094027293, -71.4119548988695 10.984164094048836, -71.28110889874763 10.989164094053493, -70.82556389832338 11.211391094260463, -70.50847289802806 11.248191094294725, -70.4466728979705 11.290000094333664, -70.23918189777727 11.353054094392391, -70.14249989768723 11.418336094453196, 
 -70.03486389758697 11.441318094474596, -70.02389989757677 11.491391094521234, -70.04779089759901 11.517773094545802, -69.987645897543 11.514718094542957, -69.87402689743719 11.426527094460823, -69.80139089736954 11.427218094461466, -69.7423998973146 11.499200094528504, -69.81653589738364 11.690973094707104, -70.18000889772216 11.603609094625739, -70.23598189777428 11.62889109464929, -70.24389989778166 11.775273094785618, -70.29403589782835 11.861664094866072, -70.28666389782148 11.92027309492066, -70.18749989772914 12.107773095095283, -70.01430889756783 12.197500095178839, -69.93471789749371 12.169718095152973, -69.85945489742362 12.071945095061906, -69.82375489739037 11.98805409498378, -69.81688189738396 11.850973094856116, -69.75778189732893 11.661391094679558, -69.7061178972808 11.548891094574785, -69.6318088972116 11.467636094499099, -69.5795178971629 11.46410009449582, -69.50695489709533 11.506945094535709, -69.36021789695867 11.493327094523039, -69.27487289687919 11.5339540945
 60869, -68.95389989658025 11.45166409448423, -68.8436818964776 11.447082094479967, -68.66042689630693 11.349864094389417, -68.60196389625249 11.290554094334183, -68.41833589608147 11.180000094231218, -68.24250889591772 10.874373093946588, -68.25195489592652 10.856664093930092, -68.32529089599481 10.843609093917934, -68.3280638959974 10.767500093847048, -68.25361789592806 10.588891093680715, -68.16514589584567 10.498891093596896, -67.86798189556892 10.464873093565217, -67.79610889550197 10.491945093590417, -67.54333589526657 10.53277309362845, -67.28029089502158 10.546664093641382, -67.00222689476261 10.610282093700633, -66.47056389426747 10.629164093718217, -66.34299089414866 10.604718093695453, -66.3102908941182 10.626018093715288)), ((-64.05555489201832 10.857218093930612, -64.1363998920936 10.945000094012357, -64.17403589212866 10.960418094026721, -64.22792689217884 10.93124509399955, -64.40569989234442 10.970136094035766, -64.37834589231893 11.056945094116614, -64.20180889215452
  11.08778209414534, -64.17584589213034 11.031664094093074, -64.10583589206514 10.995282094059192, -64.04278189200642 10.987636094052064, -63.98749989195494 11.076109094134466, -63.88493589185941 11.175618094227147, -63.84486389182209 11.127082094181944, -63.80472689178471 11.021391094083512, -63.81499989179429 10.978054094043145, -63.89000889186414 10.904445093974587, -64.05555489201832 10.857218093930612)), ((-61.163608889324976 8.68832709191068, -61.16499988932628 8.71527309193577, -61.042499889212195 8.821109092034334, -60.86055488904273 8.853336092064353, -60.97610888915035 8.725827091945604, -61.163608889324976 8.68832709191068)), ((-61.246945889402596 8.474718091711736, -61.2943088894467 8.493327091729071, -61.405281889550054 8.485836091722092, -61.543545889678825 8.54868209178062, -61.42639088956972 8.58332709181289, -61.279445889432864 8.569718091800212, -61.26149988941614 8.552964091784602, -61.27829988943179 8.516736091750872, -61.2635998894181 8.499927091735216, -61.18507
 2889344966 8.496736091732245, -61.246945889402596 8.474718091711736)), ((-61.1291728892929 8.501664091736828, -61.26368188941818 8.510209091744784, -61.253063889408295 8.545273091777446, -61.21750888937518 8.572500091802794, -61.14912688931149 8.54089109177336, -61.083617889250476 8.609718091837465, -60.99806388917081 8.59694509182556, -60.99860888917131 8.557782091789093, -61.04055488921037 8.51416409174847, -61.1291728892929 8.501664091736828)), ((-60.91028188908905 8.894164092102372, -61.01972688919098 8.846945092058391, -61.046390889215814 8.843891092055557, -60.94167288911828 9.011664092211802, -60.880345889061175 9.026527092225649, -60.840563889024125 8.99832709219939, -60.85625488903874 8.947364092151915, -60.91028188908905 8.894164092102372)), ((-65.2811088931597 10.88028209395209, -65.39334589326423 10.906945093976915, -65.41611789328543 10.927218093995805, -65.36445489323732 10.969164094034866, -65.30445489318144 10.976109094041334, -65.21215489309549 10.954164094020896, -
 65.19959089308378 10.898336093968908, -65.2811088931597 10.88028209395209)), ((-61.048054889217354 8.639718091865404, -61.146945889309464 8.654445091879111, -61.17722688933766 8.67666409189981, -60.93778188911466 8.721245091941327, -60.99680888916963 8.652636091877426, -61.048054889217354 8.639718091865404)), ((-60.85831788904065 9.06495409226143, -60.94333588911984 9.022218092221635, -61.061390889229784 8.896945092104957, -61.096672889262635 8.89090009209933, -61.07062688923838 8.97131809217423, -60.947226889123456 9.054718092251903, -60.850417889033295 9.092982092287542, -60.85831788904065 9.06495409226143)), ((-60.92333588910121 8.618327091845487, -60.988617889162 8.635554091861522, -60.84159988902509 8.726945091946632, -60.80944588899514 8.716945091937319, -60.82333588900808 8.652364091877175, -60.92333588910121 8.618327091845487)))
+ASM	American Samoa	MULTIPOLYGON (((-170.74389999137958 -14.375554929569248, -170.74941799138472 -14.373890929567693, -170.7664449914006 -14.363608929558112, -170.82322699145345 -14.323754929521002, -170.80917299144036 -14.308054929506383, -170.79765499142965 -14.299308929498238, -170.68167299132162 -14.258054929459817, -170.6640269913052 -14.255417929457352, -170.5679179912157 -14.254308929456329, -170.56187299121007 -14.269999929470941, -170.57861799122566 -14.279163929479466, -170.63726399128026 -14.289445929489048, -170.74389999137958 -14.375554929569248)))
+COK	Cook Is.	MULTIPOLYGON (((-159.7469819811379 -21.25667293597779, -159.79363598118135 -21.252781935974156, -159.83251798121756 -21.248472935970142, -159.84000898122454 -21.23916393596147, -159.83471798121963 -21.199308935924364, -159.82723598121265 -21.189863935915568, -159.7883269811764 -21.187499935913365, -159.75613598114643 -21.192363935917896, -159.73292698112482 -21.22624593594945, -159.73916398113062 -21.2524999359739, -159.7469819811379 -21.25667293597779)), ((-157.92889097944467 -21.94083593661496, -157.94696397946151 -21.93958193661379, -157.96376397947716 -21.92041793659594, -157.96363597947703 -21.90819093658456, -157.95751797947133 -21.89528193657253, -157.94778197946226 -21.88805493656581, -157.921735979438 -21.88146393655967, -157.88384497940274 -21.925208936600413, -157.88766397940628 -21.936808936611214, -157.92889097944467 -21.94083593661496)), ((-158.11667297961955 -20.019172934825278, -158.12668197962887 -20.009445934816213, -158.13041797963237 -19.995281934803
 018, -158.1253999796277 -19.978472934787362, -158.11152697961478 -19.9713179347807, -158.09475497959914 -19.97417293478337, -158.0836359795888 -19.98444593479293, -158.0813909795867 -19.996390934804054, -158.08876397959358 -20.01069993481738, -158.0983549796025 -20.016108934822412, -158.11667297961955 -20.019172934825278)), ((-157.71304497924365 -19.857226934674443, -157.71887297924908 -19.85166393466926, -157.7408179792695 -19.817645934637582, -157.73919997926802 -19.807508934628146, -157.71229997924297 -19.77312693459612, -157.70376397923502 -19.836808934655437, -157.70864497923955 -19.853054934670567, -157.71304497924365 -19.857226934674443)), ((-163.16946398432535 -18.091945933030402, -163.17128198432704 -18.08417293302317, -163.15472698431162 -18.06145493300201, -163.15725498431397 -18.080554933019798, -163.1633269843196 -18.089445933028074, -163.16946398432535 -18.091945933030402)), ((-165.84167298681402 -10.890835926323845, -165.84834498682025 -10.8842359263177, -165.82765498
 680098 -10.881317926314978, -165.84167298681402 -10.890835926323845)))
+PYF	French Polynesia	MULTIPOLYGON (((-149.1791999712959 -17.870835932824477, -149.25809097136937 -17.85278193280766, -149.27570897138577 -17.84631793280164, -149.28893597139808 -17.833054932789295, -149.29795497140648 -17.82083593277791, -149.3694729714731 -17.738890932701594, -149.3785999714816 -17.743608932705982, -149.42086397152096 -17.756108932717623, -149.47168197156827 -17.766390932727205, -149.48763597158313 -17.76597293272681, -149.59057297167902 -17.711390932675982, -149.63891797172403 -17.625972932596426, -149.64169097172663 -17.611945932583367, -149.64141797172636 -17.592781932565515, -149.63559097172094 -17.561672932536553, -149.63250897171807 -17.54999993252568, -149.62388197171003 -17.540699932517015, -149.58739097167606 -17.516181932494177, -149.4921089715873 -17.493754932473294, -149.44998197154808 -17.499445932478594, -149.41473597151526 -17.509172932487658, -149.37362697147697 -17.526945932504205, -149.3591639714635 -17.534454932511196, -149.34861797145368 -17.542
 090932518306, -149.3327639714389 -17.57028193254456, -149.32666397143322 -17.592226932564998, -149.32333597143014 -17.65249993262114, -149.3230909714299 -17.67110893263846, -149.3240359714308 -17.68778193265399, -149.32014497142717 -17.702154932667383, -149.3075089714154 -17.712635932677145, -149.29306397140192 -17.717499932681676, -149.2305639713437 -17.730281932693572, -149.2077909713225 -17.734172932697206, -149.18473597130105 -17.73139093269461, -149.1747089712917 -17.736117932699017, -149.1622269712801 -17.751390932713235, -149.1547269712731 -17.764445932725394, -149.14837297126718 -17.781954932741698, -149.1466819712656 -17.805699932763815, -149.15221797127077 -17.83361793278982, -149.15780897127598 -17.849726932804813, -149.16559097128322 -17.86360893281774, -149.1741639712912 -17.869163932822914, -149.1791999712959 -17.870835932824477)), ((-139.05474496186676 -9.859999925363809, -139.1089179619172 -9.846945925351648, -139.11913596192673 -9.843608925348533, -139.1289089619358
 2 -9.838890925344145, -139.1411089619472 -9.830835925336643, -139.15142696195682 -9.820554925327073, -139.16879096197297 -9.79375492530211, -139.1722549619762 -9.772917925282698, -139.16726396197154 -9.759999925270677, -139.04444496185715 -9.69541792521052, -139.00472696182018 -9.69694592521195, -138.97568196179313 -9.708608925222805, -138.9687639617867 -9.722363925235626, -138.9570729617758 -9.741390925253341, -138.8903179617136 -9.757226925268085, -138.85058196167662 -9.756108925267043, -138.83611796166315 -9.749863925261238, -138.82531796165307 -9.740272925252299, -138.81251796164116 -9.737917925250102, -138.8097549616386 -9.748054925259552, -138.81558196164403 -9.759445925270157, -138.8319729616593 -9.770835925280764, -138.84915496167528 -9.781117925290346, -138.89585496171878 -9.806254925313752, -138.91085496173275 -9.808335925315689, -138.9794269617966 -9.8149999253219, -138.99999996181577 -9.8149999253219, -139.01319996182806 -9.811390925318534, -139.02973596184347 -9.8072269
 25314652, -139.04862696186106 -9.808199925315563, -139.06133596187289 -9.818890925325519, -139.05474496186676 -9.859999925363809)), ((-140.17782696291272 -8.956390924522253, -140.18945496292355 -8.954163924520174, -140.2058359629388 -8.944726924511386, -140.22584496295744 -8.930417924498059, -140.2305639629618 -8.921390924489657, -140.25613596298564 -8.827363924402093, -140.25339096298308 -8.813054924388766, -140.2497549629797 -8.80278192437919, -140.2450269629753 -8.793890924370913, -140.2366639629675 -8.7838909243616, -140.2251449629568 -8.778190924356295, -140.06890896281126 -8.81167292438748, -140.04281796278696 -8.830281924404801, -140.01599096276198 -8.852845924425822, -140.01196396275824 -8.870972924442697, -140.01515496276122 -8.888472924458995, -140.0226639627682 -8.898054924467928, -140.07781796281955 -8.918054924486555, -140.0908359628317 -8.9220819244903, -140.10487296284475 -8.918754924487203, -140.1197179628586 -8.918890924487329, -140.1669639629026 -8.933054924500524,
  -140.17683596291178 -8.940135924507118, -140.17782696291272 -8.956390924522253)), ((-151.4444909734056 -16.904445931924457, -151.46543597342512 -16.902917931923028, -151.47512697343413 -16.89749993191799, -151.49169997344958 -16.849172931872985, -151.49777297345523 -16.784026931812306, -151.49136397344927 -16.759999931789935, -151.48751797344568 -16.7494459317801, -151.4725179734317 -16.73971793177104, -151.43098197339302 -16.745554931776482, -151.35111797331865 -16.84583593186987, -151.3509819733185 -16.860345931883387, -151.40032697336449 -16.888335931909452, -151.4444909734056 -16.904445931924457)), ((-149.85442697192474 -17.574445932548443, -149.86834497193772 -17.56833593254275, -149.87805497194674 -17.563617932538364, -149.9250449719905 -17.52528193250265, -149.93808197200266 -17.509726932488164, -149.941681972006 -17.497217932476516, -149.93725497200188 -17.484163932464355, -149.9227909719884 -17.477781932458413, -149.91113597197756 -17.476108932456853, -149.79462697186906 -
 17.466799932448183, -149.78529097186035 -17.47125493245234, -149.78321797185842 -17.487781932467726, -149.79849097187264 -17.52778193250498, -149.84596397191686 -17.572499932546634, -149.85442697192474 -17.574445932548443)))
+UMI	Jarvis I.	MULTIPOLYGON (((-160.02114498139323 -0.3980549165516862, -160.02810898139973 -0.3980549165516862, -160.04349098141404 -0.3922179165462438, -160.0451639814156 -0.3801359165349964, -160.03391798140512 -0.3743089165295714, -160.0177909813901 -0.3747179165299457, -160.00946398138237 -0.3847179165392589, -160.0129269813856 -0.3958359165496148, -160.02114498139323 -0.3980549165516862)))
+NIU	Niue	MULTIPOLYGON (((-169.89389099058795 -19.145554934011656, -169.9308819906224 -19.124445933991993, -169.9522359906423 -19.073335933944392, -169.93028199062184 -19.01360893388876, -169.89474499058875 -18.970281933848412, -169.88476399057944 -18.963335933841947, -169.86889999056467 -18.963617933842215, -169.8151359905146 -18.970272933848406, -169.78155499048333 -19.065281933936888, -169.79809999049874 -19.087226933957325, -169.82443599052326 -19.110835933979317, -169.85028199054733 -19.125835933993287, -169.8591639905556 -19.130554933997686, -169.88806399058254 -19.14444593401062, -169.89389099058795 -19.145554934011656)))
+WSM	Samoa	MULTIPOLYGON (((-172.59649999310494 -13.509108928762302, -172.55193599306344 -13.497217928751226, -172.47528199299205 -13.479717928734928, -172.39111799291368 -13.464172928720458, -172.36083599288548 -13.460554928717087, -172.34835499287385 -13.461390928717861, -172.303417992832 -13.472154928727889, -172.28779999281744 -13.484163928739065, -172.22249999275664 -13.563054928812548, -172.20306399273855 -13.59194592883945, -172.1933639927295 -13.613335928859371, -172.1683549927062 -13.680972928922358, -172.16781799270572 -13.691390928932066, -172.21235499274718 -13.806526929039293, -172.225035992759 -13.808890929041496, -172.25849999279018 -13.804308929037234, -172.39333599291575 -13.791672929025466, -172.48599099300202 -13.806808929039562, -172.50890899302337 -13.806663929039416, -172.5279269930411 -13.802708929035745, -172.5744359930844 -13.765835929001398, -172.59002699309892 -13.739717928977072, -172.69109999319306 -13.626108928871261, -172.7516909932495 -13.57402692882276
 , -172.77282699326918 -13.54999992880039, -172.78002699327587 -13.532572928784148, -172.7725359932689 -13.517499928770121, -172.75558199325312 -13.51028192876339, -172.73890899323757 -13.508472928761705, -172.728635993228 -13.513335928766239, -172.65527299315968 -13.519172928771681, -172.59649999310494 -13.509108928762302)), ((-171.44198199202972 -14.057499929273035, -171.4652729920514 -14.052781929268633, -171.47998199206512 -14.050554929266568, -171.52055499210292 -14.047781929263977, -171.5461089921267 -14.050281929266305, -171.5889269921666 -14.052499929268379, -171.64837299222194 -14.050281929266305, -171.76809999233345 -14.035835929252855, -171.91113599246665 -14.012499929231126, -172.05059999259655 -13.912499929137994, -172.0584999926039 -13.903190929129323, -172.06475499260972 -13.87819092910604, -172.05975499260506 -13.866945929095564, -172.02932699257673 -13.840272929070721, -171.90670899246254 -13.806663929039416, -171.8839089924413 -13.805554929038394, -171.8222639923838
 8 -13.807499929040205, -171.7480819923148 -13.83167292906272, -171.6191359921947 -13.87860892910642, -171.44418199203176 -13.984445929204995, -171.43070899201922 -14.002363929221687, -171.42919999201783 -14.01625492923462, -171.44198199202972 -14.057499929273035)))
+TKL	Tokelau	MULTIPOLYGON (((-171.84805499240792 -9.218890924766725, -171.85885499241797 -9.209654924758127, -171.86271799242155 -9.18089992473135, -171.85243599241198 -9.170626924721773, -171.84419099240432 -9.191108924740846, -171.84376399240392 -9.210835924759223, -171.84805499240792 -9.218890924766725)))
+TON	Tonga	MULTIPOLYGON (((-175.1452909954787 -21.268063935988394, -175.18639999551698 -21.252781935974156, -175.31445499563625 -21.17999993590638, -175.3236359956448 -21.174445935901204, -175.33642699565672 -21.161672935889314, -175.35140899567065 -21.14333593587223, -175.35748199567632 -21.131663935861354, -175.35999999567866 -21.10083593583265, -175.35319999567233 -21.0887549358214, -175.34112699566109 -21.074863935808466, -175.3142999956361 -21.06417293579851, -175.3035549956261 -21.069726935803672, -175.27667299560105 -21.124999935855158, -175.2452359955718 -21.12978193585961, -175.1490359954822 -21.17680893590341, -175.13836399547225 -21.175835935902498, -175.1319549954663 -21.159163935886966, -175.12945499546396 -21.14472693587352, -175.12139999545644 -21.13375493586331, -175.10723599544326 -21.12806393585801, -175.09362699543058 -21.124999935855158, -175.06542699540432 -21.125835935855932, -175.0487639953888 -21.13694593586628, -175.0459909953862 -21.149163935877652, -175.051
 69999539154 -21.161672935889314, -175.12083599545593 -21.262090935982826, -175.13503599546914 -21.267781935988125, -175.1452909954787 -21.268063935988394)), ((-173.93920899435545 -18.56889093347459, -173.93362699435025 -18.573054933478474, -173.9166909943345 -18.599726933503305, -173.9068269943253 -18.62375493352569, -173.90890899432722 -18.635563933536687, -173.98697299439993 -18.684172933581962, -174.05444499446276 -18.669726933568498, -174.06308199447082 -18.659299933558785, -174.07030899447756 -18.63597293353706, -174.06527299447285 -18.62499993352685, -174.05334499446175 -18.621117933523237, -174.03737299444688 -18.621117933523237, -174.0252999944356 -18.616672933519098, -174.01724499442813 -18.603054933506414, -174.01306399442424 -18.589726933493992, -174.00321799441505 -18.578199933483262, -173.99249099440507 -18.572226933477694, -173.9675269943818 -18.568054933473817, -173.93920899435545 -18.56889093347459)))
+WLF	Wallis & Futuna	MULTIPOLYGON (((-178.06081799819398 -14.323890929521127, -178.13739099826532 -14.317081929514785, -178.15389999828068 -14.308054929506383, -178.17110899829672 -14.287781929487494, -178.1793549983044 -14.275417929475978, -178.18832699831276 -14.256108929457994, -178.19027299831455 -14.239726929442739, -178.18169999830658 -14.232363929435891, -178.12733599825594 -14.24860892945101, -178.04301799817742 -14.31749992951518, -178.06081799819398 -14.323890929521127)), ((-176.1650359964284 -13.35305492861697, -176.16906399643216 -13.351945928615933, -176.17724499643978 -13.341390928606103, -176.18808199644988 -13.313608928580223, -176.1910999964527 -13.286945928555397, -176.18581799644775 -13.257781928528232, -176.18307299644522 -13.24360892851503, -176.1783449964408 -13.232226928504431, -176.1583549964222 -13.21486392848827, -176.14809099641263 -13.216108928489419, -176.12193599638826 -13.258608928529, -176.14202699640697 -13.34381792860836, -176.16143599642507 -13.3527
 72928616702, -176.1650359964284 -13.35305492861697)))
+ARG	Argentina	MULTIPOLYGON (((-71.85916389928599 -41.0112819543757, -71.85028189927772 -40.91250895428371, -71.95014589937072 -40.72694595411089, -71.85930889928613 -40.64347295403315, -71.77987289921215 -40.40896395381475, -71.71569989915238 -40.42361795382839, -71.6639638991042 -40.33451795374541, -71.66861789910853 -40.29694595371042, -71.7027178991403 -40.27895495369366, -71.719590899156 -40.302363953715464, -71.81806389924772 -40.20459095362441, -71.79139989922288 -40.11500895354098, -71.66694589910698 -40.04749995347811, -71.63334589907568 -39.95056395338783, -71.7050088991424

<TRUNCATED>

[19/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/serialized/SerializedStrategyTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/serialized/SerializedStrategyTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/serialized/SerializedStrategyTest.java
new file mode 100644
index 0000000..bed8339
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/serialized/SerializedStrategyTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.serialized;
+
+import java.io.IOException;
+
+import com.spatial4j.core.context.SpatialContext;
+import org.apache.lucene.spatial.SpatialMatchConcern;
+import org.apache.lucene.spatial.StrategyTestCase;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SerializedStrategyTest extends StrategyTestCase {
+
+  @Before
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    this.ctx = SpatialContext.GEO;
+    this.strategy = new SerializedDVStrategy(ctx, "serialized");
+  }
+
+  @Override
+  protected boolean needsDocValues() {
+    return (strategy instanceof SerializedDVStrategy);
+  }
+
+  @Test
+  public void testBasicOperaions() throws IOException {
+    getAddAndVerifyIndexedDocuments(DATA_SIMPLE_BBOX);
+
+    executeQueries(SpatialMatchConcern.EXACT, QTEST_Simple_Queries_BBox);
+  }
+
+  @Test
+  public void testStatesBBox() throws IOException {
+    getAddAndVerifyIndexedDocuments(DATA_STATES_BBOX);
+
+    executeQueries(SpatialMatchConcern.FILTER, QTEST_States_IsWithin_BBox);
+    executeQueries(SpatialMatchConcern.FILTER, QTEST_States_Intersects_BBox);
+  }
+
+  @Test
+  public void testCitiesIntersectsBBox() throws IOException {
+    getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS);
+
+    executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_Intersects_BBox);
+  }
+
+  //sorting is tested in DistanceStrategyTest
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java
new file mode 100644
index 0000000..8040a35
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java
@@ -0,0 +1,227 @@
+/*
+ * 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.spatial4j;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.carrotsearch.randomizedtesting.annotations.Repeat;
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.spatial.composite.CompositeSpatialStrategy;
+import org.apache.lucene.spatial.prefix.RandomSpatialOpStrategyTestCase;
+import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
+import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.apache.lucene.spatial.serialized.SerializedDVStrategy;
+import org.apache.lucene.geo3d.GeoBBoxFactory;
+import org.apache.lucene.geo3d.GeoStandardCircle;
+import org.apache.lucene.geo3d.GeoPath;
+import org.apache.lucene.geo3d.GeoPoint;
+import org.apache.lucene.geo3d.GeoPolygonFactory;
+import org.apache.lucene.geo3d.GeoShape;
+import org.apache.lucene.geo3d.PlanetModel;
+import org.junit.Test;
+
+import static com.spatial4j.core.distance.DistanceUtils.DEGREES_TO_RADIANS;
+
+public class Geo3dRptTest extends RandomSpatialOpStrategyTestCase {
+
+  private SpatialPrefixTree grid;
+  private RecursivePrefixTreeStrategy rptStrategy;
+  {
+    this.ctx = SpatialContext.GEO;
+  }
+
+  private void setupGeohashGrid() {
+    this.grid = new GeohashPrefixTree(ctx, 2);//A fairly shallow grid
+    this.rptStrategy = newRPT();
+  }
+
+  protected RecursivePrefixTreeStrategy newRPT() {
+    final RecursivePrefixTreeStrategy rpt = new RecursivePrefixTreeStrategy(this.grid,
+        getClass().getSimpleName() + "_rpt");
+    rpt.setDistErrPct(0.10);//not too many cells
+    return rpt;
+  }
+
+  @Override
+  protected boolean needsDocValues() {
+    return true;//due to SerializedDVStrategy
+  }
+
+  private void setupStrategy() {
+    //setup
+    setupGeohashGrid();
+
+    SerializedDVStrategy serializedDVStrategy = new SerializedDVStrategy(ctx, getClass().getSimpleName() + "_sdv");
+    this.strategy = new CompositeSpatialStrategy("composite_" + getClass().getSimpleName(),
+        rptStrategy, serializedDVStrategy);
+  }
+
+  @Test
+  public void testFailure1() throws IOException {
+    setupStrategy();
+    final List<GeoPoint> points = new ArrayList<GeoPoint>();
+    points.add(new GeoPoint(PlanetModel.SPHERE, 18 * DEGREES_TO_RADIANS, -27 * DEGREES_TO_RADIANS));
+    points.add(new GeoPoint(PlanetModel.SPHERE, -57 * DEGREES_TO_RADIANS, 146 * DEGREES_TO_RADIANS));
+    points.add(new GeoPoint(PlanetModel.SPHERE, 14 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS));
+    points.add(new GeoPoint(PlanetModel.SPHERE, -15 * DEGREES_TO_RADIANS, 153 * DEGREES_TO_RADIANS));
+
+    final Shape triangle = new Geo3dShape(GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points,0),ctx);
+    final Rectangle rect = ctx.makeRectangle(-49, -45, 73, 86);
+    testOperation(rect,SpatialOperation.Intersects,triangle, false);
+  }
+
+  @Test
+  public void testFailureLucene6535() throws IOException {
+    setupStrategy();
+
+    final List<GeoPoint> points = new ArrayList<>();
+    points.add(new GeoPoint(PlanetModel.SPHERE, 18 * DEGREES_TO_RADIANS, -27 * DEGREES_TO_RADIANS));
+    points.add(new GeoPoint(PlanetModel.SPHERE, -57 * DEGREES_TO_RADIANS, 146 * DEGREES_TO_RADIANS));
+    points.add(new GeoPoint(PlanetModel.SPHERE, 14 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS));
+    points.add(new GeoPoint(PlanetModel.SPHERE, -15 * DEGREES_TO_RADIANS, 153 * DEGREES_TO_RADIANS));
+    final GeoPath path = new GeoPath(PlanetModel.SPHERE, 29 * DEGREES_TO_RADIANS);
+    path.addPoint(55.0 * DEGREES_TO_RADIANS, -26.0 * DEGREES_TO_RADIANS);
+    path.addPoint(-90.0 * DEGREES_TO_RADIANS, 0.0);
+    path.addPoint(54.0 * DEGREES_TO_RADIANS, 165.0 * DEGREES_TO_RADIANS);
+    path.addPoint(-90.0 * DEGREES_TO_RADIANS, 0.0);
+    path.done();
+    final Shape shape = new Geo3dShape(path,ctx);
+    final Rectangle rect = ctx.makeRectangle(131, 143, 39, 54);
+    testOperation(rect,SpatialOperation.Intersects,shape,true);
+  }
+
+  @Test
+  @Repeat(iterations = 10)
+  public void testOperations() throws IOException {
+    setupStrategy();
+
+    testOperationRandomShapes(SpatialOperation.Intersects);
+  }
+
+  private Shape makeTriangle(double x1, double y1, double x2, double y2, double x3, double y3) {
+    final List<GeoPoint> geoPoints = new ArrayList<>();
+    geoPoints.add(new GeoPoint(PlanetModel.SPHERE, y1 * DEGREES_TO_RADIANS, x1 * DEGREES_TO_RADIANS));
+    geoPoints.add(new GeoPoint(PlanetModel.SPHERE, y2 * DEGREES_TO_RADIANS, x2 * DEGREES_TO_RADIANS));
+    geoPoints.add(new GeoPoint(PlanetModel.SPHERE, y3 * DEGREES_TO_RADIANS, x3 * DEGREES_TO_RADIANS));
+    final int convexPointIndex = 0;
+    final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, geoPoints, convexPointIndex);
+    return new Geo3dShape(shape, ctx);
+  }
+
+  @Override
+  protected Shape randomIndexedShape() {
+    return randomRectangle();
+  }
+
+  @Override
+  protected Shape randomQueryShape() {
+    final int shapeType = random().nextInt(4);
+    switch (shapeType) {
+    case 0: {
+        // Polygons
+        final int vertexCount = random().nextInt(3) + 3;
+        while (true) {
+          final List<GeoPoint> geoPoints = new ArrayList<>();
+          while (geoPoints.size() < vertexCount) {
+            final Point point = randomPoint();
+            final GeoPoint gPt = new GeoPoint(PlanetModel.SPHERE, point.getY() * DEGREES_TO_RADIANS, point.getX() * DEGREES_TO_RADIANS);
+            geoPoints.add(gPt);
+          }
+          final int convexPointIndex = random().nextInt(vertexCount);       //If we get this wrong, hopefully we get IllegalArgumentException
+          try {
+            final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, geoPoints, convexPointIndex);
+            return new Geo3dShape(shape, ctx);
+          } catch (IllegalArgumentException e) {
+            // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
+            // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
+            continue;
+          }
+        }
+      }
+    case 1: {
+        // Circles
+        while (true) {
+          final int circleRadius = random().nextInt(179) + 1;
+          final Point point = randomPoint();
+          try {
+            final GeoShape shape = new GeoStandardCircle(PlanetModel.SPHERE, point.getY() * DEGREES_TO_RADIANS, point.getX() * DEGREES_TO_RADIANS,
+              circleRadius * DEGREES_TO_RADIANS);
+            return new Geo3dShape(shape, ctx);
+          } catch (IllegalArgumentException e) {
+            // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
+            // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
+            continue;
+          }
+        }
+      }
+    case 2: {
+        // Rectangles
+        while (true) {
+          Point ulhcPoint = randomPoint();
+          Point lrhcPoint = randomPoint();
+          if (ulhcPoint.getY() < lrhcPoint.getY()) {
+            //swap
+            Point temp = ulhcPoint;
+            ulhcPoint = lrhcPoint;
+            lrhcPoint = temp;
+          }
+          try {
+            final GeoShape shape = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, ulhcPoint.getY() * DEGREES_TO_RADIANS,
+              lrhcPoint.getY() * DEGREES_TO_RADIANS,
+              ulhcPoint.getX() * DEGREES_TO_RADIANS,
+              lrhcPoint.getX() * DEGREES_TO_RADIANS);
+            //System.err.println("Trial rectangle shape: "+shape);
+            return new Geo3dShape(shape, ctx);
+          } catch (IllegalArgumentException e) {
+            // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
+            // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
+            continue;
+          }
+        }
+      }
+    case 3: {
+        // Paths
+        final int pointCount = random().nextInt(5) + 1;
+        final double width = (random().nextInt(89)+1) * DEGREES_TO_RADIANS;
+        while (true) {
+          try {
+            final GeoPath path = new GeoPath(PlanetModel.SPHERE, width);
+            for (int i = 0; i < pointCount; i++) {
+              final Point nextPoint = randomPoint();
+              path.addPoint(nextPoint.getY() * DEGREES_TO_RADIANS, nextPoint.getX() * DEGREES_TO_RADIANS);
+            }
+            path.done();
+            return new Geo3dShape(path, ctx);
+          } catch (IllegalArgumentException e) {
+            // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
+            // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
+            continue;
+          }
+        }
+      }
+    default:
+      throw new IllegalStateException("Unexpected shape type");
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTestCase.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTestCase.java
new file mode 100644
index 0000000..58b520d
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTestCase.java
@@ -0,0 +1,262 @@
+/*
+ * 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.spatial4j;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.spatial4j.core.TestLog;
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.distance.DistanceUtils;
+import com.spatial4j.core.shape.Circle;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.RectIntersectionTestHelper;
+import org.apache.lucene.geo3d.LatLonBounds;
+import org.apache.lucene.geo3d.GeoBBox;
+import org.apache.lucene.geo3d.GeoBBoxFactory;
+import org.apache.lucene.geo3d.GeoStandardCircle;
+import org.apache.lucene.geo3d.GeoPath;
+import org.apache.lucene.geo3d.GeoPoint;
+import org.apache.lucene.geo3d.GeoPolygonFactory;
+import org.apache.lucene.geo3d.GeoShape;
+import org.apache.lucene.geo3d.PlanetModel;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static com.spatial4j.core.distance.DistanceUtils.DEGREES_TO_RADIANS;
+
+public abstract class Geo3dShapeRectRelationTestCase extends RandomizedShapeTestCase {
+  protected final static double RADIANS_PER_DEGREE = Math.PI/180.0;
+
+  @Rule
+  public final TestLog testLog = TestLog.instance;
+
+  protected final PlanetModel planetModel;
+
+  public Geo3dShapeRectRelationTestCase(PlanetModel planetModel) {
+    super(SpatialContext.GEO);
+    this.planetModel = planetModel;
+  }
+
+  protected GeoBBox getBoundingBox(final GeoShape path) {
+    LatLonBounds bounds = new LatLonBounds();
+    path.getBounds(bounds);
+
+    double leftLon;
+    double rightLon;
+    if (bounds.checkNoLongitudeBound()) {
+      leftLon = -Math.PI;
+      rightLon = Math.PI;
+    } else {
+      leftLon = bounds.getLeftLongitude().doubleValue();
+      rightLon = bounds.getRightLongitude().doubleValue();
+    }
+    double minLat;
+    if (bounds.checkNoBottomLatitudeBound()) {
+      minLat = -Math.PI * 0.5;
+    } else {
+      minLat = bounds.getMinLatitude().doubleValue();
+    }
+    double maxLat;
+    if (bounds.checkNoTopLatitudeBound()) {
+      maxLat = Math.PI * 0.5;
+    } else {
+      maxLat = bounds.getMaxLatitude().doubleValue();
+    }
+    return GeoBBoxFactory.makeGeoBBox(planetModel, maxLat, minLat, leftLon, rightLon);
+  }
+
+  abstract class Geo3dRectIntersectionTestHelper extends RectIntersectionTestHelper<Geo3dShape> {
+
+    public Geo3dRectIntersectionTestHelper(SpatialContext ctx) {
+      super(ctx);
+    }
+
+    //20 times each -- should be plenty
+
+    protected int getContainsMinimum(int laps) {
+      return 20;
+    }
+
+    protected int getIntersectsMinimum(int laps) {
+      return 20;
+    }
+
+    // producing "within" cases in Geo3D based on our random shapes doesn't happen often. It'd be nice to increase this.
+    protected int getWithinMinimum(int laps) {
+      return 2;
+    }
+
+    protected int getDisjointMinimum(int laps) {
+      return 20;
+    }
+
+    protected int getBoundingMinimum(int laps) {
+      return 20;
+    }
+  }
+
+  @AwaitsFix(bugUrl = "https://issues.apache.org/jira/browse/LUCENE-6867")
+  @Test
+  public void testGeoCircleRect() {
+    new Geo3dRectIntersectionTestHelper(ctx) {
+
+      @Override
+      protected Geo3dShape generateRandomShape(Point nearP) {
+        final int circleRadius = 180 - random().nextInt(180);//no 0-radius
+        final Point point = nearP;
+        final GeoShape shape = new GeoStandardCircle(planetModel, point.getY() * DEGREES_TO_RADIANS, point.getX() * DEGREES_TO_RADIANS,
+            circleRadius * DEGREES_TO_RADIANS);
+        return new Geo3dShape(planetModel, shape, ctx);
+      }
+
+      @Override
+      protected Point randomPointInEmptyShape(Geo3dShape shape) {
+        GeoPoint geoPoint = ((GeoStandardCircle)shape.shape).getCenter();
+        return geoPointToSpatial4jPoint(geoPoint);
+      }
+
+    }.testRelateWithRectangle();
+  }
+
+  @AwaitsFix(bugUrl = "https://issues.apache.org/jira/browse/LUCENE-6867")
+  @Test
+  public void testGeoBBoxRect() {
+    new Geo3dRectIntersectionTestHelper(ctx) {
+
+      @Override
+      protected boolean isRandomShapeRectangular() {
+        return true;
+      }
+
+      @Override
+      protected Geo3dShape generateRandomShape(Point nearP) {
+        // (ignoring nearP)
+        Point ulhcPoint = randomPoint();
+        Point lrhcPoint = randomPoint();
+        if (ulhcPoint.getY() < lrhcPoint.getY()) {
+          //swap
+          Point temp = ulhcPoint;
+          ulhcPoint = lrhcPoint;
+          lrhcPoint = temp;
+        }
+        final GeoShape shape = GeoBBoxFactory.makeGeoBBox(planetModel, ulhcPoint.getY() * DEGREES_TO_RADIANS,
+            lrhcPoint.getY() * DEGREES_TO_RADIANS,
+            ulhcPoint.getX() * DEGREES_TO_RADIANS,
+            lrhcPoint.getX() * DEGREES_TO_RADIANS);
+        return new Geo3dShape(planetModel, shape, ctx);
+      }
+
+      @Override
+      protected Point randomPointInEmptyShape(Geo3dShape shape) {
+        return shape.getBoundingBox().getCenter();
+      }
+    }.testRelateWithRectangle();
+  }
+
+  @AwaitsFix(bugUrl = "https://issues.apache.org/jira/browse/LUCENE-6867")
+  @Test
+  public void testGeoPolygonRect() {
+    new Geo3dRectIntersectionTestHelper(ctx) {
+
+      @Override
+      protected Geo3dShape generateRandomShape(Point nearP) {
+        final Point centerPoint = randomPoint();
+        final int maxDistance = random().nextInt(160) + 20;
+        final Circle pointZone = ctx.makeCircle(centerPoint, maxDistance);
+        final int vertexCount = random().nextInt(3) + 3;
+        while (true) {
+          final List<GeoPoint> geoPoints = new ArrayList<>();
+          while (geoPoints.size() < vertexCount) {
+            final Point point = randomPointIn(pointZone);
+            final GeoPoint gPt = new GeoPoint(planetModel, point.getY() * DEGREES_TO_RADIANS, point.getX() * DEGREES_TO_RADIANS);
+            geoPoints.add(gPt);
+          }
+          final int convexPointIndex = random().nextInt(vertexCount); //If we get this wrong, hopefully we get IllegalArgumentException
+          try {
+            final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(planetModel, geoPoints, convexPointIndex);
+            return new Geo3dShape(planetModel, shape, ctx);
+          } catch (IllegalArgumentException e) {
+            // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
+            // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
+            continue;
+          }
+        }
+      }
+
+      @Override
+      protected Point randomPointInEmptyShape(Geo3dShape shape) {
+        throw new IllegalStateException("unexpected; need to finish test code");
+      }
+
+      @Override
+      protected int getWithinMinimum(int laps) {
+        // Long/thin so lets just find 1.
+        return 1;
+      }
+
+    }.testRelateWithRectangle();
+  }
+
+  @AwaitsFix(bugUrl = "https://issues.apache.org/jira/browse/LUCENE-6867")
+  @Test
+  public void testGeoPathRect() {
+    new Geo3dRectIntersectionTestHelper(ctx) {
+
+      @Override
+      protected Geo3dShape generateRandomShape(Point nearP) {
+        final Point centerPoint = randomPoint();
+        final int maxDistance = random().nextInt(160) + 20;
+        final Circle pointZone = ctx.makeCircle(centerPoint, maxDistance);
+        final int pointCount = random().nextInt(5) + 1;
+        final double width = (random().nextInt(89)+1) * DEGREES_TO_RADIANS;
+        while (true) {
+          try {
+            final GeoPath path = new GeoPath(planetModel, width);
+            for (int i = 0; i < pointCount; i++) {
+              final Point nextPoint = randomPointIn(pointZone);
+              path.addPoint(nextPoint.getY() * DEGREES_TO_RADIANS, nextPoint.getX() * DEGREES_TO_RADIANS);
+            }
+            path.done();
+            return new Geo3dShape(planetModel, path, ctx);
+          } catch (IllegalArgumentException e) {
+            // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
+            // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
+            continue;
+          }
+        }
+      }
+
+      @Override
+      protected Point randomPointInEmptyShape(Geo3dShape shape) {
+        throw new IllegalStateException("unexpected; need to finish test code");
+      }
+
+      @Override
+      protected int getWithinMinimum(int laps) {
+        // Long/thin so lets just find 1.
+        return 1;
+      }
+
+    }.testRelateWithRectangle();
+  }
+
+  private Point geoPointToSpatial4jPoint(GeoPoint geoPoint) {
+    return ctx.makePoint(geoPoint.getLongitude() * DistanceUtils.RADIANS_TO_DEGREES,
+        geoPoint.getLongitude() * DistanceUtils.RADIANS_TO_DEGREES);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeSphereModelRectRelationTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeSphereModelRectRelationTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeSphereModelRectRelationTest.java
new file mode 100644
index 0000000..aac0a0a
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeSphereModelRectRelationTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.spatial4j;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.spatial4j.core.shape.Rectangle;
+import org.apache.lucene.geo3d.GeoArea;
+import org.apache.lucene.geo3d.GeoBBox;
+import org.apache.lucene.geo3d.GeoBBoxFactory;
+import org.apache.lucene.geo3d.GeoStandardCircle;
+import org.apache.lucene.geo3d.GeoPoint;
+import org.apache.lucene.geo3d.GeoPolygonFactory;
+import org.apache.lucene.geo3d.GeoShape;
+import org.apache.lucene.geo3d.PlanetModel;
+import org.junit.Test;
+
+public class Geo3dShapeSphereModelRectRelationTest extends Geo3dShapeRectRelationTestCase {
+
+  public Geo3dShapeSphereModelRectRelationTest() {
+    super(PlanetModel.SPHERE);
+  }
+
+  @Test
+  public void testFailure1() {
+    final GeoBBox rect = GeoBBoxFactory.makeGeoBBox(planetModel, 88 * RADIANS_PER_DEGREE, 30 * RADIANS_PER_DEGREE, -30 * RADIANS_PER_DEGREE, 62 * RADIANS_PER_DEGREE);
+    final List<GeoPoint> points = new ArrayList<>();
+    points.add(new GeoPoint(planetModel, 66.2465299717 * RADIANS_PER_DEGREE, -29.1786158537 * RADIANS_PER_DEGREE));
+    points.add(new GeoPoint(planetModel, 43.684447915 * RADIANS_PER_DEGREE, 46.2210986329 * RADIANS_PER_DEGREE));
+    points.add(new GeoPoint(planetModel, 30.4579218227 * RADIANS_PER_DEGREE, 14.5238410082 * RADIANS_PER_DEGREE));
+    final GeoShape path = GeoPolygonFactory.makeGeoPolygon(planetModel, points,0);
+
+    final GeoPoint point = new GeoPoint(planetModel, 34.2730264413182 * RADIANS_PER_DEGREE, 82.75500168892472 * RADIANS_PER_DEGREE);
+
+    // Apparently the rectangle thinks the polygon is completely within it... "shape inside rectangle"
+    assertTrue(GeoArea.WITHIN == rect.getRelationship(path));
+
+    // Point is within path? Apparently not...
+    assertFalse(path.isWithin(point));
+
+    // If it is within the path, it must be within the rectangle, and similarly visa versa
+    assertFalse(rect.isWithin(point));
+
+  }
+
+  @Test
+  public void testFailure2_LUCENE6475() {
+    GeoShape geo3dCircle = new GeoStandardCircle(planetModel, 1.6282053147165243E-4 * RADIANS_PER_DEGREE,
+        -70.1600629789353 * RADIANS_PER_DEGREE, 86 * RADIANS_PER_DEGREE);
+    Geo3dShape geo3dShape = new Geo3dShape(planetModel, geo3dCircle, ctx);
+    Rectangle rect = ctx.makeRectangle(-118, -114, -2.0, 32.0);
+    assertTrue(geo3dShape.relate(rect).intersects());
+    // thus the bounding box must intersect too
+    assertTrue(geo3dShape.getBoundingBox().relate(rect).intersects());
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeWGS84ModelRectRelationTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeWGS84ModelRectRelationTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeWGS84ModelRectRelationTest.java
new file mode 100644
index 0000000..3b026c3
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeWGS84ModelRectRelationTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.spatial4j;
+
+import org.apache.lucene.geo3d.GeoArea;
+import org.apache.lucene.geo3d.GeoBBox;
+import org.apache.lucene.geo3d.GeoBBoxFactory;
+import org.apache.lucene.geo3d.GeoCircle;
+import org.apache.lucene.geo3d.GeoStandardCircle;
+import org.apache.lucene.geo3d.GeoPath;
+import org.apache.lucene.geo3d.GeoPoint;
+import org.apache.lucene.geo3d.PlanetModel;
+import org.junit.Test;
+
+public class Geo3dShapeWGS84ModelRectRelationTest extends Geo3dShapeRectRelationTestCase {
+
+  public Geo3dShapeWGS84ModelRectRelationTest() {
+    super(PlanetModel.WGS84);
+  }
+
+  @Test
+  public void testFailure1() {
+    final GeoBBox rect = GeoBBoxFactory.makeGeoBBox(planetModel, 90 * RADIANS_PER_DEGREE, 74 * RADIANS_PER_DEGREE,
+        40 * RADIANS_PER_DEGREE, 60 * RADIANS_PER_DEGREE);
+    final GeoPath path = new GeoPath(planetModel, 4 * RADIANS_PER_DEGREE);
+    path.addPoint(84.4987594274 * RADIANS_PER_DEGREE, -22.8345484402 * RADIANS_PER_DEGREE);
+    path.done();
+    assertTrue(GeoArea.DISJOINT == rect.getRelationship(path));
+    // This is what the test failure claimed...
+    //assertTrue(GeoArea.CONTAINS == rect.getRelationship(path));
+    //final GeoBBox bbox = getBoundingBox(path);
+    //assertFalse(GeoArea.DISJOINT == rect.getRelationship(bbox));
+  }
+
+  @Test
+  public void testFailure2() {
+    final GeoBBox rect = GeoBBoxFactory.makeGeoBBox(planetModel, -74 * RADIANS_PER_DEGREE, -90 * RADIANS_PER_DEGREE,
+        0 * RADIANS_PER_DEGREE, 26 * RADIANS_PER_DEGREE);
+    final GeoCircle circle = new GeoStandardCircle(planetModel, -87.3647352103 * RADIANS_PER_DEGREE, 52.3769709972 * RADIANS_PER_DEGREE, 1 * RADIANS_PER_DEGREE);
+    assertTrue(GeoArea.DISJOINT == rect.getRelationship(circle));
+    // This is what the test failure claimed...
+    //assertTrue(GeoArea.CONTAINS == rect.getRelationship(circle));
+    //final GeoBBox bbox = getBoundingBox(circle);
+    //assertFalse(GeoArea.DISJOINT == rect.getRelationship(bbox));
+  }
+
+  @Test
+  public void testFailure3() {
+    /*
+   [junit4]   1> S-R Rel: {}, Shape {}, Rectangle {}    lap# {} [CONTAINS, Geo3dShape{planetmodel=PlanetModel: {ab=1.0011188180710464, c=0.9977622539852008}, shape=GeoPath: {planetmodel=PlanetModel: {ab=1.0011188180710464, c=0.9977622539852008}, width=1.53588974175501(87.99999999999999),
+    points={[[X=0.12097657665150223, Y=-0.6754177666095532, Z=0.7265376136709238], [X=-0.3837892785614207, Y=0.4258049113530899, Z=0.8180007850434892]]}}},
+    Rect(minX=4.0,maxX=36.0,minY=16.0,maxY=16.0), 6981](no slf4j subst; sorry)
+   [junit4] FAILURE 0.59s | Geo3dWGS84ShapeRectRelationTest.testGeoPathRect <<<
+   [junit4]    > Throwable #1: java.lang.AssertionError: Geo3dShape{planetmodel=PlanetModel: {ab=1.0011188180710464, c=0.9977622539852008}, shape=GeoPath: {planetmodel=PlanetModel: {ab=1.0011188180710464, c=0.9977622539852008}, width=1.53588974175501(87.99999999999999),
+    points={[[X=0.12097657665150223, Y=-0.6754177666095532, Z=0.7265376136709238], [X=-0.3837892785614207, Y=0.4258049113530899, Z=0.8180007850434892]]}}} intersect Pt(x=23.81626064835212,y=16.0)
+   [junit4]    >  at __randomizedtesting.SeedInfo.seed([2595268DA3F13FEA:6CC30D8C83453E5D]:0)
+   [junit4]    >  at org.apache.lucene.spatial.spatial4j.RandomizedShapeTestCase._assertIntersect(RandomizedShapeTestCase.java:168)
+   [junit4]    >  at org.apache.lucene.spatial.spatial4j.RandomizedShapeTestCase.assertRelation(RandomizedShapeTestCase.java:153)
+   [junit4]    >  at org.apache.lucene.spatial.spatial4j.RectIntersectionTestHelper.testRelateWithRectangle(RectIntersectionTestHelper.java:128)
+   [junit4]    >  at org.apache.lucene.spatial.spatial4j.Geo3dWGS84ShapeRectRelationTest.testGeoPathRect(Geo3dWGS84ShapeRectRelationTest.java:265)
+  */
+    final GeoBBox rect = GeoBBoxFactory.makeGeoBBox(planetModel, 16 * RADIANS_PER_DEGREE, 16 * RADIANS_PER_DEGREE, 4 * RADIANS_PER_DEGREE, 36 * RADIANS_PER_DEGREE);
+    final GeoPoint pt = new GeoPoint(planetModel, 16 * RADIANS_PER_DEGREE, 23.81626064835212 * RADIANS_PER_DEGREE);
+    final GeoPath path = new GeoPath(planetModel, 88 * RADIANS_PER_DEGREE);
+    path.addPoint(46.6369060853 * RADIANS_PER_DEGREE, -79.8452213228 * RADIANS_PER_DEGREE);
+    path.addPoint(54.9779334519 * RADIANS_PER_DEGREE, 132.029177424 * RADIANS_PER_DEGREE);
+    path.done();
+    System.out.println("rect=" + rect);
+    // Rectangle is within path (this is wrong; it's on the other side.  Should be OVERLAPS)
+    assertTrue(GeoArea.OVERLAPS == rect.getRelationship(path));
+    // Rectangle contains point
+    //assertTrue(rect.isWithin(pt));
+    // Path contains point (THIS FAILS)
+    //assertTrue(path.isWithin(pt));
+    // What happens: (1) The center point of the horizontal line is within the path, in fact within a radius of one of the endpoints.
+    // (2) The point mentioned is NOT inside either SegmentEndpoint.
+    // (3) The point mentioned is NOT inside the path segment, either.  (I think it should be...)
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/RandomizedShapeTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/RandomizedShapeTestCase.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/RandomizedShapeTestCase.java
new file mode 100644
index 0000000..40d1b24
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/RandomizedShapeTestCase.java
@@ -0,0 +1,288 @@
+/*
+ * 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.spatial4j;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.distance.DistanceUtils;
+import com.spatial4j.core.shape.Circle;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.SpatialRelation;
+import com.spatial4j.core.shape.impl.Range;
+
+import static com.spatial4j.core.shape.SpatialRelation.CONTAINS;
+import static com.spatial4j.core.shape.SpatialRelation.WITHIN;
+
+import org.apache.lucene.util.LuceneTestCase;
+
+import static com.carrotsearch.randomizedtesting.RandomizedTest.*;
+
+/**
+ * A base test class with utility methods to help test shapes.
+ * Extends from RandomizedTest.
+ */
+public abstract class RandomizedShapeTestCase extends LuceneTestCase {
+
+  protected static final double EPS = 10e-9;
+
+  protected SpatialContext ctx;//needs to be set ASAP
+
+  /** Used to reduce the space of numbers to increase the likelihood that
+   * random numbers become equivalent, and thus trigger different code paths.
+   * Also makes some random shapes easier to manually examine.
+   */
+  protected final double DIVISIBLE = 2;// even coordinates; (not always used)
+
+  protected RandomizedShapeTestCase() {
+  }
+
+  public RandomizedShapeTestCase(SpatialContext ctx) {
+    this.ctx = ctx;
+  }
+
+  @SuppressWarnings("unchecked")
+  public static void checkShapesImplementEquals( Class<?>[] classes ) {
+    for( Class<?> clazz : classes ) {
+      try {
+        clazz.getDeclaredMethod( "equals", Object.class );
+      } catch (Exception e) {
+        fail("Shape needs to define 'equals' : " + clazz.getName());
+      }
+      try {
+        clazz.getDeclaredMethod( "hashCode" );
+      } catch (Exception e) {
+        fail("Shape needs to define 'hashCode' : " + clazz.getName());
+      }
+    }
+  }
+
+  //These few norm methods normalize the arguments for creating a shape to
+  // account for the dateline. Some tests loop past the dateline or have offsets
+  // that go past it and it's easier to have them coded that way and correct for
+  // it here.  These norm methods should be used when needed, not frivolously.
+
+  protected double normX(double x) {
+    return ctx.isGeo() ? DistanceUtils.normLonDEG(x) : x;
+  }
+
+  protected double normY(double y) {
+    return ctx.isGeo() ? DistanceUtils.normLatDEG(y) : y;
+  }
+
+  protected Rectangle makeNormRect(double minX, double maxX, double minY, double maxY) {
+    if (ctx.isGeo()) {
+      if (Math.abs(maxX - minX) >= 360) {
+        minX = -180;
+        maxX = 180;
+      } else {
+        minX = DistanceUtils.normLonDEG(minX);
+        maxX = DistanceUtils.normLonDEG(maxX);
+      }
+
+    } else {
+      if (maxX < minX) {
+        double t = minX;
+        minX = maxX;
+        maxX = t;
+      }
+      minX = boundX(minX, ctx.getWorldBounds());
+      maxX = boundX(maxX, ctx.getWorldBounds());
+    }
+    if (maxY < minY) {
+      double t = minY;
+      minY = maxY;
+      maxY = t;
+    }
+    minY = boundY(minY, ctx.getWorldBounds());
+    maxY = boundY(maxY, ctx.getWorldBounds());
+    return ctx.makeRectangle(minX, maxX, minY, maxY);
+  }
+
+  public static double divisible(double v, double divisible) {
+    return (int) (Math.round(v / divisible) * divisible);
+  }
+
+  protected double divisible(double v) {
+    return divisible(v, DIVISIBLE);
+  }
+
+  /** reset()'s p, and confines to world bounds. Might not be divisible if
+   * the world bound isn't divisible too.
+   */
+  protected Point divisible(Point p) {
+    Rectangle bounds = ctx.getWorldBounds();
+    double newX = boundX( divisible(p.getX()), bounds );
+    double newY = boundY( divisible(p.getY()), bounds );
+    p.reset(newX, newY);
+    return p;
+  }
+
+  static double boundX(double i, Rectangle bounds) {
+    return bound(i, bounds.getMinX(), bounds.getMaxX());
+  }
+
+  static double boundY(double i, Rectangle bounds) {
+    return bound(i, bounds.getMinY(), bounds.getMaxY());
+  }
+
+  static double bound(double i, double min, double max) {
+    if (i < min) return min;
+    if (i > max) return max;
+    return i;
+  }
+
+  protected void assertRelation(SpatialRelation expected, Shape a, Shape b) {
+    assertRelation(null, expected, a, b);
+  }
+
+  protected void assertRelation(String msg, SpatialRelation expected, Shape a, Shape b) {
+    _assertIntersect(msg, expected, a, b);
+    //check flipped a & b w/ transpose(), while we're at it
+    _assertIntersect(msg, expected.transpose(), b, a);
+  }
+
+  private void _assertIntersect(String msg, SpatialRelation expected, Shape a, Shape b) {
+    SpatialRelation sect = a.relate(b);
+    if (sect == expected)
+      return;
+    msg = ((msg == null) ? "" : msg+"\r") + a +" intersect "+b;
+    if (expected == WITHIN || expected == CONTAINS) {
+      if (a.getClass().equals(b.getClass())) // they are the same shape type
+        assertEquals(msg,a,b);
+      else {
+        //they are effectively points or lines that are the same location
+        assertTrue(msg,!a.hasArea());
+        assertTrue(msg,!b.hasArea());
+
+        Rectangle aBBox = a.getBoundingBox();
+        Rectangle bBBox = b.getBoundingBox();
+        if (aBBox.getHeight() == 0 && bBBox.getHeight() == 0
+            && (aBBox.getMaxY() == 90 && bBBox.getMaxY() == 90
+            || aBBox.getMinY() == -90 && bBBox.getMinY() == -90))
+          ;//== a point at the pole
+        else
+          assertEquals(msg, aBBox, bBBox);
+      }
+    } else {
+      assertEquals(msg,expected,sect);//always fails
+    }
+  }
+
+  protected void assertEqualsRatio(String msg, double expected, double actual) {
+    double delta = Math.abs(actual - expected);
+    double base = Math.min(actual, expected);
+    double deltaRatio = base==0 ? delta : Math.min(delta,delta / base);
+    assertEquals(msg,0,deltaRatio, EPS);
+  }
+
+  protected int randomIntBetweenDivisible(int start, int end) {
+    return randomIntBetweenDivisible(start, end, (int)DIVISIBLE);
+  }
+  /** Returns a random integer between [start, end]. Integers between must be divisible by the 3rd argument. */
+  protected int randomIntBetweenDivisible(int start, int end, int divisible) {
+    // DWS: I tested this
+    int divisStart = (int) Math.ceil( (start+1) / (double)divisible );
+    int divisEnd = (int) Math.floor( (end-1) / (double)divisible );
+    int divisRange = Math.max(0,divisEnd - divisStart + 1);
+    int r = randomInt(1 + divisRange);//remember that '0' is counted
+    if (r == 0)
+      return start;
+    if (r == 1)
+      return end;
+    return (r-2 + divisStart)*divisible;
+  }
+
+  protected Rectangle randomRectangle(Point nearP) {
+    Rectangle bounds = ctx.getWorldBounds();
+    if (nearP == null)
+      nearP = randomPointIn(bounds);
+
+    Range xRange = randomRange(rarely() ? 0 : nearP.getX(), Range.xRange(bounds, ctx));
+    Range yRange = randomRange(rarely() ? 0 : nearP.getY(), Range.yRange(bounds, ctx));
+
+    return makeNormRect(
+        divisible(xRange.getMin()),
+        divisible(xRange.getMax()),
+        divisible(yRange.getMin()),
+        divisible(yRange.getMax()) );
+  }
+
+  private Range randomRange(double near, Range bounds) {
+    double mid = near + randomGaussian() * bounds.getWidth() / 6;
+    double width = Math.abs(randomGaussian()) * bounds.getWidth() / 6;//1/3rd
+    return new Range(mid - width / 2, mid + width / 2);
+  }
+
+  private double randomGaussianZeroTo(double max) {
+    if (max == 0)
+      return max;
+    assert max > 0;
+    double r;
+    do {
+      r = Math.abs(randomGaussian()) * (max * 0.50);
+    } while (r > max);
+    return r;
+  }
+
+  protected Rectangle randomRectangle(int divisible) {
+    double rX = randomIntBetweenDivisible(-180, 180, divisible);
+    double rW = randomIntBetweenDivisible(0, 360, divisible);
+    double rY1 = randomIntBetweenDivisible(-90, 90, divisible);
+    double rY2 = randomIntBetweenDivisible(-90, 90, divisible);
+    double rYmin = Math.min(rY1,rY2);
+    double rYmax = Math.max(rY1,rY2);
+    if (rW > 0 && rX == 180)
+      rX = -180;
+    return makeNormRect(rX, rX + rW, rYmin, rYmax);
+  }
+
+  protected Point randomPoint() {
+    return randomPointIn(ctx.getWorldBounds());
+  }
+
+  protected Point randomPointIn(Circle c) {
+    double d = c.getRadius() * randomDouble();
+    double angleDEG = 360 * randomDouble();
+    Point p = ctx.getDistCalc().pointOnBearing(c.getCenter(), d, angleDEG, ctx, null);
+    assertEquals(CONTAINS,c.relate(p));
+    return p;
+  }
+
+  protected Point randomPointIn(Rectangle r) {
+    double x = r.getMinX() + randomDouble()*r.getWidth();
+    double y = r.getMinY() + randomDouble()*r.getHeight();
+    x = normX(x);
+    y = normY(y);
+    Point p = ctx.makePoint(x,y);
+    assertEquals(CONTAINS,r.relate(p));
+    return p;
+  }
+
+  protected Point randomPointInOrNull(Shape shape) {
+    if (!shape.hasArea())// or try the center?
+      throw new UnsupportedOperationException("Need area to define shape!");
+    Rectangle bbox = shape.getBoundingBox();
+    for (int i = 0; i < 1000; i++) {
+      Point p = randomPointIn(bbox);
+      if (shape.relate(p).intersects()) {
+        return p;
+      }
+    }
+    return null;//tried too many times and failed
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoPointTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoPointTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoPointTest.java
new file mode 100644
index 0000000..1d559da
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoPointTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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.spatial4j.geo3d;
+
+import org.apache.lucene.geo3d.GeoPoint;
+import org.apache.lucene.geo3d.PlanetModel;
+import org.apache.lucene.util.LuceneTestCase;
+import org.junit.Test;
+
+import com.spatial4j.core.distance.DistanceUtils;
+
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomFloat;
+
+/**
+ * Test basic GeoPoint functionality.
+ */
+public class GeoPointTest extends LuceneTestCase {
+
+  @Test
+  public void testConversion() {
+    testPointRoundTrip(PlanetModel.SPHERE, 90 * DistanceUtils.DEGREES_TO_RADIANS, 0, 1e-6);
+    testPointRoundTrip(PlanetModel.SPHERE, -90 * DistanceUtils.DEGREES_TO_RADIANS, 0, 1e-6);
+    testPointRoundTrip(PlanetModel.WGS84, 90 * DistanceUtils.DEGREES_TO_RADIANS, 0, 1e-6);
+    testPointRoundTrip(PlanetModel.WGS84, -90 * DistanceUtils.DEGREES_TO_RADIANS, 0, 1e-6);
+
+    final int times = atLeast(100);
+    for (int i = 0; i < times; i++) {
+      final double pLat = (randomFloat() * 180.0 - 90.0) * DistanceUtils.DEGREES_TO_RADIANS;
+      final double pLon = (randomFloat() * 360.0 - 180.0) * DistanceUtils.DEGREES_TO_RADIANS;
+      testPointRoundTrip(PlanetModel.SPHERE, pLat, pLon, 1e-6);//1e-6 since there's a square root in there (Karl says)
+      testPointRoundTrip(PlanetModel.WGS84, pLat, pLon, 1e-6);
+    }
+  }
+
+  protected void testPointRoundTrip(PlanetModel planetModel, double pLat, double pLon, double epsilon) {
+    final GeoPoint p1 = new GeoPoint(planetModel, pLat, pLon);
+    // In order to force the reverse conversion, we have to construct a geopoint from just x,y,z
+    final GeoPoint p2 = new GeoPoint(p1.x, p1.y, p1.z);
+    // Now, construct the final point based on getLatitude() and getLongitude()
+    final GeoPoint p3 = new GeoPoint(planetModel, p2.getLatitude(), p2.getLongitude());
+    double dist = p1.arcDistance(p3);
+    assertEquals(0, dist, epsilon);
+  }
+
+  @Test
+  public void testSurfaceDistance() {
+    final int times = atLeast(100);
+    for (int i = 0; i < times; i++) {
+      final double p1Lat = (randomFloat() * 180.0 - 90.0) * DistanceUtils.DEGREES_TO_RADIANS;
+      final double p1Lon = (randomFloat() * 360.0 - 180.0) * DistanceUtils.DEGREES_TO_RADIANS;
+      final double p2Lat = (randomFloat() * 180.0 - 90.0) * DistanceUtils.DEGREES_TO_RADIANS;
+      final double p2Lon = (randomFloat() * 360.0 - 180.0) * DistanceUtils.DEGREES_TO_RADIANS;
+      final GeoPoint p1 = new GeoPoint(PlanetModel.SPHERE, p1Lat, p1Lon);
+      final GeoPoint p2 = new GeoPoint(PlanetModel.SPHERE, p2Lat, p2Lon);
+      final double arcDistance = p1.arcDistance(p2);
+      // Compute ellipsoid distance; it should agree for a sphere
+      final double surfaceDistance = PlanetModel.SPHERE.surfaceDistance(p1,p2);
+      assertEquals(arcDistance, surfaceDistance, 1e-6);
+    }
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testBadLatLon() {
+    new GeoPoint(PlanetModel.SPHERE, 50.0, 32.2);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/vector/TestPointVectorStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/vector/TestPointVectorStrategy.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/vector/TestPointVectorStrategy.java
new file mode 100644
index 0000000..d62a0a8
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/vector/TestPointVectorStrategy.java
@@ -0,0 +1,63 @@
+/*
+ * 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.vector;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Circle;
+import com.spatial4j.core.shape.Point;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.spatial.SpatialMatchConcern;
+import org.apache.lucene.spatial.StrategyTestCase;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+public class TestPointVectorStrategy extends StrategyTestCase {
+
+  @Before
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    this.ctx = SpatialContext.GEO;
+    this.strategy = new PointVectorStrategy(ctx, getClass().getSimpleName());
+  }
+
+  @Test
+  public void testCircleShapeSupport() {
+    Circle circle = ctx.makeCircle(ctx.makePoint(0, 0), 10);
+    SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, circle);
+    Query query = this.strategy.makeQuery(args);
+
+    assertNotNull(query);
+  }
+
+  @Test(expected = UnsupportedOperationException.class)
+  public void testInvalidQueryShape() {
+    Point point = ctx.makePoint(0, 0);
+    SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, point);
+    this.strategy.makeQuery(args);
+  }
+
+  @Test
+  public void testCitiesIntersectsBBox() throws IOException {
+    getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS);
+    executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_Intersects_BBox);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/build.xml
----------------------------------------------------------------------
diff --git a/lucene/spatial/build.xml b/lucene/spatial/build.xml
index 4c348ee..08ab178 100644
--- a/lucene/spatial/build.xml
+++ b/lucene/spatial/build.xml
@@ -24,34 +24,4 @@
 
   <import file="../module-build.xml"/>
 
-  <path id="spatialjar">
-     <fileset dir="lib"/>
-  </path>
-
-  <path id="classpath">
-    <path refid="base.classpath"/>
-    <path refid="spatialjar"/>
-    <pathelement path="${queries.jar}" />
-    <pathelement path="${misc.jar}" />
-    <pathelement path="${spatial3d.jar}" />
-  </path>
-
-  <path id="test.classpath">
-    <path refid="test.base.classpath" />
-    <path refid="spatialjar"/>
-    <pathelement path="src/test-files" />
-  </path>
-
-  <target name="compile-core" depends="jar-queries,jar-misc,jar-spatial3d,common.compile-core" />
-
-  <target name="javadocs" depends="javadocs-queries,javadocs-misc,javadocs-spatial3d,compile-core,check-javadocs-uptodate"
-          unless="javadocs-uptodate-${name}">
-    <invoke-module-javadoc>
-      <links>
-        <link href="../queries"/>
-        <link href="../misc"/>
-        <link href="../spatial3d"/>
-      </links>
-    </invoke-module-javadoc>
-  </target>
 </project>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/ivy.xml
----------------------------------------------------------------------
diff --git a/lucene/spatial/ivy.xml b/lucene/spatial/ivy.xml
index 1625bfd..a427271 100644
--- a/lucene/spatial/ivy.xml
+++ b/lucene/spatial/ivy.xml
@@ -18,19 +18,4 @@
 -->
 <ivy-module version="2.0"  xmlns:maven="http://ant.apache.org/ivy/maven">
   <info organisation="org.apache.lucene" module="spatial"/>
-  <configurations defaultconfmapping="compile->master;test->master">
-    <conf name="compile" transitive="false"/>
-    <conf name="test" transitive="false"/>
-  </configurations>
-  <dependencies>
-    <dependency org="com.spatial4j" name="spatial4j" rev="${/com.spatial4j/spatial4j}" conf="compile"/>
-
-    <dependency org="com.spatial4j" name="spatial4j" rev="${/com.spatial4j/spatial4j}" conf="test">
-      <artifact name="spatial4j" type="test" ext="jar" maven:classifier="tests" />
-    </dependency>
-
-    <dependency org="org.slf4j" name="slf4j-api" rev="${/org.slf4j/slf4j-api}" conf="test"/>
-
-    <exclude org="*" ext="*" matcher="regexp" type="${ivy.exclude.types}"/>
-  </dependencies>
 </ivy-module>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/SpatialStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/SpatialStrategy.java b/lucene/spatial/src/java/org/apache/lucene/spatial/SpatialStrategy.java
deleted file mode 100644
index f433c11..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/SpatialStrategy.java
+++ /dev/null
@@ -1,149 +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;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.queries.function.valuesource.ReciprocalFloatFunction;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.spatial.query.SpatialArgs;
-
-/**
- * The SpatialStrategy encapsulates an approach to indexing and searching based
- * on shapes.
- * <p>
- * Different implementations will support different features. A strategy should
- * document these common elements:
- * <ul>
- *   <li>Can it index more than one shape per field?</li>
- *   <li>What types of shapes can be indexed?</li>
- *   <li>What types of query shapes can be used?</li>
- *   <li>What types of query operations are supported?
- *   This might vary per shape.</li>
- *   <li>Does it use some type of cache?  When?
- * </ul>
- * If a strategy only supports certain shapes at index or query time, then in
- * general it will throw an exception if given an incompatible one.  It will not
- * be coerced into compatibility.
- * <p>
- * Note that a SpatialStrategy is not involved with the Lucene stored field
- * values of shapes, which is immaterial to indexing and search.
- * <p>
- * Thread-safe.
- * <p>
- * This API is marked as experimental, however it is quite stable.
- *
- * @lucene.experimental
- */
-public abstract class SpatialStrategy {
-
-  protected final SpatialContext ctx;
-  private final String fieldName;
-
-  /**
-   * Constructs the spatial strategy with its mandatory arguments.
-   */
-  public SpatialStrategy(SpatialContext ctx, String fieldName) {
-    if (ctx == null)
-      throw new IllegalArgumentException("ctx is required");
-    this.ctx = ctx;
-    if (fieldName == null || fieldName.length() == 0)
-      throw new IllegalArgumentException("fieldName is required");
-    this.fieldName = fieldName;
-  }
-
-  public SpatialContext getSpatialContext() {
-    return ctx;
-  }
-
-  /**
-   * The name of the field or the prefix of them if there are multiple
-   * fields needed internally.
-   * @return Not null.
-   */
-  public String getFieldName() {
-    return fieldName;
-  }
-
-  /**
-   * Returns the IndexableField(s) from the {@code shape} that are to be
-   * added to the {@link org.apache.lucene.document.Document}.  These fields
-   * are expected to be marked as indexed and not stored.
-   * <p>
-   * Note: If you want to <i>store</i> the shape as a string for retrieval in
-   * search results, you could add it like this:
-   * <pre>document.add(new StoredField(fieldName,ctx.toString(shape)));</pre>
-   * The particular string representation used doesn't matter to the Strategy
-   * since it doesn't use it.
-   *
-   * @return Not null nor will it have null elements.
-   * @throws UnsupportedOperationException if given a shape incompatible with the strategy
-   */
-  public abstract Field[] createIndexableFields(Shape shape);
-
-  /**
-   * See {@link #makeDistanceValueSource(com.spatial4j.core.shape.Point, double)} called with
-   * a multiplier of 1.0 (i.e. units of degrees).
-   */
-  public ValueSource makeDistanceValueSource(Point queryPoint) {
-    return makeDistanceValueSource(queryPoint, 1.0);
-  }
-
-  /**
-   * Make a ValueSource returning the distance between the center of the
-   * indexed shape and {@code queryPoint}.  If there are multiple indexed shapes
-   * then the closest one is chosen. The result is multiplied by {@code multiplier}, which
-   * conveniently is used to get the desired units.
-   */
-  public abstract ValueSource makeDistanceValueSource(Point queryPoint, double multiplier);
-
-  /**
-   * Make a Query based principally on {@link org.apache.lucene.spatial.query.SpatialOperation}
-   * and {@link Shape} from the supplied {@code args}.  It should be constant scoring of 1.
-   *
-   * @throws UnsupportedOperationException If the strategy does not support the shape in {@code args}
-   * @throws org.apache.lucene.spatial.query.UnsupportedSpatialOperation If the strategy does not support the {@link
-   * org.apache.lucene.spatial.query.SpatialOperation} in {@code args}.
-   */
-  public abstract Query makeQuery(SpatialArgs args);
-
-  /**
-   * Returns a ValueSource with values ranging from 1 to 0, depending inversely
-   * on the distance from {@link #makeDistanceValueSource(com.spatial4j.core.shape.Point,double)}.
-   * The formula is {@code c/(d + c)} where 'd' is the distance and 'c' is
-   * one tenth the distance to the farthest edge from the center. Thus the
-   * scores will be 1 for indexed points at the center of the query shape and as
-   * low as ~0.1 at its furthest edges.
-   */
-  public final ValueSource makeRecipDistanceValueSource(Shape queryShape) {
-    Rectangle bbox = queryShape.getBoundingBox();
-    double diagonalDist = ctx.getDistCalc().distance(
-        ctx.makePoint(bbox.getMinX(), bbox.getMinY()), bbox.getMaxX(), bbox.getMaxY());
-    double distToEdge = diagonalDist * 0.5;
-    float c = (float)distToEdge * 0.1f;//one tenth
-    return new ReciprocalFloatFunction(makeDistanceValueSource(queryShape.getCenter(), 1.0), 1f, c, c);
-  }
-
-  @Override
-  public String toString() {
-    return getClass().getSimpleName()+" field:"+fieldName+" ctx="+ctx;
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxOverlapRatioValueSource.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxOverlapRatioValueSource.java b/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxOverlapRatioValueSource.java
deleted file mode 100644
index 9d0afe1..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxOverlapRatioValueSource.java
+++ /dev/null
@@ -1,251 +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.bbox;
-
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.search.Explanation;
-
-import com.spatial4j.core.shape.Rectangle;
-
-/**
- * The algorithm is implemented as envelope on envelope (rect on rect) overlays rather than
- * complex polygon on complex polygon overlays.
- * <p>
- * Spatial relevance scoring algorithm:
- * <DL>
- *   <DT>queryArea</DT> <DD>the area of the input query envelope</DD>
- *   <DT>targetArea</DT> <DD>the area of the target envelope (per Lucene document)</DD>
- *   <DT>intersectionArea</DT> <DD>the area of the intersection between the query and target envelopes</DD>
- *   <DT>queryTargetProportion</DT> <DD>A 0-1 factor that divides the score proportion between query and target.
- *   0.5 is evenly.</DD>
- *
- *   <DT>queryRatio</DT> <DD>intersectionArea / queryArea; (see note)</DD>
- *   <DT>targetRatio</DT> <DD>intersectionArea / targetArea; (see note)</DD>
- *   <DT>queryFactor</DT> <DD>queryRatio * queryTargetProportion;</DD>
- *   <DT>targetFactor</DT> <DD>targetRatio * (1 - queryTargetProportion);</DD>
- *   <DT>score</DT> <DD>queryFactor + targetFactor;</DD>
- * </DL>
- * Additionally, note that an optional minimum side length {@code minSideLength} may be used whenever an
- * area is calculated (queryArea, targetArea, intersectionArea). This allows for points or horizontal/vertical lines
- * to be used as the query shape and in such case the descending order should have smallest boxes up front. Without
- * this, a point or line query shape typically scores everything with the same value since there is 0 area.
- * <p>
- * Note: The actual computation of queryRatio and targetRatio is more complicated so that it considers
- * points and lines. Lines have the ratio of overlap, and points are either 1.0 or 0.0 depending on whether
- * it intersects or not.
- * <p>
- * Originally based on Geoportal's
- * <a href="http://geoportal.svn.sourceforge.net/svnroot/geoportal/Geoportal/trunk/src/com/esri/gpt/catalog/lucene/SpatialRankingValueSource.java">
- *   SpatialRankingValueSource</a> but modified quite a bit. GeoPortal's algorithm will yield a score of 0
- * if either a line or point is compared, and it doesn't output a 0-1 normalized score (it multiplies the factors),
- * and it doesn't support minSideLength, and it had dateline bugs.
- *
- * @lucene.experimental
- */
-public class BBoxOverlapRatioValueSource extends BBoxSimilarityValueSource {
-
-  private final boolean isGeo;//-180/+180 degrees  (not part of identity; attached to parent strategy/field)
-
-  private final Rectangle queryExtent;
-  private final double queryArea;//not part of identity
-
-  private final double minSideLength;
-
-  private final double queryTargetProportion;
-
-  //TODO option to compute geodetic area
-
-  /**
-   *
-   * @param rectValueSource mandatory; source of rectangles
-   * @param isGeo True if ctx.isGeo() and thus dateline issues should be attended to
-   * @param queryExtent mandatory; the query rectangle
-   * @param queryTargetProportion see class javadocs. Between 0 and 1.
-   * @param minSideLength see class javadocs. 0.0 will effectively disable.
-   */
-  public BBoxOverlapRatioValueSource(ValueSource rectValueSource, boolean isGeo, Rectangle queryExtent,
-                                     double queryTargetProportion, double minSideLength) {
-    super(rectValueSource);
-    this.isGeo = isGeo;
-    this.minSideLength = minSideLength;
-    this.queryExtent = queryExtent;
-    this.queryArea = calcArea(queryExtent.getWidth(), queryExtent.getHeight());
-    assert queryArea >= 0;
-    this.queryTargetProportion = queryTargetProportion;
-    if (queryTargetProportion < 0 || queryTargetProportion > 1.0)
-      throw new IllegalArgumentException("queryTargetProportion must be >= 0 and <= 1");
-  }
-
-  /** Construct with 75% weighting towards target (roughly GeoPortal's default), geo degrees assumed, no
-   * minimum side length. */
-  public BBoxOverlapRatioValueSource(ValueSource rectValueSource, Rectangle queryExtent) {
-    this(rectValueSource, true, queryExtent, 0.25, 0.0);
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (!super.equals(o)) return false;
-
-    BBoxOverlapRatioValueSource that = (BBoxOverlapRatioValueSource) o;
-
-    if (Double.compare(that.minSideLength, minSideLength) != 0) return false;
-    if (Double.compare(that.queryTargetProportion, queryTargetProportion) != 0) return false;
-    if (!queryExtent.equals(that.queryExtent)) return false;
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = super.hashCode();
-    long temp;
-    result = 31 * result + queryExtent.hashCode();
-    temp = Double.doubleToLongBits(minSideLength);
-    result = 31 * result + (int) (temp ^ (temp >>> 32));
-    temp = Double.doubleToLongBits(queryTargetProportion);
-    result = 31 * result + (int) (temp ^ (temp >>> 32));
-    return result;
-  }
-
-  @Override
-  protected String similarityDescription() {
-    return queryExtent.toString() + "," + queryTargetProportion;
-  }
-
-  @Override
-  protected double score(Rectangle target, AtomicReference<Explanation> exp) {
-    // calculate "height": the intersection height between two boxes.
-    double top = Math.min(queryExtent.getMaxY(), target.getMaxY());
-    double bottom = Math.max(queryExtent.getMinY(), target.getMinY());
-    double height = top - bottom;
-    if (height < 0) {
-      if (exp != null) {
-        exp.set(Explanation.noMatch("No intersection"));
-      }
-      return 0;//no intersection
-    }
-
-    // calculate "width": the intersection width between two boxes.
-    double width = 0;
-    {
-      Rectangle a = queryExtent;
-      Rectangle b = target;
-      if (a.getCrossesDateLine() == b.getCrossesDateLine()) {
-        //both either cross or don't
-        double left = Math.max(a.getMinX(), b.getMinX());
-        double right = Math.min(a.getMaxX(), b.getMaxX());
-        if (!a.getCrossesDateLine()) {//both don't
-          if (left <= right) {
-            width = right - left;
-          } else if (isGeo && (Math.abs(a.getMinX()) == 180 || Math.abs(a.getMaxX()) == 180)
-              && (Math.abs(b.getMinX()) == 180 || Math.abs(b.getMaxX()) == 180)) {
-            width = 0;//both adjacent to dateline
-          } else {
-            if (exp != null) {
-              exp.set(Explanation.noMatch("No intersection"));
-            }
-            return 0;//no intersection
-          }
-        } else {//both cross
-          width = right - left + 360;
-        }
-      } else {
-        if (!a.getCrossesDateLine()) {//then flip
-          a = target;
-          b = queryExtent;
-        }
-        //a crosses, b doesn't
-        double qryWestLeft = Math.max(a.getMinX(), b.getMinX());
-        double qryWestRight = b.getMaxX();
-        if (qryWestLeft < qryWestRight)
-          width += qryWestRight - qryWestLeft;
-
-        double qryEastLeft = b.getMinX();
-        double qryEastRight = Math.min(a.getMaxX(), b.getMaxX());
-        if (qryEastLeft < qryEastRight)
-          width += qryEastRight - qryEastLeft;
-
-        if (qryWestLeft > qryWestRight && qryEastLeft > qryEastRight) {
-          if (exp != null) {
-            exp.set(Explanation.noMatch("No intersection"));
-          }
-          return 0;//no intersection
-        }
-      }
-    }
-
-    // calculate queryRatio and targetRatio
-    double intersectionArea = calcArea(width, height);
-    double queryRatio;
-    if (queryArea > 0) {
-      queryRatio = intersectionArea / queryArea;
-    } else if (queryExtent.getHeight() > 0) {//vert line
-      queryRatio = height / queryExtent.getHeight();
-    } else if (queryExtent.getWidth() > 0) {//horiz line
-      queryRatio = width / queryExtent.getWidth();
-    } else {
-      queryRatio = queryExtent.relate(target).intersects() ? 1 : 0;//could be optimized
-    }
-
-    double targetArea = calcArea(target.getWidth(), target.getHeight());
-    assert targetArea >= 0;
-    double targetRatio;
-    if (targetArea > 0) {
-      targetRatio = intersectionArea / targetArea;
-    } else if (target.getHeight() > 0) {//vert line
-      targetRatio = height / target.getHeight();
-    } else if (target.getWidth() > 0) {//horiz line
-      targetRatio = width / target.getWidth();
-    } else {
-      targetRatio = target.relate(queryExtent).intersects() ? 1 : 0;//could be optimized
-    }
-    assert queryRatio >= 0 && queryRatio <= 1 : queryRatio;
-    assert targetRatio >= 0 && targetRatio <= 1 : targetRatio;
-
-    // combine ratios into a score
-
-    double queryFactor = queryRatio * queryTargetProportion;
-    double targetFactor = targetRatio * (1.0 - queryTargetProportion);
-    double score = queryFactor + targetFactor;
-
-    if (exp!=null) {
-      String minSideDesc = minSideLength > 0.0 ? " (minSide="+minSideLength+")" : "";
-      exp.set(Explanation.match((float) score,
-          this.getClass().getSimpleName()+": queryFactor + targetFactor",
-          Explanation.match((float)intersectionArea, "IntersectionArea" + minSideDesc,
-              Explanation.match((float)width, "width"),
-              Explanation.match((float)height, "height"),
-              Explanation.match((float)queryTargetProportion, "queryTargetProportion")),
-          Explanation.match((float)queryFactor, "queryFactor",
-              Explanation.match((float)targetRatio, "ratio"),
-              Explanation.match((float)queryArea,  "area of " + queryExtent + minSideDesc)),
-          Explanation.match((float)targetFactor, "targetFactor",
-              Explanation.match((float)targetRatio, "ratio"),
-              Explanation.match((float)targetArea,  "area of " + target + minSideDesc))));
-    }
-
-    return score;
-  }
-
-  /** Calculates the area while applying the minimum side length. */
-  private double calcArea(double width, double height) {
-    return Math.max(minSideLength, width) * Math.max(minSideLength, height);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxSimilarityValueSource.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxSimilarityValueSource.java b/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxSimilarityValueSource.java
deleted file mode 100644
index 15cd646..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxSimilarityValueSource.java
+++ /dev/null
@@ -1,117 +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.bbox;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.queries.function.FunctionValues;
-import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
-import org.apache.lucene.search.Explanation;
-import org.apache.lucene.search.IndexSearcher;
-
-import com.spatial4j.core.shape.Rectangle;
-
-/**
- * A base class for calculating a spatial relevance rank per document from a provided
- * {@link ValueSource} in which {@link FunctionValues#objectVal(int)} returns a {@link
- * com.spatial4j.core.shape.Rectangle}.
- * <p>
- * Implementers: remember to implement equals and hashCode if you have
- * fields!
- *
- * @lucene.experimental
- */
-public abstract class BBoxSimilarityValueSource extends ValueSource {
-
-  private final ValueSource bboxValueSource;
-
-  public BBoxSimilarityValueSource(ValueSource bboxValueSource) {
-    this.bboxValueSource = bboxValueSource;
-  }
-
-  @Override
-  public void createWeight(Map context, IndexSearcher searcher) throws IOException {
-    bboxValueSource.createWeight(context, searcher);
-  }
-
-  @Override
-  public String description() {
-    return getClass().getSimpleName()+"(" + bboxValueSource.description() + "," + similarityDescription() + ")";
-  }
-
-  /** A comma-separated list of configurable items of the subclass to put into {@link #description()}. */
-  protected abstract String similarityDescription();
-
-  @Override
-  public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
-
-    final FunctionValues shapeValues = bboxValueSource.getValues(context, readerContext);
-
-    return new DoubleDocValues(this) {
-      @Override
-      public double doubleVal(int doc) {
-        //? limit to Rect or call getBoundingBox()? latter would encourage bad practice
-        final Rectangle rect = (Rectangle) shapeValues.objectVal(doc);
-        return rect==null ? 0 : score(rect, null);
-      }
-
-      @Override
-      public boolean exists(int doc) {
-        return shapeValues.exists(doc);
-      }
-
-      @Override
-      public Explanation explain(int doc) {
-        final Rectangle rect = (Rectangle) shapeValues.objectVal(doc);
-        if (rect == null)
-          return Explanation.noMatch("no rect");
-        AtomicReference<Explanation> explanation = new AtomicReference<>();
-        score(rect, explanation);
-        return explanation.get();
-      }
-    };
-  }
-
-  /**
-   * Return a relevancy score. If {@code exp} is provided then diagnostic information is added.
-   * @param rect The indexed rectangle; not null.
-   * @param exp Optional diagnostic holder.
-   * @return a score.
-   */
-  protected abstract double score(Rectangle rect, AtomicReference<Explanation> exp);
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;//same class
-
-    BBoxSimilarityValueSource that = (BBoxSimilarityValueSource) o;
-
-    if (!bboxValueSource.equals(that.bboxValueSource)) return false;
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    return bboxValueSource.hashCode();
-  }
-}


[16/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/package-info.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/package-info.java
deleted file mode 100644
index dcccdc3..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/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.
- */
- 
-/** 
- * Prefix Tree Strategy.
- */
-package org.apache.lucene.spatial.prefix;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/Cell.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/Cell.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/Cell.java
deleted file mode 100644
index fe3846d..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/Cell.java
+++ /dev/null
@@ -1,109 +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.prefix.tree;
-
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.SpatialRelation;
-import org.apache.lucene.util.BytesRef;
-
-/**
- * Represents a grid cell. Cell instances are generally very transient and may be re-used
- * internally.  To get an instance, you could start with {@link SpatialPrefixTree#getWorldCell()}.
- * And from there you could either traverse down the tree with {@link #getNextLevelCells(com.spatial4j.core.shape.Shape)},
- * or you could read an indexed term via {@link SpatialPrefixTree#readCell(org.apache.lucene.util.BytesRef,Cell)}.
- * When a cell is read from a term, it is comprised of just the base bytes plus optionally a leaf flag.
- *
- * @lucene.experimental
- */
-public interface Cell {
-
-//  If we bring this back; perhaps do so as a method that un-shares its internal state: void unshare();
-//  /** Resets the state of this cell such that it is identical to {@code source}. This can be used for
-//   * cloning a cell to have a safe copy, and it also might be used to position this cell
-//   * before calling {@link #readCell(org.apache.lucene.util.BytesRef)} in a loop if you know the first term
-//   * is going to be close to some other cell, thereby saving some computations. */
-//  void copyFrom(Cell source);
-
-  /** Gets the relationship this cell has with the shape from which it was filtered from, assuming it came from a
-   * {@link CellIterator}. Arguably it belongs there but it's very convenient here. */
-  SpatialRelation getShapeRel();
-
-  /** See {@link #getShapeRel()}.
-   * @lucene.internal */
-  void setShapeRel(SpatialRelation rel);
-
-  /**
-   * Some cells are flagged as leaves, which are indexed as such. A leaf cell is either within some
-   * shape or it both intersects and the cell is at an accuracy threshold such that no smaller cells
-   * for the shape will be represented.
-   */
-  boolean isLeaf();
-
-  /** Set this cell to be a leaf. Warning: never call on a cell
-   * initialized to reference the same bytes from termsEnum, which should be treated as immutable.
-   * Note: not supported at level 0.
-   * @lucene.internal */
-  void setLeaf();
-
-  /**
-   * Returns the bytes for this cell, with a leaf byte <em>if this is a leaf cell</em>.
-   * The result param is used to save object allocation, though its bytes aren't used.
-   * @param result where the result goes, or null to create new
-   */
-  BytesRef getTokenBytesWithLeaf(BytesRef result);
-
-  /**
-   * Returns the bytes for this cell, without a leaf set. The bytes should sort before
-   * {@link #getTokenBytesWithLeaf(org.apache.lucene.util.BytesRef)}.
-   * The result param is used to save object allocation, though its bytes aren't used.
-   * @param result where the result goes, or null to create new
-   */
-  BytesRef getTokenBytesNoLeaf(BytesRef result);
-
-  /** Level 0 is the world (and has no parent), from then on a higher level means a smaller
-   * cell than the level before it.
-   */
-  int getLevel();
-
-  /**
-   * Gets the cells at the next grid cell level underneath this one, optionally filtered by
-   * {@code shapeFilter}. The returned cells should have {@link #getShapeRel()} set to
-   * their relation with {@code shapeFilter}.  In addition, for non-points {@link #isLeaf()}
-   * must be true when that relation is WITHIN.
-   * <p>
-   * IMPORTANT: Cells returned from this iterator can be shared, as well as the bytes.
-   * <p>
-   * Precondition: Never called when getLevel() == maxLevel.
-   *
-   * @param shapeFilter an optional filter for the returned cells.
-   * @return A set of cells (no dups), sorted. Not Modifiable.
-   */
-  CellIterator getNextLevelCells(Shape shapeFilter);
-
-  /** Gets the shape for this cell; typically a Rectangle. */
-  Shape getShape();
-
-  /**
-   * Returns if the target term is within/underneath this cell; not necessarily a direct
-   * descendant.
-   * @param c the term
-   */
-  boolean isPrefixOf(Cell c);
-
-  /** Equivalent to {@code this.getTokenBytesNoLeaf(null).compareTo(fromCell.getTokenBytesNoLeaf(null))}. */
-  int compareToNoLeaf(Cell fromCell);
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/CellIterator.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/CellIterator.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/CellIterator.java
deleted file mode 100644
index 1cef37a..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/CellIterator.java
+++ /dev/null
@@ -1,76 +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.prefix.tree;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * An Iterator of SpatialPrefixTree Cells. The order is always sorted without duplicates.
- *
- * @lucene.experimental
- */
-public abstract class CellIterator implements Iterator<Cell> {
-
-  //note: nextCell or thisCell can be non-null but neither at the same time. That's
-  // because they might return the same instance when re-used!
-
-  protected Cell nextCell;//to be returned by next(), and null'ed after
-  protected Cell thisCell;//see next() & thisCell(). Should be cleared in hasNext().
-
-  /** Returns the cell last returned from {@link #next()}. It's cleared by hasNext(). */
-  public Cell thisCell() {
-    assert thisCell != null : "Only call thisCell() after next(), not hasNext()";
-    return thisCell;
-  }
-
-  // Arguably this belongs here and not on Cell
-  //public SpatialRelation getShapeRel()
-
-  /**
-   * Gets the next cell that is &gt;= {@code fromCell}, compared using non-leaf bytes. If it returns null then
-   * the iterator is exhausted.
-   */
-  public Cell nextFrom(Cell fromCell) {
-    while (true) {
-      if (!hasNext())
-        return null;
-      Cell c = next();//will update thisCell
-      if (c.compareToNoLeaf(fromCell) >= 0) {
-        return c;
-      }
-    }
-  }
-
-  /** This prevents sub-cells (those underneath the current cell) from being iterated to,
-   *  if applicable, otherwise a NO-OP. */
-  @Override
-  public void remove() {
-    assert thisCell != null;
-  }
-
-  @Override
-  public Cell next() {
-    if (nextCell == null) {
-      if (!hasNext())
-        throw new NoSuchElementException();
-    }
-    thisCell = nextCell;
-    nextCell = null;
-    return thisCell;
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTree.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTree.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTree.java
deleted file mode 100644
index 13281f3..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTree.java
+++ /dev/null
@@ -1,444 +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.prefix.tree;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import com.spatial4j.core.shape.Shape;
-
-/**
- * A PrefixTree for date ranges in which the levels of the tree occur at natural periods of time (e.g. years,
- * months, ...). You pass in {@link Calendar} objects with the desired fields set and the unspecified
- * fields unset, which conveys the precision.  The implementation makes some optimization assumptions about a
- * {@link java.util.GregorianCalendar}; others could probably be supported easily.
- * <p>
- * Warning: If you construct a Calendar and then get something from the object like a field (e.g. year) or
- * milliseconds, then every field is fully set by side-effect. So after setting the fields, pass it to this
- * API first.
- * @lucene.experimental
- */
-public class DateRangePrefixTree extends NumberRangePrefixTree {
-
-  /*
-    WARNING  java.util.Calendar is tricky to work with:
-    * If you "get" any field value, every field becomes "set". This can introduce a Heisenbug effect,
-        when in a debugger in some cases. Fortunately, Calendar.toString() doesn't apply.
-    * Beware Calendar underflow of the underlying long.  If you create a Calendar from LONG.MIN_VALUE, and clear
-     a field, it will underflow and appear close to LONG.MAX_VALUE (BC to AD).
-
-    There are no doubt other reasons but those two were hard fought lessons here.
-
-    TODO Improvements:
-    * Make max precision configurable (i.e. to SECOND).
-    * Make min & max year span configurable. Use that to remove pointless top levels of the SPT.
-        If year span is > 10k, then add 1k year level. If year span is > 10k of 1k levels, add 1M level.
-    * NumberRangePrefixTree: override getTreeCellIterator for optimized case where the shape isn't a date span; use
-      FilterCellIterator of the cell stack.
-
-  */
-
-  private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
-  private static Calendar CAL_TMP;//template
-  static {
-    CAL_TMP = Calendar.getInstance(UTC, Locale.ROOT);
-    CAL_TMP.clear();
-  }
-
-  private static final Calendar MINCAL = (Calendar) CAL_TMP.clone();
-  private static final Calendar MAXCAL = (Calendar) CAL_TMP.clone();
-  static {
-    MINCAL.setTimeInMillis(Long.MIN_VALUE);
-    MAXCAL.setTimeInMillis(Long.MAX_VALUE);
-  }
-  //BC years are decreasing, remember.  Yet ActualMaximum is the numerically high value, ActualMinimum is 1.
-  private static final int BC_FIRSTYEAR = MINCAL.getActualMaximum(Calendar.YEAR);
-  private static final int BC_LASTYEAR = MINCAL.getActualMinimum(Calendar.YEAR);//1
-  private static final int BC_YEARS = BC_FIRSTYEAR - BC_LASTYEAR + 1;
-  private static final int AD_FIRSTYEAR = MAXCAL.getActualMinimum(Calendar.YEAR);//1
-  private static final int AD_LASTYEAR = MAXCAL.getActualMaximum(Calendar.YEAR);
-  private static final int AD_YEAR_BASE =  (((BC_YEARS-1) / 1000_000)+1) * 1000_000;
-  static { assert BC_LASTYEAR == 1 && AD_FIRSTYEAR == 1; }
-
-  //how many million years are there?
-  private static final int NUM_MYEARS = (AD_YEAR_BASE + AD_LASTYEAR) / 1000_000;
-
-  private static int calFieldLen(int field) {
-    return CAL_TMP.getMaximum(field) - CAL_TMP.getMinimum(field) + 1;
-  }
-
-  private static final int[] FIELD_BY_LEVEL = {
-      -1/*unused*/, -1, -1, Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH,
-      Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND};
-  private static final int yearLevel = 3;
-
-  public static final DateRangePrefixTree INSTANCE = new DateRangePrefixTree();
-
-  private final UnitNRShape minLV, maxLV;
-  private final UnitNRShape gregorianChangeDateLV;
-
-  protected DateRangePrefixTree() {
-    super(new int[]{//sublevels by level
-        NUM_MYEARS,
-        1000,//1 thousand thousand-years in a million years
-        1000,//1 thousand years in a thousand-year
-        calFieldLen(Calendar.MONTH),
-        calFieldLen(Calendar.DAY_OF_MONTH),
-        calFieldLen(Calendar.HOUR_OF_DAY),
-        calFieldLen(Calendar.MINUTE),
-        calFieldLen(Calendar.SECOND),
-        calFieldLen(Calendar.MILLISECOND),
-    });
-    maxLV = toShape((Calendar)MAXCAL.clone());
-    minLV = toShape((Calendar)MINCAL.clone());
-    if (MAXCAL instanceof GregorianCalendar) {
-      //TODO this should be a configurable param by passing a Calendar serving as a template.
-      GregorianCalendar gCal = (GregorianCalendar)MAXCAL;
-      gregorianChangeDateLV = toUnitShape(gCal.getGregorianChange());
-    } else {
-      gregorianChangeDateLV = null;
-    }
-  }
-
-  @Override
-  public int getNumSubCells(UnitNRShape lv) {
-    int cmp = comparePrefix(lv, maxLV);
-    assert cmp <= 0;
-    if (cmp == 0)//edge case (literally!)
-      return maxLV.getValAtLevel(lv.getLevel()+1);
-
-    // if using GregorianCalendar and we're after the "Gregorian change date" then we'll compute
-    //  the sub-cells ourselves more efficiently without the need to construct a Calendar.
-    cmp = gregorianChangeDateLV != null ? comparePrefix(lv, gregorianChangeDateLV) : -1;
-    //TODO consider also doing fast-path if field is <= hours even if before greg change date
-    if (cmp >= 0) {
-      int result = fastSubCells(lv);
-      assert result == slowSubCells(lv) : "fast/slow numSubCells inconsistency";
-      return result;
-    } else {
-      return slowSubCells(lv);
-    }
-  }
-
-  private int fastSubCells(UnitNRShape lv) {
-    if (lv.getLevel() == yearLevel+1) {//month
-      switch (lv.getValAtLevel(lv.getLevel())) {
-        case Calendar.SEPTEMBER:
-        case Calendar.APRIL:
-        case Calendar.JUNE:
-        case Calendar.NOVEMBER:
-          return 30;
-        case Calendar.FEBRUARY:
-          //get the year (negative numbers for BC)
-          int yearAdj = lv.getValAtLevel(1) * 1_000_000;
-          yearAdj += lv.getValAtLevel(2) * 1000;
-          yearAdj += lv.getValAtLevel(3);
-          int year = yearAdj - AD_YEAR_BASE;
-          if (year % 4 == 0 && !(year % 100 == 0 && year % 400 != 0) )//leap year
-            return 29;
-          else
-            return 28;
-        default:
-          return 31;
-      }
-    } else {//typical:
-      return super.getNumSubCells(lv);
-    }
-  }
-
-  private int slowSubCells(UnitNRShape lv) {
-    int field = FIELD_BY_LEVEL[lv.getLevel()+1];
-    //short-circuit optimization (GregorianCalendar assumptions)
-    if (field == -1 || field == Calendar.YEAR || field >= Calendar.HOUR_OF_DAY)//TODO make configurable
-      return super.getNumSubCells(lv);
-    Calendar cal = toCalendar(lv);//somewhat heavyweight op; ideally should be stored on UnitNRShape somehow
-    return cal.getActualMaximum(field) - cal.getActualMinimum(field) + 1;
-  }
-
-  /** Calendar utility method:
-   * Returns a new {@link Calendar} in UTC TimeZone, ROOT Locale, with all fields cleared. */
-  public Calendar newCal() {
-    return (Calendar) CAL_TMP.clone();
-  }
-
-  /** Calendar utility method:
-   * Returns the spatial prefix tree level for the corresponding {@link java.util.Calendar} field, such as
-   * {@link java.util.Calendar#YEAR}.  If there's no match, the next greatest level is returned as a negative value.
-   */
-  public int getTreeLevelForCalendarField(int calField) {
-    for (int i = yearLevel; i < FIELD_BY_LEVEL.length; i++) {
-      if (FIELD_BY_LEVEL[i] == calField) {
-        return i;
-      } else if (FIELD_BY_LEVEL[i] > calField) {
-        return -1 * i;
-      }
-    }
-    throw new IllegalArgumentException("Bad calendar field?: " + calField);
-  }
-
-  /** Calendar utility method:
-   * Gets the Calendar field code of the last field that is set prior to an unset field. It only
-   * examines fields relevant to the prefix tree. If no fields are set, it returns -1. */
-  public int getCalPrecisionField(Calendar cal) {
-    int lastField = -1;
-    for (int level = yearLevel; level < FIELD_BY_LEVEL.length; level++) {
-      int field = FIELD_BY_LEVEL[level];
-      if (!cal.isSet(field))
-        break;
-      lastField = field;
-    }
-    return lastField;
-  }
-
-  /** Calendar utility method:
-   * Calls {@link Calendar#clear(int)} for every field after {@code field}. Beware of Calendar underflow. */
-  public void clearFieldsAfter(Calendar cal, int field) {
-    if (field == -1) {
-      cal.clear();
-      return;
-    }
-    int assertEra = -1;
-    assert (assertEra = (((Calendar)cal.clone()).get(Calendar.ERA))) >= 0;//a trick to only get this if assert enabled
-    for (int f = field+1; f < Calendar.FIELD_COUNT; f++) {
-      cal.clear(f);
-    }
-    assert ((Calendar)cal.clone()).get(Calendar.ERA) == assertEra : "Calendar underflow";
-  }
-
-  /** Converts {@code value} from a {@link Calendar} or {@link Date} to a {@link Shape}. Other arguments
-   * result in a {@link java.lang.IllegalArgumentException}.
-   */
-  @Override
-  public UnitNRShape toUnitShape(Object value) {
-    if (value instanceof Calendar) {
-      return toShape((Calendar) value);
-    } else if (value instanceof Date) {
-      Calendar cal = newCal();
-      cal.setTime((Date)value);
-      return toShape(cal);
-    }
-    throw new IllegalArgumentException("Expecting Calendar or Date but got: "+value.getClass());
-  }
-
-  /** Converts the Calendar into a Shape.
-   * The isSet() state of the Calendar is re-instated when done. */
-  public UnitNRShape toShape(Calendar cal) {
-    // Convert a Calendar into a stack of cell numbers
-    final int calPrecField = getCalPrecisionField(cal);//must call first; getters set all fields
-    try {
-      int[] valStack = new int[maxLevels];//starts at level 1, not 0
-      int len = 0;
-      if (calPrecField >= Calendar.YEAR) {//year or better precision
-        int year = cal.get(Calendar.YEAR);
-        int yearAdj = cal.get(Calendar.ERA) == 0 ? AD_YEAR_BASE - (year - 1) : AD_YEAR_BASE + year;
-
-        valStack[len++] = yearAdj / 1000_000;
-        yearAdj -= valStack[len-1] * 1000_000;
-        valStack[len++] = yearAdj / 1000;
-        yearAdj -= valStack[len-1] * 1000;
-        valStack[len++] = yearAdj;
-        for (int level = yearLevel+1; level < FIELD_BY_LEVEL.length; level++) {
-          int field = FIELD_BY_LEVEL[level];
-          if (field > calPrecField)
-            break;
-          valStack[len++] = cal.get(field) - cal.getActualMinimum(field);
-        }
-      }
-
-      return toShape(valStack, len);
-    } finally {
-      clearFieldsAfter(cal, calPrecField);//restore precision state modified by get()
-    }
-  }
-
-  /** Calls {@link #toCalendar(org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape)}. */
-  @Override
-  public Object toObject(UnitNRShape shape) {
-    return toCalendar(shape);
-  }
-
-  /** Converts the {@link org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape} shape to a
-   * corresponding Calendar that is cleared below its level. */
-  public Calendar toCalendar(UnitNRShape lv) {
-    if (lv.getLevel() == 0)
-      return newCal();
-    if (comparePrefix(lv, minLV) <= 0) {//shouldn't typically happen; sometimes in a debugger
-      return (Calendar) MINCAL.clone();//full precision; truncation would cause underflow
-    }
-    assert comparePrefix(lv, maxLV) <= 0;
-    Calendar cal = newCal();
-
-    int yearAdj = lv.getValAtLevel(1) * 1_000_000;
-    if (lv.getLevel() > 1) {
-      yearAdj += lv.getValAtLevel(2) * 1000;
-      if (lv.getLevel() > 2) {
-        yearAdj += lv.getValAtLevel(3);
-      }
-    }
-    if (yearAdj > AD_YEAR_BASE) {
-      cal.set(Calendar.ERA, 1);
-      cal.set(Calendar.YEAR, yearAdj - AD_YEAR_BASE);//setting the year resets the era
-    } else {
-      cal.set(Calendar.ERA, 0);//we assert this "sticks" at the end
-      cal.set(Calendar.YEAR, (AD_YEAR_BASE - yearAdj) + 1);
-    }
-    for (int level = yearLevel+1; level <= lv.getLevel(); level++) {
-      int field = FIELD_BY_LEVEL[level];
-      cal.set(field, lv.getValAtLevel(level) + cal.getActualMinimum(field));
-    }
-    assert yearAdj > AD_YEAR_BASE || ((Calendar)cal.clone()).get(Calendar.ERA) == 0 : "ERA / YEAR underflow";
-    return cal;
-  }
-
-  @Override
-  protected String toString(UnitNRShape lv) {
-    return toString(toCalendar(lv));
-  }
-
-  /** Calendar utility method:
-   * Formats the calendar to ISO-8601 format, to include proper BC handling (1BC is "0000", 2BC is "-0001", etc.);
-   * and WITHOUT a trailing 'Z'.
-   * A fully cleared calendar will yield the string "*".
-   * The isSet() state of the Calendar is re-instated when done. */
-   @SuppressWarnings("fallthrough")
-  public String toString(Calendar cal) {
-    final int calPrecField = getCalPrecisionField(cal);//must call first; getters set all fields
-    if (calPrecField == -1)
-      return "*";
-    try {
-      //TODO not fully optimized; but it's at least not used in 'search'.
-      //TODO maybe borrow code from Solr DateUtil (put in Lucene util somewhere), and have it reference this back?
-      String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS";
-      int ptnLen = 0;
-      switch (calPrecField) {//switch fall-through is deliberate
-        case Calendar.MILLISECOND: ptnLen += 4;
-        case Calendar.SECOND: ptnLen += 3;
-        case Calendar.MINUTE: ptnLen += 3;
-        case Calendar.HOUR_OF_DAY: ptnLen += 5;
-        case Calendar.DAY_OF_MONTH: ptnLen += 3;
-        case Calendar.MONTH: ptnLen += 3;
-        case Calendar.YEAR: ptnLen += 4;
-        break;
-        default: throw new IllegalStateException(""+calPrecField);
-      }
-      pattern = pattern.substring(0, ptnLen);
-      SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.ROOT);
-      format.setTimeZone(cal.getTimeZone());
-      if (cal.get(Calendar.ERA) == 0) {//BC
-        //SDF doesn't do this properly according to ISO-8601
-        // Example: 1BC == "0000" (actually 0 AD), 2BC == "-0001", 3BC == "-0002", ...
-        final int yearOrig = cal.get(Calendar.YEAR);
-        cal.set(Calendar.YEAR, yearOrig-1);
-        String str;
-        try {
-          str = format.format(cal.getTime());
-        } finally {
-          //reset to what it was
-          cal.set(Calendar.ERA, 0);//necessary!
-          cal.set(Calendar.YEAR, yearOrig);
-        }
-        if (yearOrig > 1)
-          return "-" + str;
-        else
-          return "0000" + str.substring(4);
-      }
-      return format.format(cal.getTime());
-    } finally {
-      clearFieldsAfter(cal, calPrecField);//restore precision state modified by get()
-    }
-  }
-
-  @Override
-  protected UnitNRShape parseUnitShape(String str) throws ParseException {
-    return toShape(parseCalendar(str));
-  }
-
-  /** Calendar utility method:
-   * The reverse of {@link #toString(java.util.Calendar)}. It will only set the fields found, leaving
-   * the remainder in an un-set state. A leading '-' or '+' is optional (positive assumed), and a
-   * trailing 'Z' is also optional.
-   * @param str not null and not empty
-   * @return not null
-   */
-  public Calendar parseCalendar(String str) throws ParseException {
-    // example: +2014-10-23T21:22:33.159Z
-    if (str == null || str.isEmpty())
-      throw new IllegalArgumentException("str is null or blank");
-    Calendar cal = newCal();
-    if (str.equals("*"))
-      return cal;
-    int offset = 0;//a pointer
-    try {
-      //year & era:
-      int lastOffset = str.charAt(str.length()-1) == 'Z' ? str.length() - 1 : str.length();
-      int hyphenIdx = str.indexOf('-', 1);//look past possible leading hyphen
-      if (hyphenIdx < 0)
-        hyphenIdx = lastOffset;
-      int year = Integer.parseInt(str.substring(offset, hyphenIdx));
-      cal.set(Calendar.ERA, year <= 0 ? 0 : 1);
-      cal.set(Calendar.YEAR, year <= 0 ? -1*year + 1 : year);
-      offset = hyphenIdx + 1;
-      if (lastOffset < offset)
-        return cal;
-
-      //NOTE: We aren't validating separator chars, and we unintentionally accept leading +/-.
-      // The str.substring()'s hopefully get optimized to be stack-allocated.
-
-      //month:
-      cal.set(Calendar.MONTH, Integer.parseInt(str.substring(offset, offset+2)) - 1);//starts at 0
-      offset += 3;
-      if (lastOffset < offset)
-        return cal;
-      //day:
-      cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(str.substring(offset, offset+2)));
-      offset += 3;
-      if (lastOffset < offset)
-        return cal;
-      //hour:
-      cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(str.substring(offset, offset+2)));
-      offset += 3;
-      if (lastOffset < offset)
-        return cal;
-      //minute:
-      cal.set(Calendar.MINUTE, Integer.parseInt(str.substring(offset, offset+2)));
-      offset += 3;
-      if (lastOffset < offset)
-        return cal;
-      //second:
-      cal.set(Calendar.SECOND, Integer.parseInt(str.substring(offset, offset+2)));
-      offset += 3;
-      if (lastOffset < offset)
-        return cal;
-      //ms:
-      cal.set(Calendar.MILLISECOND, Integer.parseInt(str.substring(offset, offset+3)));
-      offset += 3;//last one, move to next char
-      if (lastOffset == offset)
-        return cal;
-    } catch (Exception e) {
-      ParseException pe = new ParseException("Improperly formatted date: "+str, offset);
-      pe.initCause(e);
-      throw pe;
-    }
-    throw new ParseException("Improperly formatted date: "+str, offset);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/FilterCellIterator.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/FilterCellIterator.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/FilterCellIterator.java
deleted file mode 100644
index e4f50e0..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/FilterCellIterator.java
+++ /dev/null
@@ -1,61 +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.prefix.tree;
-
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.SpatialRelation;
-
-import java.util.Iterator;
-
-/**
- * A filtering iterator of Cells. Those not matching the provided shape (disjoint) are
- * skipped. If {@code shapeFilter} is null then all cells are returned.
- *
- * @lucene.internal
- */
-class FilterCellIterator extends CellIterator {
-  final Iterator<Cell> baseIter;
-  final Shape shapeFilter;
-
-  FilterCellIterator(Iterator<Cell> baseIter, Shape shapeFilter) {
-    this.baseIter = baseIter;
-    this.shapeFilter = shapeFilter;
-  }
-
-  @Override
-  public boolean hasNext() {
-    thisCell = null;
-    if (nextCell != null)//calling hasNext twice in a row
-      return true;
-    while (baseIter.hasNext()) {
-      nextCell = baseIter.next();
-      if (shapeFilter == null) {
-        return true;
-      } else {
-        SpatialRelation rel = nextCell.getShape().relate(shapeFilter);
-        if (rel.intersects()) {
-          nextCell.setShapeRel(rel);
-          if (rel == SpatialRelation.WITHIN)
-            nextCell.setLeaf();
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/GeohashPrefixTree.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/GeohashPrefixTree.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/GeohashPrefixTree.java
deleted file mode 100644
index fa4e987..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/GeohashPrefixTree.java
+++ /dev/null
@@ -1,162 +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.prefix.tree;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.io.GeohashUtils;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.util.BytesRef;
-
-/**
- * A {@link SpatialPrefixTree} based on
- * <a href="http://en.wikipedia.org/wiki/Geohash">Geohashes</a>.
- * Uses {@link GeohashUtils} to do all the geohash work.
- *
- * @lucene.experimental
- */
-public class GeohashPrefixTree extends LegacyPrefixTree {
-
-  /**
-   * Factory for creating {@link GeohashPrefixTree} instances with useful defaults
-   */
-  public static class Factory extends SpatialPrefixTreeFactory {
-
-    @Override
-    protected int getLevelForDistance(double degrees) {
-      GeohashPrefixTree grid = new GeohashPrefixTree(ctx, GeohashPrefixTree.getMaxLevelsPossible());
-      return grid.getLevelForDistance(degrees);
-    }
-
-    @Override
-    protected SpatialPrefixTree newSPT() {
-      return new GeohashPrefixTree(ctx,
-          maxLevels != null ? maxLevels : GeohashPrefixTree.getMaxLevelsPossible());
-    }
-  }
-
-  public GeohashPrefixTree(SpatialContext ctx, int maxLevels) {
-    super(ctx, maxLevels);
-    Rectangle bounds = ctx.getWorldBounds();
-    if (bounds.getMinX() != -180)
-      throw new IllegalArgumentException("Geohash only supports lat-lon world bounds. Got "+bounds);
-    int MAXP = getMaxLevelsPossible();
-    if (maxLevels <= 0 || maxLevels > MAXP)
-      throw new IllegalArgumentException("maxLevels must be [1-"+MAXP+"] but got "+ maxLevels);
-  }
-
-  /** Any more than this and there's no point (double lat and lon are the same). */
-  public static int getMaxLevelsPossible() {
-    return GeohashUtils.MAX_PRECISION;
-  }
-
-  @Override
-  public Cell getWorldCell() {
-    return new GhCell(BytesRef.EMPTY_BYTES, 0, 0);
-  }
-
-  @Override
-  public int getLevelForDistance(double dist) {
-    if (dist == 0)
-      return maxLevels;//short circuit
-    final int level = GeohashUtils.lookupHashLenForWidthHeight(dist, dist);
-    return Math.max(Math.min(level, maxLevels), 1);
-  }
-
-  @Override
-  protected Cell getCell(Point p, int level) {
-    return new GhCell(GeohashUtils.encodeLatLon(p.getY(), p.getX(), level));//args are lat,lon (y,x)
-  }
-
-  private static byte[] stringToBytesPlus1(String token) {
-    //copy ASCII token to byte array with one extra spot for eventual LEAF_BYTE if needed
-    byte[] bytes = new byte[token.length() + 1];
-    for (int i = 0; i < token.length(); i++) {
-      bytes[i] = (byte) token.charAt(i);
-    }
-    return bytes;
-  }
-
-  private class GhCell extends LegacyCell {
-
-    private String geohash;//cache; never has leaf byte, simply a geohash
-
-    GhCell(String geohash) {
-      super(stringToBytesPlus1(geohash), 0, geohash.length());
-      this.geohash = geohash;
-      if (isLeaf() && getLevel() < getMaxLevels())//we don't have a leaf byte at max levels (an opt)
-        this.geohash = geohash.substring(0, geohash.length() - 1);
-    }
-
-    GhCell(byte[] bytes, int off, int len) {
-      super(bytes, off, len);
-    }
-
-    @Override
-    protected GeohashPrefixTree getGrid() { return GeohashPrefixTree.this; }
-
-    @Override
-    protected int getMaxLevels() { return maxLevels; }
-
-    @Override
-    protected void readCell(BytesRef bytesRef) {
-      super.readCell(bytesRef);
-      geohash = null;
-    }
-
-    @Override
-    public Collection<Cell> getSubCells() {
-      String[] hashes = GeohashUtils.getSubGeohashes(getGeohash());//sorted
-      List<Cell> cells = new ArrayList<>(hashes.length);
-      for (String hash : hashes) {
-        cells.add(new GhCell(hash));
-      }
-      return cells;
-    }
-
-    @Override
-    public int getSubCellsSize() {
-      return 32;//8x4
-    }
-
-    @Override
-    protected GhCell getSubCell(Point p) {
-      return (GhCell) getGrid().getCell(p, getLevel() + 1);//not performant!
-    }
-
-    @Override
-    public Shape getShape() {
-      if (shape == null) {
-        shape = GeohashUtils.decodeBoundary(getGeohash(), getGrid().getSpatialContext());
-      }
-      return shape;
-    }
-
-    private String getGeohash() {
-      if (geohash == null)
-        geohash = getTokenBytesNoLeaf(null).utf8ToString();
-      return geohash;
-    }
-
-  }//class GhCell
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/LegacyCell.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/LegacyCell.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/LegacyCell.java
deleted file mode 100644
index 27c56a7..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/LegacyCell.java
+++ /dev/null
@@ -1,242 +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.prefix.tree;
-
-import java.util.Collection;
-
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.SpatialRelation;
-import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.StringHelper;
-
-/** The base for the original two SPT's: Geohash and Quad. Don't subclass this for new SPTs.
- * @lucene.internal */
-//public for RPT pruneLeafyBranches code
-public abstract class LegacyCell implements Cell {
-
-  // Important: A LegacyCell doesn't share state for getNextLevelCells(), and
-  //  LegacySpatialPrefixTree assumes this in its simplify tree logic.
-
-  private static final byte LEAF_BYTE = '+';//NOTE: must sort before letters & numbers
-
-  //Arguably we could simply use a BytesRef, using an extra Object.
-  protected byte[] bytes;//generally bigger to potentially hold a leaf
-  protected int b_off;
-  protected int b_len;//doesn't reflect leaf; same as getLevel()
-
-  protected boolean isLeaf;
-
-  /**
-   * When set via getSubCells(filter), it is the relationship between this cell
-   * and the given shape filter. Doesn't participate in shape equality.
-   */
-  protected SpatialRelation shapeRel;
-
-  protected Shape shape;//cached
-
-  /** Warning: Refers to the same bytes (no copy). If {@link #setLeaf()} is subsequently called then it
-   * may modify bytes. */
-  protected LegacyCell(byte[] bytes, int off, int len) {
-    this.bytes = bytes;
-    this.b_off = off;
-    this.b_len = len;
-    readLeafAdjust();
-  }
-
-  protected void readCell(BytesRef bytes) {
-    shapeRel = null;
-    shape = null;
-    this.bytes = bytes.bytes;
-    this.b_off = bytes.offset;
-    this.b_len = (short) bytes.length;
-    readLeafAdjust();
-  }
-
-  protected void readLeafAdjust() {
-    isLeaf = (b_len > 0 && bytes[b_off + b_len - 1] == LEAF_BYTE);
-    if (isLeaf)
-      b_len--;
-    if (getLevel() == getMaxLevels())
-      isLeaf = true;
-  }
-
-  protected abstract SpatialPrefixTree getGrid();
-
-  protected abstract int getMaxLevels();
-
-  @Override
-  public SpatialRelation getShapeRel() {
-    return shapeRel;
-  }
-
-  @Override
-  public void setShapeRel(SpatialRelation rel) {
-    this.shapeRel = rel;
-  }
-
-  @Override
-  public boolean isLeaf() {
-    return isLeaf;
-  }
-
-  @Override
-  public void setLeaf() {
-    isLeaf = true;
-  }
-
-  @Override
-  public BytesRef getTokenBytesWithLeaf(BytesRef result) {
-    result = getTokenBytesNoLeaf(result);
-    if (!isLeaf || getLevel() == getMaxLevels())
-      return result;
-    if (result.bytes.length < result.offset + result.length + 1) {
-      assert false : "Not supposed to happen; performance bug";
-      byte[] copy = new byte[result.length + 1];
-      System.arraycopy(result.bytes, result.offset, copy, 0, result.length - 1);
-      result.bytes = copy;
-      result.offset = 0;
-    }
-    result.bytes[result.offset + result.length++] = LEAF_BYTE;
-    return result;
-  }
-
-  @Override
-  public BytesRef getTokenBytesNoLeaf(BytesRef result) {
-    if (result == null)
-      return new BytesRef(bytes, b_off, b_len);
-    result.bytes = bytes;
-    result.offset = b_off;
-    result.length = b_len;
-    return result;
-  }
-
-  @Override
-  public int getLevel() {
-    return b_len;
-  }
-
-  @Override
-  public CellIterator getNextLevelCells(Shape shapeFilter) {
-    assert getLevel() < getGrid().getMaxLevels();
-    if (shapeFilter instanceof Point) {
-      LegacyCell cell = getSubCell((Point) shapeFilter);
-      cell.shapeRel = SpatialRelation.CONTAINS;
-      return new SingletonCellIterator(cell);
-    } else {
-      return new FilterCellIterator(getSubCells().iterator(), shapeFilter);
-    }
-  }
-
-  /**
-   * Performant implementations are expected to implement this efficiently by
-   * considering the current cell's boundary.
-   * <p>
-   * Precondition: Never called when getLevel() == maxLevel.
-   * Precondition: this.getShape().relate(p) != DISJOINT.
-   */
-  protected abstract LegacyCell getSubCell(Point p);
-
-  /**
-   * Gets the cells at the next grid cell level that covers this cell.
-   * Precondition: Never called when getLevel() == maxLevel.
-   *
-   * @return A set of cells (no dups), sorted, modifiable, not empty, not null.
-   */
-  protected abstract Collection<Cell> getSubCells();
-
-  /**
-   * {@link #getSubCells()}.size() -- usually a constant. Should be &gt;=2
-   */
-  public abstract int getSubCellsSize();
-
-  @Override
-  public boolean isPrefixOf(Cell c) {
-    //Note: this only works when each level uses a whole number of bytes.
-    LegacyCell cell = (LegacyCell)c;
-    boolean result = sliceEquals(cell.bytes, cell.b_off, cell.b_len, bytes, b_off, b_len);
-    assert result == StringHelper.startsWith(c.getTokenBytesNoLeaf(null), getTokenBytesNoLeaf(null));
-    return result;
-  }
-
-  /** Copied from {@link org.apache.lucene.util.StringHelper#startsWith(BytesRef, BytesRef)}
-   *  which calls this. This is to avoid creating a BytesRef.  */
-  private static boolean sliceEquals(byte[] sliceToTest_bytes, int sliceToTest_offset, int sliceToTest_length,
-                                     byte[] other_bytes, int other_offset, int other_length) {
-    if (sliceToTest_length < other_length) {
-      return false;
-    }
-    int i = sliceToTest_offset;
-    int j = other_offset;
-    final int k = other_offset + other_length;
-
-    while (j < k) {
-      if (sliceToTest_bytes[i++] != other_bytes[j++]) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  @Override
-  public int compareToNoLeaf(Cell fromCell) {
-    LegacyCell b = (LegacyCell) fromCell;
-    return compare(bytes, b_off, b_len, b.bytes, b.b_off, b.b_len);
-  }
-
-  /** Copied from {@link BytesRef#compareTo(BytesRef)}.
-   * This is to avoid creating a BytesRef. */
-  protected static int compare(byte[] aBytes, int aUpto, int a_length, byte[] bBytes, int bUpto, int b_length) {
-    final int aStop = aUpto + Math.min(a_length, b_length);
-    while(aUpto < aStop) {
-      int aByte = aBytes[aUpto++] & 0xff;
-      int bByte = bBytes[bUpto++] & 0xff;
-
-      int diff = aByte - bByte;
-      if (diff != 0) {
-        return diff;
-      }
-    }
-
-    // One is a prefix of the other, or, they are equal:
-    return a_length - b_length;
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    //this method isn't "normally" called; just in asserts/tests
-    if (obj instanceof Cell) {
-      Cell cell = (Cell) obj;
-      return getTokenBytesWithLeaf(null).equals(cell.getTokenBytesWithLeaf(null));
-    } else {
-      return false;
-    }
-  }
-
-  @Override
-  public int hashCode() {
-    return getTokenBytesWithLeaf(null).hashCode();
-  }
-
-  @Override
-  public String toString() {
-    //this method isn't "normally" called; just in asserts/tests
-    return getTokenBytesWithLeaf(null).utf8ToString();
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/LegacyPrefixTree.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/LegacyPrefixTree.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/LegacyPrefixTree.java
deleted file mode 100644
index 672c2fe..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/LegacyPrefixTree.java
+++ /dev/null
@@ -1,84 +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.prefix.tree;
-
-import java.util.Arrays;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.util.BytesRef;
-
-/** The base for the original two SPT's: Geohash and Quad. Don't subclass this for new SPTs.
- * @lucene.internal */
-abstract class LegacyPrefixTree extends SpatialPrefixTree {
-  public LegacyPrefixTree(SpatialContext ctx, int maxLevels) {
-    super(ctx, maxLevels);
-  }
-
-  public double getDistanceForLevel(int level) {
-    if (level < 1 || level > getMaxLevels())
-      throw new IllegalArgumentException("Level must be in 1 to maxLevels range");
-    //TODO cache for each level
-    Cell cell = getCell(ctx.getWorldBounds().getCenter(), level);
-    Rectangle bbox = cell.getShape().getBoundingBox();
-    double width = bbox.getWidth();
-    double height = bbox.getHeight();
-    //Use standard cartesian hypotenuse. For geospatial, this answer is larger
-    // than the correct one but it's okay to over-estimate.
-    return Math.sqrt(width * width + height * height);
-  }
-
-  /**
-   * Returns the cell containing point {@code p} at the specified {@code level}.
-   */
-  protected abstract Cell getCell(Point p, int level);
-
-  @Override
-  public Cell readCell(BytesRef term, Cell scratch) {
-    LegacyCell cell = (LegacyCell) scratch;
-    if (cell == null)
-      cell = (LegacyCell) getWorldCell();
-    cell.readCell(term);
-    return cell;
-  }
-
-  @Override
-  public CellIterator getTreeCellIterator(Shape shape, int detailLevel) {
-    if (!(shape instanceof Point))
-      return super.getTreeCellIterator(shape, detailLevel);
-
-    //This specialization is here because the legacy implementations don't have a fast implementation of
-    // cell.getSubCells(point). It's fastest here to encode the full bytes for detailLevel, and create
-    // subcells from the bytesRef in a loop. This avoids an O(N^2) encode, and we have O(N) instead.
-
-    Cell cell = getCell((Point) shape, detailLevel);
-    assert cell instanceof LegacyCell;
-    BytesRef fullBytes = cell.getTokenBytesNoLeaf(null);
-    //fill in reverse order to be sorted
-    Cell[] cells = new Cell[detailLevel];
-    for (int i = 1; i < detailLevel; i++) {
-      fullBytes.length = i;
-      Cell parentCell = readCell(fullBytes, null);
-      cells[i-1] = parentCell;
-    }
-    cells[detailLevel-1] = cell;
-    return new FilterCellIterator(Arrays.asList(cells).iterator(), null);//null filter
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/NumberRangePrefixTree.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/NumberRangePrefixTree.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/NumberRangePrefixTree.java
deleted file mode 100644
index 40e80bc..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/NumberRangePrefixTree.java
+++ /dev/null
@@ -1,989 +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.prefix.tree;
-
-import java.text.ParseException;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.context.SpatialContextFactory;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.SpatialRelation;
-import com.spatial4j.core.shape.impl.RectangleImpl;
-import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.StringHelper;
-
-/**
- * A SpatialPrefixTree for single-dimensional numbers and number ranges of fixed precision values (not floating point).
- * Despite its name, the indexed values (and queries) need not actually be ranges, they can be unit instance/values.
- * <p>
- * Why might you use this instead of Lucene's built-in integer/long support?  Here are some reasons with features based
- * on code in this class, <em>or are possible based on this class but require a subclass to fully realize it</em>.
- * <ul>
- *   <li>Index ranges, not just unit instances. This is especially useful when the requirement calls for a
- *   multi-valued range.</li>
- *   <li>Instead of a fixed "precisionStep", this prefixTree can have a customizable number of child values for any
- *   prefix (up to 32768). This allows exact alignment of the prefix-tree with typical/expected values, which
- *   results in better performance.  For example in a Date implementation, every month can get its own dedicated prefix,
- *   every day, etc., even though months vary in duration.</li>
- *   <li>Arbitrary precision, like {@link java.math.BigDecimal}.</li>
- *   <li>Standard Lucene integer/long indexing always indexes the full precision of those data types but this one
- *   is customizable.</li>
- * </ul>
- *
- * Unlike "normal" spatial components in this module, this special-purpose one only works with {@link Shape}s
- * created by the methods on this class, not from any {@link com.spatial4j.core.context.SpatialContext}.
- *
- * @see org.apache.lucene.spatial.prefix.NumberRangePrefixTreeStrategy
- * @see <a href="https://issues.apache.org/jira/browse/LUCENE-5648">LUCENE-5648</a>
- * @lucene.experimental
- */
-public abstract class NumberRangePrefixTree extends SpatialPrefixTree {
-
-  //
-  //    Dummy SpatialContext
-  //
-
-  private static final SpatialContext DUMMY_CTX;
-  static {
-    SpatialContextFactory factory = new SpatialContextFactory();
-    factory.geo = false;
-    factory.worldBounds = new RectangleImpl(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 0L, 0L, null);
-    DUMMY_CTX = factory.newSpatialContext();
-  }
-
-  /** Base interface for {@link Shape}s this prefix tree supports. It extends {@link Shape} (Spatial4j) for compatibility
-   * with the spatial API even though it doesn't intermix with conventional 2D shapes.
-   * @lucene.experimental
-   */
-  public static interface NRShape extends Shape, Cloneable {
-    /** The result should be parseable by {@link #parseShape(String)}. */
-    abstract String toString();
-
-    /** Returns this shape rounded to the target level. If we are already more course than the level then the shape is
-     * simply returned.  The result may refer to internal state of the argument so you may want to clone it.
-     */
-    public NRShape roundToLevel(int targetLevel);
-  }
-
-  //
-  //  Factory / Conversions / parsing relating to NRShapes
-  //
-
-  /** Converts the value to a unit shape. Doesn't parse strings; see {@link #parseShape(String)} for
-   * that. This is the reverse of {@link #toObject(org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape)}. */
-  public abstract UnitNRShape toUnitShape(Object value);
-
-  /** Returns a shape that represents the continuous range between {@code start} and {@code end}. It will
-   * be normalized, and so sometimes a {@link org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape}
-   * will be returned, other times a
-   * {@link org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.SpanUnitsNRShape} will be.
-   *
-   * @throws IllegalArgumentException if the arguments are in the wrong order, or if either contains the other (yet they
-   * aren't equal).
-   */
-  public NRShape toRangeShape(UnitNRShape startUnit, UnitNRShape endUnit) {
-    //note: this normalization/optimization process is actually REQUIRED based on assumptions elsewhere.
-    //Normalize start & end
-    startUnit = startUnit.getShapeAtLevel(truncateStartVals(startUnit, 0)); // chops off trailing min-vals (zeroes)
-    endUnit = endUnit.getShapeAtLevel(truncateEndVals(endUnit, 0)); // chops off trailing max-vals
-    //Optimize to just start or end if it's equivalent, e.g. April to April 1st is April 1st.
-    int cmp = comparePrefix(startUnit, endUnit);
-    if (cmp > 0) {
-      throw new IllegalArgumentException("Wrong order: "+ startUnit +" TO "+ endUnit);
-    }
-    if (cmp == 0) {//one is a prefix of the other
-      if (startUnit.getLevel() == endUnit.getLevel()) {
-        //same
-        return startUnit;
-      } else if (endUnit.getLevel() > startUnit.getLevel()) {
-        // e.g. April to April 1st
-        if (truncateStartVals(endUnit, startUnit.getLevel()) == startUnit.getLevel()) {
-          return endUnit;
-        }
-      } else {//minLV level > maxLV level
-        // e.g. April 30 to April
-        if (truncateEndVals(startUnit, endUnit.getLevel()) == endUnit.getLevel()) {
-          return startUnit;
-        }
-      }
-    }
-    return new SpanUnitsNRShape(startUnit, endUnit);
-  }
-
-  /** From lv.getLevel on up, it returns the first Level seen with val != 0. It doesn't check past endLevel. */
-  private int truncateStartVals(UnitNRShape lv, int endLevel) {
-    for (int level = lv.getLevel(); level > endLevel; level--) {
-      if (lv.getValAtLevel(level) != 0)
-        return level;
-    }
-    return endLevel;
-  }
-
-  private int truncateEndVals(UnitNRShape lv, int endLevel) {
-    for (int level = lv.getLevel(); level > endLevel; level--) {
-      int max = getNumSubCells(lv.getShapeAtLevel(level - 1)) - 1;
-      if (lv.getValAtLevel(level) != max)
-        return level;
-    }
-    return endLevel;
-  }
-
-  /** Converts a UnitNRShape shape to the corresponding type supported by this class, such as a Calendar/BigDecimal.
-   * This is the reverse of {@link #toUnitShape(Object)}.
-   */
-  public abstract Object toObject(UnitNRShape shape);
-
-  /** A string representation of the UnitNRShape that is parse-able by {@link #parseUnitShape(String)}. */
-  protected abstract String toString(UnitNRShape lv);
-
-  protected static String toStringUnitRaw(UnitNRShape lv) {
-    StringBuilder buf = new StringBuilder(100);
-    buf.append('[');
-    for (int level = 1; level <= lv.getLevel(); level++) {
-      buf.append(lv.getValAtLevel(level)).append(',');
-    }
-    buf.setLength(buf.length()-1);//chop off ','
-    buf.append(']');
-    return buf.toString();
-  }
-
-  /** Detects a range pattern and parses it, otherwise it's parsed as one shape via
-   * {@link #parseUnitShape(String)}.  The range pattern looks like this BNF:
-   * <pre>
-   *   '[' + parseShapeLV + ' TO ' + parseShapeLV + ']'
-   * </pre>
-   * It's the same thing as the toString() of the range shape, notwithstanding range optimization.
-   *
-   * @param str not null or empty
-   * @return not null
-   * @throws java.text.ParseException If there is a problem
-   */
-  public NRShape parseShape(String str) throws ParseException {
-    if (str == null || str.isEmpty())
-      throw new IllegalArgumentException("str is null or blank");
-    if (str.charAt(0) == '[') {
-      if (str.charAt(str.length()-1) != ']')
-        throw new ParseException("If starts with [ must end with ]; got "+str, str.length()-1);
-      int middle = str.indexOf(" TO ");
-      if (middle < 0)
-        throw new ParseException("If starts with [ must contain ' TO '; got "+str, -1);
-      String leftStr = str.substring(1, middle);
-      String rightStr = str.substring(middle + " TO ".length(), str.length()-1);
-      return toRangeShape(parseUnitShape(leftStr), parseUnitShape(rightStr));
-    } else if (str.charAt(0) == '{') {
-      throw new ParseException("Exclusive ranges not supported; got "+str, 0);
-    } else {
-      return parseUnitShape(str);
-    }
-  }
-
-  /** Parse a String to a UnitNRShape. "*" should be the full-range (level 0 shape). */
-  protected abstract UnitNRShape parseUnitShape(String str) throws ParseException;
-
-
-  //
-  //    UnitNRShape
-  //
-
-  /**
-   * A unit value Shape implemented as a stack of numbers, one for each level in the prefix tree. It directly
-   * corresponds to a {@link Cell}.  Spatially speaking, it's analogous to a Point but 1D and has some precision width.
-   * @lucene.experimental
-   */
-  public static interface UnitNRShape extends NRShape, Comparable<UnitNRShape> {
-    //note: formerly known as LevelledValue; thus some variables still use 'lv'
-
-    /** Get the prefix tree level, the higher the more precise. 0 means the world (universe). */
-    int getLevel();
-    /** Gets the value at the specified level of this unit. level must be &gt;= 0 and &lt;= getLevel(). */
-    int getValAtLevel(int level);
-    /** Gets an ancestor at the specified level. It shares state, so you may want to clone() it. */
-    UnitNRShape getShapeAtLevel(int level);
-    @Override
-    UnitNRShape roundToLevel(int targetLevel);
-
-    /** Deep clone */
-    UnitNRShape clone();
-  }
-
-  /** Compares a to b, returning less than 0, 0, or greater than 0, if a is less than, equal to, or
-   * greater than b, respectively, up to their common prefix (i.e. only min(a.levels,b.levels) are compared).
-   * @lucene.internal */
-  protected static int comparePrefix(UnitNRShape a, UnitNRShape b) {
-    int minLevel = Math.min(a.getLevel(), b.getLevel());
-    for (int level = 1; level <= minLevel; level++) {
-      int diff = a.getValAtLevel(level) - b.getValAtLevel(level);
-      if (diff != 0)
-        return diff;
-    }
-    return 0;
-  }
-
-
-  //
-  //    SpanUnitsNRShape
-  //
-
-  /** A range Shape; based on a pair of {@link org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape}.
-   * Spatially speaking, it's analogous to a Rectangle but 1D. It might have been named with Range in the name but it
-   * may be confusing since even the {@link org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape}
-   * is in some sense a range.
-   * @lucene.experimental */
-  public class SpanUnitsNRShape implements NRShape {
-
-    private final UnitNRShape minLV, maxLV;
-    private final int lastLevelInCommon;//computed; not part of identity
-
-    /** Don't call directly; see
-     * {@link #toRangeShape(org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape, org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape)}. */
-    private SpanUnitsNRShape(UnitNRShape minLV, UnitNRShape maxLV) {
-      this.minLV = minLV;
-      this.maxLV = maxLV;
-
-      //calc lastLevelInCommon
-      int level = 1;
-      for (; level <= minLV.getLevel() && level <= maxLV.getLevel(); level++) {
-        if (minLV.getValAtLevel(level) != maxLV.getValAtLevel(level))
-          break;
-      }
-      lastLevelInCommon = level - 1;
-    }
-
-    @Override
-    public SpatialContext getContext() {
-      return DUMMY_CTX;
-    }
-
-    public UnitNRShape getMinUnit() { return minLV; }
-
-    public UnitNRShape getMaxUnit() { return maxLV; }
-
-    /** How many levels are in common between minUnit and maxUnit, not including level 0. */
-    private int getLevelsInCommon() { return lastLevelInCommon; }
-
-    @Override
-    public NRShape roundToLevel(int targetLevel) {
-      return toRangeShape(minLV.roundToLevel(targetLevel), maxLV.roundToLevel(targetLevel));
-    }
-
-    @Override
-    public SpatialRelation relate(Shape shape) {
-//      if (shape instanceof UnitNRShape)
-//        return relate((UnitNRShape)shape);
-      if (shape instanceof SpanUnitsNRShape)
-        return relate((SpanUnitsNRShape) shape);
-      return shape.relate(this).transpose();//probably a UnitNRShape
-    }
-
-    public SpatialRelation relate(SpanUnitsNRShape ext) {
-      //This logic somewhat mirrors RectangleImpl.relate_range()
-      int extMin_intMax = comparePrefix(ext.getMinUnit(), getMaxUnit());
-      if (extMin_intMax > 0)
-        return SpatialRelation.DISJOINT;
-      int extMax_intMin = comparePrefix(ext.getMaxUnit(), getMinUnit());
-      if (extMax_intMin < 0)
-        return SpatialRelation.DISJOINT;
-      int extMin_intMin = comparePrefix(ext.getMinUnit(), getMinUnit());
-      int extMax_intMax = comparePrefix(ext.getMaxUnit(), getMaxUnit());
-      if ((extMin_intMin > 0 || extMin_intMin == 0 && ext.getMinUnit().getLevel() >= getMinUnit().getLevel())
-          && (extMax_intMax < 0 || extMax_intMax == 0 && ext.getMaxUnit().getLevel() >= getMaxUnit().getLevel()))
-        return SpatialRelation.CONTAINS;
-      if ((extMin_intMin < 0 || extMin_intMin == 0 && ext.getMinUnit().getLevel() <= getMinUnit().getLevel())
-          && (extMax_intMax > 0 || extMax_intMax == 0 && ext.getMaxUnit().getLevel() <= getMaxUnit().getLevel()))
-        return SpatialRelation.WITHIN;
-      return SpatialRelation.INTERSECTS;
-    }
-
-    @Override
-    public Rectangle getBoundingBox() { throw new UnsupportedOperationException(); }
-
-    @Override
-    public boolean hasArea() { return true; }
-
-    @Override
-    public double getArea(SpatialContext spatialContext) { throw new UnsupportedOperationException(); }
-
-    @Override
-    public Point getCenter() { throw new UnsupportedOperationException(); }
-
-    @Override
-    public Shape getBuffered(double v, SpatialContext spatialContext) { throw new UnsupportedOperationException(); }
-
-    @Override
-    public boolean isEmpty() { return false; }
-
-    /** A deep clone. */
-    @Override
-    public SpanUnitsNRShape clone() {
-      return new SpanUnitsNRShape(minLV.clone(), maxLV.clone());
-    }
-
-    @Override
-    public String toString() {
-      return "[" + NumberRangePrefixTree.this.toString(minLV) + " TO "
-          + NumberRangePrefixTree.this.toString(maxLV) + "]";
-    }
-
-    @Override
-    public boolean equals(Object o) {
-      if (this == o) return true;
-      if (o == null || getClass() != o.getClass()) return false;
-
-      SpanUnitsNRShape spanShape = (SpanUnitsNRShape) o;
-
-      if (!maxLV.equals(spanShape.maxLV)) return false;
-      if (!minLV.equals(spanShape.minLV)) return false;
-
-      return true;
-    }
-
-    @Override
-    public int hashCode() {
-      int result = minLV.hashCode();
-      result = 31 * result + maxLV.hashCode();
-      return result;
-    }
-  }// class SpanUnitsNRShape
-
-  //
-  //    NumberRangePrefixTree
-  //
-
-  protected final int[] maxSubCellsByLevel;
-  protected final int[] termLenByLevel;
-  protected final int[] levelByTermLen;
-  protected final int maxTermLen; // how long could cell.getToken... (that is a leaf) possibly be?
-
-  protected NumberRangePrefixTree(int[] maxSubCellsByLevel) {
-    super(DUMMY_CTX, maxSubCellsByLevel.length);
-    this.maxSubCellsByLevel = maxSubCellsByLevel;
-
-    // Fill termLenByLevel
-    this.termLenByLevel = new int[maxLevels + 1];
-    termLenByLevel[0] = 0;
-    final int MAX_STATES = 1 << 15;//1 bit less than 2 bytes
-    for (int level = 1; level <= maxLevels; level++) {
-      final int states = maxSubCellsByLevel[level - 1];
-      if (states >= MAX_STATES || states <= 1) {
-        throw new IllegalArgumentException("Max states is "+MAX_STATES+", given "+states+" at level "+level);
-      }
-      boolean twoBytes = states >= 256;
-      termLenByLevel[level] = termLenByLevel[level-1] + (twoBytes ? 2 : 1);
-    }
-    maxTermLen = termLenByLevel[maxLevels] + 1;// + 1 for leaf byte
-
-    // Fill levelByTermLen
-    levelByTermLen = new int[maxTermLen];
-    levelByTermLen[0] = 0;
-    for (int level = 1; level < termLenByLevel.length; level++) {
-      int termLen = termLenByLevel[level];
-      int prevTermLen = termLenByLevel[level-1];
-      if (termLen - prevTermLen == 2) {//2 byte delta
-        //if the term doesn't completely cover this cell then it must be a leaf of the prior.
-        levelByTermLen[termLen-1] = -1;//won't be used; otherwise erroneous
-        levelByTermLen[termLen] = level;
-      } else {//1 byte delta
-        assert termLen - prevTermLen == 1;
-        levelByTermLen[termLen] = level;
-      }
-    }
-
-  }
-
-  @Override
-  public String toString() {
-    return getClass().getSimpleName();
-  }
-
-  @Override
-  public int getLevelForDistance(double dist) {
-    //note: it might be useful to compute which level has a raw width (counted in
-    // bottom units, e.g. milliseconds), that covers the provided dist in those units?
-    return maxLevels; // thus always use full precision. We don't do approximations in this tree/strategy.
-    //throw new UnsupportedOperationException("Not applicable.");
-  }
-
-  @Override
-  public double getDistanceForLevel(int level) {
-    //note: we could compute this... should we?
-    throw new UnsupportedOperationException("Not applicable.");
-  }
-
-  protected UnitNRShape toShape(int[] valStack, int len) {
-    final NRCell[] cellStack = newCellStack(len);
-    for (int i = 0; i < len; i++) {
-      cellStack[i+1].resetCellWithCellNum(valStack[i]);
-    }
-    return cellStack[len];
-  }
-
-  @Override
-  public Cell getWorldCell() {
-    return newCellStack(maxLevels)[0];
-  }
-
-  protected NRCell[] newCellStack(int levels) {
-    final NRCell[] cellsByLevel = new NRCell[levels + 1];
-    final BytesRef term = new BytesRef(maxTermLen);
-    for (int level = 0; level <= levels; level++) {
-      cellsByLevel[level] = new NRCell(cellsByLevel,term,level);
-    }
-    return cellsByLevel;
-  }
-
-  @Override
-  public Cell readCell(BytesRef term, Cell scratch) {
-    if (scratch == null)
-      scratch = getWorldCell();
-
-    //We decode level #, leaf boolean, and populate bytes by reference. We don't decode the stack.
-
-    //reverse lookup term length to the level and hence the cell
-    NRCell[] cellsByLevel = ((NRCell) scratch).cellsByLevel;
-    boolean isLeaf = term.bytes[term.offset + term.length - 1] == 0;
-    int lenNoLeaf = isLeaf ? term.length - 1 : term.length;
-
-    NRCell result = cellsByLevel[levelByTermLen[lenNoLeaf]];
-    if (cellsByLevel[0].termBuf == null)
-      cellsByLevel[0].termBuf = result.term.bytes;//a kluge; see cell.ensureOwnTermBytes()
-    result.term.bytes = term.bytes;
-    result.term.offset = term.offset;
-    result.term.length = lenNoLeaf;//technically this isn't used but may help debugging
-    result.reset();
-    if (isLeaf)
-      result.setLeaf();
-
-    result.cellNumber = -1;//lazy decode flag
-
-    return result;
-  }
-
-  /** Returns the number of sub-cells beneath the given UnitNRShape. */
-  public int getNumSubCells(UnitNRShape lv) {
-    return maxSubCellsByLevel[lv.getLevel()];
-  }
-
-  //
-  //    NRCell
-  //
-
-  /** Most of the PrefixTree implementation is in this one class, which is both
-   * the Cell, the CellIterator, and the Shape to reduce object allocation. It's implemented as a re-used array/stack
-   * of Cells at adjacent levels, that all have a reference back to the cell array to traverse. They also share a common
-   * BytesRef for the term.
-   * @lucene.internal */
-  protected class NRCell extends CellIterator implements Cell, UnitNRShape {
-
-    //Shared: (TODO put this in a new class)
-    final NRCell[] cellsByLevel;
-    final BytesRef term;//AKA the token
-    byte[] termBuf;// see ensureOwnTermBytes(), only for cell0
-
-    //Cell state...
-    final int cellLevel; // assert levelStack[cellLevel] == this
-    int cellNumber; //relative to parent cell. It's unused for level 0. Starts at 0.
-
-    SpatialRelation cellShapeRel;
-    boolean cellIsLeaf;
-
-    //CellIterator state is defined further below
-
-    NRCell(NRCell[] cellsByLevel, BytesRef term, int cellLevel) {
-      this.cellsByLevel = cellsByLevel;
-      this.term = term;
-      this.cellLevel = cellLevel;
-      this.cellNumber = cellLevel == 0 ? 0 : -1;
-      this.cellIsLeaf = false;
-      assert cellsByLevel[cellLevel] == null;
-    }
-
-    /** Ensure we own term.bytes so that it's safe to modify. We detect via a kluge in which cellsByLevel[0].termBuf
-     * is non-null, which is a pre-allocated for use to replace term.bytes. */
-    void ensureOwnTermBytes() {
-      NRCell cell0 = cellsByLevel[0];
-      if (cell0.termBuf == null)
-        return;//we already own the bytes
-      System.arraycopy(term.bytes, term.offset, cell0.termBuf, 0, term.length);
-      term.bytes = cell0.termBuf;
-      term.offset = 0;
-      cell0.termBuf = null;
-    }
-
-    private void reset() {
-      this.cellIsLeaf = false;
-      this.cellShapeRel = null;
-    }
-
-    private void resetCellWithCellNum(int cellNumber) {
-      reset();
-
-      //update bytes
-      //  note: see lazyInitCellNumsFromBytes() for the reverse
-      if (cellNumber >= 0) {//valid
-        ensureOwnTermBytes();
-        int termLen = termLenByLevel[getLevel()];
-        boolean twoBytes = (termLen - termLenByLevel[getLevel()-1]) > 1;
-        if (twoBytes) {
-          //right 7 bits, plus 1 (may overflow to 8th bit which is okay)
-          term.bytes[termLen-2] = (byte) (cellNumber >> 7);
-          term.bytes[termLen-1] = (byte) ((cellNumber & 0x7F) + 1);
-        } else {
-          term.bytes[termLen-1] = (byte) (cellNumber+1);
-        }
-        assert term.bytes[termLen-1] != 0;
-        term.length = termLen;
-      }
-      this.cellNumber = cellNumber;
-    }
-
-    private void ensureDecoded() {
-      if (cellNumber >= 0)
-        return;
-      //Decode cell numbers from bytes. This is the inverse of resetCellWithCellNum().
-      for (int level = 1; level <= getLevel(); level++) {
-        NRCell cell = cellsByLevel[level];
-        int termLen = termLenByLevel[level];
-        boolean twoBytes = (termLen - termLenByLevel[level-1]) > 1;
-        if (twoBytes) {
-          int byteH = (term.bytes[term.offset + termLen - 2] & 0xFF);
-          int byteL = (term.bytes[term.offset + termLen - 1] & 0xFF);
-          assert byteL - 1 < (1<<7);
-          cell.cellNumber = (byteH << 7) + (byteL-1);
-          assert cell.cellNumber < 1<<15;
-        } else {
-          cell.cellNumber = (term.bytes[term.offset + termLen - 1] & 0xFF) - 1;
-          assert cell.cellNumber < 255;
-        }
-        cell.assertDecoded();
-      }
-    }
-
-    private void assertDecoded() {
-      assert cellNumber >= 0 : "Illegal state; ensureDecoded() wasn't called";
-    }
-
-    @Override // for Cell & for UnitNRShape
-    public int getLevel() {
-      return cellLevel;
-    }
-
-    @Override
-    public SpatialRelation getShapeRel() {
-      return cellShapeRel;
-    }
-
-    @Override
-    public void setShapeRel(SpatialRelation rel) {
-      cellShapeRel = rel;
-    }
-
-    @Override
-    public boolean isLeaf() {
-      return cellIsLeaf;
-    }
-
-    @Override
-    public void setLeaf() {
-      cellIsLeaf = true;
-    }
-
-    @Override
-    public UnitNRShape getShape() {
-      ensureDecoded();
-      return this;
-    }
-
-    @Override
-    public BytesRef getTokenBytesNoLeaf(BytesRef result) {
-      if (result == null)
-        result = new BytesRef();
-      result.bytes = term.bytes;
-      result.offset = term.offset;
-      result.length = termLenByLevel[cellLevel];
-      assert result.length <= term.length;
-      return result;
-    }
-
-    @Override
-    public BytesRef getTokenBytesWithLeaf(BytesRef result) {
-      ensureOwnTermBytes();//normally shouldn't do anything
-      result = getTokenBytesNoLeaf(result);
-      if (isLeaf()) {
-        result.bytes[result.length++] = 0;
-      }
-      return result;
-    }
-
-    @Override
-    public boolean isPrefixOf(Cell c) {
-      NRCell otherCell = (NRCell) c;
-      assert term != otherCell.term;
-      //trick to re-use bytesref; provided that we re-instate it
-      int myLastLen = term.length;
-      term.length = termLenByLevel[getLevel()];
-      int otherLastLen = otherCell.term.length;
-      otherCell.term.length = termLenByLevel[otherCell.getLevel()];
-      boolean answer = StringHelper.startsWith(otherCell.term, term);
-      term.length = myLastLen;
-      otherCell.term.length = otherLastLen;
-      return answer;
-    }
-
-    @Override
-    public int compareToNoLeaf(Cell fromCell) {
-      final NRCell nrCell = (NRCell) fromCell;
-      assert term != nrCell.term;
-      //trick to re-use bytesref; provided that we re-instate it
-      int myLastLen = term.length;
-      int otherLastLen = nrCell.term.length;
-      term.length = termLenByLevel[getLevel()];
-      nrCell.term.length = termLenByLevel[nrCell.getLevel()];
-      int answer = term.compareTo(nrCell.term);
-      term.length = myLastLen;
-      nrCell.term.length = otherLastLen;
-      return answer;
-    }
-
-    @Override
-    public CellIterator getNextLevelCells(Shape shapeFilter) {
-      ensureDecoded();
-      NRCell subCell = cellsByLevel[cellLevel + 1];
-      subCell.initIter(shapeFilter);
-      return subCell;
-    }
-
-    //----------- CellIterator
-
-    Shape iterFilter;//UnitNRShape or NRShape
-    boolean iterFirstIsIntersects;
-    boolean iterLastIsIntersects;
-    int iterFirstCellNumber;
-    int iterLastCellNumber;
-
-    private void initIter(Shape filter) {
-      cellNumber = -1;
-      if (filter instanceof UnitNRShape && ((UnitNRShape) filter).getLevel() == 0)
-        filter = null;//world means everything -- no filter
-      iterFilter = filter;
-
-      NRCell parent = getShapeAtLevel(getLevel() - 1);
-
-      // Initialize iter* members.
-
-      //no filter means all subcells
-      if (filter == null) {
-        iterFirstCellNumber = 0;
-        iterFirstIsIntersects = false;
-        iterLastCellNumber = getNumSubCells(parent) - 1;
-        iterLastIsIntersects = false;
-        return;
-      }
-
-      final UnitNRShape minLV;
-      final UnitNRShape maxLV;
-      final int lastLevelInCommon;//between minLV & maxLV
-      if (filter instanceof SpanUnitsNRShape) {
-        SpanUnitsNRShape spanShape = (SpanUnitsNRShape) iterFilter;
-        minLV = spanShape.getMinUnit();
-        maxLV = spanShape.getMaxUnit();
-        lastLevelInCommon = spanShape.getLevelsInCommon();
-      } else {
-        minLV = (UnitNRShape) iterFilter;
-        maxLV = minLV;
-        lastLevelInCommon = minLV.getLevel();
-      }
-
-      //fast path optimization that is usually true, but never first level
-      if (iterFilter == parent.iterFilter &&
-          (getLevel() <= lastLevelInCommon || parent.iterFirstCellNumber != parent.iterLastCellNumber)) {
-        //TODO benchmark if this optimization pays off. We avoid two comparePrefixLV calls.
-        if (parent.iterFirstIsIntersects && parent.cellNumber == parent.iterFirstCellNumber
-            && minLV.getLevel() >= getLevel()) {
-          iterFirstCellNumber = minLV.getValAtLevel(getLevel());
-          iterFirstIsIntersects = (minLV.getLevel() > getLevel());
-        } else {
-          iterFirstCellNumber = 0;
-          iterFirstIsIntersects = false;
-        }
-        if (parent.iterLastIsIntersects && parent.cellNumber == parent.iterLastCellNumber
-            && maxLV.getLevel() >= getLevel()) {
-          iterLastCellNumber = maxLV.getValAtLevel(getLevel());
-          iterLastIsIntersects = (maxLV.getLevel() > getLevel());
-        } else {
-          iterLastCellNumber = getNumSubCells(parent) - 1;
-          iterLastIsIntersects = false;
-        }
-        if (iterFirstCellNumber == iterLastCellNumber) {
-          if (iterLastIsIntersects)
-            iterFirstIsIntersects = true;
-          else if (iterFirstIsIntersects)
-            iterLastIsIntersects = true;
-        }
-        return;
-      }
-
-      //not common to get here, except for level 1 which always happens
-
-      int startCmp = comparePrefix(minLV, parent);
-      if (startCmp > 0) {//start comes after this cell
-        iterFirstCellNumber = 0;
-        iterFirstIsIntersects = false;
-        iterLastCellNumber = -1;//so ends early (no cells)
-        iterLastIsIntersects = false;
-        return;
-      }
-      int endCmp = comparePrefix(maxLV, parent);//compare to end cell
-      if (endCmp < 0) {//end comes before this cell
-        iterFirstCellNumber = 0;
-        iterFirstIsIntersects = false;
-        iterLastCellNumber = -1;//so ends early (no cells)
-        iterLastIsIntersects = false;
-        return;
-      }
-      if (startCmp < 0 || minLV.getLevel() < getLevel()) {
-        //start comes before...
-        iterFirstCellNumber = 0;
-        iterFirstIsIntersects = false;
-      } else {
-        iterFirstCellNumber = minLV.getValAtLevel(getLevel());
-        iterFirstIsIntersects = (minLV.getLevel() > getLevel());
-      }
-      if (endCmp > 0 || maxLV.getLevel() < getLevel()) {
-        //end comes after...
-        iterLastCellNumber = getNumSubCells(parent) - 1;
-        iterLastIsIntersects = false;
-      } else {
-        iterLastCellNumber = maxLV.getValAtLevel(getLevel());
-        iterLastIsIntersects = (maxLV.getLevel() > getLevel());
-      }
-      if (iterFirstCellNumber == iterLastCellNumber) {
-        if (iterLastIsIntersects)
-          iterFirstIsIntersects = true;
-        else if (iterFirstIsIntersects)
-          iterLastIsIntersects = true;
-      }
-    }
-
-    @Override
-    public boolean hasNext() {
-      thisCell = null;
-      if (nextCell != null)//calling hasNext twice in a row
-        return true;
-
-      if (cellNumber >= iterLastCellNumber)
-        return false;
-
-      resetCellWithCellNum(cellNumber < iterFirstCellNumber ? iterFirstCellNumber : cellNumber + 1);
-
-      boolean hasChildren =
-          (cellNumber == iterFirstCellNumber && iterFirstIsIntersects)
-              || (cellNumber == iterLastCellNumber && iterLastIsIntersects);
-
-      if (!hasChildren) {
-        setLeaf();
-        setShapeRel(SpatialRelation.WITHIN);
-      } else if (iterFirstCellNumber == iterLastCellNumber) {
-        setShapeRel(SpatialRelation.CONTAINS);
-      } else {
-        setShapeRel(SpatialRelation.INTERSECTS);
-      }
-
-      nextCell = this;
-      return true;
-    }
-
-    //TODO override nextFrom to be more efficient
-
-    //----------- UnitNRShape
-
-    @Override
-    public int getValAtLevel(int level) {
-      final int result = cellsByLevel[level].cellNumber;
-      assert result >= 0;//initialized (decoded)
-      return result;
-    }
-
-    @Override
-    public NRCell getShapeAtLevel(int level) {
-      assert level <= cellLevel;
-      return cellsByLevel[level];
-    }
-
-    @Override
-    public UnitNRShape roundToLevel(int targetLevel) {
-      if (getLevel() <= targetLevel) {
-        return this;
-      } else {
-        return getShapeAtLevel(targetLevel);
-      }
-    }
-
-    @Override
-    public SpatialRelation relate(Shape shape) {
-      assertDecoded();
-      if (shape == iterFilter && cellShapeRel != null)
-        return cellShapeRel;
-      if (shape instanceof UnitNRShape)
-        return relate((UnitNRShape)shape);
-      if (shape instanceof SpanUnitsNRShape)
-        return relate((SpanUnitsNRShape)shape);
-      return shape.relate(this).transpose();
-    }
-
-    public SpatialRelation relate(UnitNRShape lv) {
-      assertDecoded();
-      int cmp = comparePrefix(this, lv);
-      if (cmp != 0)
-        return SpatialRelation.DISJOINT;
-      if (getLevel() > lv.getLevel())
-        return SpatialRelation.WITHIN;
-      return SpatialRelation.CONTAINS;//or equals
-      //no INTERSECTS; that won't happen.
-    }
-
-    public SpatialRelation relate(SpanUnitsNRShape spanShape) {
-      assertDecoded();
-      int startCmp = comparePrefix(spanShape.getMinUnit(), this);
-      if (startCmp > 0) {//start comes after this cell
-        return SpatialRelation.DISJOINT;
-      }
-      int endCmp = comparePrefix(spanShape.getMaxUnit(), this);
-      if (endCmp < 0) {//end comes before this cell
-        return SpatialRelation.DISJOINT;
-      }
-      int nrMinLevel = spanShape.getMinUnit().getLevel();
-      int nrMaxLevel = spanShape.getMaxUnit().getLevel();
-      if ((startCmp < 0 || startCmp == 0 && nrMinLevel <= getLevel())
-          && (endCmp > 0 || endCmp == 0 && nrMaxLevel <= getLevel()))
-        return SpatialRelation.WITHIN;//or equals
-      //At this point it's Contains or Within.
-      if (startCmp != 0 || endCmp != 0)
-        return SpatialRelation.INTERSECTS;
-      //if min or max Level is less, it might be on the equivalent edge.
-      for (;nrMinLevel < getLevel(); nrMinLevel++) {
-        if (getValAtLevel(nrMinLevel + 1) != 0)
-          return SpatialRelation.INTERSECTS;
-      }
-      for (;nrMaxLevel < getLevel(); nrMaxLevel++) {
-        if (getValAtLevel(nrMaxLevel + 1) != getNumSubCells(getShapeAtLevel(nrMaxLevel)) - 1)
-          return SpatialRelation.INTERSECTS;
-      }
-      return SpatialRelation.CONTAINS;
-    }
-
-    @Override
-    public UnitNRShape clone() {
-      //no leaf distinction; this is purely based on UnitNRShape
-      NRCell cell = (NRCell) readCell(getTokenBytesNoLeaf(null), null);
-      cell.ensureOwnTermBytes();
-      return cell.getShape();
-    }
-
-    @Override
-    public int compareTo(UnitNRShape o) {
-      assertDecoded();
-      //no leaf distinction; this is purely based on UnitNRShape
-      int cmp = comparePrefix(this, o);
-      if (cmp != 0) {
-        return cmp;
-      } else {
-        return getLevel() - o.getLevel();
-      }
-    }
-
-    @Override
-    public Rectangle getBoundingBox() {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean hasArea() {
-      return true;
-    }
-
-    @Override
-    public double getArea(SpatialContext ctx) {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Point getCenter() {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Shape getBuffered(double distance, SpatialContext ctx) { throw new UnsupportedOperationException(); }
-
-    @Override
-    public boolean isEmpty() {
-      return false;
-    }
-
-    //------- Object
-
-    @Override
-    public boolean equals(Object obj) {
-      if (!(obj instanceof NRCell)) {
-        return false;
-      }
-      if (this == obj)
-        return true;
-      NRCell nrCell = (NRCell) obj;
-      assert term != nrCell.term;
-      if (getLevel() != nrCell.getLevel())
-        return false;
-      //trick to re-use bytesref; provided that we re-instate it
-      int myLastLen = term.length;
-      int otherLastLen = nrCell.term.length;
-      boolean answer = getTokenBytesNoLeaf(term).equals(nrCell.getTokenBytesNoLeaf(nrCell.term));
-      term.length = myLastLen;
-      nrCell.term.length = otherLastLen;
-      return answer;
-    }
-
-    @Override
-    public SpatialContext getContext() {
-      return DUMMY_CTX;
-    }
-
-    @Override
-    public int hashCode() {
-      //trick to re-use bytesref; provided that we re-instate it
-      int myLastLen = term.length;
-      int result = getTokenBytesNoLeaf(term).hashCode();
-      term.length = myLastLen;
-      return result;
-    }
-
-    @Override
-    public String toString() {
-      return NumberRangePrefixTree.this.toString(getShape());
-    }
-
-    /** Configure your IDE to use this. */
-    public String toStringDebug() {
-      String pretty = toString();
-      if (getLevel() == 0)
-        return pretty;
-      return toStringUnitRaw(this) + (isLeaf() ? "•" : "") + " " + pretty;
-    }
-
-  } // END OF NRCell
-
-}


[45/50] [abbrv] lucene-solr git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/lucene-solr

Posted by ho...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/lucene-solr


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/b6ec9596
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/b6ec9596
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/b6ec9596

Branch: refs/heads/jira/SOLR-445
Commit: b6ec95961ddfe1a2d766a452bf60bde9744ef5d9
Parents: 37cf228 e44eebf
Author: Mike McCandless <mi...@apache.org>
Authored: Tue Mar 1 05:01:41 2016 -0500
Committer: Mike McCandless <mi...@apache.org>
Committed: Tue Mar 1 05:01:41 2016 -0500

----------------------------------------------------------------------
 solr/CHANGES.txt                                         |  2 ++
 .../java/org/apache/solr/cloud/rule/ReplicaAssigner.java |  9 +++------
 solr/example/files/conf/params.json                      |  6 +++++-
 solr/example/files/conf/solrconfig.xml                   | 11 ++---------
 4 files changed, 12 insertions(+), 16 deletions(-)
----------------------------------------------------------------------



[06/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/DateNRStrategyTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/DateNRStrategyTest.java b/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/DateNRStrategyTest.java
deleted file mode 100644
index 7cd4723..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/DateNRStrategyTest.java
+++ /dev/null
@@ -1,143 +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.prefix;
-
-import java.io.IOException;
-import java.util.Calendar;
-
-import com.carrotsearch.randomizedtesting.annotations.Repeat;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.spatial.prefix.tree.DateRangePrefixTree;
-import org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape;
-import org.apache.lucene.spatial.query.SpatialOperation;
-import org.junit.Before;
-import org.junit.Test;
-
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomBoolean;
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween;
-
-public class DateNRStrategyTest extends RandomSpatialOpStrategyTestCase {
-
-  static final int ITERATIONS = 10;
-
-  DateRangePrefixTree tree;
-
-  long randomCalWindowMs;
-
-  @Before
-  public void setUp() throws Exception {
-    super.setUp();
-    tree = DateRangePrefixTree.INSTANCE;
-    if (randomBoolean()) {
-      strategy = new NumberRangePrefixTreeStrategy(tree, "dateRange");
-    } else {
-      //Test the format that existed <= Lucene 5.0
-      strategy = new NumberRangePrefixTreeStrategy(tree, "dateRange") {
-        @Override
-        protected CellToBytesRefIterator newCellToBytesRefIterator() {
-          return new CellToBytesRefIterator50();
-        }
-      };
-    }
-    Calendar tmpCal = tree.newCal();
-    int randomCalWindowField = randomIntBetween(1, Calendar.ZONE_OFFSET - 1);//we're not allowed to add zone offset
-    tmpCal.add(randomCalWindowField, 2_000);
-    randomCalWindowMs = Math.max(2000L, tmpCal.getTimeInMillis());
-  }
-
-  @Test
-  @Repeat(iterations = ITERATIONS)
-  public void testIntersects() throws IOException {
-    testOperationRandomShapes(SpatialOperation.Intersects);
-  }
-
-  @Test
-  @Repeat(iterations = ITERATIONS)
-  public void testWithin() throws IOException {
-    testOperationRandomShapes(SpatialOperation.IsWithin);
-  }
-
-  @Test
-  @Repeat(iterations = ITERATIONS)
-  public void testContains() throws IOException {
-    testOperationRandomShapes(SpatialOperation.Contains);
-  }
-
-  @Test
-  public void testWithinSame() throws IOException {
-    final Calendar cal = tree.newCal();
-    testOperation(
-        tree.toShape(cal),
-        SpatialOperation.IsWithin,
-        tree.toShape(cal), true);//is within itself
-  }
-
-  @Test
-  public void testWorld() throws IOException {
-    testOperation(
-        tree.toShape(tree.newCal()),//world matches everything
-        SpatialOperation.Contains,
-        tree.toShape(randomCalendar()), true);
-  }
-
-  @Test
-  public void testBugInitIterOptimization() throws Exception {
-    //bug due to fast path initIter() optimization
-    testOperation(
-        tree.parseShape("[2014-03-27T23 TO 2014-04-01T01]"),
-        SpatialOperation.Intersects,
-        tree.parseShape("[2014-04 TO 2014-04-01T02]"), true);
-  }
-
-  @Override
-  protected Shape randomIndexedShape() {
-    Calendar cal1 = randomCalendar();
-    UnitNRShape s1 = tree.toShape(cal1);
-    if (rarely()) {
-      return s1;
-    }
-    try {
-      Calendar cal2 = randomCalendar();
-      UnitNRShape s2 = tree.toShape(cal2);
-      if (cal1.compareTo(cal2) < 0) {
-        return tree.toRangeShape(s1, s2);
-      } else {
-        return tree.toRangeShape(s2, s1);
-      }
-    } catch (IllegalArgumentException e) {
-      assert e.getMessage().startsWith("Differing precision");
-      return s1;
-    }
-  }
-
-  private Calendar randomCalendar() {
-    Calendar cal = tree.newCal();
-    cal.setTimeInMillis(random().nextLong() % randomCalWindowMs);
-    try {
-      tree.clearFieldsAfter(cal, random().nextInt(Calendar.FIELD_COUNT+1)-1);
-    } catch (AssertionError e) {
-      if (!e.getMessage().equals("Calendar underflow"))
-        throw e;
-    }
-    return cal;
-  }
-
-  @Override
-  protected Shape randomQueryShape() {
-    return randomIndexedShape();
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/HeatmapFacetCounterTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/HeatmapFacetCounterTest.java b/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/HeatmapFacetCounterTest.java
deleted file mode 100644
index 124af79..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/HeatmapFacetCounterTest.java
+++ /dev/null
@@ -1,252 +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.prefix;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.carrotsearch.randomizedtesting.annotations.Repeat;
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.context.SpatialContextFactory;
-import com.spatial4j.core.distance.DistanceUtils;
-import com.spatial4j.core.shape.Circle;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.SpatialRelation;
-import com.spatial4j.core.shape.impl.RectangleImpl;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.TotalHitCountCollector;
-import org.apache.lucene.spatial.StrategyTestCase;
-import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.util.Bits;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import static com.carrotsearch.randomizedtesting.RandomizedTest.atMost;
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween;
-
-public class HeatmapFacetCounterTest extends StrategyTestCase {
-
-  SpatialPrefixTree grid;
-
-  int cellsValidated;
-  int cellValidatedNonZero;
-
-  @Before
-  public void setUp() throws Exception {
-    super.setUp();
-    cellsValidated = cellValidatedNonZero = 0;
-    ctx = SpatialContext.GEO;
-    grid = new QuadPrefixTree(ctx, randomIntBetween(1, 8));
-    strategy = new RecursivePrefixTreeStrategy(grid, getTestClass().getSimpleName());
-    if (rarely()) {
-      ((PrefixTreeStrategy) strategy).setPointsOnly(true);
-    }
-  }
-
-  @After
-  public void after() {
-    log.info("Validated " + cellsValidated + " cells, " + cellValidatedNonZero + " non-zero");
-  }
-
-  @Test
-  public void testStatic() throws IOException {
-    //Some specific tests (static, not random).
-    adoc("0", ctx.makeRectangle(179.8, -170, -90, -80));//barely crosses equator
-    adoc("1", ctx.makePoint(-180, -85));//a pt within the above rect
-    adoc("2", ctx.makePoint(172, -85));//a pt to left of rect
-    commit();
-
-    validateHeatmapResultLoop(ctx.makeRectangle(+170, +180, -90, -85), 1, 100);
-    validateHeatmapResultLoop(ctx.makeRectangle(-180, -160, -89, -50), 1, 100);
-    validateHeatmapResultLoop(ctx.makeRectangle(179, 179, -89, -50), 1, 100);//line
-    // We could test anything and everything at this point... I prefer we leave that to random testing and then
-    // add specific tests if we find a bug.
-  }
-
-  @Test
-  public void testQueryCircle() throws IOException {
-    //overwrite setUp; non-geo bounds is more straight-forward; otherwise 88,88 would actually be practically north,
-    final SpatialContextFactory spatialContextFactory = new SpatialContextFactory();
-    spatialContextFactory.geo = false;
-    spatialContextFactory.worldBounds = new RectangleImpl(-90, 90, -90, 90, null);
-    ctx = spatialContextFactory.newSpatialContext();
-    final int LEVEL = 4;
-    grid = new QuadPrefixTree(ctx, LEVEL);
-    strategy = new RecursivePrefixTreeStrategy(grid, getTestClass().getSimpleName());
-    Circle circle = ctx.makeCircle(0, 0, 89);
-    adoc("0", ctx.makePoint(88, 88));//top-right, inside bbox of circle but not the circle
-    adoc("1", ctx.makePoint(0, 0));//clearly inside; dead center in fact
-    commit();
-    final HeatmapFacetCounter.Heatmap heatmap = HeatmapFacetCounter.calcFacets(
-        (PrefixTreeStrategy) strategy, indexSearcher.getTopReaderContext(), null,
-        circle, LEVEL, 1000);
-    //assert that only one point is found, not 2
-    boolean foundOne = false;
-    for (int count : heatmap.counts) {
-      switch (count) {
-        case 0: break;
-        case 1:
-          assertFalse(foundOne);//this is the first
-          foundOne = true;
-          break;
-        default:
-          fail("counts should be 0 or 1: " + count);
-      }
-    }
-    assertTrue(foundOne);
-  }
-
-  /** Recursively facet & validate at higher resolutions until we've seen enough. We assume there are
-   * some non-zero cells. */
-  private void validateHeatmapResultLoop(Rectangle inputRange, int facetLevel, int cellCountRecursThreshold)
-      throws IOException {
-    if (facetLevel > grid.getMaxLevels()) {
-      return;
-    }
-    final int maxCells = 10_000;
-    final HeatmapFacetCounter.Heatmap heatmap = HeatmapFacetCounter.calcFacets(
-        (PrefixTreeStrategy) strategy, indexSearcher.getTopReaderContext(), null, inputRange, facetLevel, maxCells);
-    int preNonZero = cellValidatedNonZero;
-    validateHeatmapResult(inputRange, facetLevel, heatmap);
-    assert cellValidatedNonZero - preNonZero > 0;//we validated more non-zero cells
-    if (heatmap.counts.length < cellCountRecursThreshold) {
-      validateHeatmapResultLoop(inputRange, facetLevel + 1, cellCountRecursThreshold);
-    }
-  }
-
-  @Test
-  @Repeat(iterations = 20)
-  public void testRandom() throws IOException {
-    // Tests using random index shapes & query shapes. This has found all sorts of edge case bugs (e.g. dateline,
-    // cell border, overflow(?)).
-
-    final int numIndexedShapes = 1 + atMost(9);
-    List<Shape> indexedShapes = new ArrayList<>(numIndexedShapes);
-    for (int i = 0; i < numIndexedShapes; i++) {
-      indexedShapes.add(randomIndexedShape());
-    }
-
-    //Main index loop:
-    for (int i = 0; i < indexedShapes.size(); i++) {
-      Shape shape = indexedShapes.get(i);
-      adoc("" + i, shape);
-
-      if (random().nextInt(10) == 0)
-        commit();//intermediate commit, produces extra segments
-    }
-    //delete some documents randomly
-    for (int id = 0; id < indexedShapes.size(); id++) {
-      if (random().nextInt(10) == 0) {
-        deleteDoc("" + id);
-        indexedShapes.set(id, null);
-      }
-    }
-
-    commit();
-
-    // once without dateline wrap
-    final Rectangle rect = randomRectangle();
-    queryHeatmapRecursive(usually() ? ctx.getWorldBounds() : rect, 1);
-    // and once with dateline wrap
-    if (rect.getWidth() > 0) {
-      double shift = random().nextDouble() % rect.getWidth();
-      queryHeatmapRecursive(ctx.makeRectangle(
-              DistanceUtils.normLonDEG(rect.getMinX() - shift),
-              DistanceUtils.normLonDEG(rect.getMaxX() - shift),
-              rect.getMinY(), rect.getMaxY()),
-          1);
-    }
-  }
-
-  /** Build heatmap, validate results, then descend recursively to another facet level. */
-  private boolean queryHeatmapRecursive(Rectangle inputRange, int facetLevel) throws IOException {
-    if (!inputRange.hasArea()) {
-      // Don't test line inputs. It's not that we don't support it but it is more challenging to test if per-chance it
-      // coincides with a grid line due due to edge overlap issue for some grid implementations (geo & quad).
-      return false;
-    }
-    Bits filter = null; //FYI testing filtering of underlying PrefixTreeFacetCounter is done in another test
-    //Calculate facets
-    final int maxCells = 10_000;
-    final HeatmapFacetCounter.Heatmap heatmap = HeatmapFacetCounter.calcFacets(
-        (PrefixTreeStrategy) strategy, indexSearcher.getTopReaderContext(), filter, inputRange, facetLevel, maxCells);
-
-    validateHeatmapResult(inputRange, facetLevel, heatmap);
-
-    boolean foundNonZeroCount = false;
-    for (int count : heatmap.counts) {
-      if (count > 0) {
-        foundNonZeroCount = true;
-        break;
-      }
-    }
-
-    //Test again recursively to higher facetLevel (more detailed cells)
-    if (foundNonZeroCount && cellsValidated <= 500 && facetLevel != grid.getMaxLevels() && inputRange.hasArea()) {
-      for (int i = 0; i < 5; i++) {//try multiple times until we find non-zero counts
-        if (queryHeatmapRecursive(randomRectangle(inputRange), facetLevel + 1)) {
-          break;//we found data here so we needn't try again
-        }
-      }
-    }
-    return foundNonZeroCount;
-  }
-
-  private void validateHeatmapResult(Rectangle inputRange, int facetLevel, HeatmapFacetCounter.Heatmap heatmap)
-      throws IOException {
-    final Rectangle heatRect = heatmap.region;
-    assertTrue(heatRect.relate(inputRange) == SpatialRelation.CONTAINS || heatRect.equals(inputRange));
-    final double cellWidth = heatRect.getWidth() / heatmap.columns;
-    final double cellHeight = heatRect.getHeight() / heatmap.rows;
-    for (int c = 0; c < heatmap.columns; c++) {
-      for (int r = 0; r < heatmap.rows; r++) {
-        final int facetCount = heatmap.getCount(c, r);
-        double x = DistanceUtils.normLonDEG(heatRect.getMinX() + c * cellWidth + cellWidth / 2);
-        double y = DistanceUtils.normLatDEG(heatRect.getMinY() + r * cellHeight + cellHeight / 2);
-        Point pt =  ctx.makePoint(x, y);
-        assertEquals(countMatchingDocsAtLevel(pt, facetLevel), facetCount);
-      }
-    }
-  }
-
-  private int countMatchingDocsAtLevel(Point pt, int facetLevel) throws IOException {
-    // we use IntersectsPrefixTreeFilter directly so that we can specify the level to go to exactly.
-    RecursivePrefixTreeStrategy strategy = (RecursivePrefixTreeStrategy) this.strategy;
-    Query filter = new IntersectsPrefixTreeQuery(
-        pt, strategy.getFieldName(), grid, facetLevel, grid.getMaxLevels());
-    final TotalHitCountCollector collector = new TotalHitCountCollector();
-    indexSearcher.search(filter, collector);
-    cellsValidated++;
-    if (collector.getTotalHits() > 0) {
-      cellValidatedNonZero++;
-    }
-    return collector.getTotalHits();
-  }
-
-  private Shape randomIndexedShape() {
-    if (((PrefixTreeStrategy) strategy).isPointsOnly() || random().nextBoolean()) {
-      return randomPoint();
-    } else {
-      return randomRectangle();
-    }
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/JtsPolygonTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/JtsPolygonTest.java b/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/JtsPolygonTest.java
deleted file mode 100644
index 62b0466..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/JtsPolygonTest.java
+++ /dev/null
@@ -1,117 +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.prefix;
-
-import com.spatial4j.core.context.SpatialContextFactory;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.Field.Store;
-import org.apache.lucene.document.TextField;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.ScoreDoc;
-import org.apache.lucene.search.TopDocs;
-import org.apache.lucene.spatial.StrategyTestCase;
-import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
-import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.query.SpatialOperation;
-import org.junit.Test;
-
-import java.text.ParseException;
-import java.util.HashMap;
-
-public class JtsPolygonTest extends StrategyTestCase {
-
-  private static final double LUCENE_4464_distErrPct = SpatialArgs.DEFAULT_DISTERRPCT;//DEFAULT 2.5%
-
-  public JtsPolygonTest() {
-    try {
-      HashMap<String, String> args = new HashMap<>();
-      args.put("spatialContextFactory",
-          "com.spatial4j.core.context.jts.JtsSpatialContextFactory");
-      ctx = SpatialContextFactory.makeSpatialContext(args, getClass().getClassLoader());
-    } catch (NoClassDefFoundError e) {
-      assumeTrue("This test requires JTS jar: "+e, false);
-    }
-
-    GeohashPrefixTree grid = new GeohashPrefixTree(ctx, 11);//< 1 meter == 11 maxLevels
-    this.strategy = new RecursivePrefixTreeStrategy(grid, getClass().getSimpleName());
-    ((RecursivePrefixTreeStrategy)this.strategy).setDistErrPct(LUCENE_4464_distErrPct);//1% radius (small!)
-  }
-
-  @Test
-  /** LUCENE-4464 */
-  public void testCloseButNoMatch() throws Exception {
-    getAddAndVerifyIndexedDocuments("LUCENE-4464.txt");
-    SpatialArgs args = q(
-        "POLYGON((-93.18100824442227 45.25676372469945," +
-            "-93.23182001200654 45.21421290799412," +
-            "-93.16315546122038 45.23742639412364," +
-            "-93.18100824442227 45.25676372469945))",
-        LUCENE_4464_distErrPct);
-    SearchResults got = executeQuery(strategy.makeQuery(args), 100);
-    assertEquals(1, got.numFound);
-    assertEquals("poly2", got.results.get(0).document.get("id"));
-    //did not find poly 1 !
-  }
-
-  private SpatialArgs q(String shapeStr, double distErrPct) throws ParseException {
-    Shape shape = ctx.readShapeFromWkt(shapeStr);
-    SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, shape);
-    args.setDistErrPct(distErrPct);
-    return args;
-  }
-
-  /**
-   * A PrefixTree pruning optimization gone bad.
-   * See <a href="https://issues.apache.org/jira/browse/LUCENE-4770">LUCENE-4770</a>.
-   */
-  @Test
-  public void testBadPrefixTreePrune() throws Exception {
-  
-    Shape area = ctx.readShapeFromWkt("POLYGON((-122.83 48.57, -122.77 48.56, -122.79 48.53, -122.83 48.57))");
-    
-    SpatialPrefixTree trie = new QuadPrefixTree(ctx, 12);
-    TermQueryPrefixTreeStrategy strategy = new TermQueryPrefixTreeStrategy(trie, "geo");
-    Document doc = new Document();
-    doc.add(new TextField("id", "1", Store.YES));
-
-    Field[] fields = strategy.createIndexableFields(area, 0.025);
-    for (Field field : fields) {
-      doc.add(field);  
-    }
-    addDocument(doc);
-
-    Point upperleft = ctx.makePoint(-122.88, 48.54);
-    Point lowerright = ctx.makePoint(-122.82, 48.62);
-    
-    Query query = strategy.makeQuery(new SpatialArgs(SpatialOperation.Intersects, ctx.makeRectangle(upperleft, lowerright)));
-    commit();
-    
-    TopDocs search = indexSearcher.search(query, 10);
-    ScoreDoc[] scoreDocs = search.scoreDocs;
-    for (ScoreDoc scoreDoc : scoreDocs) {
-      System.out.println(indexSearcher.doc(scoreDoc.doc));
-    }
-
-    assertEquals(1, search.totalHits);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/NumberRangeFacetsTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/NumberRangeFacetsTest.java b/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/NumberRangeFacetsTest.java
deleted file mode 100644
index 11e1d18..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/NumberRangeFacetsTest.java
+++ /dev/null
@@ -1,275 +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.prefix;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.List;
-
-import com.carrotsearch.randomizedtesting.annotations.Repeat;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.queries.TermsQuery;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.SimpleCollector;
-import org.apache.lucene.spatial.StrategyTestCase;
-import org.apache.lucene.spatial.prefix.NumberRangePrefixTreeStrategy.Facets;
-import org.apache.lucene.spatial.prefix.tree.Cell;
-import org.apache.lucene.spatial.prefix.tree.CellIterator;
-import org.apache.lucene.spatial.prefix.tree.DateRangePrefixTree;
-import org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree;
-import org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape;
-import org.apache.lucene.util.Bits;
-import org.apache.lucene.util.FixedBitSet;
-import org.junit.Before;
-import org.junit.Test;
-
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomInt;
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween;
-
-public class NumberRangeFacetsTest extends StrategyTestCase {
-
-  DateRangePrefixTree tree;
-
-  int randomCalWindowField;
-  long randomCalWindowMs;
-
-  @Before
-  public void setUp() throws Exception {
-    super.setUp();
-    tree = DateRangePrefixTree.INSTANCE;
-    strategy = new NumberRangePrefixTreeStrategy(tree, "dateRange");
-    Calendar tmpCal = tree.newCal();
-    randomCalWindowField = randomIntBetween(1, Calendar.ZONE_OFFSET - 1);//we're not allowed to add zone offset
-    tmpCal.add(randomCalWindowField, 2_000);
-    randomCalWindowMs = Math.max(2000L, tmpCal.getTimeInMillis());
-  }
-
-  @Repeat(iterations = 20)
-  @Test
-  public void test() throws IOException {
-    //generate test data
-    List<Shape> indexedShapes = new ArrayList<>();
-    final int numIndexedShapes = random().nextInt(15);
-    for (int i = 0; i < numIndexedShapes; i++) {
-      indexedShapes.add(randomShape());
-    }
-
-    //Main index loop:
-    for (int i = 0; i < indexedShapes.size(); i++) {
-      Shape shape = indexedShapes.get(i);
-      adoc(""+i, shape);
-
-      if (random().nextInt(10) == 0)
-        commit();//intermediate commit, produces extra segments
-    }
-
-    //delete some documents randomly
-    for (int id = 0; id < indexedShapes.size(); id++) {
-      if (random().nextInt(10) == 0) {
-        deleteDoc(""+id);
-        indexedShapes.set(id, null);
-      }
-    }
-
-    commit();
-
-    //Main query loop:
-    for (int queryIdx = 0; queryIdx < 10; queryIdx++) {
-      preQueryHavoc();
-
-      // We need to have a facet range window to do the facets between (a start time & end time). We randomly
-      // pick a date, decide the level we want to facet on, and then pick a right end time that is up to 2 thousand
-      // values later.
-      int calFieldFacet = randomCalWindowField - 1;
-      if (calFieldFacet > 1 && rarely()) {
-        calFieldFacet--;
-      }
-      final Calendar leftCal = randomCalendar();
-      leftCal.add(calFieldFacet, -1 * randomInt(1000));
-      Calendar rightCal = (Calendar) leftCal.clone();
-      rightCal.add(calFieldFacet, randomInt(2000));
-      // Pick facet detail level based on cal field.
-      int detailLevel = tree.getTreeLevelForCalendarField(calFieldFacet);
-      if (detailLevel < 0) {//no exact match
-        detailLevel = -1 * detailLevel;
-      }
-
-      //Randomly pick a filter/acceptDocs
-      Bits topAcceptDocs = null;
-      List<Integer> acceptFieldIds = new ArrayList<>();
-      if (usually()) {
-        //get all possible IDs into a list, random shuffle it, then randomly choose how many of the first we use to
-        // replace the list.
-        for (int i = 0; i < indexedShapes.size(); i++) {
-          if (indexedShapes.get(i) == null) { // we deleted this one
-            continue;
-          }
-          acceptFieldIds.add(i);
-        }
-        Collections.shuffle(acceptFieldIds, random());
-        acceptFieldIds = acceptFieldIds.subList(0, randomInt(acceptFieldIds.size()));
-        if (!acceptFieldIds.isEmpty()) {
-          List<Term> terms = new ArrayList<>();
-          for (Integer acceptDocId : acceptFieldIds) {
-            terms.add(new Term("id", acceptDocId.toString()));
-          }
-
-          topAcceptDocs = searchForDocBits(new TermsQuery(terms));
-        }
-      }
-
-      //Lets do it!
-      NumberRangePrefixTree.NRShape facetRange = tree.toRangeShape(tree.toShape(leftCal), tree.toShape(rightCal));
-      Facets facets = ((NumberRangePrefixTreeStrategy) strategy)
-          .calcFacets(indexSearcher.getTopReaderContext(), topAcceptDocs, facetRange, detailLevel);
-
-      //System.out.println("Q: " + queryIdx + " " + facets);
-
-      //Verify results. We do it by looping over indexed shapes and reducing the facet counts.
-      Shape facetShapeRounded = facetRange.roundToLevel(detailLevel);
-      for (int indexedShapeId = 0; indexedShapeId < indexedShapes.size(); indexedShapeId++) {
-        if (topAcceptDocs != null && !acceptFieldIds.contains(indexedShapeId)) {
-          continue;// this doc was filtered out via acceptDocs
-        }
-        Shape indexedShape = indexedShapes.get(indexedShapeId);
-        if (indexedShape == null) {//was deleted
-          continue;
-        }
-        Shape indexedShapeRounded = ((NumberRangePrefixTree.NRShape) indexedShape).roundToLevel(detailLevel);
-        if (!indexedShapeRounded.relate(facetShapeRounded).intersects()) { // no intersection at all
-          continue;
-        }
-        // walk the cells
-        final CellIterator cellIterator = tree.getTreeCellIterator(indexedShape, detailLevel);
-        while (cellIterator.hasNext()) {
-          Cell cell = cellIterator.next();
-          if (!cell.getShape().relate(facetShapeRounded).intersects()) {
-            cellIterator.remove();//no intersection; prune
-            continue;
-          }
-          assert cell.getLevel() <= detailLevel;
-
-          if (cell.getLevel() == detailLevel) {
-            //count it
-            UnitNRShape shape = (UnitNRShape) cell.getShape();
-            final UnitNRShape parentShape = shape.getShapeAtLevel(detailLevel - 1);//get parent
-            final Facets.FacetParentVal facetParentVal = facets.parents.get(parentShape);
-            assertNotNull(facetParentVal);
-            int index = shape.getValAtLevel(shape.getLevel());
-            assertNotNull(facetParentVal.childCounts);
-            assert facetParentVal.childCounts[index] > 0;
-            facetParentVal.childCounts[index]--;
-
-          } else if (cell.isLeaf()) {
-            //count it, and remove/prune.
-            if (cell.getLevel() < detailLevel - 1) {
-              assert facets.topLeaves > 0;
-              facets.topLeaves--;
-            } else {
-              UnitNRShape shape = (UnitNRShape) cell.getShape();
-              final UnitNRShape parentShape = shape.getShapeAtLevel(detailLevel - 1);//get parent
-              final Facets.FacetParentVal facetParentVal = facets.parents.get(parentShape);
-              assertNotNull(facetParentVal);
-              assert facetParentVal.parentLeaves > 0;
-              facetParentVal.parentLeaves--;
-            }
-
-            cellIterator.remove();
-          }
-        }
-      }
-      // At this point; all counts should be down to zero.
-      assertTrue(facets.topLeaves == 0);
-      for (Facets.FacetParentVal facetParentVal : facets.parents.values()) {
-        assertTrue(facetParentVal.parentLeaves == 0);
-        if (facetParentVal.childCounts != null) {
-          for (int childCount : facetParentVal.childCounts) {
-            assertTrue(childCount == 0);
-          }
-        }
-      }
-
-    }
-  }
-
-  private Bits searchForDocBits(Query query) throws IOException {
-    FixedBitSet bitSet = new FixedBitSet(indexSearcher.getIndexReader().maxDoc());
-    indexSearcher.search(query,
-        new SimpleCollector() {
-          int leafDocBase;
-          @Override
-          public void collect(int doc) throws IOException {
-            bitSet.set(leafDocBase + doc);
-          }
-
-          @Override
-          protected void doSetNextReader(LeafReaderContext context) throws IOException {
-            leafDocBase = context.docBase;
-          }
-
-          @Override
-          public boolean needsScores() {
-            return false;
-          }
-        });
-    return bitSet;
-  }
-
-  private void preQueryHavoc() {
-    if (strategy instanceof RecursivePrefixTreeStrategy) {
-      RecursivePrefixTreeStrategy rpts = (RecursivePrefixTreeStrategy) strategy;
-      int scanLevel = randomInt(rpts.getGrid().getMaxLevels());
-      rpts.setPrefixGridScanLevel(scanLevel);
-    }
-  }
-
-  protected Shape randomShape() {
-    Calendar cal1 = randomCalendar();
-    UnitNRShape s1 = tree.toShape(cal1);
-    if (rarely()) {
-      return s1;
-    }
-    try {
-      Calendar cal2 = randomCalendar();
-      UnitNRShape s2 = tree.toShape(cal2);
-      if (cal1.compareTo(cal2) < 0) {
-        return tree.toRangeShape(s1, s2);
-      } else {
-        return tree.toRangeShape(s2, s1);
-      }
-    } catch (IllegalArgumentException e) {
-      assert e.getMessage().startsWith("Differing precision");
-      return s1;
-    }
-  }
-
-  private Calendar randomCalendar() {
-    Calendar cal = tree.newCal();
-    cal.setTimeInMillis(random().nextLong() % randomCalWindowMs);
-    try {
-      tree.clearFieldsAfter(cal, random().nextInt(Calendar.FIELD_COUNT+1)-1);
-    } catch (AssertionError e) {
-      if (!e.getMessage().equals("Calendar underflow"))
-        throw e;
-    }
-    return cal;
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpFuzzyPrefixTree50Test.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpFuzzyPrefixTree50Test.java b/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpFuzzyPrefixTree50Test.java
deleted file mode 100644
index e932fe9..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpFuzzyPrefixTree50Test.java
+++ /dev/null
@@ -1,31 +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.prefix;
-
-/** Test RandomSpatialOpFuzzyPrefixTreeTest using the PrefixTree index format found in 5.0 and prior. */
-public class RandomSpatialOpFuzzyPrefixTree50Test extends RandomSpatialOpFuzzyPrefixTreeTest {
-
-  protected RecursivePrefixTreeStrategy newRPT() {
-    return new RecursivePrefixTreeStrategy(this.grid, getClass().getSimpleName()) {
-      @Override
-      protected CellToBytesRefIterator newCellToBytesRefIterator() {
-        return new CellToBytesRefIterator50();
-      }
-    };
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpFuzzyPrefixTreeTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpFuzzyPrefixTreeTest.java b/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpFuzzyPrefixTreeTest.java
deleted file mode 100644
index 8db131c..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpFuzzyPrefixTreeTest.java
+++ /dev/null
@@ -1,533 +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.prefix;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import com.carrotsearch.randomizedtesting.annotations.Repeat;
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.context.SpatialContextFactory;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.ShapeCollection;
-import com.spatial4j.core.shape.SpatialRelation;
-import com.spatial4j.core.shape.impl.RectangleImpl;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.StoredField;
-import org.apache.lucene.document.StringField;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.spatial.StrategyTestCase;
-import org.apache.lucene.spatial.prefix.tree.Cell;
-import org.apache.lucene.spatial.prefix.tree.CellIterator;
-import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
-import org.apache.lucene.spatial.prefix.tree.PackedQuadPrefixTree;
-import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.query.SpatialOperation;
-import org.junit.Test;
-
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomBoolean;
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomInt;
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween;
-import static com.spatial4j.core.shape.SpatialRelation.CONTAINS;
-import static com.spatial4j.core.shape.SpatialRelation.DISJOINT;
-import static com.spatial4j.core.shape.SpatialRelation.INTERSECTS;
-import static com.spatial4j.core.shape.SpatialRelation.WITHIN;
-
-/** Randomized PrefixTree test that considers the fuzziness of the
- * results introduced by grid approximation. */
-public class RandomSpatialOpFuzzyPrefixTreeTest extends StrategyTestCase {
-
-  static final int ITERATIONS = 10;
-
-  protected SpatialPrefixTree grid;
-  private SpatialContext ctx2D;
-
-  public void setupGrid(int maxLevels) throws IOException {
-    if (randomBoolean())
-      setupQuadGrid(maxLevels, randomBoolean());
-    else
-      setupGeohashGrid(maxLevels);
-    setupCtx2D(ctx);
-
-    // set prune independently on strategy & grid randomly; should work
-    ((RecursivePrefixTreeStrategy)strategy).setPruneLeafyBranches(randomBoolean());
-    if (this.grid instanceof PackedQuadPrefixTree) {
-      ((PackedQuadPrefixTree) this.grid).setPruneLeafyBranches(randomBoolean());
-    }
-
-    if (maxLevels == -1 && rarely()) {
-      ((PrefixTreeStrategy) strategy).setPointsOnly(true);
-    }
-
-    log.info("Strategy: " + strategy.toString());
-  }
-
-  private void setupCtx2D(SpatialContext ctx) {
-    if (!ctx.isGeo())
-      ctx2D = ctx;
-    //A non-geo version of ctx.
-    SpatialContextFactory ctxFactory = new SpatialContextFactory();
-    ctxFactory.geo = false;
-    ctxFactory.worldBounds = ctx.getWorldBounds();
-    ctx2D = ctxFactory.newSpatialContext();
-  }
-
-  private void setupQuadGrid(int maxLevels, boolean packedQuadPrefixTree) {
-    //non-geospatial makes this test a little easier (in gridSnap), and using boundary values 2^X raises
-    // the prospect of edge conditions we want to test, plus makes for simpler numbers (no decimals).
-    SpatialContextFactory factory = new SpatialContextFactory();
-    factory.geo = false;
-    factory.worldBounds = new RectangleImpl(0, 256, -128, 128, null);
-    this.ctx = factory.newSpatialContext();
-    //A fairly shallow grid, and default 2.5% distErrPct
-    if (maxLevels == -1)
-      maxLevels = randomIntBetween(1, 8);//max 64k cells (4^8), also 256*256
-    if (packedQuadPrefixTree) {
-      this.grid = new PackedQuadPrefixTree(ctx, maxLevels);
-    } else {
-      this.grid = new QuadPrefixTree(ctx, maxLevels);
-    }
-    this.strategy = newRPT();
-  }
-
-  public void setupGeohashGrid(int maxLevels) {
-    this.ctx = SpatialContext.GEO;
-    //A fairly shallow grid, and default 2.5% distErrPct
-    if (maxLevels == -1)
-      maxLevels = randomIntBetween(1, 3);//max 16k cells (32^3)
-    this.grid = new GeohashPrefixTree(ctx, maxLevels);
-    this.strategy = newRPT();
-  }
-
-  protected RecursivePrefixTreeStrategy newRPT() {
-    return new RecursivePrefixTreeStrategy(this.grid, getClass().getSimpleName());
-  }
-
-  @Test
-  @Repeat(iterations = ITERATIONS)
-  public void testIntersects() throws IOException {
-    setupGrid(-1);
-    doTest(SpatialOperation.Intersects);
-  }
-
-  @Test
-  @Repeat(iterations = ITERATIONS)
-  public void testWithin() throws IOException {
-    setupGrid(-1);
-    doTest(SpatialOperation.IsWithin);
-  }
-
-  @Test
-  @Repeat(iterations = ITERATIONS)
-  public void testContains() throws IOException {
-    setupGrid(-1);
-    doTest(SpatialOperation.Contains);
-  }
-
-  /** See LUCENE-5062, {@link ContainsPrefixTreeQuery#multiOverlappingIndexedShapes}. */
-  @Test
-  public void testContainsPairOverlap() throws IOException {
-    setupQuadGrid(3, randomBoolean());
-    adoc("0", new ShapePair(ctx.makeRectangle(0, 33, -128, 128), ctx.makeRectangle(33, 128, -128, 128), true));
-    commit();
-    Query query = strategy.makeQuery(new SpatialArgs(SpatialOperation.Contains,
-        ctx.makeRectangle(0, 128, -16, 128)));
-    SearchResults searchResults = executeQuery(query, 1);
-    assertEquals(1, searchResults.numFound);
-  }
-
-  @Test
-  public void testWithinDisjointParts() throws IOException {
-    setupQuadGrid(7, randomBoolean());
-    //one shape comprised of two parts, quite separated apart
-    adoc("0", new ShapePair(ctx.makeRectangle(0, 10, -120, -100), ctx.makeRectangle(220, 240, 110, 125), false));
-    commit();
-    //query surrounds only the second part of the indexed shape
-    Query query = strategy.makeQuery(new SpatialArgs(SpatialOperation.IsWithin,
-        ctx.makeRectangle(210, 245, 105, 128)));
-    SearchResults searchResults = executeQuery(query, 1);
-    //we shouldn't find it because it's not completely within
-    assertTrue(searchResults.numFound == 0);
-  }
-
-  @Test /** LUCENE-4916 */
-  public void testWithinLeafApproxRule() throws IOException {
-    setupQuadGrid(2, randomBoolean());//4x4 grid
-    //indexed shape will simplify to entire right half (2 top cells)
-    adoc("0", ctx.makeRectangle(192, 204, -128, 128));
-    commit();
-
-    ((RecursivePrefixTreeStrategy) strategy).setPrefixGridScanLevel(randomInt(2));
-
-    //query does NOT contain it; both indexed cells are leaves to the query, and
-    // when expanded to the full grid cells, the top one's top row is disjoint
-    // from the query and thus not a match.
-    assertTrue(executeQuery(strategy.makeQuery(
-        new SpatialArgs(SpatialOperation.IsWithin, ctx.makeRectangle(38, 192, -72, 56))
-    ), 1).numFound==0);//no-match
-
-    //this time the rect is a little bigger and is considered a match. It's
-    // an acceptable false-positive because of the grid approximation.
-    assertTrue(executeQuery(strategy.makeQuery(
-        new SpatialArgs(SpatialOperation.IsWithin, ctx.makeRectangle(38, 192, -72, 80))
-    ), 1).numFound==1);//match
-  }
-
-  @Test
-  public void testShapePair() {
-    ctx = SpatialContext.GEO;
-    setupCtx2D(ctx);
-
-    Shape leftShape = new ShapePair(ctx.makeRectangle(-74, -56, -8, 1), ctx.makeRectangle(-180, 134, -90, 90), true);
-    Shape queryShape = ctx.makeRectangle(-180, 180, -90, 90);
-    assertEquals(SpatialRelation.WITHIN, leftShape.relate(queryShape));
-  }
-
-  //Override so we can index parts of a pair separately, resulting in the detailLevel
-  // being independent for each shape vs the whole thing
-  @Override
-  protected Document newDoc(String id, Shape shape) {
-    Document doc = new Document();
-    doc.add(new StringField("id", id, Field.Store.YES));
-    if (shape != null) {
-      Collection<Shape> shapes;
-      if (shape instanceof ShapePair) {
-        shapes = new ArrayList<>(2);
-        shapes.add(((ShapePair)shape).shape1);
-        shapes.add(((ShapePair)shape).shape2);
-      } else {
-        shapes = Collections.singleton(shape);
-      }
-      for (Shape shapei : shapes) {
-        for (Field f : strategy.createIndexableFields(shapei)) {
-          doc.add(f);
-        }
-      }
-      if (storeShape)//just for diagnostics
-        doc.add(new StoredField(strategy.getFieldName(), shape.toString()));
-    }
-    return doc;
-  }
-
-  @SuppressWarnings("fallthrough")
-  private void doTest(final SpatialOperation operation) throws IOException {
-    //first show that when there's no data, a query will result in no results
-    {
-      Query query = strategy.makeQuery(new SpatialArgs(operation, randomRectangle()));
-      SearchResults searchResults = executeQuery(query, 1);
-      assertEquals(0, searchResults.numFound);
-    }
-
-    final boolean biasContains = (operation == SpatialOperation.Contains);
-
-    //Main index loop:
-    Map<String, Shape> indexedShapes = new LinkedHashMap<>();
-    Map<String, Shape> indexedShapesGS = new LinkedHashMap<>();//grid snapped
-    final int numIndexedShapes = randomIntBetween(1, 6);
-    boolean indexedAtLeastOneShapePair = false;
-    final boolean pointsOnly = ((PrefixTreeStrategy) strategy).isPointsOnly();
-    for (int i = 0; i < numIndexedShapes; i++) {
-      String id = "" + i;
-      Shape indexedShape;
-      int R = random().nextInt(12);
-      if (R == 0) {//1 in 12
-        indexedShape = null;
-      } else if (R == 1 || pointsOnly) {//1 in 12
-        indexedShape = randomPoint();//just one point
-      } else if (R <= 4) {//3 in 12
-        //comprised of more than one shape
-        indexedShape = randomShapePairRect(biasContains);
-        indexedAtLeastOneShapePair = true;
-      } else {
-        indexedShape = randomRectangle();//just one rect
-      }
-
-      indexedShapes.put(id, indexedShape);
-      indexedShapesGS.put(id, gridSnap(indexedShape));
-
-      adoc(id, indexedShape);
-
-      if (random().nextInt(10) == 0)
-        commit();//intermediate commit, produces extra segments
-
-    }
-    //delete some documents randomly
-    Iterator<String> idIter = indexedShapes.keySet().iterator();
-    while (idIter.hasNext()) {
-      String id = idIter.next();
-      if (random().nextInt(10) == 0) {
-        deleteDoc(id);
-        idIter.remove();
-        indexedShapesGS.remove(id);
-      }
-    }
-
-    commit();
-
-    //Main query loop:
-    final int numQueryShapes = atLeast(20);
-    for (int i = 0; i < numQueryShapes; i++) {
-      int scanLevel = randomInt(grid.getMaxLevels());
-      ((RecursivePrefixTreeStrategy) strategy).setPrefixGridScanLevel(scanLevel);
-
-      final Shape queryShape;
-      switch (randomInt(10)) {
-        case 0: queryShape = randomPoint(); break;
-// LUCENE-5549
-//TODO debug: -Dtests.method=testWithin -Dtests.multiplier=3 -Dtests.seed=5F5294CE2E075A3E:AAD2F0F79288CA64
-//        case 1:case 2:case 3:
-//          if (!indexedAtLeastOneShapePair) { // avoids ShapePair.relate(ShapePair), which isn't reliable
-//            queryShape = randomShapePairRect(!biasContains);//invert biasContains for query side
-//            break;
-//          }
-
-        case 4:
-          //choose an existing indexed shape
-          if (!indexedShapes.isEmpty()) {
-            Shape tmp = indexedShapes.values().iterator().next();
-            if (tmp instanceof Point || tmp instanceof Rectangle) {//avoids null and shapePair
-              queryShape = tmp;
-              break;
-            }
-          }//else fall-through
-
-        default: queryShape = randomRectangle();
-      }
-      final Shape queryShapeGS = gridSnap(queryShape);
-
-      final boolean opIsDisjoint = operation == SpatialOperation.IsDisjointTo;
-
-      //Generate truth via brute force:
-      // We ensure true-positive matches (if the predicate on the raw shapes match
-      //  then the search should find those same matches).
-      // approximations, false-positive matches
-      Set<String> expectedIds = new LinkedHashSet<>();//true-positives
-      Set<String> secondaryIds = new LinkedHashSet<>();//false-positives (unless disjoint)
-      for (Map.Entry<String, Shape> entry : indexedShapes.entrySet()) {
-        String id = entry.getKey();
-        Shape indexedShapeCompare = entry.getValue();
-        if (indexedShapeCompare == null)
-          continue;
-        Shape queryShapeCompare = queryShape;
-
-        if (operation.evaluate(indexedShapeCompare, queryShapeCompare)) {
-          expectedIds.add(id);
-          if (opIsDisjoint) {
-            //if no longer intersect after buffering them, for disjoint, remember this
-            indexedShapeCompare = indexedShapesGS.get(id);
-            queryShapeCompare = queryShapeGS;
-            if (!operation.evaluate(indexedShapeCompare, queryShapeCompare))
-              secondaryIds.add(id);
-          }
-        } else if (!opIsDisjoint) {
-          //buffer either the indexed or query shape (via gridSnap) and try again
-          if (operation == SpatialOperation.Intersects) {
-            indexedShapeCompare = indexedShapesGS.get(id);
-            queryShapeCompare = queryShapeGS;
-            //TODO Unfortunately, grid-snapping both can result in intersections that otherwise
-            // wouldn't happen when the grids are adjacent. Not a big deal but our test is just a
-            // bit more lenient.
-          } else if (operation == SpatialOperation.Contains) {
-            indexedShapeCompare = indexedShapesGS.get(id);
-          } else if (operation == SpatialOperation.IsWithin) {
-            queryShapeCompare = queryShapeGS;
-          }
-          if (operation.evaluate(indexedShapeCompare, queryShapeCompare))
-            secondaryIds.add(id);
-        }
-      }
-
-      //Search and verify results
-      SpatialArgs args = new SpatialArgs(operation, queryShape);
-      if (queryShape instanceof ShapePair)
-        args.setDistErrPct(0.0);//a hack; we want to be more detailed than gridSnap(queryShape)
-      Query query = strategy.makeQuery(args);
-      SearchResults got = executeQuery(query, 100);
-      Set<String> remainingExpectedIds = new LinkedHashSet<>(expectedIds);
-      for (SearchResult result : got.results) {
-        String id = result.getId();
-        boolean removed = remainingExpectedIds.remove(id);
-        if (!removed && (!opIsDisjoint && !secondaryIds.contains(id))) {
-          fail("Shouldn't match", id, indexedShapes, indexedShapesGS, queryShape);
-        }
-      }
-      if (opIsDisjoint)
-        remainingExpectedIds.removeAll(secondaryIds);
-      if (!remainingExpectedIds.isEmpty()) {
-        String id = remainingExpectedIds.iterator().next();
-        fail("Should have matched", id, indexedShapes, indexedShapesGS, queryShape);
-      }
-    }
-  }
-
-  private Shape randomShapePairRect(boolean biasContains) {
-    Rectangle shape1 = randomRectangle();
-    Rectangle shape2 = randomRectangle();
-    return new ShapePair(shape1, shape2, biasContains);
-  }
-
-  private void fail(String label, String id, Map<String, Shape> indexedShapes, Map<String, Shape> indexedShapesGS, Shape queryShape) {
-    System.err.println("Ig:" + indexedShapesGS.get(id) + " Qg:" + gridSnap(queryShape));
-    fail(label + " I#" + id + ":" + indexedShapes.get(id) + " Q:" + queryShape);
-  }
-
-//  private Rectangle inset(Rectangle r) {
-//    //typically inset by 1 (whole numbers are easy to read)
-//    double d = Math.min(1.0, grid.getDistanceForLevel(grid.getMaxLevels()) / 4);
-//    return ctx.makeRectangle(r.getMinX() + d, r.getMaxX() - d, r.getMinY() + d, r.getMaxY() - d);
-//  }
-
-  protected Shape gridSnap(Shape snapMe) {
-    if (snapMe == null)
-      return null;
-    if (snapMe instanceof ShapePair) {
-      ShapePair me = (ShapePair) snapMe;
-      return new ShapePair(gridSnap(me.shape1), gridSnap(me.shape2), me.biasContainsThenWithin);
-    }
-    if (snapMe instanceof Point) {
-      snapMe = snapMe.getBoundingBox();
-    }
-    //The next 4 lines mimic PrefixTreeStrategy.createIndexableFields()
-    double distErrPct = ((PrefixTreeStrategy) strategy).getDistErrPct();
-    double distErr = SpatialArgs.calcDistanceFromErrPct(snapMe, distErrPct, ctx);
-    int detailLevel = grid.getLevelForDistance(distErr);
-    CellIterator cells = grid.getTreeCellIterator(snapMe, detailLevel);
-
-    //calc bounding box of cells.
-    List<Shape> cellShapes = new ArrayList<>(1024);
-    while (cells.hasNext()) {
-      Cell cell = cells.next();
-      if (!cell.isLeaf())
-        continue;
-      cellShapes.add(cell.getShape());
-    }
-    return new ShapeCollection<>(cellShapes, ctx).getBoundingBox();
-  }
-
-  /**
-   * An aggregate of 2 shapes. Unfortunately we can't simply use a ShapeCollection because:
-   * (a) ambiguity between CONTAINS and WITHIN for equal shapes, and
-   * (b) adjacent pairs could as a whole contain the input shape.
-   * The tests here are sensitive to these matters, although in practice ShapeCollection
-   * is fine.
-   */
-  private class ShapePair extends ShapeCollection<Shape> {
-
-    final Shape shape1, shape2;
-    final Shape shape1_2D, shape2_2D;//not geo (bit of a hack)
-    final boolean biasContainsThenWithin;
-
-    public ShapePair(Shape shape1, Shape shape2, boolean containsThenWithin) {
-      super(Arrays.asList(shape1, shape2), RandomSpatialOpFuzzyPrefixTreeTest.this.ctx);
-      this.shape1 = shape1;
-      this.shape2 = shape2;
-      this.shape1_2D = toNonGeo(shape1);
-      this.shape2_2D = toNonGeo(shape2);
-      biasContainsThenWithin = containsThenWithin;
-    }
-
-    private Shape toNonGeo(Shape shape) {
-      if (!ctx.isGeo())
-        return shape;//already non-geo
-      if (shape instanceof Rectangle) {
-        Rectangle rect = (Rectangle) shape;
-        if (rect.getCrossesDateLine()) {
-          return new ShapePair(
-              ctx2D.makeRectangle(rect.getMinX(), 180, rect.getMinY(), rect.getMaxY()),
-              ctx2D.makeRectangle(-180, rect.getMaxX(), rect.getMinY(), rect.getMaxY()),
-              biasContainsThenWithin);
-        } else {
-          return ctx2D.makeRectangle(rect.getMinX(), rect.getMaxX(), rect.getMinY(), rect.getMaxY());
-        }
-      }
-      //no need to do others; this addresses the -180/+180 ambiguity corner test problem
-      return shape;
-    }
-
-    @Override
-    public SpatialRelation relate(Shape other) {
-      SpatialRelation r = relateApprox(other);
-      if (r == DISJOINT)
-        return r;
-      if (r == CONTAINS)
-        return r;
-      if (r == WITHIN && !biasContainsThenWithin)
-        return r;
-
-      //See if the correct answer is actually Contains, when the indexed shapes are adjacent,
-      // creating a larger shape that contains the input shape.
-      boolean pairTouches = shape1.relate(shape2).intersects();
-      if (!pairTouches)
-        return r;
-      //test all 4 corners
-      // Note: awkwardly, we use a non-geo context for this because in geo, -180 & +180 are the same place, which means
-      //  that "other" might wrap the world horizontally and yet all its corners could be in shape1 (or shape2) even
-      //  though shape1 is only adjacent to the dateline. I couldn't think of a better way to handle this.
-      Rectangle oRect = (Rectangle)other;
-      if (cornerContainsNonGeo(oRect.getMinX(), oRect.getMinY())
-          && cornerContainsNonGeo(oRect.getMinX(), oRect.getMaxY())
-          && cornerContainsNonGeo(oRect.getMaxX(), oRect.getMinY())
-          && cornerContainsNonGeo(oRect.getMaxX(), oRect.getMaxY()) )
-        return CONTAINS;
-      return r;
-    }
-
-    private boolean cornerContainsNonGeo(double x, double y) {
-      Shape pt = ctx2D.makePoint(x, y);
-      return shape1_2D.relate(pt).intersects() || shape2_2D.relate(pt).intersects();
-    }
-
-    private SpatialRelation relateApprox(Shape other) {
-      if (biasContainsThenWithin) {
-        if (shape1.relate(other) == CONTAINS || shape1.equals(other)
-            || shape2.relate(other) == CONTAINS || shape2.equals(other)) return CONTAINS;
-
-        if (shape1.relate(other) == WITHIN && shape2.relate(other) == WITHIN) return WITHIN;
-
-      } else {
-        if ((shape1.relate(other) == WITHIN || shape1.equals(other))
-            && (shape2.relate(other) == WITHIN || shape2.equals(other))) return WITHIN;
-
-        if (shape1.relate(other) == CONTAINS || shape2.relate(other) == CONTAINS) return CONTAINS;
-      }
-
-      if (shape1.relate(other).intersects() || shape2.relate(other).intersects())
-        return INTERSECTS;//might actually be 'CONTAINS' if the pair are adjacent but we handle that later
-      return DISJOINT;
-    }
-
-    @Override
-    public String toString() {
-      return "ShapePair(" + shape1 + " , " + shape2 + ")";
-    }
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpStrategyTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpStrategyTestCase.java b/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpStrategyTestCase.java
deleted file mode 100644
index 87f1071..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpStrategyTestCase.java
+++ /dev/null
@@ -1,141 +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.prefix;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.spatial.StrategyTestCase;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.query.SpatialOperation;
-
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomInt;
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween;
-
-/** Base test harness, ideally for SpatialStrategy impls that have exact results
- * (not grid approximated), hence "not fuzzy".
- */
-public abstract class RandomSpatialOpStrategyTestCase extends StrategyTestCase {
-
-  //Note: this is partially redundant with StrategyTestCase.runTestQuery & testOperation
-
-  protected void testOperationRandomShapes(final SpatialOperation operation) throws IOException {
-
-    final int numIndexedShapes = randomIntBetween(1, 6);
-    List<Shape> indexedShapes = new ArrayList<>(numIndexedShapes);
-    for (int i = 0; i < numIndexedShapes; i++) {
-      indexedShapes.add(randomIndexedShape());
-    }
-
-    final int numQueryShapes = atLeast(20);
-    List<Shape> queryShapes = new ArrayList<>(numQueryShapes);
-    for (int i = 0; i < numQueryShapes; i++) {
-      queryShapes.add(randomQueryShape());
-    }
-
-    testOperation(operation, indexedShapes, queryShapes, true/*havoc*/);
-  }
-
-  protected void testOperation(final SpatialOperation operation,
-                               List<Shape> indexedShapes, List<Shape> queryShapes, boolean havoc) throws IOException {
-    //first show that when there's no data, a query will result in no results
-    {
-      Query query = strategy.makeQuery(new SpatialArgs(operation, randomQueryShape()));
-      SearchResults searchResults = executeQuery(query, 1);
-      assertEquals(0, searchResults.numFound);
-    }
-
-    //Main index loop:
-    for (int i = 0; i < indexedShapes.size(); i++) {
-      Shape shape = indexedShapes.get(i);
-      adoc(""+i, shape);
-
-      if (havoc && random().nextInt(10) == 0)
-        commit();//intermediate commit, produces extra segments
-    }
-    if (havoc) {
-      //delete some documents randomly
-      for (int id = 0; id < indexedShapes.size(); id++) {
-        if (random().nextInt(10) == 0) {
-          deleteDoc(""+id);
-          indexedShapes.set(id, null);
-        }
-      }
-    }
-
-    commit();
-
-    //Main query loop:
-    for (int queryIdx = 0; queryIdx < queryShapes.size(); queryIdx++) {
-      final Shape queryShape = queryShapes.get(queryIdx);
-
-      if (havoc)
-        preQueryHavoc();
-
-      //Generate truth via brute force:
-      // We ensure true-positive matches (if the predicate on the raw shapes match
-      //  then the search should find those same matches).
-      Set<String> expectedIds = new LinkedHashSet<>();//true-positives
-      for (int id = 0; id < indexedShapes.size(); id++) {
-        Shape indexedShape = indexedShapes.get(id);
-        if (indexedShape == null)
-          continue;
-        if (operation.evaluate(indexedShape, queryShape)) {
-          expectedIds.add(""+id);
-        }
-      }
-
-      //Search and verify results
-      SpatialArgs args = new SpatialArgs(operation, queryShape);
-      Query query = strategy.makeQuery(args);
-      SearchResults got = executeQuery(query, 100);
-      Set<String> remainingExpectedIds = new LinkedHashSet<>(expectedIds);
-      for (SearchResult result : got.results) {
-        String id = result.getId();
-        if (!remainingExpectedIds.remove(id)) {
-          fail("qIdx:" + queryIdx + " Shouldn't match", id, indexedShapes, queryShape, operation);
-        }
-      }
-      if (!remainingExpectedIds.isEmpty()) {
-        String id = remainingExpectedIds.iterator().next();
-        fail("qIdx:" + queryIdx + " Should have matched", id, indexedShapes, queryShape, operation);
-      }
-    }
-  }
-
-  private void fail(String label, String id, List<Shape> indexedShapes, Shape queryShape, SpatialOperation operation) {
-    fail("[" + operation + "] " + label
-        + " I#" + id + ":" + indexedShapes.get(Integer.parseInt(id)) + " Q:" + queryShape);
-  }
-
-  protected void preQueryHavoc() {
-    if (strategy instanceof RecursivePrefixTreeStrategy) {
-      RecursivePrefixTreeStrategy rpts = (RecursivePrefixTreeStrategy) strategy;
-      int scanLevel = randomInt(rpts.getGrid().getMaxLevels());
-      rpts.setPrefixGridScanLevel(scanLevel);
-    }
-  }
-
-  protected abstract Shape randomIndexedShape();
-
-  protected abstract Shape randomQueryShape();
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java b/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java
deleted file mode 100644
index a53d52d..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java
+++ /dev/null
@@ -1,122 +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.prefix;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.distance.DistanceUtils;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.spatial.SpatialMatchConcern;
-import org.apache.lucene.spatial.StrategyTestCase;
-import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.query.SpatialOperation;
-import org.junit.Test;
-
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
-
-public class TestRecursivePrefixTreeStrategy extends StrategyTestCase {
-
-  private int maxLength;
-
-  //Tests should call this first.
-  private void init(int maxLength) {
-    this.maxLength = maxLength;
-    this.ctx = SpatialContext.GEO;
-    GeohashPrefixTree grid = new GeohashPrefixTree(ctx, maxLength);
-    this.strategy = new RecursivePrefixTreeStrategy(grid, getClass().getSimpleName());
-  }
-
-  @Test
-  public void testFilterWithVariableScanLevel() throws IOException {
-    init(GeohashPrefixTree.getMaxLevelsPossible());
-    getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS);
-
-    //execute queries for each prefix grid scan level
-    for(int i = 0; i <= maxLength; i++) {
-      ((RecursivePrefixTreeStrategy)strategy).setPrefixGridScanLevel(i);
-      executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_Intersects_BBox);
-    }
-  }
-
-  @Test
-  public void testOneMeterPrecision() {
-    init(GeohashPrefixTree.getMaxLevelsPossible());
-    GeohashPrefixTree grid = (GeohashPrefixTree) ((RecursivePrefixTreeStrategy) strategy).getGrid();
-    //DWS: I know this to be true.  11 is needed for one meter
-    double degrees = DistanceUtils.dist2Degrees(0.001, DistanceUtils.EARTH_MEAN_RADIUS_KM);
-    assertEquals(11, grid.getLevelForDistance(degrees));
-  }
-
-  @Test
-  public void testPrecision() throws IOException{
-    init(GeohashPrefixTree.getMaxLevelsPossible());
-
-    Point iPt = ctx.makePoint(2.8028712999999925, 48.3708044);//lon, lat
-    addDocument(newDoc("iPt", iPt));
-    commit();
-
-    Point qPt = ctx.makePoint(2.4632387000000335, 48.6003516);
-
-    final double KM2DEG = DistanceUtils.dist2Degrees(1, DistanceUtils.EARTH_MEAN_RADIUS_KM);
-    final double DEG2KM = 1 / KM2DEG;
-
-    final double DIST = 35.75;//35.7499...
-    assertEquals(DIST, ctx.getDistCalc().distance(iPt, qPt) * DEG2KM, 0.001);
-
-    //distErrPct will affect the query shape precision. The indexed precision
-    // was set to nearly zilch via init(GeohashPrefixTree.getMaxLevelsPossible());
-    final double distErrPct = 0.025; //the suggested default, by the way
-    final double distMult = 1+distErrPct;
-
-    assertTrue(35.74*distMult >= DIST);
-    checkHits(q(qPt, 35.74 * KM2DEG, distErrPct), 1, null);
-
-    assertTrue(30*distMult < DIST);
-    checkHits(q(qPt, 30 * KM2DEG, distErrPct), 0, null);
-
-    assertTrue(33*distMult < DIST);
-    checkHits(q(qPt, 33 * KM2DEG, distErrPct), 0, null);
-
-    assertTrue(34*distMult < DIST);
-    checkHits(q(qPt, 34 * KM2DEG, distErrPct), 0, null);
-  }
-
-  private SpatialArgs q(Point pt, double distDEG, double distErrPct) {
-    Shape shape = ctx.makeCircle(pt, distDEG);
-    SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects,shape);
-    args.setDistErrPct(distErrPct);
-    return args;
-  }
-
-  private void checkHits(SpatialArgs args, int assertNumFound, int[] assertIds) {
-    SearchResults got = executeQuery(strategy.makeQuery(args), 100);
-    assertEquals("" + args, assertNumFound, got.numFound);
-    if (assertIds != null) {
-      Set<Integer> gotIds = new HashSet<>();
-      for (SearchResult result : got.results) {
-        gotIds.add(Integer.valueOf(result.document.get("id")));
-      }
-      for (int assertId : assertIds) {
-        assertTrue("has "+assertId,gotIds.contains(assertId));
-      }
-    }
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestTermQueryPrefixGridStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestTermQueryPrefixGridStrategy.java b/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestTermQueryPrefixGridStrategy.java
deleted file mode 100644
index 1a912c0..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestTermQueryPrefixGridStrategy.java
+++ /dev/null
@@ -1,63 +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.prefix;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.StoredField;
-import org.apache.lucene.document.StringField;
-import org.apache.lucene.spatial.SpatialTestCase;
-import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
-import org.apache.lucene.spatial.query.SpatialArgsParser;
-import org.junit.Test;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-
-public class TestTermQueryPrefixGridStrategy extends SpatialTestCase {
-
-  @Test
-  public void testNGramPrefixGridLosAngeles() throws IOException {
-    SpatialContext ctx = SpatialContext.GEO;
-    TermQueryPrefixTreeStrategy prefixGridStrategy = new TermQueryPrefixTreeStrategy(new QuadPrefixTree(ctx), "geo");
-
-    Shape point = ctx.makePoint(-118.243680, 34.052230);
-
-    Document losAngeles = new Document();
-    losAngeles.add(new StringField("name", "Los Angeles", Field.Store.YES));
-    for (Field field : prefixGridStrategy.createIndexableFields(point)) {
-      losAngeles.add(field);
-    }
-    losAngeles.add(new StoredField(prefixGridStrategy.getFieldName(), point.toString()));//just for diagnostics
-
-    addDocumentsAndCommit(Arrays.asList(losAngeles));
-
-    // This won't work with simple spatial context...
-    SpatialArgsParser spatialArgsParser = new SpatialArgsParser();
-    // TODO... use a non polygon query
-//    SpatialArgs spatialArgs = spatialArgsParser.parse(
-//        "Intersects(POLYGON((-127.00390625 39.8125,-112.765625 39.98828125,-111.53515625 31.375,-125.94921875 30.14453125,-127.00390625 39.8125)))",
-//        new SimpleSpatialContext());
-
-//    Query query = prefixGridStrategy.makeQuery(spatialArgs, fieldInfo);
-//    SearchResults searchResults = executeQuery(query, 1);
-//    assertEquals(1, searchResults.numFound);
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTreeTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTreeTest.java b/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTreeTest.java
deleted file mode 100644
index 74a989e..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTreeTest.java
+++ /dev/null
@@ -1,175 +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.prefix.tree;
-
-import java.text.ParseException;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.SpatialRelation;
-import org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape;
-import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.LuceneTestCase;
-
-public class DateRangePrefixTreeTest extends LuceneTestCase {
-
-  private DateRangePrefixTree tree = DateRangePrefixTree.INSTANCE;
-
-  public void testRoundTrip() throws Exception {
-    Calendar cal = tree.newCal();
-
-    assertEquals("*", tree.toString(cal));
-
-    //test no underflow
-    assertTrue(tree.toShape(new int[]{0}, 1).toString().startsWith("-"));
-
-    //Some arbitrary date
-    cal.set(2014, Calendar.MAY, 9);
-    roundTrip(cal);
-    assertEquals("2014-05-09",tree.toString(cal));
-
-    //Earliest date
-    cal.setTimeInMillis(Long.MIN_VALUE);
-    roundTrip(cal);
-
-    //Farthest date
-    cal.setTimeInMillis(Long.MAX_VALUE);
-    roundTrip(cal);
-
-    //1BC is "0000".
-    cal.clear();
-    cal.set(Calendar.ERA, GregorianCalendar.BC);
-    cal.set(Calendar.YEAR, 1);
-    roundTrip(cal);
-    assertEquals("0000", tree.toString(cal));
-    //adding a "+" parses to the same; and a trailing 'Z' is fine too
-    assertEquals(cal, tree.parseCalendar("+0000Z"));
-
-    //2BC is "-0001"
-    cal.clear();
-    cal.set(Calendar.ERA, GregorianCalendar.BC);
-    cal.set(Calendar.YEAR, 2);
-    roundTrip(cal);
-    assertEquals("-0001", tree.toString(cal));
-
-    //1AD is "0001"
-    cal.clear();
-    cal.set(Calendar.YEAR, 1);
-    roundTrip(cal);
-    assertEquals("0001", tree.toString(cal));
-
-    //test random
-    cal.setTimeInMillis(random().nextLong());
-    roundTrip(cal);
-  }
-
-  //copies from DateRangePrefixTree
-  private static final int[] CAL_FIELDS = {
-      Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH,
-      Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND};
-
-  private void roundTrip(Calendar calOrig) throws ParseException {
-    Calendar cal = (Calendar) calOrig.clone();
-    String lastString = null;
-    while (true) {
-      String calString = tree.toString(cal);
-      assert lastString == null || calString.length() < lastString.length();
-      //test parseCalendar
-      assertEquals(cal, tree.parseCalendar(calString));
-
-      //to Shape and back to Cal
-      UnitNRShape shape = tree.toShape(cal);
-      Calendar cal2 = tree.toCalendar(shape);
-      assertEquals(calString, tree.toString(cal2));
-
-      if (!calString.equals("*")) {//not world cell
-        //to Term and back to Cell
-        Cell cell = (Cell) shape;
-        BytesRef term = cell.getTokenBytesNoLeaf(null);
-        Cell cell2 = tree.readCell(BytesRef.deepCopyOf(term), null);
-        assertEquals(calString, cell, cell2);
-        Calendar cal3 = tree.toCalendar((UnitNRShape) cell2.getShape());
-        assertEquals(calString, tree.toString(cal3));
-
-        // setLeaf comparison
-        cell2.setLeaf();
-        BytesRef termLeaf = cell2.getTokenBytesWithLeaf(null);
-        assertTrue(term.compareTo(termLeaf) < 0);
-        assertEquals(termLeaf.length, term.length + 1);
-        assertEquals(0, termLeaf.bytes[termLeaf.offset + termLeaf.length - 1]);
-        assertTrue(cell.isPrefixOf(cell2));
-      }
-
-      //end of loop; decide if should loop again with lower precision
-      final int calPrecField = tree.getCalPrecisionField(cal);
-      if (calPrecField == -1)
-        break;
-      int fieldIdx = Arrays.binarySearch(CAL_FIELDS, calPrecField);
-      assert fieldIdx >= 0;
-      int prevPrecField = (fieldIdx == 0 ? -1 : CAL_FIELDS[--fieldIdx]);
-      try {
-        tree.clearFieldsAfter(cal, prevPrecField);
-      } catch (AssertionError e) {
-        if (e.getMessage().equals("Calendar underflow"))
-          return;
-        throw e;
-      }
-      lastString = calString;
-    }
-  }
-
-  public void testShapeRelations() throws ParseException {
-    //note: left range is 264000 at the thousand year level whereas right value is exact year
-    assertEquals(SpatialRelation.WITHIN,
-        tree.parseShape("[-264000 TO -264000-11-20]").relate(tree.parseShape("-264000")));
-
-    Shape shapeA = tree.parseShape("[3122-01-23 TO 3122-11-27]");
-    Shape shapeB = tree.parseShape("[3122-08 TO 3122-11]");
-    assertEquals(SpatialRelation.INTERSECTS, shapeA.relate(shapeB));
-
-    shapeA = tree.parseShape("3122");
-    shapeB = tree.parseShape("[* TO 3122-10-31]");
-    assertEquals(SpatialRelation.INTERSECTS, shapeA.relate(shapeB));
-
-    shapeA = tree.parseShape("[3122-05-28 TO 3122-06-29]");
-    shapeB = tree.parseShape("[3122 TO 3122-04]");
-    assertEquals(SpatialRelation.DISJOINT, shapeA.relate(shapeB));
-  }
-
-  public void testShapeRangeOptimizer() throws ParseException {
-    assertEquals("[2014-08 TO 2014-09]", tree.parseShape("[2014-08-01 TO 2014-09-30]").toString());
-
-    assertEquals("2014", tree.parseShape("[2014-01-01 TO 2014-12-31]").toString());
-
-    assertEquals("2014",    tree.parseShape("[2014-01 TO 2014]").toString());
-    assertEquals("2014-01", tree.parseShape("[2014 TO 2014-01]").toString());
-    assertEquals("2014-12", tree.parseShape("[2014-12 TO 2014]").toString());
-
-    assertEquals("[2014 TO 2014-04-06]", tree.parseShape("[2014-01 TO 2014-04-06]").toString());
-
-    assertEquals("*", tree.parseShape("[* TO *]").toString());
-
-    assertEquals("2014-08-01", tree.parseShape("[2014-08-01 TO 2014-08-01]").toString());
-
-    assertEquals("[2014 TO 2014-09-15]", tree.parseShape("[2014 TO 2014-09-15]").toString());
-
-    assertEquals("[* TO 2014-09-15]", tree.parseShape("[* TO 2014-09-15]").toString());
-  }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeTest.java b/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeTest.java
deleted file mode 100644
index 9f6c625..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeTest.java
+++ /dev/null
@@ -1,114 +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.prefix.tree;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.Field.Store;
-import org.apache.lucene.document.TextField;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.ScoreDoc;
-import org.apache.lucene.search.TopDocs;
-import org.apache.lucene.spatial.SpatialTestCase;
-import org.apache.lucene.spatial.prefix.TermQueryPrefixTreeStrategy;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.query.SpatialOperation;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class SpatialPrefixTreeTest extends SpatialTestCase {
-
-  //TODO plug in others and test them
-  private SpatialContext ctx;
-  private SpatialPrefixTree trie;
-
-  @Override
-  @Before
-  public void setUp() throws Exception {
-    super.setUp();
-    ctx = SpatialContext.GEO;
-  }
-
-  @Test
-  public void testCellTraverse() {
-    trie = new GeohashPrefixTree(ctx,4);
-
-    Cell prevC = null;
-    Cell c = trie.getWorldCell();
-    assertEquals(0, c.getLevel());
-    assertEquals(ctx.getWorldBounds(), c.getShape());
-    while (c.getLevel() < trie.getMaxLevels()) {
-      prevC = c;
-      List<Cell> subCells = new ArrayList<>();
-      CellIterator subCellsIter = c.getNextLevelCells(null);
-      while (subCellsIter.hasNext()) {
-        subCells.add(subCellsIter.next());
-      }
-      c = subCells.get(random().nextInt(subCells.size()-1));
-      
-      assertEquals(prevC.getLevel()+1,c.getLevel());
-      Rectangle prevNShape = (Rectangle) prevC.getShape();
-      Shape s = c.getShape();
-      Rectangle sbox = s.getBoundingBox();
-      assertTrue(prevNShape.getWidth() > sbox.getWidth());
-      assertTrue(prevNShape.getHeight() > sbox.getHeight());
-    }
-  }
-  /**
-   * A PrefixTree pruning optimization gone bad, applicable when optimize=true.
-   * See <a href="https://issues.apache.org/jira/browse/LUCENE-4770">LUCENE-4770</a>.
-   */
-  @Test
-  public void testBadPrefixTreePrune() throws Exception {
-
-    trie = new QuadPrefixTree(ctx, 12);
-    TermQueryPrefixTreeStrategy strategy = new TermQueryPrefixTreeStrategy(trie, "geo");
-    Document doc = new Document();
-    doc.add(new TextField("id", "1", Store.YES));
-
-    Shape area = ctx.makeRectangle(-122.82, -122.78, 48.54, 48.56);
-
-    Field[] fields = strategy.createIndexableFields(area, 0.025);
-    for (Field field : fields) {
-      doc.add(field);
-    }
-    addDocument(doc);
-
-    Point upperleft = ctx.makePoint(-122.88, 48.54);
-    Point lowerright = ctx.makePoint(-122.82, 48.62);
-
-    Query query = strategy.makeQuery(new SpatialArgs(SpatialOperation.Intersects, ctx.makeRectangle(upperleft, lowerright)));
-
-    commit();
-
-    TopDocs search = indexSearcher.search(query, 10);
-    ScoreDoc[] scoreDocs = search.scoreDocs;
-    for (ScoreDoc scoreDoc : scoreDocs) {
-      System.out.println(indexSearcher.doc(scoreDoc.doc));
-    }
-
-    assertEquals(1, search.totalHits);
-  }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/query/SpatialArgsParserTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/query/SpatialArgsParserTest.java b/lucene/spatial/src/test/org/apache/lucene/spatial/query/SpatialArgsParserTest.java
deleted file mode 100644
index 93b95f3..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/query/SpatialArgsParserTest.java
+++ /dev/null
@@ -1,77 +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.query;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Rectangle;
-import org.apache.lucene.util.LuceneTestCase;
-import org.junit.Test;
-
-import java.text.ParseException;
-
-//Tests SpatialOperation somewhat too
-public class SpatialArgsParserTest extends LuceneTestCase {
-
-  private SpatialContext ctx = SpatialContext.GEO;
-
-  //The args parser is only dependent on the ctx for IO so I don't care to test
-  // with other implementations.
-
-  @Test
-  public void testArgsParser() throws Exception {
-    SpatialArgsParser parser = new SpatialArgsParser();
-
-    String arg = SpatialOperation.IsWithin + "(Envelope(-10, 10, 20, -20))";
-    SpatialArgs out = parser.parse(arg, ctx);
-    assertEquals(SpatialOperation.IsWithin, out.getOperation());
-    Rectangle bounds = (Rectangle) out.getShape();
-    assertEquals(-10.0, bounds.getMinX(), 0D);
-    assertEquals(10.0, bounds.getMaxX(), 0D);
-
-    // Disjoint should not be scored
-    arg = SpatialOperation.IsDisjointTo + " (Envelope(-10,-20,20,10))";
-    out = parser.parse(arg, ctx);
-    assertEquals(SpatialOperation.IsDisjointTo, out.getOperation());
-
-    // spatial operations need args
-    expectThrows(Exception.class, () -> {
-      parser.parse(SpatialOperation.IsDisjointTo + "[ ]", ctx);
-    });
-
-    // unknown operation
-    expectThrows(Exception.class, () -> {
-      parser.parse("XXXX(Envelope(-10, 10, 20, -20))", ctx);
-    });
-
-    assertAlias(SpatialOperation.IsWithin, "CoveredBy");
-    assertAlias(SpatialOperation.IsWithin, "COVEREDBY");
-    assertAlias(SpatialOperation.IsWithin, "coveredBy");
-    assertAlias(SpatialOperation.IsWithin, "Within");
-    assertAlias(SpatialOperation.IsEqualTo, "Equals");
-    assertAlias(SpatialOperation.IsDisjointTo, "disjoint");
-    assertAlias(SpatialOperation.Contains, "Covers");
-  }
-
-  private void assertAlias(SpatialOperation op, final String name) throws ParseException {
-    String arg;
-    SpatialArgs out;
-    arg = name + "(Point(0 0))";
-    out = new SpatialArgsParser().parse(arg, ctx);
-    assertEquals(op, out.getOperation());
-  }
-
-}


[07/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test-files/simple-Queries-BBox.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test-files/simple-Queries-BBox.txt b/lucene/spatial/src/test-files/simple-Queries-BBox.txt
deleted file mode 100644
index 9f3d5b0..0000000
--- a/lucene/spatial/src/test-files/simple-Queries-BBox.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-C5 @ IsWithin(ENVELOPE(-6, 6, 6, -6))
-C5 @ BBoxWithin(ENVELOPE(-6, 6, 6, -6))
-C10 @ Contains(ENVELOPE(-6, 6, 6, -6))
-C10 @ IsEqualTo(ENVELOPE(-10, 10, 10, -10))
-C5 C10 @ Intersects(ENVELOPE(-2, 2, 2, -2))
- @ Overlaps(ENVELOPE(-2, 2, 2, -2))
-C5 @ Overlaps(ENVELOPE(-2, 2, 8, -2))
-C5 C10 @ BBoxIntersects(ENVELOPE(-2, 2, 2, -2))
-NW15 @ IsDisjointTo(ENVELOPE(-10, 10, 10, -10))
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test-files/states-Intersects-BBox.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test-files/states-Intersects-BBox.txt b/lucene/spatial/src/test-files/states-Intersects-BBox.txt
deleted file mode 100644
index a45df7b..0000000
--- a/lucene/spatial/src/test-files/states-Intersects-BBox.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-WY CO	@ Intersects(ENVELOPE(-106.964844, -105.734375, 42.800781, 39.460938))
-TX @ Intersects(ENVELOPE(-99.669922, -98.439453, 32.253906, 30.583984))
-MS TX LA @ Intersects(ENVELOPE(-95.363281, -90.133789, 32.473633, 29.792969))
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test-files/states-IsWithin-BBox.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test-files/states-IsWithin-BBox.txt b/lucene/spatial/src/test-files/states-IsWithin-BBox.txt
deleted file mode 100644
index 6a504da..0000000
--- a/lucene/spatial/src/test-files/states-IsWithin-BBox.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-KS	@ IsWithin(ENVELOPE(-103.493164, -93.825195, 41.086914, 36.208984))
-WA @ IsWithin(ENVELOPE(-126.916016, -115.314453, 50.688965, 44.36084))
-MA CT RI @ IsWithin(ENVELOPE(-73.894043, -69.521484, 43.198242, 40.825195))
-AL GA @ IsWithin(ENVELOPE(-89.472656, -80.244141, 35.90332, 29.311523))
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/DistanceStrategyTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/DistanceStrategyTest.java b/lucene/spatial/src/test/org/apache/lucene/spatial/DistanceStrategyTest.java
deleted file mode 100644
index 9a29677..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/DistanceStrategyTest.java
+++ /dev/null
@@ -1,135 +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;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.document.FieldType;
-import org.apache.lucene.index.IndexOptions;
-import org.apache.lucene.spatial.bbox.BBoxStrategy;
-import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
-import org.apache.lucene.spatial.prefix.TermQueryPrefixTreeStrategy;
-import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
-import org.apache.lucene.spatial.prefix.tree.PackedQuadPrefixTree;
-import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.spatial.serialized.SerializedDVStrategy;
-import org.apache.lucene.spatial.vector.PointVectorStrategy;
-import org.junit.Test;
-
-public class DistanceStrategyTest extends StrategyTestCase {
-  @ParametersFactory(argumentFormatting = "strategy=%s")
-  public static Iterable<Object[]> parameters() {
-    List<Object[]> ctorArgs = new ArrayList<>();
-
-    SpatialContext ctx = SpatialContext.GEO;
-    SpatialPrefixTree grid;
-    SpatialStrategy strategy;
-
-    grid = new QuadPrefixTree(ctx,25);
-    strategy = new RecursivePrefixTreeStrategy(grid, "recursive_quad");
-    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
-
-    grid = new GeohashPrefixTree(ctx,12);
-    strategy = new TermQueryPrefixTreeStrategy(grid, "termquery_geohash");
-    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
-
-    grid = new PackedQuadPrefixTree(ctx,25);
-    strategy = new RecursivePrefixTreeStrategy(grid, "recursive_packedquad");
-    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
-
-    strategy = new PointVectorStrategy(ctx, "pointvector");
-    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
-
-    strategy = new BBoxStrategy(ctx, "bbox");
-    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
-
-    strategy = new SerializedDVStrategy(ctx, "serialized");
-    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
-
-    return ctorArgs;
-  }
-
-  public DistanceStrategyTest(String suiteName, SpatialStrategy strategy) {
-    this.ctx = strategy.getSpatialContext();
-    this.strategy = strategy;
-  }
-
-  @Override
-  public void setUp() throws Exception {
-    super.setUp();
-    if (strategy instanceof BBoxStrategy && random().nextBoolean()) {//disable indexing sometimes
-      BBoxStrategy bboxStrategy = (BBoxStrategy)strategy;
-      final FieldType fieldType = new FieldType(bboxStrategy.getFieldType());
-      fieldType.setIndexOptions(IndexOptions.NONE);
-      bboxStrategy.setFieldType(fieldType);
-    }
-  }
-
-  @Override
-  protected boolean needsDocValues() {
-    return true;
-  }
-
-  @Test
-  public void testDistanceOrder() throws IOException {
-    adoc("100", ctx.makePoint(2, 1));
-    adoc("101", ctx.makePoint(-1, 4));
-    adoc("103", (Shape)null);//test score for nothing
-    adoc("999", ctx.makePoint(2, 1));//test deleted
-    commit();
-    deleteDoc("999");
-    commit();
-    //FYI distances are in docid order
-    checkDistValueSource(ctx.makePoint(4, 3), 2.8274937f, 5.0898066f, 180f);
-    checkDistValueSource(ctx.makePoint(0, 4), 3.6043684f, 0.9975641f, 180f);
-  }
-
-  @Test
-  public void testRecipScore() throws IOException {
-    Point p100 = ctx.makePoint(2, 1);
-    adoc("100", p100);
-    Point p101 = ctx.makePoint(-1, 4);
-    adoc("101", p101);
-    adoc("103", (Shape)null);//test score for nothing
-    adoc("999", ctx.makePoint(2, 1));//test deleted
-    commit();
-    deleteDoc("999");
-    commit();
-
-    double dist = ctx.getDistCalc().distance(p100, p101);
-    Shape queryShape = ctx.makeCircle(2.01, 0.99, dist);
-    checkValueSource(strategy.makeRecipDistanceValueSource(queryShape),
-        new float[]{1.00f, 0.10f, 0f}, 0.09f);
-  }
-
-  void checkDistValueSource(Point pt, float... distances) throws IOException {
-    float multiplier = random().nextFloat() * 100f;
-    float[] dists2 = Arrays.copyOf(distances, distances.length);
-    for (int i = 0; i < dists2.length; i++) {
-      dists2[i] *= multiplier;
-    }
-    checkValueSource(strategy.makeDistanceValueSource(pt, multiplier), dists2, 1.0e-3f);
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/PortedSolr3Test.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/PortedSolr3Test.java b/lucene/spatial/src/test/org/apache/lucene/spatial/PortedSolr3Test.java
deleted file mode 100644
index 8506c86..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/PortedSolr3Test.java
+++ /dev/null
@@ -1,167 +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;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.distance.DistanceUtils;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
-import org.apache.lucene.spatial.prefix.TermQueryPrefixTreeStrategy;
-import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
-import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.query.SpatialOperation;
-import org.apache.lucene.spatial.vector.PointVectorStrategy;
-import org.junit.Test;
-
-/**
- * Based off of Solr 3's SpatialFilterTest.
- */
-public class PortedSolr3Test extends StrategyTestCase {
-
-  @ParametersFactory(argumentFormatting = "strategy=%s")
-  public static Iterable<Object[]> parameters() {
-    List<Object[]> ctorArgs = new ArrayList<>();
-
-    SpatialContext ctx = SpatialContext.GEO;
-    SpatialPrefixTree grid;
-    SpatialStrategy strategy;
-
-    grid = new GeohashPrefixTree(ctx,12);
-    strategy = new RecursivePrefixTreeStrategy(grid, "recursive_geohash");
-    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
-
-    grid = new QuadPrefixTree(ctx,25);
-    strategy = new RecursivePrefixTreeStrategy(grid, "recursive_quad");
-    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
-
-    grid = new GeohashPrefixTree(ctx,12);
-    strategy = new TermQueryPrefixTreeStrategy(grid, "termquery_geohash");
-    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
-
-    strategy = new PointVectorStrategy(ctx, "pointvector");
-    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
-
-    return ctorArgs;
-  }
-
-  public PortedSolr3Test(String suiteName, SpatialStrategy strategy) {
-    this.ctx = strategy.getSpatialContext();
-    this.strategy = strategy;
-  }
-
-  private void setupDocs() throws Exception {
-    super.deleteAll();
-    adoc("1", ctx.makePoint(-79.9289094, 32.7693246));
-    adoc("2", ctx.makePoint(-80.9289094, 33.7693246));
-    adoc("3", ctx.makePoint(50.9289094, -32.7693246));
-    adoc("4", ctx.makePoint(60.9289094, -50.7693246));
-    adoc("5", ctx.makePoint(0, 0));
-    adoc("6", ctx.makePoint(0.1, 0.1));
-    adoc("7", ctx.makePoint(-0.1, -0.1));
-    adoc("8", ctx.makePoint(179.9, 0));
-    adoc("9", ctx.makePoint(-179.9, 0));
-    adoc("10", ctx.makePoint(50, 89.9));
-    adoc("11", ctx.makePoint(-130, 89.9));
-    adoc("12", ctx.makePoint(50, -89.9));
-    adoc("13", ctx.makePoint(-130, -89.9));
-    commit();
-  }
-
-
-  @Test
-  public void testIntersections() throws Exception {
-    setupDocs();
-    //Try some edge cases
-      //NOTE: 2nd arg is distance in kilometers
-    checkHitsCircle(ctx.makePoint(1, 1), 175, 3, 5, 6, 7);
-    checkHitsCircle(ctx.makePoint(179.8, 0), 200, 2, 8, 9);
-    checkHitsCircle(ctx.makePoint(50, 89.8), 200, 2, 10, 11);//this goes over the north pole
-    checkHitsCircle(ctx.makePoint(50, -89.8), 200, 2, 12, 13);//this goes over the south pole
-    //try some normal cases
-    checkHitsCircle(ctx.makePoint(-80.0, 33.0), 300, 2);
-    //large distance
-    checkHitsCircle(ctx.makePoint(1, 1), 5000, 3, 5, 6, 7);
-    //Because we are generating a box based on the west/east longitudes and the south/north latitudes, which then
-    //translates to a range query, which is slightly more inclusive.  Thus, even though 0.0 is 15.725 kms away,
-    //it will be included, b/c of the box calculation.
-    checkHitsBBox(ctx.makePoint(0.1, 0.1), 15, 2, 5, 6);
-    //try some more
-    deleteAll();
-    adoc("14", ctx.makePoint(5, 0));
-    adoc("15", ctx.makePoint(15, 0));
-    //3000KM from 0,0, see http://www.movable-type.co.uk/scripts/latlong.html
-    adoc("16", ctx.makePoint(19.79750, 18.71111));
-    adoc("17", ctx.makePoint(-95.436643, 44.043900));
-    commit();
-
-    checkHitsCircle(ctx.makePoint(0, 0), 1000, 1, 14);
-    checkHitsCircle(ctx.makePoint(0, 0), 2000, 2, 14, 15);
-    checkHitsBBox(ctx.makePoint(0, 0), 3000, 3, 14, 15, 16);
-    checkHitsCircle(ctx.makePoint(0, 0), 3001, 3, 14, 15, 16);
-    checkHitsCircle(ctx.makePoint(0, 0), 3000.1, 3, 14, 15, 16);
-
-    //really fine grained distance and reflects some of the vagaries of how we are calculating the box
-    checkHitsCircle(ctx.makePoint(-96.789603, 43.517030), 109, 0);
-
-    // falls outside of the real distance, but inside the bounding box
-    checkHitsCircle(ctx.makePoint(-96.789603, 43.517030), 110, 0);
-    checkHitsBBox(ctx.makePoint(-96.789603, 43.517030), 110, 1, 17);
-  }
-
-  //---- these are similar to Solr test methods
-
-  private void checkHitsCircle(Point pt, double distKM, int assertNumFound, int... assertIds) {
-    _checkHits(false, pt, distKM, assertNumFound, assertIds);
-  }
-  private void checkHitsBBox(Point pt, double distKM, int assertNumFound, int... assertIds) {
-    _checkHits(true, pt, distKM, assertNumFound, assertIds);
-  }
-
-  private void _checkHits(boolean bbox, Point pt, double distKM, int assertNumFound, int... assertIds) {
-    SpatialOperation op = SpatialOperation.Intersects;
-    double distDEG = DistanceUtils.dist2Degrees(distKM, DistanceUtils.EARTH_MEAN_RADIUS_KM);
-    Shape shape = ctx.makeCircle(pt, distDEG);
-    if (bbox)
-      shape = shape.getBoundingBox();
-
-    SpatialArgs args = new SpatialArgs(op,shape);
-    //args.setDistPrecision(0.025);
-    Query query = strategy.makeQuery(args);
-    SearchResults results = executeQuery(query, 100);
-    assertEquals(""+shape,assertNumFound,results.numFound);
-    if (assertIds != null) {
-      Set<Integer> resultIds = new HashSet<>();
-      for (SearchResult result : results.results) {
-        resultIds.add(Integer.valueOf(result.document.get("id")));
-      }
-      for (int assertId : assertIds) {
-        assertTrue("has " + assertId, resultIds.contains(assertId));
-      }
-    }
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/QueryEqualsHashCodeTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/QueryEqualsHashCodeTest.java b/lucene/spatial/src/test/org/apache/lucene/spatial/QueryEqualsHashCodeTest.java
deleted file mode 100644
index b1a5e54..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/QueryEqualsHashCodeTest.java
+++ /dev/null
@@ -1,119 +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;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.spatial.bbox.BBoxStrategy;
-import org.apache.lucene.spatial.composite.CompositeSpatialStrategy;
-import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
-import org.apache.lucene.spatial.prefix.TermQueryPrefixTreeStrategy;
-import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
-import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.query.SpatialOperation;
-import org.apache.lucene.spatial.serialized.SerializedDVStrategy;
-import org.apache.lucene.spatial.vector.PointVectorStrategy;
-import org.apache.lucene.util.LuceneTestCase;
-import org.junit.Test;
-
-public class QueryEqualsHashCodeTest extends LuceneTestCase {
-
-  private final SpatialContext ctx = SpatialContext.GEO;
-
-  private SpatialOperation predicate;
-
-  @Test
-  public void testEqualsHashCode() {
-
-    switch (random().nextInt(4)) {//0-3
-      case 0: predicate = SpatialOperation.Contains; break;
-      case 1: predicate = SpatialOperation.IsWithin; break;
-
-      default: predicate = SpatialOperation.Intersects; break;
-    }
-    final SpatialPrefixTree gridQuad = new QuadPrefixTree(ctx,10);
-    final SpatialPrefixTree gridGeohash = new GeohashPrefixTree(ctx,10);
-
-    Collection<SpatialStrategy> strategies = new ArrayList<>();
-    RecursivePrefixTreeStrategy recursive_geohash = new RecursivePrefixTreeStrategy(gridGeohash, "recursive_geohash");
-    strategies.add(recursive_geohash);
-    strategies.add(new TermQueryPrefixTreeStrategy(gridQuad, "termquery_quad"));
-    strategies.add(new PointVectorStrategy(ctx, "pointvector"));
-    strategies.add(new BBoxStrategy(ctx, "bbox"));
-    final SerializedDVStrategy serialized = new SerializedDVStrategy(ctx, "serialized");
-    strategies.add(serialized);
-    strategies.add(new CompositeSpatialStrategy("composite", recursive_geohash, serialized));
-    for (SpatialStrategy strategy : strategies) {
-      testEqualsHashcode(strategy);
-    }
-  }
-
-  private void testEqualsHashcode(final SpatialStrategy strategy) {
-    final SpatialArgs args1 = makeArgs1();
-    final SpatialArgs args2 = makeArgs2();
-    testEqualsHashcode(args1, args2, new ObjGenerator() {
-      @Override
-      public Object gen(SpatialArgs args) {
-        return strategy.makeQuery(args);
-      }
-    });
-    testEqualsHashcode(args1, args2, new ObjGenerator() {
-      @Override
-      public Object gen(SpatialArgs args) {
-        return strategy.makeDistanceValueSource(args.getShape().getCenter());
-      }
-    });
-  }
-
-  private void testEqualsHashcode(SpatialArgs args1, SpatialArgs args2, ObjGenerator generator) {
-    Object first;
-    try {
-      first = generator.gen(args1);
-    } catch (UnsupportedOperationException e) {
-      return;
-    }
-    if (first == null)
-      return;//unsupported op?
-    Object second = generator.gen(args1);//should be the same
-    assertEquals(first, second);
-    assertEquals(first.hashCode(), second.hashCode());
-    assertTrue(args1.equals(args2) == false);
-    second = generator.gen(args2);//now should be different
-    assertTrue(first.equals(second) == false);
-    assertTrue(first.hashCode() != second.hashCode());
-  }
-
-  private SpatialArgs makeArgs1() {
-    final Shape shape1 = ctx.makeRectangle(0, 0, 10, 10);
-    return new SpatialArgs(predicate, shape1);
-  }
-
-  private SpatialArgs makeArgs2() {
-    final Shape shape2 = ctx.makeRectangle(0, 0, 20, 20);
-    return new SpatialArgs(predicate, shape2);
-  }
-
-  interface ObjGenerator {
-    Object gen(SpatialArgs args);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialArgsTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialArgsTest.java b/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialArgsTest.java
deleted file mode 100644
index 09b5d46..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialArgsTest.java
+++ /dev/null
@@ -1,50 +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;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-
-public class SpatialArgsTest {
-
-  @Test
-  public void calcDistanceFromErrPct() {
-    final SpatialContext ctx = SpatialContext.GEO;
-    final double DEP = 0.5;//distErrPct
-
-    //the result is the diagonal distance from the center to the closest corner,
-    // times distErrPct
-
-    Shape superwide = ctx.makeRectangle(-180, 180, 0, 0);
-    //0 distErrPct means 0 distance always
-    assertEquals(0, SpatialArgs.calcDistanceFromErrPct(superwide, 0, ctx), 0);
-    assertEquals(180 * DEP, SpatialArgs.calcDistanceFromErrPct(superwide, DEP, ctx), 0);
-
-    Shape supertall = ctx.makeRectangle(0, 0, -90, 90);
-    assertEquals(90 * DEP, SpatialArgs.calcDistanceFromErrPct(supertall, DEP, ctx), 0);
-
-    Shape upperhalf = ctx.makeRectangle(-180, 180, 0, 90);
-    assertEquals(45 * DEP, SpatialArgs.calcDistanceFromErrPct(upperhalf, DEP, ctx), 0.0001);
-
-    Shape midCircle = ctx.makeCircle(0, 0, 45);
-    assertEquals(60 * DEP, SpatialArgs.calcDistanceFromErrPct(midCircle, DEP, ctx), 0.0001);
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialExample.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialExample.java b/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialExample.java
deleted file mode 100644
index 1bd7159..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialExample.java
+++ /dev/null
@@ -1,200 +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;
-
-import java.io.IOException;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.distance.DistanceUtils;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.NumericDocValuesField;
-import org.apache.lucene.document.StoredField;
-import org.apache.lucene.index.DirectoryReader;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.IndexWriter;
-import org.apache.lucene.index.IndexWriterConfig;
-import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.MatchAllDocsQuery;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.Sort;
-import org.apache.lucene.search.SortField;
-import org.apache.lucene.search.TopDocs;
-import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
-import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.query.SpatialArgsParser;
-import org.apache.lucene.spatial.query.SpatialOperation;
-import org.apache.lucene.store.Directory;
-import org.apache.lucene.store.RAMDirectory;
-import org.apache.lucene.util.LuceneTestCase;
-
-/**
- * This class serves as example code to show how to use the Lucene spatial
- * module.
- */
-public class SpatialExample extends LuceneTestCase {
-
-  //Note: Test invoked via TestTestFramework.spatialExample()
-
-  public static void main(String[] args) throws Exception {
-    new SpatialExample().test();
-  }
-
-  public void test() throws Exception {
-    init();
-    indexPoints();
-    search();
-  }
-
-  /**
-   * The Spatial4j {@link SpatialContext} is a sort of global-ish singleton
-   * needed by Lucene spatial.  It's a facade to the rest of Spatial4j, acting
-   * as a factory for {@link Shape}s and provides access to reading and writing
-   * them from Strings.
-   */
-  private SpatialContext ctx;//"ctx" is the conventional variable name
-
-  /**
-   * The Lucene spatial {@link SpatialStrategy} encapsulates an approach to
-   * indexing and searching shapes, and providing distance values for them.
-   * It's a simple API to unify different approaches. You might use more than
-   * one strategy for a shape as each strategy has its strengths and weaknesses.
-   * <p />
-   * Note that these are initialized with a field name.
-   */
-  private SpatialStrategy strategy;
-
-  private Directory directory;
-
-  protected void init() {
-    //Typical geospatial context
-    //  These can also be constructed from SpatialContextFactory
-    this.ctx = SpatialContext.GEO;
-
-    int maxLevels = 11;//results in sub-meter precision for geohash
-    //TODO demo lookup by detail distance
-    //  This can also be constructed from SpatialPrefixTreeFactory
-    SpatialPrefixTree grid = new GeohashPrefixTree(ctx, maxLevels);
-
-    this.strategy = new RecursivePrefixTreeStrategy(grid, "myGeoField");
-
-    this.directory = new RAMDirectory();
-  }
-
-  private void indexPoints() throws Exception {
-    IndexWriterConfig iwConfig = new IndexWriterConfig(null);
-    IndexWriter indexWriter = new IndexWriter(directory, iwConfig);
-
-    //Spatial4j is x-y order for arguments
-    indexWriter.addDocument(newSampleDocument(
-        2, ctx.makePoint(-80.93, 33.77)));
-
-    //Spatial4j has a WKT parser which is also "x y" order
-    indexWriter.addDocument(newSampleDocument(
-        4, ctx.readShapeFromWkt("POINT(60.9289094 -50.7693246)")));
-
-    indexWriter.addDocument(newSampleDocument(
-        20, ctx.makePoint(0.1,0.1), ctx.makePoint(0, 0)));
-
-    indexWriter.close();
-  }
-
-  private Document newSampleDocument(int id, Shape... shapes) {
-    Document doc = new Document();
-    doc.add(new StoredField("id", id));
-    doc.add(new NumericDocValuesField("id", id));
-    //Potentially more than one shape in this field is supported by some
-    // strategies; see the javadocs of the SpatialStrategy impl to see.
-    for (Shape shape : shapes) {
-      for (Field f : strategy.createIndexableFields(shape)) {
-        doc.add(f);
-      }
-      //store it too; the format is up to you
-      //  (assume point in this example)
-      Point pt = (Point) shape;
-      doc.add(new StoredField(strategy.getFieldName(), pt.getX()+" "+pt.getY()));
-    }
-
-    return doc;
-  }
-
-  private void search() throws Exception {
-    IndexReader indexReader = DirectoryReader.open(directory);
-    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
-    Sort idSort = new Sort(new SortField("id", SortField.Type.INT));
-
-    //--Filter by circle (<= distance from a point)
-    {
-      //Search with circle
-      //note: SpatialArgs can be parsed from a string
-      SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects,
-          ctx.makeCircle(-80.0, 33.0, DistanceUtils.dist2Degrees(200, DistanceUtils.EARTH_MEAN_RADIUS_KM)));
-      Query query = strategy.makeQuery(args);
-      TopDocs docs = indexSearcher.search(query, 10, idSort);
-      assertDocMatchedIds(indexSearcher, docs, 2);
-      //Now, lets get the distance for the 1st doc via computing from stored point value:
-      // (this computation is usually not redundant)
-      Document doc1 = indexSearcher.doc(docs.scoreDocs[0].doc);
-      String doc1Str = doc1.getField(strategy.getFieldName()).stringValue();
-      //assume doc1Str is "x y" as written in newSampleDocument()
-      int spaceIdx = doc1Str.indexOf(' ');
-      double x = Double.parseDouble(doc1Str.substring(0, spaceIdx));
-      double y = Double.parseDouble(doc1Str.substring(spaceIdx+1));
-      double doc1DistDEG = ctx.calcDistance(args.getShape().getCenter(), x, y);
-      assertEquals(121.6d, DistanceUtils.degrees2Dist(doc1DistDEG, DistanceUtils.EARTH_MEAN_RADIUS_KM), 0.1);
-      //or more simply:
-      assertEquals(121.6d, doc1DistDEG * DistanceUtils.DEG_TO_KM, 0.1);
-    }
-    //--Match all, order by distance ascending
-    {
-      Point pt = ctx.makePoint(60, -50);
-      ValueSource valueSource = strategy.makeDistanceValueSource(pt, DistanceUtils.DEG_TO_KM);//the distance (in km)
-      Sort distSort = new Sort(valueSource.getSortField(false)).rewrite(indexSearcher);//false=asc dist
-      TopDocs docs = indexSearcher.search(new MatchAllDocsQuery(), 10, distSort);
-      assertDocMatchedIds(indexSearcher, docs, 4, 20, 2);
-      //To get the distance, we could compute from stored values like earlier.
-      // However in this example we sorted on it, and the distance will get
-      // computed redundantly.  If the distance is only needed for the top-X
-      // search results then that's not a big deal. Alternatively, try wrapping
-      // the ValueSource with CachingDoubleValueSource then retrieve the value
-      // from the ValueSource now. See LUCENE-4541 for an example.
-    }
-    //demo arg parsing
-    {
-      SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects,
-          ctx.makeCircle(-80.0, 33.0, 1));
-      SpatialArgs args2 = new SpatialArgsParser().parse("Intersects(BUFFER(POINT(-80 33),1))", ctx);
-      assertEquals(args.toString(),args2.toString());
-    }
-
-    indexReader.close();
-  }
-
-  private void assertDocMatchedIds(IndexSearcher indexSearcher, TopDocs docs, int... ids) throws IOException {
-    int[] gotIds = new int[docs.totalHits];
-    for (int i = 0; i < gotIds.length; i++) {
-      gotIds[i] = indexSearcher.doc(docs.scoreDocs[i].doc).getField("id").numericValue().intValue();
-    }
-    assertArrayEquals(ids,gotIds);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialMatchConcern.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialMatchConcern.java b/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialMatchConcern.java
deleted file mode 100644
index e995ee1..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialMatchConcern.java
+++ /dev/null
@@ -1,31 +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;
-
-public class SpatialMatchConcern {
-  public final boolean orderIsImportant;
-  public final boolean resultsAreSuperset; // if the strategy can not give exact answers, but used to limit results
-
-  private SpatialMatchConcern( boolean order, boolean superset ) {
-    this.orderIsImportant = order;
-    this.resultsAreSuperset = superset;
-  }
-
-  public static final SpatialMatchConcern EXACT = new SpatialMatchConcern( true, false );
-  public static final SpatialMatchConcern FILTER = new SpatialMatchConcern( false, false );
-  public static final SpatialMatchConcern SUPERSET = new SpatialMatchConcern( false, true );
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestCase.java b/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestCase.java
deleted file mode 100644
index 31b57f9..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestCase.java
+++ /dev/null
@@ -1,281 +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;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.logging.Logger;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.distance.DistanceUtils;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-
-import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.analysis.MockAnalyzer;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.index.DirectoryReader;
-import org.apache.lucene.index.IndexWriterConfig;
-import org.apache.lucene.index.RandomIndexWriter;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.ScoreDoc;
-import org.apache.lucene.search.TopDocs;
-import org.apache.lucene.store.Directory;
-import org.apache.lucene.uninverting.UninvertingReader;
-import org.apache.lucene.uninverting.UninvertingReader.Type;
-import org.apache.lucene.util.IOUtils;
-import org.apache.lucene.util.LuceneTestCase;
-import org.apache.lucene.util.LuceneTestCase.SuppressSysoutChecks;
-import org.apache.lucene.util.TestUtil;
-
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomDouble;
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomGaussian;
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomInt;
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween;
-
-/** A base test class for spatial lucene. It's mostly Lucene generic. */
-@SuppressSysoutChecks(bugUrl = "These tests use JUL extensively.")
-public abstract class SpatialTestCase extends LuceneTestCase {
-
-  protected Logger log = Logger.getLogger(getClass().getName());
-
-  private DirectoryReader indexReader;
-  protected RandomIndexWriter indexWriter;
-  private Directory directory;
-  private Analyzer analyzer;
-  protected IndexSearcher indexSearcher;
-
-  protected SpatialContext ctx;//subclass must initialize
-
-  protected Map<String,Type> uninvertMap = new HashMap<>();
-  
-  @Override
-  public void setUp() throws Exception {
-    super.setUp();
-    // TODO: change this module to index docvalues instead of uninverting
-    uninvertMap.clear();
-    uninvertMap.put("pointvector__x", Type.DOUBLE);
-    uninvertMap.put("pointvector__y", Type.DOUBLE);
-
-    directory = newDirectory();
-    final Random random = random();
-    analyzer = new MockAnalyzer(random);
-    indexWriter = new RandomIndexWriter(random,directory, newIWConfig(random, analyzer));
-    indexReader = UninvertingReader.wrap(indexWriter.getReader(), uninvertMap);
-    indexSearcher = newSearcher(indexReader);
-  }
-
-  protected IndexWriterConfig newIWConfig(Random random, Analyzer analyzer) {
-    final IndexWriterConfig indexWriterConfig = LuceneTestCase.newIndexWriterConfig(random, analyzer);
-    //TODO can we randomly choose a doc-values supported format?
-    if (needsDocValues())
-      indexWriterConfig.setCodec( TestUtil.getDefaultCodec());
-    return indexWriterConfig;
-  }
-
-  protected boolean needsDocValues() {
-    return false;
-  }
-
-  @Override
-  public void tearDown() throws Exception {
-    IOUtils.close(indexWriter, indexReader, analyzer, directory);
-    super.tearDown();
-  }
-
-  // ================================================= Helper Methods ================================================
-
-  protected void addDocument(Document doc) throws IOException {
-    indexWriter.addDocument(doc);
-  }
-
-  protected void addDocumentsAndCommit(List<Document> documents) throws IOException {
-    for (Document document : documents) {
-      indexWriter.addDocument(document);
-    }
-    commit();
-  }
-
-  protected void deleteAll() throws IOException {
-    indexWriter.deleteAll();
-  }
-
-  protected void commit() throws IOException {
-    indexWriter.commit();
-    DirectoryReader newReader = DirectoryReader.openIfChanged(indexReader);
-    if (newReader != null) {
-      IOUtils.close(indexReader);
-      indexReader = newReader;
-    }
-    indexSearcher = newSearcher(indexReader);
-  }
-
-  protected void verifyDocumentsIndexed(int numDocs) {
-    assertEquals(numDocs, indexReader.numDocs());
-  }
-
-  protected SearchResults executeQuery(Query query, int numDocs) {
-    try {
-      TopDocs topDocs = indexSearcher.search(query, numDocs);
-
-      List<SearchResult> results = new ArrayList<>();
-      for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
-        results.add(new SearchResult(scoreDoc.score, indexSearcher.doc(scoreDoc.doc)));
-      }
-      return new SearchResults(topDocs.totalHits, results);
-    } catch (IOException ioe) {
-      throw new RuntimeException("IOException thrown while executing query", ioe);
-    }
-  }
-
-  protected Point randomPoint() {
-    final Rectangle WB = ctx.getWorldBounds();
-    return ctx.makePoint(
-        randomIntBetween((int) WB.getMinX(), (int) WB.getMaxX()),
-        randomIntBetween((int) WB.getMinY(), (int) WB.getMaxY()));
-  }
-
-  protected Rectangle randomRectangle() {
-    return randomRectangle(ctx.getWorldBounds());
-  }
-
-  protected Rectangle randomRectangle(Rectangle bounds) {
-    double[] xNewStartAndWidth = randomSubRange(bounds.getMinX(), bounds.getWidth());
-    double xMin = xNewStartAndWidth[0];
-    double xMax = xMin + xNewStartAndWidth[1];
-    if (bounds.getCrossesDateLine()) {
-      xMin = DistanceUtils.normLonDEG(xMin);
-      xMax = DistanceUtils.normLonDEG(xMax);
-    }
-
-    double[] yNewStartAndHeight = randomSubRange(bounds.getMinY(), bounds.getHeight());
-    double yMin = yNewStartAndHeight[0];
-    double yMax = yMin + yNewStartAndHeight[1];
-
-    return ctx.makeRectangle(xMin, xMax, yMin, yMax);
-  }
-
-  /** Returns new minStart and new length that is inside the range specified by the arguments. */
-  protected double[] randomSubRange(double boundStart, double boundLen) {
-    if (boundLen >= 3 && usually()) { // typical
-      // prefer integers for ease of debugability ... and prefer 1/16th of bound
-      int intBoundStart = (int) Math.ceil(boundStart);
-      int intBoundEnd = (int) (boundStart + boundLen);
-      int intBoundLen = intBoundEnd - intBoundStart;
-      int newLen = (int) randomGaussianMeanMax(intBoundLen / 16.0, intBoundLen);
-      int newStart = intBoundStart + randomInt(intBoundLen - newLen);
-      return new double[]{newStart, newLen};
-    } else { // (no int rounding)
-      double newLen = randomGaussianMeanMax(boundLen / 16, boundLen);
-      double newStart = boundStart + (boundLen - newLen == 0 ? 0 : (randomDouble() % (boundLen - newLen)));
-      return new double[]{newStart, newLen};
-    }
-  }
-
-  private double randomGaussianMinMeanMax(double min, double mean, double max) {
-    assert mean > min;
-    return randomGaussianMeanMax(mean - min, max - min) + min;
-  }
-
-  /**
-   * Within one standard deviation (68% of the time) the result is "close" to
-   * mean. By "close": when greater than mean, it's the lesser of 2*mean or half
-   * way to max, when lesser than mean, it's the greater of max-2*mean or half
-   * way to 0. The other 32% of the time it's in the rest of the range, touching
-   * either 0 or max but never exceeding.
-   */
-  private double randomGaussianMeanMax(double mean, double max) {
-    // DWS: I verified the results empirically
-    assert mean <= max && mean >= 0;
-    double g = randomGaussian();
-    double mean2 = mean;
-    double flip = 1;
-    if (g < 0) {
-      mean2 = max - mean;
-      flip = -1;
-      g *= -1;
-    }
-    // pivot is the distance from mean2 towards max where the boundary of
-    // 1 standard deviation alters the calculation
-    double pivotMax = max - mean2;
-    double pivot = Math.min(mean2, pivotMax / 2);//from 0 to max-mean2
-    assert pivot >= 0 && pivotMax >= pivot && g >= 0;
-    double pivotResult;
-    if (g <= 1)
-      pivotResult = pivot * g;
-    else
-      pivotResult = Math.min(pivotMax, (g - 1) * (pivotMax - pivot) + pivot);
-
-    double result = mean + flip * pivotResult;
-    return (result < 0 || result > max) ? mean : result; // due this due to computational numerical precision
-  }
-
-  // ================================================= Inner Classes =================================================
-
-  protected static class SearchResults {
-
-    public int numFound;
-    public List<SearchResult> results;
-
-    public SearchResults(int numFound, List<SearchResult> results) {
-      this.numFound = numFound;
-      this.results = results;
-    }
-
-    public StringBuilder toDebugString() {
-      StringBuilder str = new StringBuilder();
-      str.append("found: ").append(numFound).append('[');
-      for(SearchResult r : results) {
-        String id = r.getId();
-        str.append(id).append(", ");
-      }
-      str.append(']');
-      return str;
-    }
-
-    @Override
-    public String toString() {
-      return "[found:"+numFound+" "+results+"]";
-    }
-  }
-
-  protected static class SearchResult {
-
-    public float score;
-    public Document document;
-
-    public SearchResult(float score, Document document) {
-      this.score = score;
-      this.document = document;
-    }
-
-    public String getId() {
-      return document.get("id");
-    }
-    
-    @Override
-    public String toString() {
-      return "["+score+"="+document+"]";
-    }
-  }
-}
-

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestData.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestData.java b/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestData.java
deleted file mode 100644
index 27d47b3..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestData.java
+++ /dev/null
@@ -1,71 +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;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Shape;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-// This class is modelled after SpatialTestQuery.
-// Before Lucene 4.7, this was a bit different in Spatial4j as SampleData & SampleDataReader.
-
-public class SpatialTestData {
-  public String id;
-  public String name;
-  public Shape shape;
-
-  /** Reads the stream, consuming a format that is a tab-separated values of 3 columns:
-   * an "id", a "name" and the "shape".  Empty lines and lines starting with a '#' are skipped.
-   * The stream is closed.
-   */
-  public static Iterator<SpatialTestData> getTestData(InputStream in, SpatialContext ctx) throws IOException {
-    List<SpatialTestData> results = new ArrayList<>();
-    BufferedReader bufInput = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
-    try {
-      String line;
-      while ((line = bufInput.readLine()) != null) {
-        if (line.length() == 0 || line.charAt(0) == '#')
-          continue;
-
-        SpatialTestData data = new SpatialTestData();
-        String[] vals = line.split("\t");
-        if (vals.length != 3)
-          throw new RuntimeException("bad format; expecting 3 tab-separated values for line: "+line);
-        data.id = vals[0];
-        data.name = vals[1];
-        try {
-          data.shape = ctx.readShapeFromWkt(vals[2]);
-        } catch (ParseException e) {
-          throw new RuntimeException(e);
-        }
-        results.add(data);
-      }
-    } finally {
-      bufInput.close();
-    }
-    return results.iterator();
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestQuery.java b/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestQuery.java
deleted file mode 100644
index bac90cf..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestQuery.java
+++ /dev/null
@@ -1,96 +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;
-
-import com.spatial4j.core.context.SpatialContext;
-
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.query.SpatialArgsParser;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.StringTokenizer;
-
-/**
- * Helper class to execute queries
- */
-public class SpatialTestQuery {
-  public String testname;
-  public String line;
-  public int lineNumber = -1;
-  public SpatialArgs args;
-  public List<String> ids = new ArrayList<>();
-
-  /**
-   * Get Test Queries.  The InputStream is closed.
-   */
-  public static Iterator<SpatialTestQuery> getTestQueries(
-      final SpatialArgsParser parser,
-      final SpatialContext ctx,
-      final String name,
-      final InputStream in ) throws IOException {
-
-    List<SpatialTestQuery> results = new ArrayList<>();
-
-    BufferedReader bufInput = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
-    try {
-      String line;
-      for (int lineNumber = 1; (line = bufInput.readLine()) != null; lineNumber++) {
-        SpatialTestQuery test = new SpatialTestQuery();
-        test.line = line;
-        test.lineNumber = lineNumber;
-
-        try {
-          // skip a comment
-          if( line.startsWith( "[" ) ) {
-            int idx = line.indexOf( ']' );
-            if( idx > 0 ) {
-              line = line.substring( idx+1 );
-            }
-          }
-
-          int idx = line.indexOf('@');
-          StringTokenizer st = new StringTokenizer(line.substring(0, idx));
-          while (st.hasMoreTokens()) {
-            test.ids.add(st.nextToken().trim());
-          }
-          test.args = parser.parse(line.substring(idx + 1).trim(), ctx);
-          results.add(test);
-        }
-        catch( Exception ex ) {
-          throw new RuntimeException( "invalid query line: "+test.line, ex );
-        }
-      }
-    } finally {
-      bufInput.close();
-    }
-    return results.iterator();
-  }
-
-  @Override
-  public String toString() {
-    if (line != null)
-      return line;
-    return args.toString()+" "+ids;
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/StrategyTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/StrategyTestCase.java b/lucene/spatial/src/test/org/apache/lucene/spatial/StrategyTestCase.java
deleted file mode 100644
index 00e437b..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/StrategyTestCase.java
+++ /dev/null
@@ -1,252 +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;
-
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.logging.Logger;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.StoredField;
-import org.apache.lucene.document.StringField;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.queries.function.FunctionQuery;
-import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.search.CheckHits;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.ScoreDoc;
-import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.search.TopDocs;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.query.SpatialArgsParser;
-import org.apache.lucene.spatial.query.SpatialOperation;
-
-public abstract class StrategyTestCase extends SpatialTestCase {
-
-  public static final String DATA_SIMPLE_BBOX = "simple-bbox.txt";
-  public static final String DATA_STATES_POLY = "states-poly.txt";
-  public static final String DATA_STATES_BBOX = "states-bbox.txt";
-  public static final String DATA_COUNTRIES_POLY = "countries-poly.txt";
-  public static final String DATA_COUNTRIES_BBOX = "countries-bbox.txt";
-  public static final String DATA_WORLD_CITIES_POINTS = "world-cities-points.txt";
-
-  public static final String QTEST_States_IsWithin_BBox   = "states-IsWithin-BBox.txt";
-  public static final String QTEST_States_Intersects_BBox = "states-Intersects-BBox.txt";
-  public static final String QTEST_Cities_Intersects_BBox = "cities-Intersects-BBox.txt";
-  public static final String QTEST_Simple_Queries_BBox = "simple-Queries-BBox.txt";
-
-  protected Logger log = Logger.getLogger(getClass().getName());
-
-  protected final SpatialArgsParser argsParser = new SpatialArgsParser();
-
-  protected SpatialStrategy strategy;
-  protected boolean storeShape = true;
-
-  protected void executeQueries(SpatialMatchConcern concern, String... testQueryFile) throws IOException {
-    log.info("testing queried for strategy "+strategy);
-    for( String path : testQueryFile ) {
-      Iterator<SpatialTestQuery> testQueryIterator = getTestQueries(path, ctx);
-      runTestQueries(testQueryIterator, concern);
-    }
-  }
-
-  protected void getAddAndVerifyIndexedDocuments(String testDataFile) throws IOException {
-    List<Document> testDocuments = getDocuments(testDataFile);
-    addDocumentsAndCommit(testDocuments);
-    verifyDocumentsIndexed(testDocuments.size());
-  }
-
-  protected List<Document> getDocuments(String testDataFile) throws IOException {
-    return getDocuments(getSampleData(testDataFile));
-  }
-
-  protected List<Document> getDocuments(Iterator<SpatialTestData> sampleData) {
-    List<Document> documents = new ArrayList<>();
-    while (sampleData.hasNext()) {
-      SpatialTestData data = sampleData.next();
-      Document document = new Document();
-      document.add(new StringField("id", data.id, Field.Store.YES));
-      document.add(new StringField("name", data.name, Field.Store.YES));
-      Shape shape = data.shape;
-      shape = convertShapeFromGetDocuments(shape);
-      if (shape != null) {
-        for (Field f : strategy.createIndexableFields(shape)) {
-          document.add(f);
-        }
-        if (storeShape)//just for diagnostics
-          document.add(new StoredField(strategy.getFieldName(), shape.toString()));
-      }
-
-      documents.add(document);
-    }
-    return documents;
-  }
-
-  /** Subclasses may override to transform or remove a shape for indexing */
-  protected Shape convertShapeFromGetDocuments(Shape shape) {
-    return shape;
-  }
-
-  protected Iterator<SpatialTestData> getSampleData(String testDataFile) throws IOException {
-    String path = "data/" + testDataFile;
-    InputStream stream = getClass().getClassLoader().getResourceAsStream(path);
-    if (stream == null)
-      throw new FileNotFoundException("classpath resource not found: "+path);
-    return SpatialTestData.getTestData(stream, ctx);//closes the InputStream
-  }
-
-  protected Iterator<SpatialTestQuery> getTestQueries(String testQueryFile, SpatialContext ctx) throws IOException {
-    InputStream in = getClass().getClassLoader().getResourceAsStream(testQueryFile);
-    return SpatialTestQuery.getTestQueries(
-        argsParser, ctx, testQueryFile, in );//closes the InputStream
-  }
-
-  public void runTestQueries(
-      Iterator<SpatialTestQuery> queries,
-      SpatialMatchConcern concern) {
-    while (queries.hasNext()) {
-      SpatialTestQuery q = queries.next();
-      runTestQuery(concern, q);
-    }
-  }
-
-  public void runTestQuery(SpatialMatchConcern concern, SpatialTestQuery q) {
-    String msg = q.toString(); //"Query: " + q.args.toString(ctx);
-    SearchResults got = executeQuery(makeQuery(q), Math.max(100, q.ids.size()+1));
-    if (storeShape && got.numFound > 0) {
-      //check stored value is there
-      assertNotNull(got.results.get(0).document.get(strategy.getFieldName()));
-    }
-    if (concern.orderIsImportant) {
-      Iterator<String> ids = q.ids.iterator();
-      for (SearchResult r : got.results) {
-        String id = r.document.get("id");
-        if (!ids.hasNext()) {
-          fail(msg + " :: Did not get enough results.  Expect" + q.ids + ", got: " + got.toDebugString());
-        }
-        assertEquals("out of order: " + msg, ids.next(), id);
-      }
-
-      if (ids.hasNext()) {
-        fail(msg + " :: expect more results then we got: " + ids.next());
-      }
-    } else {
-      // We are looking at how the results overlap
-      if (concern.resultsAreSuperset) {
-        Set<String> found = new HashSet<>();
-        for (SearchResult r : got.results) {
-          found.add(r.document.get("id"));
-        }
-        for (String s : q.ids) {
-          if (!found.contains(s)) {
-            fail("Results are mising id: " + s + " :: " + found);
-          }
-        }
-      } else {
-        List<String> found = new ArrayList<>();
-        for (SearchResult r : got.results) {
-          found.add(r.document.get("id"));
-        }
-
-        // sort both so that the order is not important
-        Collections.sort(q.ids);
-        Collections.sort(found);
-        assertEquals(msg, q.ids.toString(), found.toString());
-      }
-    }
-  }
-
-  protected Query makeQuery(SpatialTestQuery q) {
-    return strategy.makeQuery(q.args);
-  }
-
-  protected void adoc(String id, String shapeStr) throws IOException, ParseException {
-    Shape shape = shapeStr==null ? null : ctx.readShapeFromWkt(shapeStr);
-    addDocument(newDoc(id, shape));
-  }
-  protected void adoc(String id, Shape shape) throws IOException {
-    addDocument(newDoc(id, shape));
-  }
-
-  protected Document newDoc(String id, Shape shape) {
-    Document doc = new Document();
-    doc.add(new StringField("id", id, Field.Store.YES));
-    if (shape != null) {
-      for (Field f : strategy.createIndexableFields(shape)) {
-        doc.add(f);
-      }
-      if (storeShape)
-        doc.add(new StoredField(strategy.getFieldName(), shape.toString()));//not to be parsed; just for debug
-    }
-    return doc;
-  }
-
-  protected void deleteDoc(String id) throws IOException {
-    indexWriter.deleteDocuments(new TermQuery(new Term("id", id)));
-  }
-
-  /** scores[] are in docId order */
-  protected void checkValueSource(ValueSource vs, float scores[], float delta) throws IOException {
-    FunctionQuery q = new FunctionQuery(vs);
-
-//    //TODO is there any point to this check?
-//    int expectedDocs[] = new int[scores.length];//fill with ascending 0....length-1
-//    for (int i = 0; i < expectedDocs.length; i++) {
-//      expectedDocs[i] = i;
-//    }
-//    CheckHits.checkHits(random(), q, "", indexSearcher, expectedDocs);
-
-    //TopDocs is sorted but we actually don't care about the order
-    TopDocs docs = indexSearcher.search(q, 1000);//calculates the score
-    for (int i = 0; i < docs.scoreDocs.length; i++) {
-      ScoreDoc gotSD = docs.scoreDocs[i];
-      float expectedScore = scores[gotSD.doc];
-      assertEquals("Not equal for doc "+gotSD.doc, expectedScore, gotSD.score, delta);
-    }
-
-    CheckHits.checkExplanations(q, "", indexSearcher);
-  }
-
-  protected void testOperation(Shape indexedShape, SpatialOperation operation,
-                               Shape queryShape, boolean match) throws IOException {
-    assertTrue("Faulty test",
-        operation.evaluate(indexedShape, queryShape) == match ||
-            indexedShape.equals(queryShape) &&
-              (operation == SpatialOperation.Contains || operation == SpatialOperation.IsWithin));
-    adoc("0", indexedShape);
-    commit();
-    Query query = strategy.makeQuery(new SpatialArgs(operation, queryShape));
-    SearchResults got = executeQuery(query, 1);
-    assert got.numFound <= 1 : "unclean test env";
-    if ((got.numFound == 1) != match)
-      fail(operation+" I:" + indexedShape + " Q:" + queryShape);
-    deleteAll();//clean up after ourselves
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/TestTestFramework.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/TestTestFramework.java b/lucene/spatial/src/test/org/apache/lucene/spatial/TestTestFramework.java
deleted file mode 100644
index 6a8d59c..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/TestTestFramework.java
+++ /dev/null
@@ -1,68 +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;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Rectangle;
-import org.apache.lucene.spatial.query.SpatialArgsParser;
-import org.apache.lucene.spatial.query.SpatialOperation;
-import org.apache.lucene.util.LuceneTestCase;
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-
-/**
- * Make sure we are reading the tests as expected
- */
-public class TestTestFramework extends LuceneTestCase {
-
-  @Test
-  public void testQueries() throws IOException {
-    String name = StrategyTestCase.QTEST_Cities_Intersects_BBox;
-
-    InputStream in = getClass().getClassLoader().getResourceAsStream(name);
-    SpatialContext ctx = SpatialContext.GEO;
-    Iterator<SpatialTestQuery> iter = SpatialTestQuery.getTestQueries(
-        new SpatialArgsParser(), ctx, name, in );//closes the InputStream
-    List<SpatialTestQuery> tests = new ArrayList<>();
-    while( iter.hasNext() ) {
-      tests.add( iter.next() );
-    }
-    Assert.assertEquals( 3, tests.size() );
-
-    SpatialTestQuery sf = tests.get(0);
-    // assert
-    Assert.assertEquals( 1, sf.ids.size() );
-    Assert.assertTrue( sf.ids.get(0).equals( "G5391959" ) );
-    Assert.assertTrue( sf.args.getShape() instanceof Rectangle);
-    Assert.assertEquals(SpatialOperation.Intersects, sf.args.getOperation());
-  }
-
-  @Test
-  public void spatialExample() throws Exception {
-    //kind of a hack so that SpatialExample is tested despite
-    // it not starting or ending with "Test".
-    SpatialExample.main(null);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java b/lucene/spatial/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java
deleted file mode 100644
index 6140996..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java
+++ /dev/null
@@ -1,301 +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.bbox;
-
-import java.io.IOException;
-
-import com.carrotsearch.randomizedtesting.annotations.Repeat;
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.context.SpatialContextFactory;
-import com.spatial4j.core.distance.DistanceUtils;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.impl.RectangleImpl;
-import org.apache.lucene.document.FieldType;
-import org.apache.lucene.index.DocValuesType;
-import org.apache.lucene.index.IndexOptions;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.spatial.SpatialMatchConcern;
-import org.apache.lucene.spatial.prefix.RandomSpatialOpStrategyTestCase;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.query.SpatialOperation;
-import org.apache.lucene.spatial.util.ShapeAreaValueSource;
-import org.junit.Ignore;
-import org.junit.Test;
-
-public class TestBBoxStrategy extends RandomSpatialOpStrategyTestCase {
-
-  @Override
-  protected boolean needsDocValues() {
-    return true;
-  }
-
-  @Override
-  protected Shape randomIndexedShape() {
-    Rectangle world = ctx.getWorldBounds();
-    if (random().nextInt(10) == 0) // increased chance of getting one of these
-      return world;
-
-    int worldWidth = (int) Math.round(world.getWidth());
-    int deltaLeft = nextIntInclusive(worldWidth);
-    int deltaRight = nextIntInclusive(worldWidth - deltaLeft);
-    int worldHeight = (int) Math.round(world.getHeight());
-    int deltaTop = nextIntInclusive(worldHeight);
-    int deltaBottom = nextIntInclusive(worldHeight - deltaTop);
-    if (ctx.isGeo() && (deltaLeft != 0 || deltaRight != 0)) {
-      //if geo & doesn't world-wrap, we shift randomly to potentially cross dateline
-      int shift = nextIntInclusive(360);
-      return ctx.makeRectangle(
-          DistanceUtils.normLonDEG(world.getMinX() + deltaLeft + shift),
-          DistanceUtils.normLonDEG(world.getMaxX() - deltaRight + shift),
-          world.getMinY() + deltaBottom, world.getMaxY() - deltaTop);
-    } else {
-      return ctx.makeRectangle(
-          world.getMinX() + deltaLeft, world.getMaxX() - deltaRight,
-          world.getMinY() + deltaBottom, world.getMaxY() - deltaTop);
-    }
-  }
-
-  /** next int, inclusive, rounds to multiple of 10 if given evenly divisible. */
-  private int nextIntInclusive(int toInc) {
-    final int DIVIS = 10;
-    if (toInc % DIVIS == 0) {
-      return random().nextInt(toInc/DIVIS + 1) * DIVIS;
-    } else {
-      return random().nextInt(toInc + 1);
-    }
-  }
-
-  @Override
-  protected Shape randomQueryShape() {
-    return randomIndexedShape();
-  }
-
-  @Test
-  @Repeat(iterations = 15)
-  public void testOperations() throws IOException {
-    //setup
-    if (random().nextInt(4) > 0) {//75% of the time choose geo (more interesting to test)
-      this.ctx = SpatialContext.GEO;
-    } else {
-      SpatialContextFactory factory = new SpatialContextFactory();
-      factory.geo = false;
-      factory.worldBounds = new RectangleImpl(-300, 300, -100, 100, null);
-      this.ctx = factory.newSpatialContext();
-    }
-    this.strategy = new BBoxStrategy(ctx, "bbox");
-    //test we can disable docValues for predicate tests
-    if (random().nextBoolean()) {
-      BBoxStrategy bboxStrategy = (BBoxStrategy) strategy;
-      FieldType fieldType = new FieldType(bboxStrategy.getFieldType());
-      fieldType.setDocValuesType(DocValuesType.NONE);
-      bboxStrategy.setFieldType(fieldType);
-    }
-    for (SpatialOperation operation : SpatialOperation.values()) {
-      if (operation == SpatialOperation.Overlaps)
-        continue;//unsupported
-      testOperationRandomShapes(operation);
-
-      deleteAll();
-      commit();
-    }
-  }
-
-  @Test
-  public void testIntersectsBugDatelineEdge() throws IOException {
-    setupGeo();
-    testOperation(
-        ctx.makeRectangle(160, 180, -10, 10),
-        SpatialOperation.Intersects,
-        ctx.makeRectangle(-180, -160, -10, 10), true);
-  }
-
-  @Test
-  public void testIntersectsWorldDatelineEdge() throws IOException {
-    setupGeo();
-    testOperation(
-        ctx.makeRectangle(-180, 180, -10, 10),
-        SpatialOperation.Intersects,
-        ctx.makeRectangle(180, 180, -10, 10), true);
-  }
-
-  @Test
-  public void testWithinBugDatelineEdge() throws IOException {
-    setupGeo();
-    testOperation(
-        ctx.makeRectangle(180, 180, -10, 10),
-        SpatialOperation.IsWithin,
-        ctx.makeRectangle(-180, -100, -10, 10), true);
-  }
-
-  @Test
-  public void testContainsBugDatelineEdge() throws IOException {
-    setupGeo();
-    testOperation(
-        ctx.makeRectangle(-180, -150, -10, 10),
-        SpatialOperation.Contains,
-        ctx.makeRectangle(180, 180, -10, 10), true);
-  }
-
-  @Test
-  public void testWorldContainsXDL() throws IOException {
-    setupGeo();
-    testOperation(
-        ctx.makeRectangle(-180, 180, -10, 10),
-        SpatialOperation.Contains,
-        ctx.makeRectangle(170, -170, -10, 10), true);
-  }
-
-  /** See https://github.com/spatial4j/spatial4j/issues/85 */
-  @Test
-  public void testAlongDatelineOppositeSign() throws IOException {
-    // Due to Spatial4j bug #85, we can't simply do:
-    //    testOperation(indexedShape,
-    //        SpatialOperation.IsWithin,
-    //        queryShape, true);
-
-    //both on dateline but expressed using opposite signs
-    setupGeo();
-    final Rectangle indexedShape = ctx.makeRectangle(180, 180, -10, 10);
-    final Rectangle queryShape = ctx.makeRectangle(-180, -180, -20, 20);
-    final SpatialOperation operation = SpatialOperation.IsWithin;
-    final boolean match = true;//yes it is within
-
-    //the rest is super.testOperation without leading assert:
-
-    adoc("0", indexedShape);
-    commit();
-    Query query = strategy.makeQuery(new SpatialArgs(operation, queryShape));
-    SearchResults got = executeQuery(query, 1);
-    assert got.numFound <= 1 : "unclean test env";
-    if ((got.numFound == 1) != match)
-      fail(operation+" I:" + indexedShape + " Q:" + queryShape);
-    deleteAll();//clean up after ourselves
-  }
-
-  private void setupGeo() {
-    this.ctx = SpatialContext.GEO;
-    this.strategy = new BBoxStrategy(ctx, "bbox");
-  }
-
-  // OLD STATIC TESTS (worthless?)
-
-  @Test @Ignore("Overlaps not supported")
-  public void testBasicOperaions() throws IOException {
-    setupGeo();
-    getAddAndVerifyIndexedDocuments(DATA_SIMPLE_BBOX);
-
-    executeQueries(SpatialMatchConcern.EXACT, QTEST_Simple_Queries_BBox);
-  }
-
-  @Test
-  public void testStatesBBox() throws IOException {
-    setupGeo();
-    getAddAndVerifyIndexedDocuments(DATA_STATES_BBOX);
-
-    executeQueries(SpatialMatchConcern.FILTER, QTEST_States_IsWithin_BBox);
-    executeQueries(SpatialMatchConcern.FILTER, QTEST_States_Intersects_BBox);
-  }
-
-  @Test
-  public void testCitiesIntersectsBBox() throws IOException {
-    setupGeo();
-    getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS);
-
-    executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_Intersects_BBox);
-  }
-
-  /* Convert DATA_WORLD_CITIES_POINTS to bbox */
-  @Override
-  protected Shape convertShapeFromGetDocuments(Shape shape) {
-    return shape.getBoundingBox();
-  }
-
-  public void testOverlapRatio() throws IOException {
-    setupGeo();
-
-    //Simply assert null shape results in 0
-    adoc("999", (Shape) null);
-    commit();
-    BBoxStrategy bboxStrategy = (BBoxStrategy) strategy;
-    checkValueSource(bboxStrategy.makeOverlapRatioValueSource(randomRectangle(), 0.0), new float[]{0f}, 0f);
-
-    //we test raw BBoxOverlapRatioValueSource without actual indexing
-    for (int SHIFT = 0; SHIFT < 360; SHIFT += 10) {
-      Rectangle queryBox = shiftedRect(0, 40, -20, 20, SHIFT);//40x40, 1600 area
-
-      final boolean MSL = random().nextBoolean();
-      final double minSideLength = MSL ? 0.1 : 0.0;
-      BBoxOverlapRatioValueSource sim = new BBoxOverlapRatioValueSource(null, true, queryBox, 0.5, minSideLength);
-      int nudge = SHIFT == 0 ? 0 : random().nextInt(3) * 10 - 10;//-10, 0, or 10.  Keep 0 on first round.
-
-      final double EPS = 0.0000001;
-
-      assertEquals("within", (200d/1600d * 0.5) + (0.5), sim.score(shiftedRect(10, 30, 0, 10, SHIFT + nudge), null), EPS);
-
-      assertEquals("in25%", 0.25, sim.score(shiftedRect(30, 70, -20, 20, SHIFT), null), EPS);
-
-      assertEquals("wrap", 0.2794117, sim.score(shiftedRect(30, 10, -20, 20, SHIFT + nudge), null), EPS);
-
-      assertEquals("no intersection H", 0.0, sim.score(shiftedRect(-10, -10, -20, 20, SHIFT), null), EPS);
-      assertEquals("no intersection V", 0.0, sim.score(shiftedRect(0, 20, -30, -30, SHIFT), null), EPS);
-
-      assertEquals("point", 0.5 + (MSL?(0.1*0.1/1600.0/2.0):0), sim.score(shiftedRect(0, 0, 0, 0, SHIFT), null), EPS);
-
-      assertEquals("line 25% intersection", 0.25/2 + (MSL?(10.0*0.1/1600.0/2.0):0.0), sim.score(shiftedRect(-30, 10, 0, 0, SHIFT), null), EPS);
-
-      //test with point query
-      sim = new BBoxOverlapRatioValueSource(null, true, shiftedRect(0, 0, 0, 0, SHIFT), 0.5, minSideLength);
-      assertEquals("same", 1.0, sim.score(shiftedRect(0, 0, 0, 0, SHIFT), null), EPS);
-      assertEquals("contains", 0.5 + (MSL?(0.1*0.1/(30*10)/2.0):0.0), sim.score(shiftedRect(0, 30, 0, 10, SHIFT), null), EPS);
-
-      //test with line query (vertical this time)
-      sim = new BBoxOverlapRatioValueSource(null, true, shiftedRect(0, 0, 20, 40, SHIFT), 0.5, minSideLength);
-      assertEquals("line 50%", 0.5, sim.score(shiftedRect(0, 0, 10, 30, SHIFT), null), EPS);
-      assertEquals("point", 0.5 + (MSL?(0.1*0.1/(20*0.1)/2.0):0.0), sim.score(shiftedRect(0, 0, 30, 30, SHIFT), null), EPS);
-    }
-
-  }
-
-  private Rectangle shiftedRect(double minX, double maxX, double minY, double maxY, int xShift) {
-    return ctx.makeRectangle(
-        DistanceUtils.normLonDEG(minX + xShift),
-        DistanceUtils.normLonDEG(maxX + xShift),
-        minY, maxY);
-  }
-
-  public void testAreaValueSource() throws IOException {
-    setupGeo();
-    //test we can disable indexed for this test
-    BBoxStrategy bboxStrategy = (BBoxStrategy) strategy;
-    if (random().nextBoolean()) {
-      FieldType fieldType = new FieldType(bboxStrategy.getFieldType());
-      fieldType.setIndexOptions(IndexOptions.NONE);
-      bboxStrategy.setFieldType(fieldType);
-    }
-
-    adoc("100", ctx.makeRectangle(0, 20, 40, 80));
-    adoc("999", (Shape) null);
-    commit();
-    checkValueSource(new ShapeAreaValueSource(bboxStrategy.makeShapeValueSource(), ctx, false, 1.0),
-        new float[]{800f, 0f}, 0f);
-    checkValueSource(new ShapeAreaValueSource(bboxStrategy.makeShapeValueSource(), ctx, true, 1.0),//geo
-        new float[]{391.93f, 0f}, 0.01f);
-    checkValueSource(new ShapeAreaValueSource(bboxStrategy.makeShapeValueSource(), ctx, true, 2.0),
-        new float[]{783.86f, 0f}, 0.01f); // testing with a different multiplier
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/composite/CompositeStrategyTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/composite/CompositeStrategyTest.java b/lucene/spatial/src/test/org/apache/lucene/spatial/composite/CompositeStrategyTest.java
deleted file mode 100644
index 8e1bb51..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/composite/CompositeStrategyTest.java
+++ /dev/null
@@ -1,142 +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.composite;
-
-import java.io.IOException;
-
-import com.carrotsearch.randomizedtesting.annotations.Repeat;
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.context.SpatialContextFactory;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.impl.RectangleImpl;
-import org.apache.lucene.spatial.prefix.RandomSpatialOpStrategyTestCase;
-import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
-import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
-import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.spatial.query.SpatialOperation;
-import org.apache.lucene.spatial.serialized.SerializedDVStrategy;
-import org.junit.Test;
-
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomBoolean;
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomDouble;
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween;
-
-public class CompositeStrategyTest extends RandomSpatialOpStrategyTestCase {
-
-  private SpatialPrefixTree grid;
-  private RecursivePrefixTreeStrategy rptStrategy;
-
-  private void setupQuadGrid(int maxLevels) {
-    //non-geospatial makes this test a little easier (in gridSnap), and using boundary values 2^X raises
-    // the prospect of edge conditions we want to test, plus makes for simpler numbers (no decimals).
-    SpatialContextFactory factory = new SpatialContextFactory();
-    factory.geo = false;
-    factory.worldBounds = new RectangleImpl(0, 256, -128, 128, null);
-    this.ctx = factory.newSpatialContext();
-    //A fairly shallow grid
-    if (maxLevels == -1)
-      maxLevels = randomIntBetween(1, 8);//max 64k cells (4^8), also 256*256
-    this.grid = new QuadPrefixTree(ctx, maxLevels);
-    this.rptStrategy = newRPT();
-  }
-
-  private void setupGeohashGrid(int maxLevels) {
-    this.ctx = SpatialContext.GEO;
-    //A fairly shallow grid
-    if (maxLevels == -1)
-      maxLevels = randomIntBetween(1, 3);//max 16k cells (32^3)
-    this.grid = new GeohashPrefixTree(ctx, maxLevels);
-    this.rptStrategy = newRPT();
-  }
-
-  protected RecursivePrefixTreeStrategy newRPT() {
-    final RecursivePrefixTreeStrategy rpt = new RecursivePrefixTreeStrategy(this.grid,
-        getClass().getSimpleName() + "_rpt");
-    rpt.setDistErrPct(0.10);//not too many cells
-    return rpt;
-  }
-
-  @Test
-  @Repeat(iterations = 20)
-  public void testOperations() throws IOException {
-    //setup
-    if (randomBoolean()) {
-      setupQuadGrid(-1);
-    } else {
-      setupGeohashGrid(-1);
-    }
-    SerializedDVStrategy serializedDVStrategy = new SerializedDVStrategy(ctx, getClass().getSimpleName() + "_sdv");
-    this.strategy = new CompositeSpatialStrategy("composite_" + getClass().getSimpleName(),
-        rptStrategy, serializedDVStrategy);
-
-    //Do it!
-
-    for (SpatialOperation pred : SpatialOperation.values()) {
-      if (pred == SpatialOperation.BBoxIntersects || pred == SpatialOperation.BBoxWithin) {
-        continue;
-      }
-      if (pred == SpatialOperation.IsDisjointTo) {//TODO
-        continue;
-      }
-      testOperationRandomShapes(pred);
-      deleteAll();
-      commit();
-    }
-  }
-
-  @Override
-  protected boolean needsDocValues() {
-    return true;//due to SerializedDVStrategy
-  }
-
-  @Override
-  protected Shape randomIndexedShape() {
-    return randomShape();
-  }
-
-  @Override
-  protected Shape randomQueryShape() {
-    return randomShape();
-  }
-
-  private Shape randomShape() {
-    return random().nextBoolean() ? randomCircle() : randomRectangle();
-  }
-
-  //TODO move up
-  private Shape randomCircle() {
-    final Point point = randomPoint();
-    //TODO pick using gaussian
-    double radius;
-    if (ctx.isGeo()) {
-      radius = randomDouble() * 100;
-    } else {
-      //find distance to closest edge
-      final Rectangle worldBounds = ctx.getWorldBounds();
-      double maxRad = point.getX() - worldBounds.getMinX();
-      maxRad = Math.min(maxRad, worldBounds.getMaxX() - point.getX());
-      maxRad = Math.min(maxRad, point.getY() - worldBounds.getMinY());
-      maxRad = Math.min(maxRad, worldBounds.getMaxY() - point.getY());
-      radius = randomDouble() * maxRad;
-    }
-
-    return ctx.makeCircle(point, radius);
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/CellToBytesRefIterator50.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/CellToBytesRefIterator50.java b/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/CellToBytesRefIterator50.java
deleted file mode 100644
index cccec8e..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/CellToBytesRefIterator50.java
+++ /dev/null
@@ -1,44 +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.prefix;
-
-import org.apache.lucene.spatial.prefix.tree.Cell;
-import org.apache.lucene.util.BytesRef;
-
-/** For testing Lucene <= 5.0. Index redundant prefixes for leaf cells. Fixed in LUCENE-4942. */
-class CellToBytesRefIterator50 extends CellToBytesRefIterator {
-
-  Cell repeatCell;
-
-  @Override
-  public BytesRef next() {
-    if (repeatCell != null) {
-      bytesRef = repeatCell.getTokenBytesWithLeaf(bytesRef);
-      repeatCell = null;
-      return bytesRef;
-    }
-    if (!cellIter.hasNext()) {
-      return null;
-    }
-    Cell cell = cellIter.next();
-    bytesRef = cell.getTokenBytesNoLeaf(bytesRef);
-    if (cell.isLeaf()) {
-      repeatCell = cell;
-    }
-    return bytesRef;
-  }
-}


[34/50] [abbrv] lucene-solr git commit: SOLR-445: have to dedup remote DBQ errors because it's a broadcast to all leaders.

Posted by ho...@apache.org.
SOLR-445: have to dedup remote DBQ errors because it's a broadcast to all leaders.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/cffca39c
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/cffca39c
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/cffca39c

Branch: refs/heads/jira/SOLR-445
Commit: cffca39cb8c84c24065b724d46806bf800834431
Parents: 7fd9d2e
Author: Chris Hostetter <ho...@apache.org>
Authored: Mon Feb 29 16:10:11 2016 -0700
Committer: Chris Hostetter <ho...@apache.org>
Committed: Mon Feb 29 16:10:11 2016 -0700

----------------------------------------------------------------------
 .../processor/TolerantUpdateProcessor.java      | 59 +++++++++++++++++---
 1 file changed, 52 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cffca39c/solr/core/src/java/org/apache/solr/update/processor/TolerantUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/update/processor/TolerantUpdateProcessor.java b/solr/core/src/java/org/apache/solr/update/processor/TolerantUpdateProcessor.java
index 68be135..a325420 100644
--- a/solr/core/src/java/org/apache/solr/update/processor/TolerantUpdateProcessor.java
+++ b/solr/core/src/java/org/apache/solr/update/processor/TolerantUpdateProcessor.java
@@ -18,8 +18,10 @@ package org.apache.solr.update.processor;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
+import java.util.Set;
 
 
 import org.apache.lucene.util.BytesRef;
@@ -94,6 +96,27 @@ public class TolerantUpdateProcessor extends UpdateRequestProcessor {
    */
   private final List<KnownErr> knownErrors = new ArrayList<KnownErr>();
 
+  // Kludge: Because deleteByQuery updates are forwarded to every leader, we can get identical
+  // errors reported by every leader for the same underlying problem.
+  //
+  // It would be nice if we could cleanly handle the unlikely (but possible) situation of an
+  // update stream that includes multiple identical DBQs, with identical failures, and 
+  // to report each one once, for example...
+  //   add: id#1
+  //   dbq: foo:bar
+  //   add: id#2
+  //   add: id#3
+  //   dbq: foo:bar
+  //
+  // ...but i can't figure out a way to accurately identify & return duplicate 
+  // KnownErrs from duplicate identical underlying requests w/o erroneously returning identical 
+  // KnownErrs for the *same* underlying request but from diff shards.
+  //
+  // So as a kludge, we keep track of them for deduping against identical remote failures
+  //
+  // :nocommit: probably need to use this for "commit" as well?
+  private Set<KnownErr> knownDBQErrors = new HashSet<>();
+        
   private final FirstErrTracker firstErrTracker = new FirstErrTracker();
   private final DistribPhase distribPhase;
 
@@ -162,9 +185,19 @@ public class TolerantUpdateProcessor extends UpdateRequestProcessor {
 
       // nocommit: do we need isLeader type logic like processAdd ? does processAdd even need it?
       
-      CmdType type = cmd.isDeleteById() ? CmdType.DELID : CmdType.DELQ;
-      String id = cmd.isDeleteById() ? cmd.id : cmd.query;
-      knownErrors.add(new KnownErr(type, id, t.getMessage()));
+      KnownErr err = new KnownErr(cmd.isDeleteById() ? CmdType.DELID : CmdType.DELQ,
+                                  cmd.isDeleteById() ? cmd.id : cmd.query,
+                                  t.getMessage());
+      knownErrors.add(err);
+
+      // NOTE: we're not using this to dedup before adding to knownErrors.
+      // if we're lucky enough to get an immediate local failure (ie: we're a leader, or some other processor
+      // failed) then recording the multiple failures is a good thing -- helps us with an accurate fail
+      // fast if we exceed maxErrors
+      if (CmdType.DELQ.equals(err.type)) {
+        knownDBQErrors.add(err);
+      }
+      
       if (knownErrors.size() > maxErrors) {
         firstErrTracker.throwFirst();
       }
@@ -187,6 +220,7 @@ public class TolerantUpdateProcessor extends UpdateRequestProcessor {
     } catch (DistributedUpdateProcessor.DistributedUpdatesAsyncException duae) {
       firstErrTracker.caught(duae);
 
+      
       // adjust out stats based on the distributed errors
       for (Error error : duae.errors) {
         // we can't trust the req info from the Error, because multiple original requests might have been
@@ -205,14 +239,25 @@ public class TolerantUpdateProcessor extends UpdateRequestProcessor {
           log.warn("remote error has no metadata to aggregate: " + remoteErr.getMessage(), remoteErr);
           continue;
         }
-        
+
         for (int i = 0; i < remoteErrMetadata.size(); i++) {
           KnownErr err = KnownErr.parseMetadataIfKnownErr(remoteErrMetadata.getName(i),
                                                           remoteErrMetadata.getVal(i));
-          if (null != err) {
-            knownErrors.add(err);
+          if (null == err) {
+            // some metadata unrelated to this update processor
+            continue;
+          }
+
+          if (CmdType.DELQ.equals(err.type)) {
+            if (knownDBQErrors.contains(err)) {
+              // we've already seen this identical error, probably a dup from another shard
+              continue;
+            } else {
+              knownDBQErrors.add(err);
+            }
           }
-          // else: some metadata unrelated to this update processor
+          
+          knownErrors.add(err);
         }
       }
     }


[39/50] [abbrv] lucene-solr git commit: SOLR-445: refactor duplicate test code

Posted by ho...@apache.org.
SOLR-445: refactor duplicate test code


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/ad34d3b8
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/ad34d3b8
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/ad34d3b8

Branch: refs/heads/jira/SOLR-445
Commit: ad34d3b861db1d9033675aad3212750dd7187ffe
Parents: 5fab8bc
Author: Chris Hostetter <ho...@apache.org>
Authored: Mon Feb 29 18:07:16 2016 -0700
Committer: Chris Hostetter <ho...@apache.org>
Committed: Mon Feb 29 18:07:16 2016 -0700

----------------------------------------------------------------------
 .../cloud/TestTolerantUpdateProcessorCloud.java | 28 +++-----------------
 1 file changed, 4 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ad34d3b8/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java b/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
index 016a897..410b142 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
@@ -665,34 +665,14 @@ public class TestTolerantUpdateProcessorCloud extends SolrCloudTestCase {
   }
   
   /** convinience method when the only type of errors you expect are 'add' errors */
-  // nocommit: refactor to be wrapper arround assertUpdateTolerantErrors
   public static void assertUpdateTolerantAddErrors(String assertionMsgPrefix,
                                                    UpdateResponse response,
                                                    String... errorIdsExpected) {
-    @SuppressWarnings("unchecked")
-    List<SimpleOrderedMap<String>> errors = (List<SimpleOrderedMap<String>>)
-      response.getResponseHeader().get("errors");
-    assertNotNull(assertionMsgPrefix + ": Null errors: " + response.toString(), errors);
-    assertEquals(assertionMsgPrefix + ": Num error ids: " + errors.toString(),
-                 errorIdsExpected.length, errors.size());
-
-    Set<String> addErrorIdsExpected = new HashSet<String>(Arrays.asList(errorIdsExpected));
-
-    for (SimpleOrderedMap<String> err : errors) {
-      String assertErrPre = assertionMsgPrefix + ": " + err.toString();
-      
-      assertEquals(assertErrPre + " ... nocommit: this err type not handled yet",
-                   "ADD", err.get("type"));
-      
-      String id = err.get("id");
-      assertNotNull(assertErrPre + " ... null id", id);
-      assertTrue(assertErrPre + " ... unexpected id", addErrorIdsExpected.contains(id));
-
+    ExpectedErr[] expected = new ExpectedErr[errorIdsExpected.length];
+    for (int i = 0; i < expected.length; i++) {
+      expected[i] = addErr(errorIdsExpected[i]);
     }
-
-    // nocommit: retire numErrors, we've already checked errors.size()
-    assertEquals(assertionMsgPrefix + ": numErrors: " + response.toString(),
-                 errorIdsExpected.length, response.getResponseHeader().get("numErrors"));
+    assertUpdateTolerantErrors(assertionMsgPrefix, response, expected);
   }
 
   /** 


[11/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test-files/data/geonames-IE.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test-files/data/geonames-IE.txt b/lucene/spatial/src/test-files/data/geonames-IE.txt
deleted file mode 100644
index baa7b74..0000000
--- a/lucene/spatial/src/test-files/data/geonames-IE.txt
+++ /dev/null
@@ -1,22929 +0,0 @@
-2652852	Cliff	Cliff		54.48333	-8.11667	S	EST	IE		U	06			0		76	Europe/Dublin	2010-08-14
-2654332	Bun Cranncha	Bun Cranncha	Buncrana	55.13333	-7.45	P	PPL	IE		U	06			5546		63	Europe/Dublin	2010-08-14
-2960863	Dromore West	Dromore West	Dromore,Dromore West	54.25167	-8.89306	P	PPL	IE	IE	C	25			0		32	Europe/Dublin	2010-08-14
-2960864	Dromore	Dromore	Dromore,Dromore House	52.93111	-8.96833	S	EST	IE	IE	M	03			0		36	Europe/Dublin	2010-08-14
-2960865	Youghal Harbour	Youghal Harbour		51.95194	-7.83972	H	HBR	IE		00	00			0		1	Europe/Dublin	2010-08-14
-2960866	Youghal Bay	Youghal Bay		52.89944	-8.30361	H	BAY	IE		M	26			0		55	Europe/Dublin	2010-08-14
-2960867	Youghal Bay	Youghal Bay		51.91	-7.81917	H	BAY	IE		00	00			0		-9999	Europe/Dublin	2010-08-14
-2960868	Youghal	Youghal		52.88861	-8.3075	P	PPL	IE		M	26			0		61	Europe/Dublin	2010-08-14
-2960869	Eochaill	Eochaill	Youghal	51.95	-7.85056	P	PPL	IE		M	04			6868		1	Europe/Dublin	2010-08-14
-2960870	Yellow River	Yellow River		54.13972	-8.02722	H	STM	IE		C	14			0		58	Europe/Dublin	2010-08-14
-2960871	Yellow River	Yellow River		54.05	-7.83333	H	STM	IE		C	14			0		76	Europe/Dublin	2010-08-14
-2960872	Yellow River	Yellow River		53.81667	-9	H	STM	IE		C	20			0		51	Europe/Dublin	2010-08-14
-2960873	Yellow River	Yellow River		53.38556	-7.08361	H	STM	IE		00	00			0		108	Europe/Dublin	2010-08-14
-2960874	Yellow Furze	Yellow Furze		53.67333	-6.57167	P	PPL	IE		L	21			0		86	Europe/Dublin	2010-08-14
-2960875	Woodville	Woodville		54.13333	-9.31667	P	PPL	IE		C	20			0		42	Europe/Dublin	2010-08-14
-2960876	Woodville	Woodville		53.85	-7.56667	S	BLDG	IE		L	18			0		71	Europe/Dublin	2010-08-14
-2960877	Wood View	Wood View		52.83333	-7.21667	S	EST	IE		L	13			0		135	Europe/Dublin	2010-08-14
-2960878	Woodtown House	Woodtown House	Woodtown,Woodtown House	53.58139	-6.98639	S	EST	IE	IE	L	21			0		92	Europe/Dublin	2010-08-14
-2960879	Woodstown	Woodstown		52.19667	-7.01	P	PPL	IE		M	27			0		75	Europe/Dublin	2010-08-14
-2960880	Woodstock House	Woodstock House	Woodstock,Woodstock House	52.47861	-7.05639	S	EST	IE	IE	L	13			0		32	Europe/Dublin	2010-08-14
-2960881	Woodsgift House	Woodsgift House	Woodsgift,Woodsgift House	52.70694	-7.515	S	EST	IE	IE	L	13			0		152	Europe/Dublin	2010-08-14
-2960882	Woodrooff House	Woodrooff House	Woodroof House,Woodrooff House	52.38222	-7.81944	S	EST	IE	IE	M	26			0		122	Europe/Dublin	2010-11-04
-2960883	Woodpark	Woodpark		53.44417	-6.48417	S	EST	IE		L	21			0		78	Europe/Dublin	2010-08-14
-2960884	Woodpark	Woodpark		52.92583	-8.45833	S	EST	IE		M	03			0		53	Europe/Dublin	2010-08-14
-2960885	Woodmount	Woodmount		53.33583	-8.16167	S	EST	IE		C	24			0		73	Europe/Dublin	2010-08-14
-2960886	Wood Lodge	Wood Lodge		54.03333	-7.16667	S	BLDG	IE		U	02			0		111	Europe/Dublin	2010-08-14
-2960887	Woodlawn Station	Woodlawn Station	Woodlawn,Woodlawn Station	53.35	-8.46667	S	RSTN	IE	IE	C	10			0		76	Europe/Dublin	2010-08-14
-2960888	Woodlawn	Woodlawn	Woodlawn,Woodlawn House	53.32889	-8.47889	S	EST	IE	IE	C	10			0		76	Europe/Dublin	2010-08-14
-2960889	Woodlands Station	Woodlands Station	Woodlands,Woodlands Station	51.55	-9.51667	S	RSTN	IE	IE	M	04			0		145	Europe/Dublin	2010-08-14
-2960890	Woodhouse	Woodhouse		52.12389	-7.475	S	EST	IE		M	27			0		1	Europe/Dublin	2010-08-14
-2960891	Wood Hill	Wood Hill		54.75944	-8.41833	S	EST	IE		U	06			0		32	Europe/Dublin	2010-08-14
-2960892	Woodfort	Woodfort	Woodfoot,Woodfort	53.88333	-6.83333	P	PPL	IE		L	21			0		111	Europe/Dublin	2010-08-10
-2960893	Woodfort	Woodfort		52.15944	-8.34139	S	EST	IE		M	04			0		40	Europe/Dublin	2010-08-14
-2960894	Woodford River	Woodford River	Rosmore,Woodford River	53.02028	-8.31639	H	STM	IE	IE	C	10			0		55	Europe/Dublin	2010-08-14
-2960895	Woodford	Woodford	An Chraig,An Chráig,An Ghraig,An Ghráig,Woodford	53.04833	-8.40028	P	PPL	IE		C	10			0		76	Europe/Dublin	2010-08-14
-2960896	Woodford	Woodford		52.05	-9.45	P	PPL	IE		M	11			0		92	Europe/Dublin	1993-12-27
-2960897	Woodfield House	Woodfield House		53.86667	-8.88333	S	EST	IE		C	20			0		70	Europe/Dublin	1993-12-27
-2960898	Woodfield House	Woodfield House		53.37028	-7.62167	S	EST	IE		L	23			0		74	Europe/Dublin	2010-08-14
-2960899	Woodfield House	Woodfield House		53.11667	-7.9	S	EST	IE		L	23			0		70	Europe/Dublin	2010-08-14
-2960900	Woodenbridge Junction Station	Woodenbridge Junction Station	Woodenbridge,Woodenbridge Junction,Woodenbridge Junction Station	52.83333	-6.23333	S	RSTN	IE	IE	L	31			0		40	Europe/Dublin	2010-08-14
-2960901	Woodenbridge	Woodenbridge		52.83222	-6.23639	P	PPL	IE		L	31			0		43	Europe/Dublin	2010-08-14
-2960902	Woodbrook House	Woodbrook House	Woodbrook,Woodbrook House	53.12944	-7.23583	S	HSEC	IE	IE	L	15			0		101	Europe/Dublin	2010-08-14
-2960903	Woodbrook	Woodbrook		52.54806	-6.73861	S	EST	IE		L	30			0		131	Europe/Dublin	2010-08-14
-2960904	Woodbrook	Woodbrook		51.71667	-9.13333	S	EST	IE		M	04			0		89	Europe/Dublin	1993-12-27
-2960905	Woodbine Hill	Woodbine Hill		51.95472	-7.82944	S	EST	IE		M	04			0		1	Europe/Dublin	2010-08-14
-2960906	Wingfield House	Wingfield House		52.7725	-6.39194	S	EST	IE		L	30			0		154	Europe/Dublin	2010-08-14
-2960907	Windy Harbour	Windy Harbour		53.74083	-6.66472	P	PPL	IE		L	21			0		130	Europe/Dublin	2010-08-14
-2960908	Windy Gap	Windy Gap		52.03333	-9.93333	T	GAP	IE		M	11			0		269	Europe/Dublin	2010-08-14
-2960909	Windgap	Windgap	Bearna na Gaoithe,Bearra na Gaoithe,Windgap	52.46556	-7.39972	P	PPL	IE		L	13			0		152	Europe/Dublin	2010-08-14
-2960910	Windfield House	Windfield House		53.43333	-8.63333	S	EST	IE		C	10			0		76	Europe/Dublin	1993-12-27
-2960911	Wilton House	Wilton House	Wilton,Wilton House	52.72222	-7.54806	S	EST	IE	IE	L	13			0		137	Europe/Dublin	2010-08-14
-2960912	Wilton Castle	Wilton Castle	Wilton Castle,Wilton House	52.45917	-6.61639	S	EST	IE	IE	L	30			0		63	Europe/Dublin	2010-08-14
-2960913	Wilmount House	Wilmount House		52.58333	-6.71667	S	EST	IE		L	30			0		150	Europe/Dublin	2010-08-14
-2960914	Wilmount House	Wilmount House		52.41667	-6.45611	S	EST	IE		L	30			0		24	Europe/Dublin	2010-08-14
-2960915	Wilmount	Wilmount		53.74833	-6.89528	S	EST	IE		L	21			0		71	Europe/Dublin	2010-08-14
-2960916	Wills Grove	Wills Grove		53.73333	-8.41667	S	RUIN	IE		C	24			0		76	Europe/Dublin	1993-12-27
-2960917	Willsbrook House	Willsbrook House		53.73333	-8.48333	S	BLDG	IE		C	24			0		74	Europe/Dublin	1993-12-27
-2960918	Willmount House	Willmount House		53.11611	-6.55833	S	HSEC	IE		L	31			0		198	Europe/Dublin	2010-08-14
-2960919	Willmount	Willmount		53.26667	-8.76667	S	EST	IE		C	10			0		30	Europe/Dublin	1993-12-27
-2960920	Willmount	Willmount		52.55472	-7.56556	S	EST	IE		M	26			0		150	Europe/Dublin	2010-08-14
-2960921	Williamstown Lodge	Williamstown Lodge		52.95	-8.33333	S	BLDG	IE		M	03			0		55	Europe/Dublin	2010-08-14
-2960922	Williamstown House	Williamstown House		53.88333	-6.41417	S	EST	IE		L	19			0		3	Europe/Dublin	2010-08-14
-2960923	Williamstown Harbour	Williamstown Harbour		52.95	-8.33333	H	HBR	IE		M	03			0		55	Europe/Dublin	2010-08-14
-2960924	Williamstown	Williamstown		53.68333	-8.58333	P	PPL	IE		C	10			0		76	Europe/Dublin	1993-12-27
-2960925	Williamstown	Williamstown		53.75222	-6.87333	S	EST	IE		L	21			0		70	Europe/Dublin	2010-08-14
-2960926	Willbrook	Willbrook		53.29361	-6.31194	P	PPL	IE		L	07			0		76	Europe/Dublin	2010-08-14
-2960927	Willbrook	Willbrook		52.93778	-9.12806	P	PPL	IE		M	03			0		95	Europe/Dublin	2010-08-14
-2960928	Wilkinstown	Wilkinstown		53.73556	-6.71306	P	PPL	IE		L	21			0		73	Europe/Dublin	2010-08-14
-2960929	Wilford House	Wilford House		52.55722	-7.55889	S	EST	IE		M	26			0		150	Europe/Dublin	2010-08-14
-2960930	Wild Bellows Rock	Wild Bellows Rock		53.34417	-10.05056	T	RK	IE		C	10			0		-9999	Europe/Dublin	1999-03-04
-2960931	Wicklow Mountains	Wicklow Mountains	Wicklow Hills,Wicklow Mountains	53.08333	-6.33333	T	MTS	IE		L	31			0		439	Europe/Dublin	2010-08-10
-2960932	Wicklow Head	Wicklow Head		52.96056	-5.99889	T	CAPE	IE		L	31			0		-9999	Europe/Dublin	2010-08-14
-2960933	Wicklow Gap	Wicklow Gap		53.04056	-6.40194	T	GAP	IE		L	31			0		528	Europe/Dublin	2010-08-14
-2960934	Wicklow Gap	Wicklow Gap		52.75667	-6.35944	T	GAP	IE		L	30			0		160	Europe/Dublin	2010-08-14
-2960935	Cill Mhantáin	Cill Mhantain	Contae Chill Mhantain,Contae Chill Mhantáin,County Wicklow,Wicklow	53	-6.41667	A	ADM2	IE		L	31			119873		371	Europe/Dublin	2010-08-14
-2960936	Cill Mhantáin	Cill Mhantain	Cill Maintain,Cill Maintainn,Cill Maintáinn,Cill Manntein,Cill Manntéin,Cill Mantan,Cill Mhanntain,Wicklow	52.975	-6.04944	P	PPLA2	IE		L	31			10461		69	Europe/Dublin	2010-08-14
-2960937	Whiting Bay	Whiting Bay		51.94694	-7.78139	H	BAY	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
-2960938	Whitfield Court	Whitfield Court	Whitfield,Whitfield Court	52.22278	-7.21722	S	EST	IE	IE	M	27			0		54	Europe/Dublin	2010-08-14
-2960939	Whitewood House	Whitewood House	Whitewood,Whitewood House	53.84139	-6.78333	S	EST	IE	IE	L	21			0		72	Europe/Dublin	2010-08-14
-2960940	Whitewell House	Whitewell House		53.43333	-7.31667	S	EST	IE		L	29			0		130	Europe/Dublin	1993-12-27
-2960941	Whites Town	Whites Town		53.99778	-6.12778	P	PPL	IE		L	19			0		1	Europe/Dublin	2010-08-14
-2960942	White River	White River		53.85972	-6.38694	H	STM	IE		L	19			0		8	Europe/Dublin	2010-08-14
-2960943	White River	White River		52.59556	-9.19361	H	STM	IE		M	16			0		15	Europe/Dublin	2010-08-14
-2960944	White Point	White Point		51.85	-8.31667	T	PT	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
-2960945	White Mountain	White Mountain		52.48333	-6.83333	T	MT	IE		L	30			0		215	Europe/Dublin	2010-08-14
-2960946	White Lough	White Lough		53.70194	-7.22	H	LK	IE		00				0		151	Europe/Dublin	1999-03-22
-2960947	Whitehill House	Whitehill House		53.73333	-7.63333	S	EST	IE		L	18			0		76	Europe/Dublin	1993-12-27
-2960948	Whitehall	Whitehall		53.75	-7.93333	P	PPL	IE		C	24			0		66	Europe/Dublin	1993-12-27
-2960949	Paulstown	Paulstown	Baile Phoil,Baile Phóil,Paulstown,Whitehall	52.68111	-7.02222	P	PPL	IE		L	13			0		55	Europe/Dublin	2010-08-14
-2960950	Whitegate	Whitegate		53.73333	-7.31667	P	PPL	IE		L	29			0		211	Europe/Dublin	1993-12-27
-2960951	Whitegate	Whitegate	An Geata Ban,An Geata Bán,Whitegate	52.94917	-8.37139	P	PPL	IE		M	03			0		56	Europe/Dublin	2010-08-14
-2960952	Whitegate	Whitegate	An Geata Ban,An Geata Bán,Whitegate	51.83056	-8.22972	P	PPL	IE		M	04			0		1	Europe/Dublin	2010-08-14
-2960953	Whitechurch	Whitechurch		52.37139	-7.39306	P	PPL	IE		L	13			0		32	Europe/Dublin	2010-08-14
-2960954	Whitechurch	Whitechurch		52.31778	-6.96611	P	PPL	IE		L	30			0		46	Europe/Dublin	2010-08-14
-2960955	Whitechurch	Whitechurch		52.10944	-7.74944	P	PPL	IE		M	27			0		62	Europe/Dublin	2010-08-14
-2960956	Whitechurch	Whitechurch		51.98139	-8.51389	P	PPL	IE		M	04			0		152	Europe/Dublin	2010-08-14
-2960957	White Castle	White Castle		55.13333	-7.16667	P	PPL	IE		U	06			0		-9999	Europe/Dublin	1993-12-27
-2960958	White Ball Head	White Ball Head		51.59667	-10.055	T	CAPE	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
-2960959	Whiddy Island	Whiddy Island	Whiddy Island	51.70139	-9.49972	T	ISL	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
-2960960	Wheelam Cross Roads	Wheelam Cross Roads		53.20278	-6.87083	P	PPL	IE		L	12			0		157	Europe/Dublin	2010-08-14
-2960961	Whale Head	Whale Head		55.0525	-7.57389	T	CAPE	IE		U	06			0		1	Europe/Dublin	2010-08-14
-2960962	Wexford Harbour	Wexford Harbour	Wexford Harbour	52.33833	-6.40417	H	HBR	IE		L	30			0		-9999	Europe/Dublin	2010-08-14
-2960963	Loch Garman	Loch Garman	Contae Loch Garman,County Wexford,Wexford	52.5	-6.66667	A	ADM2	IE		L	30			121122		76	Europe/Dublin	2010-08-14
-2960964	Loch Garman	Loch Garman	Loch Garman,Wexford	52.33417	-6.4575	P	PPLA2	IE		L	30			17708		-9999	Europe/Dublin	2010-08-14
-2960965	West Village	West Village		51.88333	-8.6	P	PPL	IE		M	04			0		66	Europe/Dublin	2010-08-14
-2960966	West Town	West Town	Baile Thiar,West Town	55.26528	-8.22583	P	PPL	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
-2960967	West Sister	West Sister	Beenhenry,West Sister	52.2	-10.43333	T	HLL	IE	IE	M	11			0		61	Europe/Dublin	2010-08-14
-2960968	Westport House	Westport House		53.8	-9.51667	S	EST	IE		C	20			0		108	Europe/Dublin	1993-12-27
-2960969	Westport Bay	Westport Bay		53.8	-9.63333	H	BAY	IE		C	20			0		-9999	Europe/Dublin	1993-12-27
-2960970	Cathair na Mart	Cathair na Mart	Westport	53.8	-9.51667	P	PPL	IE		C	20			6200		108	Europe/Dublin	2010-08-14
-2960971	Westmoreland Fort	Westmoreland Fort	Fort Westmoreland,Westmoreland Fort	51.83333	-8.28333	S	FT	IE	IE	M	04			0		-9999	Europe/Dublin	2010-08-14
-2960972	An Iarmhí	An Iarmhi	Contae na hIarmhi,Contae na hIarmhí,County Westmeath,Westmeath	53.5	-7.5	A	ADM2	IE		L	29			75298		144	Europe/Dublin	2010-08-14
-2960973	Westland Row Station	Westland Row Station	Westland Row Passenger Station	53.35	-6.25	S	RSTN	IE	IE	L	07			0		1	Europe/Dublin	2010-08-14
-2960974	Westland House	Westland House		53.785	-6.89694	S	EST	IE		L	21			0		79	Europe/Dublin	2010-08-14
-2960975	Westfield	Westfield		51.55	-9.38333	S	EST	IE		M	04			0		92	Europe/Dublin	1993-12-27
-2960976	West Cove	West Cove		51.77917	-10.07694	P	PPL	IE		M	11			0		134	Europe/Dublin	2010-08-14
-2960977	West Court	West Court		52.54917	-7.39389	S	EST	IE		L	13			0		71	Europe/Dublin	2010-08-14
-2960978	Wells House	Wells House	Wells,Wells House	52.52833	-6.34444	S	EST	IE	IE	L	30			0		58	Europe/Dublin	2010-08-14
-2960979	Wellmount House	Wellmount House		53.10472	-8.22778	S	BLDG	IE		C	10			0		77	Europe/Dublin	2010-08-14
-2960980	Wellingtonbridge	Wellingtonbridge	Wellingtonbridge	52.26333	-6.77833	P	PPL	IE		L	30			0		5	Europe/Dublin	2010-08-14
-2960981	Welchtown	Welchtown		54.81861	-7.87083	P	PPL	IE		U	06			0		84	Europe/Dublin	2010-08-14
-2960982	Webbsborough	Webbsborough	Webbsborough,Webbsborough House	52.75083	-7.23111	S	BLDG	IE	IE	L	13			0		128	Europe/Dublin	2010-08-14
-2960983	Weatherstown	Weatherstown		52.37361	-7.03944	P	PPL	IE		L	13			0		108	Europe/Dublin	2010-08-14
-2960984	Waterville	Waterville	An Coirean,An Coireán,Waterville	51.83333	-10.16667	P	PPL	IE		M	11			0		14	Europe/Dublin	2010-08-14
-2960985	Waterstown House	Waterstown House	Waterstown,Waterstown House	53.46667	-7.85	S	EST	IE		L	29			0		136	Europe/Dublin	2010-08-10
-2960986	Waterloo	Waterloo		53.93333	-7.13028	P	PPL	IE		U	02			0		171	Europe/Dublin	2010-08-14
-2960987	Watergrasshill	Watergrasshill	Cnocan na Biolrai,Cnocán na Biolraí,Watergrasshill	52.01139	-8.34417	P	PPL	IE		M	04			0		156	Europe/Dublin	2010-08-14
-2960988	Waterford North Station	Waterford North Station	Waterford,Waterford North Station	52.26667	-7.11667	S	RSTN	IE	IE	L	13			0		58	Europe/Dublin	2010-08-14
-2960989	Waterford Manor Station	Waterford Manor Station	Manor Station,Waterford Manor Station	52.25	-7.11667	S	RSTN	IE	IE	M	27			0		17	Europe/Dublin	2010-08-14
-2960990	Waterford Harbour	Waterford Harbour		52.17917	-6.93056	H	ESTY	IE		00				0		-9999	Europe/Dublin	1998-01-09
-2960991	Port Láirge	Port Lairge	Contae Phort Lairge,Contae Phort Láirge,County Waterford,Waterford	52.25	-7.5	A	ADM2	IE		M	27			104132		178	Europe/Dublin	2010-08-14
-2960992	Port Láirge	Port Lairge	Port Lairge,Port Láirge,Uoterford,Waterford,Waterford city,u~otafodo,Уотерфорд,ウォーターフォード	52.25833	-7.11194	P	PPLA2	IE		M	27			47904		8	Europe/Dublin	2010-08-14
-2960993	Waterfall	Waterfall		51.85944	-8.55917	P	PPL	IE		M	04			0		77	Europe/Dublin	2010-08-14
-2960994	Waterdale	Waterdale	Waterdale,Waterdale House	53.36667	-8.95	S	BLDG	IE		C	10			0		21	Europe/Dublin	2010-08-10
-2960995	Watch House Village	Watch House Village	Watch House,Watch House Village	52.69083	-6.63972	P	PPL	IE	IE	L	30			0		76	Europe/Dublin	2010-08-14
-2960996	Warrenstown House	Warrenstown House		53.51667	-6.61667	S	EST	IE		L	21			0		92	Europe/Dublin	1993-12-27
-2960997	Warrens Grove	Warrens Grove		51.85	-8.83333	S	EST	IE		M	04			0		79	Europe/Dublin	2010-08-14
-2960998	Warrens Court	Warrens Court		51.85472	-8.91278	S	EST	IE		M	04			0		146	Europe/Dublin	2010-08-14
-2960999	War Hill	War Hill		53.13778	-6.25389	T	MT	IE		L	31			0	685	439	Europe/Dublin	2010-08-14
-2961000	Hill of Ward	Hill of Ward	Hill of Ward	53.62444	-6.88611	T	HLL	IE		L	21			0		79	Europe/Dublin	2010-08-14
-2961001	Ward	Ward		53.43306	-6.33333	P	PPL	IE		L	07			0		66	Europe/Dublin	2010-08-14
-2961002	Walterstown	Walterstown		53.61278	-6.55306	P	PPL	IE		L	21			0		79	Europe/Dublin	2010-08-14
-2961003	Walshtown	Walshtown		51.98306	-8.18722	P	PPL	IE		M	04			0		130	Europe/Dublin	2010-08-14
-2961004	Walshpool Lough	Walshpool Lough		53.8	-9.18333	H	LK	IE		C	20			0		65	Europe/Dublin	1993-12-27
-2961005	Virginia Road	Virginia Road	Virginia Road,Virginia Road Station	53.75	-7.01667	S	RSTN	IE		L	21			0		160	Europe/Dublin	2010-08-10
-2961006	Virginia	Virginia	Achadh an Iuir,Achadh an Iúir,Virginia	53.83389	-7.07556	P	PPL	IE		U	02			0		120	Europe/Dublin	2010-08-14
-2961007	Violetstown House	Violetstown House		53.48333	-7.28333	S	EST	IE		L	29			0		124	Europe/Dublin	1993-12-27
-2961008	Violet Hill	Violet Hill		52.74444	-7.56083	S	EST	IE		L	13			0		142	Europe/Dublin	2010-08-14
-2961009	Vinegar Hill	Vinegar Hill		52.50417	-6.54611	T	HLL	IE		L	30			0		61	Europe/Dublin	2010-08-14
-2961010	Villierstown	Villierstown	An Baile Nua,Villierstown	52.08889	-7.85306	P	PPL	IE		M	27			0		75	Europe/Dublin	2010-08-14
-2961011	Vicarstown Cross Roads	Vicarstown Cross Roads	Vicarstown,Vicarstown Cross Roads	51.93333	-8.65	P	PPL	IE	IE	M	04			0		76	Europe/Dublin	2010-08-14
-2961012	Vicarstown	Vicarstown		53.04917	-7.08861	P	PPL	IE		L	15			0		71	Europe/Dublin	2010-08-14
-2961013	Ventry Harbour	Ventry Harbour		52.12278	-10.35583	H	HBR	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
-2961014	Ventry	Ventry	Ceann Tra,Ceann Trá,Ventry	52.1325	-10.36694	P	PPL	IE		M	11			0		1	Europe/Dublin	2010-08-14
-2961015	Velvetstown House	Velvetstown House		52.25	-8.66667	S	EST	IE		M	04			0		114	Europe/Dublin	1993-12-27
-2961016	Lough Vearty	Lough Vearty	Lough Vearty	54.53333	-8	H	LK	IE		00				0		177	Europe/Dublin	1998-02-19
-2961017	Lough Beagh	Lough Beagh	Lough Beagh,Lough Veagh	55.03833	-7.97167	H	LK	IE	IE	U	06			0		70	Europe/Dublin	2010-08-14
-2961018	Vartry River	Vartry River		53.00278	-6.05528	H	STM	IE		L	31			0		-9999	Europe/Dublin	2010-08-14
-2961019	Valencia River	Valencia River	Valencia River,Valentia River	51.93222	-10.27806	H	STM	IE	IE	M	11			0		-9999	Europe/Dublin	2010-08-14
-2961020	Valencia Island	Valencia Island	Valencia Island,Valentia Island	51.90833	-10.37194	T	ISL	IE	IE	M	11			0		28	Europe/Dublin	2010-08-14
-2961021	Valencia Harbour Station	Valencia Harbour Station	Valencia Harbour,Valencia Harbour Station,Valentia Harbour	51.91667	-10.28333	S	RSTN	IE	IE	M	11			0		-9999	Europe/Dublin	2010-08-14
-2961022	Valencia Harbour	Valencia Harbour	Valencia Harbour,Valentia Harbour	51.93	-10.30306	H	HBR	IE		M	11			0		35	Europe/Dublin	2010-08-14
-2961023	Urris Hills	Urris Hills		55.22389	-7.51889	T	MTS	IE		U	06			0		269	Europe/Dublin	2010-08-14
-2961024	Urrin River	Urrin River		52.49278	-6.56722	H	STM	IE		L	30			0		52	Europe/Dublin	2010-08-14
-2961025	Urlingford	Urlingford	Ath na nUrlainn,Urlingford,Áth na nUrlainn	52.72056	-7.5825	P	PPL	IE		L	13			0		143	Europe/Dublin	2010-08-14
-2961026	Urlaur Lough	Urlaur Lough		53.83333	-8.73333	H	LK	IE		C	20			0		54	Europe/Dublin	1993-12-27
-2961027	Uregare House	Uregare House	Uregare,Uregare House	52.45	-8.56667	S	EST	IE		M	16			0		75	Europe/Dublin	2010-08-10
-2961028	Urbalreagh	Urbalreagh		55.33639	-7.28528	P	PPL	IE		U	06			0		76	Europe/Dublin	2010-08-14
-2961029	Upton House	Upton House		51.79917	-8.68833	S	EST	IE		M	04			0		76	Europe/Dublin	2010-08-14
-2961030	Upton	Upton		51.79222	-8.67333	P	PPL	IE		M	04			0		76	Europe/Dublin	2010-08-14
-2961031	Upper Court	Upper Court		52.72611	-7.40667	S	EST	IE		L	13			0		128	Europe/Dublin	2010-08-14
-2961032	Upperchurch	Upperchurch	Upperchurch	52.70333	-8.0175	P	PPL	IE		M	26			0		289	Europe/Dublin	2010-11-04
-2961033	Unshin River	Unshin River		54.19139	-8.48167	H	STM	IE		C	25			0		59	Europe/Dublin	2010-08-14
-2961034	Lough Unshin	Lough Unshin		54.52028	-8.07917	H	LK	IE		U	06			0		403	Europe/Dublin	2010-08-14
-2961035	Unionhall	Unionhall	Breantra,Bréantrá,Unionhall	51.55	-9.13333	P	PPL	IE		M	04			0		28	Europe/Dublin	2010-08-14
-2961036	Umrycam	Umrycam		55.18333	-7.7	P	PPL	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
-2961037	Ummeryroe	Ummeryroe		54.11667	-8.28333	P	PPL	IE		C	25			0		142	Europe/Dublin	1993-12-27
-2961038	Umma House	Umma House		53.45	-7.7	S	EST	IE		L	29			0		76	Europe/Dublin	1993-12-27
-2961039	Umfin Island	Umfin Island		55.10194	-8.36583	T	ISL	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
-2961040	Ullard	Ullard		52.57972	-6.93083	P	PPL	IE		L	13			0		27	Europe/Dublin	2010-08-14
-2961041	Lough Ugga Beg	Lough Ugga Beg		53.27194	-9.4325	H	LK	IE		C	10			0		74	Europe/Dublin	2010-08-14
-2961042	Tyrrelstown House	Tyrrelstown House		53.4	-6.4	S	EST	IE		L	07			0		36	Europe/Dublin	2010-08-14
-2961043	Tyrrellspass	Tyrrellspass	Bealach an Tirialaigh,Tyrrellspass,Tyrrelspass	53.38889	-7.37361	P	PPL	IE		L	29			0		133	Europe/Dublin	2010-08-14
-2961044	Tyredagh Castle	Tyredagh Castle	Tyredach Castle,Tyredagh Castle	52.88472	-8.79861	S	RUIN	IE	IE	M	03			0		66	Europe/Dublin	2010-08-14
-2961045	Tyrcallen	Tyrcallen		54.82528	-7.74417	S	EST	IE		U	06			0		82	Europe/Dublin	2010-08-14
-2961046	Tynagh	Tynagh	Tine,Tynagh,Tíne	53.14944	-8.3725	P	PPL	IE	IE	C	10			0		75	Europe/Dublin	2010-08-14
-2961047	Tyholland Bridge	Tyholland Bridge	Tyholland,Tyholland Bridge	54.25	-6.9	P	PPL	IE	IE	00				0		65	Europe/Dublin	2010-08-10
-2961048	Two Rock Mountain	Two Rock Mountain		53.23472	-6.24167	T	MT	IE		L	07			0	517	453	Europe/Dublin	2010-08-14
-2961049	Twomileditch	Twomileditch		53.30389	-8.99778	P	PPL	IE		C	10			0		3	Europe/Dublin	2010-08-14
-2961050	Twomileborris	Twomileborris		52.67167	-7.72	P	PPL	IE		M	26			0		124	Europe/Dublin	2010-08-14
-2961051	The Twelve Pins	The Twelve Pins	Beanna Beola,Benna Beola,The Twelve Bens,The Twelve Pins,Twelve Pins of Bennebeola	53.5	-9.83333	T	MTS	IE	IE	C	10			0		402	Europe/Dublin	2010-08-14
-2961052	Tuskar Rock	Tuskar Rock	Tuskar Rock	52.19889	-6.19833	T	RK	IE		L	30			0		-9999	Europe/Dublin	2010-08-14
-2961053	Turvey House	Turvey House		53.49667	-6.17556	S	EST	IE		L	07			0		1	Europe/Dublin	2010-08-14
-2961054	Turners Rock	Turners Rock		51.79222	-9.58111	T	MT	IE		M	04			0		233	Europe/Dublin	2010-08-14
-2961055	Turloughmore	Turloughmore		53.37472	-8.86472	P	PPL	IE		C	10			0		27	Europe/Dublin	2010-08-14
-2961056	Turlough	Turlough	Turlach,Turlough	53.88333	-9.21667	P	PPL	IE	IE	C	20			0		38	Europe/Dublin	2010-08-14
-2961057	Turlough	Turlough		53.09222	-9.06528	P	PPL	IE		M	03			0		68	Europe/Dublin	2010-08-14
-2961058	Turkstown	Turkstown		52.32333	-7.30389	P	PPL	IE		L	13			0		13	Europe/Dublin	2010-08-14
-2961059	Turbotston	Turbotston	Turbotston,Turbotstown,Turbotstown House	53.7	-7.35	S	EST	IE	IE	L	29			0		79	Europe/Dublin	2010-08-14
-2961060	Turbot Island	Turbot Island	Talbot Island,Turbot Island	53.50194	-10.14806	T	ISL	IE	IE	C	10			0		-9999	Europe/Dublin	2010-08-14
-2961061	Tulsk	Tulsk	Tuilsce,Tulsk	53.78333	-8.25	P	PPL	IE	IE	C	24			0		75	Europe/Dublin	2010-08-14
-2961062	Tullyvin House	Tullyvin House	Tullyvin,Tullyvin House	54.05	-7.15	S	HSEC	IE	IE	U	02			0		76	Europe/Dublin	2010-08-14
-2961063	Tullyvin	Tullyvin		54.04833	-7.14472	P	PPL	IE		U	02			0		76	Europe/Dublin	2010-08-14
-2961064	Tullynascreen	Tullynascreen		54.17472	-8.28167	P	PPL	IE		C	14			0		174	Europe/Dublin	2010-08-14
-2961065	Tullynahinnera	Tullynahinnera	Tullynahinera,Tullynahinnera	54.08333	-6.8	P	PPL	IE	IE	00				0		152	Europe/Dublin	2010-08-10
-2961066	Tullymurray	Tullymurray		54.13333	-8.1	P	PPL	IE		C	14			0		58	Europe/Dublin	1993-12-27
-2961067	Tullymore	Tullymore	Tullamore,Tullymore	54.52111	-8.17806	P	PPL	IE	IE	U	06			0		67	Europe/Dublin	2010-08-14
-2961068	Tully Lough	Tully Lough	Tally Lough,Tully Lough	53.58972	-9.97972	H	LK	IE		C	10			0		15	Europe/Dublin	2010-08-14
-2961069	Tullylease	Tullylease		52.3	-8.95	P	PPL	IE		M	04			0		155	Europe/Dublin	1993-12-27
-2961070	Tullyleague	Tullyleague		52.53611	-9.30028	P	PPL	IE		M	16			0		148	Europe/Dublin	2010-08-14
-2961071	Tullyglass House	Tullyglass House	Tullyglass,Tullyglass House	51.76	-8.86361	S	BLDG	IE	IE	M	04			0		110	Europe/Dublin	2010-08-14
-2961072	Tullycreen Upper	Tullycreen Upper	Tullycreen,Tullycreen Upper,Tullycrine	52.68389	-9.35583	P	PPL	IE	IE	M	03			0		27	Europe/Dublin	2010-08-14
-2961073	Tullycreen Lower	Tullycreen Lower		52.66833	-9.32722	P	PPL	IE		M	03			0		24	Europe/Dublin	2010-08-14
-2961074	Tullycanna	Tullycanna		52.2675	-6.66861	P	PPL	IE		L	30			0		35	Europe/Dublin	2010-08-14
-2961075	Tullybrook	Tullybrook		54.63194	-8.07889	P	PPL	IE		U	06			0		53	Europe/Dublin	2010-08-14
-2961076	Tullyard	Tullyard		53.58194	-6.79333	S	EST	IE		L	21			0		77	Europe/Dublin	2010-08-14
-2961077	Tullyallen	Tullyallen	Tullyallen	53.73611	-6.42278	P	PPL	IE		L	19			0		60	Europe/Dublin	2010-08-14
-2961078	Tully	Tully		53.23333	-9.48333	P	PPL	IE		C	10			0		-9999	Europe/Dublin	1993-12-27
-2961079	Tullow	Tullow	An Tulach,Tullow	52.80028	-6.73694	P	PPL	IE		L	01			2424		86	Europe/Dublin	2010-08-14
-2961080	Tullira Castle	Tullira Castle		53.13611	-8.78444	S	HSEC	IE		C	10			0		33	Europe/Dublin	2010-08-14
-2961081	Tullig Point	Tullig Point		52.61417	-9.80417	T	PT	IE		M	03			0		2	Europe/Dublin	2010-08-14
-2961082	Tullig	Tullig		52.61472	-9.77611	P	PPL	IE		M	03			0		30	Europe/Dublin	2010-08-14
-2961083	Tullig	Tullig		52.11278	-9.85444	P	PPL	IE		M	11			0		8	Europe/Dublin	2010-08-14
-2961084	Tullaroan	Tullaroan	Tullaroan	52.66222	-7.43639	P	PPL	IE		L	13			0		152	Europe/Dublin	2010-08-14
-2961085	Tullamore River	Tullamore River	Clonmore,Tullamore River	53.27722	-7.5775	H	STM	IE	IE	L	23			0		71	Europe/Dublin	2010-08-14
-2961086	Tullamore	Tullamore	Tulach Mhor,Tulach Mhór	53.27389	-7.48889	P	PPLA2	IE		L	23			11575		73	Europe/Dublin	2010-08-14
-2961087	Tullamore	Tullamore		52.49167	-9.48778	P	PPL	IE		M	11			0		68	Europe/Dublin	2010-08-14
-2961088	Tullaher Lough	Tullaher Lough	Lough Trullaher,Tullaher Lough	52.69861	-9.54528	H	LK	IE	IE	M	03			0		1	Europe/Dublin	2010-08-14
-2961089	Tullagh Point	Tullagh Point		55.29472	-7.46722	T	PT	IE		U	06			0		2	Europe/Dublin	2010-08-14
-2961090	Tullaghought	Tullaghought		52.42194	-7.36167	P	PPL	IE		L	13			0		169	Europe/Dublin	2010-08-14
-2961091	Tullagher	Tullagher		52.43167	-7.04556	P	PPL	IE		L	13			0		134	Europe/Dublin	2010-08-14
-2961092	Tullagh Bay	Tullagh Bay		55.28639	-7.44361	H	BAY	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
-2961093	Tullaghanoge	Tullaghanoge		53.58889	-6.87222	P	PPL	IE		L	21			0		77	Europe/Dublin	2010-08-14
-2961094	Tullaghan Bay	Tullaghan Bay	Tallaghan Bay,Tullaghan Bay	54.09111	-9.86889	H	BAY	IE	IE	C	20			0		-9999	Europe/Dublin	2010-08-14
-2961095	Tullaghan	Tullaghan		54.46833	-8.33111	P	PPL	IE		C	14			0		1	Europe/Dublin	2010-08-14
-2961096	Tulla	Tulla	An Tulach,Tulla	52.86472	-8.76056	P	PPL	IE		M	03			0		152	Europe/Dublin	2010-08-14
-2961097	Tudenham Park	Tudenham Park		53.46667	-7.35	S	EST	IE		L	29			0		117	Europe/Dublin	1993-12-27
-2961098	Tubber	Tubber	Tobar,Tubber	52.99889	-8.88528	P	PPL	IE		C	10			0		47	Europe/Dublin	2010-08-14
-2961099	Tuam	Tuam	Tuaim,Tuam	53.51667	-8.85	P	PPL	IE		C	10			6130		48	Europe/Dublin	2010-08-14
-2961100	Truskmore	Truskmore		54.37639	-8.37222	T	MT	IE		00				0	646	591	Europe/Dublin	2006-01-16
-2961101	Trusk Lough	Trusk Lough		54.75722	-7.79917	H	LK	IE		U	06			0		161	Europe/Dublin	2010-08-14
-2961102	Trusklieve	Trusklieve		52.62778	-9.76444	P	PPL	IE		M	03			0		73	Europe/Dublin	2010-08-14
-2961103	Trubley Castle	Trubley Castle		53.56667	-6.71667	S	RUIN	IE		L	21			0		57	Europe/Dublin	1993-12-27
-2961104	Trough	Trough		52.73333	-8.61667	P	PPL	IE		M	03			0		79	Europe/Dublin	1993-12-27
-2961105	Triogue River	Triogue River	Tiogue River,Triogue River	53.11389	-7.28972	H	STM	IE	IE	L	15			0		107	Europe/Dublin	2010-08-14
-2961106	Trimoge River	Trimoge River		53.91667	-9.01667	H	STM	IE		C	20			0		30	Europe/Dublin	1993-12-27
-2961107	Baile Átha Troim	Baile Atha Troim	Baile Atha Troim,Baile Átha Troim,Trim	53.555	-6.79167	P	PPL	IE		L	21			1800		62	Europe/Dublin	2010-09-05
-2961108	The Triangle	The Triangle		53.76667	-9.4	P	PPLL	IE		C	20			0		137	Europe/Dublin	2010-08-14
-2961109	Tremone Bay	Tremone Bay		55.26667	-7.06667	H	BAY	IE		U	06			0		1	Europe/Dublin	1993-12-27
-2961110	Tremblestown River	Tremblestown River		53.55417	-6.83167	H	STM	IE		L	21			0		66	Europe/Dublin	2010-08-14
-2961111	Treantagh	Treantagh		54.92667	-7.4875	P	PPL	IE		U	06			0		52	Europe/Dublin	2010-08-14
-2961112	Trawmore Bay	Trawmore Bay		54.18361	-9.9575	H	BAY	IE		C	20			0		-9999	Europe/Dublin	2010-08-14
-2961113	Trawenagh Bay	Trawenagh Bay		54.89333	-8.35417	H	BAY	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
-2961114	Trawbreaga Bay	Trawbreaga Bay	Trawbreaga Bay,Trawbreaga Lough	55.285	-7.29472	H	BAY	IE	IE	U	06			0		-9999	Europe/Dublin	2010-08-14
-2961115	Traverston House	Traverston House		52.7975	-8.16444	S	EST	IE		M	26			0		118	Europe/Dublin	2010-08-14
-2961116	Tranarossan Bay	Tranarossan Bay	Tranarossan Bay,Tranrossan Bay	55.23056	-7.82444	H	BAY	IE	IE	U	06			0		-9999	Europe/Dublin	2010-08-14
-2961117	Tranagh	Tranagh		52.69472	-7.6025	P	PPL	IE		M	26			0		138	Europe/Dublin	2010-08-14
-2961118	Tramore Bay	Tramore Bay		55.18333	-8.03333	H	BAY	IE		U	06			0		-9999	Europe/Dublin	1993-12-27
-2961119	Tramore Bay	Tramore Bay		52.13917	-7.1325	H	BAY	IE		M	27			0		-9999	Europe/Dublin	2010-08-14
-2961120	Trá Mhór	Tra Mhor	Tramore	52.16235	-7.15244	P	PPL	IE		M	27			9164		2	Europe/Dublin	2010-08-14
-2961121	Tralong Bay	Tralong Bay		51.55694	-9.05861	H	BAY	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
-2961122	Tralee Bay	Tralee Bay	Tralee Bay	52.27833	-9.93139	H	BAY	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
-2961123	Trá Lí	Tra Li	Tra Li,Tralee,Trá Lí	52.27042	-9.70264	P	PPLA2	IE		M	11			22941	912	48	Europe/Dublin	2010-10-06
-2961124	Tracton	Tracton		51.76139	-8.41639	P	PPL	IE		M	04			0		76	Europe/Dublin	2010-08-14
-2961125	Tracarta	Tracarta		51.51583	-9.19389	P	PPL	IE		M	04			0		6	Europe/Dublin	2010-08-14
-2961126	Trabolgan House	Trabolgan House		51.79972	-8.23583	S	EST	IE		M	04			0		1	Europe/Dublin	2010-08-14
-2961127	Townley Hall	Townley Hall		53.72944	-6.44722	S	EST	IE		L	19			0		54	Europe/Dublin	2010-08-14
-2961128	Towerhill House	Towerhill House		53.71667	-9.2	S	EST	IE		C	20			0		46	Europe/Dublin	1993-12-27
-2961129	Tower	Tower	Tower,Tower Village	51.91667	-8.6	P	PPL	IE		M	04			3099		70	Europe/Dublin	2010-08-14
-2961130	Tourin	Tourin		52.11667	-7.86667	P	PPL	IE		M	27			0		17	Europe/Dublin	1993-12-27
-2961131	Tourig River	Tourig River		51.97778	-7.8625	H	STM	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
-2961132	Tory Sound	Tory Sound		55.21667	-8.2	H	SD	IE		U	06			0		-9999	Europe/Dublin	1993-12-27
-2961133	Toraigh	Toraigh	Toraigh,Tory Island	55.26444	-8.22111	T	ISL	IE		U	06			0		15	Europe/Dublin	2010-08-14
-2961134	The Tor Rocks	The Tor Rocks		55.43333	-7.25	T	RKS	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
-2961135	Torneady Point	Torneady Point	Tornado Point,Torneady Point	55.02167	-8.54028	T	PT	IE	IE	U	06			0		35	Europe/Dublin	2010-08-14
-2961136	Tormore Island	Tormore Island		54.76389	-8.69222	T	ISL	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
-2961137	Torc Mountain	Torc Mountain	Torc Mountain	52	-9.51667	T	MT	IE		M	11			0		189	Europe/Dublin	2010-08-10
-2961138	Torc Cascade	Torc Cascade	Torc Cascade,Tore Cascade	52	-9.5	H	FLLS	IE		M	11			0		378	Europe/Dublin	2010-08-10
-2961139	Toormore Bay	Toormore Bay		51.50194	-9.65583	H	BAY	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
-2961140	Toormore	Toormore		53.79278	-10.03417	L	LCTY	IE		C	20			0		111	Europe/Dublin	2010-08-14
-2961141	Toormore	Toormore		51.52083	-9.65611	P	PPL	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
-2961142	Toormakeady Lodge	Toormakeady Lodge	Toormakeady,Toormakeady Lodge	53.65	-9.38333	S	EST	IE		C	20			0		59	Europe/Dublin	2010-08-10
-2961143	Toormakeady	Toormakeady		53.65	-9.36667	P	PPL	IE		C	20			0		59	Europe/Dublin	1993-12-27
-2961144	Tooreeny	Tooreeny		53	-8.38333	P	PPL	IE		C	10			0		68	Europe/Dublin	2010-08-14
-2961145	Tooreens	Tooreens		51.84278	-10.02861	P	PPL	IE		M	11			0		421	Europe/Dublin	2010-08-14
-2961146	Tooreengarriv	Tooreengarriv		52.16667	-9.28333	P	PPL	IE		M	11			0		241	Europe/Dublin	1993-12-27
-2961147	Tooreendonnell	Tooreendonnell		52.495	-9.22694	P	PPL	IE		M	16			0		152	Europe/Dublin	2010-08-14
-2961148	Tooreencahill	Tooreencahill		52.15	-9.25	P	PPL	IE		M	11			0		181	Europe/Dublin	1993-12-27
-2961149	Tooreenbrien Bridge	Tooreenbrien Bridge	Tooreenbrien,Tooreenbrien Bridge	52.6925	-8.27361	P	PPL	IE	IE	M	26			0		288	Europe/Dublin	2010-11-04
-2961150	Tooreen	Tooreen		53.66667	-9.28333	P	PPL	IE		C	20			0		49	Europe/Dublin	1993-12-27
-2961151	Tooreen	Tooreen		51.55	-9.83333	P	PPL	IE		M	04			0		-9999	Europe/Dublin	1993-12-27
-2961152	Tooravoola	Tooravoola		53.05667	-8.64028	P	PPL	IE		C	10			0		146	Europe/Dublin	2010-08-14
-2961153	Tooraneena	Tooraneena		52.20222	-7.715	P	PPL	IE		M	27			0		152	Europe/Dublin	2010-08-14
-2961154	Toor	Toor		51.8	-10.16667	P	PPL	IE		M	11			0		39	Europe/Dublin	2010-08-14
-2961155	Toon River	Toon River		51.88333	-9.01667	H	STM	IE		M	04			0		104	Europe/Dublin	1993-12-27
-2961156	Toonagh House	Toonagh House		52.88778	-9.02833	S	EST	IE		M	03			0		50	Europe/Dublin	2010-08-14
-2961157	Toomyvara	Toomyvara	Toomyvara,Tuaim Ui Mheara,Tuaim Uí Mheára	52.84972	-8.03222	P	PPL	IE		M	38			0		157	Europe/Dublin	2010-11-04
-2961158	Toomona House	Toomona House		53.76667	-8.28333	S	EST	IE		C	24			0		78	Europe/Dublin	1993-12-27
-2961159	Toomard	Toomard		53.53333	-8.46667	P	PPL	IE		C	10			0		73	Europe/Dublin	1993-12-27
-2961160	Tooban Junction	Tooban Junction		55.05	-7.43333	S	RSTN	IE		U	06			0		55	Europe/Dublin	1993-12-27
-2961161	Tonlegee House	Tonlegee House	Tonlegee,Tonlegee House	52.9775	-6.98917	S	EST	IE	IE	L	15			0		59	Europe/Dublin	2010-08-14
-2961162	Tonduff	Tonduff		55.2	-7.51667	P	PPL	IE		U	06			0		62	Europe/Dublin	1993-12-27
-2961163	Tomies Mountain	Tomies Mountain		52.01667	-9.61667	T	MT	IE		M	11			0		432	Europe/Dublin	1993-12-27
-2961164	Tomhaggard	Tomhaggard		52.21194	-6.51778	P	PPL	IE		L	30			0		11	Europe/Dublin	2010-08-14
-2961165	Tuamgraney	Tuamgraney	Tomgraney,Tuaim Greine,Tuaim Gréine,Tuamgraney	52.89722	-8.53861	P	PPL	IE		M	03			0		75	Europe/Dublin	2010-08-14
-2961166	Tombrack	Tombrack		52.60278	-6.5475	P	PPL	IE		L	30			0		71	Europe/Dublin	2010-08-14
-2961167	Tomacurry	Tomacurry		52.55333	-6.56	P	PPL	IE		L	30			0		56	Europe/Dublin	2010-08-14
-2961168	Tolka River	Tolka River	An Tulca,Tolka River	53.34972	-6.23889	H	STM	IE	IE	00				0		1	Europe/Dublin	2010-08-10
-2961169	Toghermore	Toghermore		53.48333	-8.81667	S	EST	IE		C	10			0		43	Europe/Dublin	1993-12-27
-2961170	The Togher	The Togher		53.07972	-7.19972	P	PPL	IE		L	15			0		134	Europe/Dublin	2010-08-14
-2961171	Togher	Togher		53.84278	-6.30278	P	PPL	IE		L	19			0		21	Europe/Dublin	2010-08-14
-2961172	Togher	Togher		53.08167	-6.52	P	PPL	IE		L	31			0		280	Europe/Dublin	2010-08-14
-2961173	Roundwood	Roundwood	An Tochar,An Tóchar,Roundwood,Togher	53.05861	-6.22611	P	PPL	IE		L	31			0		258	Europe/Dublin	2010-08-14
-2961174	Togher	Togher		51.8775	-8.49167	P	PPL	IE		M	04			0		56	Europe/Dublin	2010-08-14
-2961175	Togher	Togher		51.78111	-9.15556	P	PPL	IE		M	04			0		145	Europe/Dublin	2010-08-14
-2961176	Toem	Toem		52.57667	-8.19611	P	PPL	IE		M	26			0		96	Europe/Dublin	2010-08-14
-2961177	Toe Head Bay	Toe Head Bay		51.49111	-9.25167	H	BAY	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
-2961178	Toe Head	Toe Head		51.48583	-9.23556	T	CAPE	IE		M	04			0		3	Europe/Dublin	2010-08-14
-2961179	Tobertynan House	Tobertynan House	Tobertynan,Tobertynan House	53.48528	-6.8575	S	EST	IE	IE	L	21			0		79	Europe/Dublin	2010-08-14
-2961180	Toberscanavan	Toberscanavan		54.16694	-8.48556	P	PPL	IE		C	25			0		66	Europe/Dublin	2010-08-14
-2961181	Toberdan	Toberdan		53.53333	-8.06667	P	PPL	IE		C	24			0		76	Europe/Dublin	1993-12-27
-2961182	Tobercurry	Tobercurry	Tobar an Choire,Tobercurry,Tubbercurry	54.05	-8.73333	P	PPL	IE		C	25			0		92	Europe/Dublin	2010-08-14
-2961183	Tober	Tober		54.21667	-8.00194	P	PPL	IE		U	02			0		158	Europe/Dublin	2010-08-14
-2961184	Tober	Tober		53.375	-7.65611	P	PPL	IE		L	23			0		73	Europe/Dublin	2010-08-14
-2961185	Tivoli House	Tivoli House		51.9	-8.43333	S	EST	IE		M	04			0		27	Europe/Dublin	2010-08-14
-2961186	Tirraboy	Tirraboy		55.25	-7.15	P	PPL	IE		U	06			0		25	Europe/Dublin	1993-12-27
-2961187	Tirneevin	Tirneevin		53.06417	-8.88306	P	PPL	IE		C	10			0		44	Europe/Dublin	2010-08-14
-2961188	Tiragarvan	Tiragarvan		53.98333	-6.76667	P	PPL	IE		00				0		99	Europe/Dublin	1993-12-27
-2961189	Tipperary South Riding	Tipperary South Riding	South Riding,Tipperary County South Riding	52.41667	-7.83333	A	ADM2	IE		00	40			80276		151	Europe/Dublin	2010-08-14
-2961190	Tipperary North Riding	Tipperary North Riding	North Riding,Tipperary County North Riding	52.75	-7.83333	A	ADM2	IE		00	38			61926		104	Europe/Dublin	2010-08-14
-2961191	County Tipperary	County Tipperary	Contae Thiobraid Arann,Contae Thiobraid Árann,County Tipperary,Tiobraid Arann,Tiobraid Árann,Tipperary	52.66667	-7.83333	A	ADMD	IE	IE	M	26			0		93	Europe/Dublin	2010-11-04
-2961192	Tiobraid Árann	Tiobraid Arann	Tipperary	52.47333	-8.15583	P	PPL	IE		M	26			4976		166	Europe/Dublin	2010-08-14
-2961193	Tintrim House	Tintrim House		52.96417	-8.34556	S	EST	IE		M	03			0		56	Europe/Dublin	2010-08-14
-2961194	Tintern Abbey	Tintern Abbey		52.23528	-6.83333	S	MSTY	IE		L	30			0		3	Europe/Dublin	2010-08-14
-2961195	Tinny Park	Tinny Park		53.68333	-8.38333	P	PPL	IE		C	24			0		76	Europe/Dublin	1993-12-27
-2961196	Tinnaslatty House	Tinnaslatty House		52.8	-7.41667	S	RUIN	IE		L	13			0		154	Europe/Dublin	2010-08-14
-2961197	Timnapark House	Timnapark House	Timnapark House,Tinnapark,Tinnapark House	53.1	-6.11667	S	HSEC	IE	IE	L	31			0		114	Europe/Dublin	2010-08-14
-2961198	Tinnahinch	Tinnahinch		52.53861	-6.94806	P	PPL	IE		L	01			0		28	Europe/Dublin	2010-08-14
-2961199	Tinnaglogh	Tinnaglogh		52.26806	-6.89722	P	PPL	IE		L	30			0		64	Europe/Dublin	2010-08-14
-2961200	Tinkerslane	Tinkerslane		53.505	-6.98111	P	PPL	IE		L	21			0		84	Europe/Dublin	2010-08-14
-2961201	Tincoora	Tincoora		52.1	-8.86667	P	PPL	IE		M	04			0		156	Europe/Dublin	1993-12-27
-2961202	Tinarana House	Tinarana House	Tinarana,Tinarana House	52.86444	-8.44917	S	EST	IE	IE	M	03			0		55	Europe/Dublin	2010-08-14
-2961203	Tinalira	Tinalira		52.18472	-7.72806	P	PPL	IE		M	27			0		133	Europe/Dublin	1997-12-15
-2961204	Tinahely	Tinahely	Tigh na hEille,Tigh na hÉille,Tinahely	52.79667	-6.46333	P	PPL	IE	IE	L	31			0		121	Europe/Dublin	2010-08-14
-2961205	Timoney Park	Timoney Park	Timaney Park,Timoney Park	52.91139	-7.72333	S	EST	IE	IE	M	26			0		153	Europe/Dublin	2010-11-04
-2961206	Timolin	Timolin		52.9825	-6.81167	P	PPL	IE		L	12			0		138	Europe/Dublin	2010-08-14
-2961207	Timoleague	Timoleague	Tigh Molaige,Timoleague	51.64222	-8.77306	P	PPL	IE	IE	M	04			0		25	Europe/Dublin	2010-08-14
-2961208	Timahoe	Timahoe		53.335	-6.83861	P	PPL	IE		L	12			0		92	Europe/Dublin	2010-08-14
-2961209	Timahoe	Timahoe	Tigh Mochua,Timahoe	52.95833	-7.20528	P	PPL	IE	IE	L	15			0		152	Europe/Dublin	2010-08-14
-2961210	Tiltinbane	Tiltinbane	Tiltinbane	54.21972	-7.85778	T	MT	IE		00				0	594	453	Europe/Dublin	2006-01-16
-2961211	Tievemore House	Tievemore House		54.59444	-7.77472	S	HSEC	IE		U	06			0		173	Europe/Dublin	2010-08-14
-2961212	Tievemore	Tievemore		54.58333	-7.76667	P	PPL	IE		00				0		330	Europe/Dublin	1993-12-27
-2961213	Tiaquin	Tiaquin		53.35972	-8.63333	P	PPL	IE		C	10			0		74	Europe/Dublin	2010-08-14
-2961214	Durlas	Durlas	Thurles	52.68194	-7.80222	P	PPL	IE		M	26			7588		98	Europe/Dublin	2010-08-14
-2961215	The Three Sisters	The Three Sisters		52.20167	-10.42194	T	HLLS	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
-2961216	The Pigeons	The Pigeons	The Pigeons,Three Jolly Pigeons	53.5	-7.81667	P	PPL	IE	IE	L	29			0		77	Europe/Dublin	2010-08-14
-2961217	Threecastles House	Threecastles House	Three Castles,Threecastles House	52.71	-7.32	S	EST	IE	IE	L	13			0		67	Europe/Dublin	2010-08-14
-2961218	Three Castle Head	Three Castle Head		51.48278	-9.83667	T	CAPE	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
-2961219	Thomastown Park	Thomastown Park	Thomastown House,Thomastown Park	53.36583	-8.07333	S	EST	IE	IE	C	24			0		123	Europe/Dublin	2010-08-14
-2961220	Thomaston Park	Thomaston Park	Thomaston Park,Thomastown House,Thomastown Park	53.13389	-7.79583	S	EST	IE	IE	L	23			0		76	Europe/Dublin	2010-08-14
-2961221	Thomastown Castle	Thomastown Castle		53.93333	-6.58333	S	EST	IE		00				0		44	Europe/Dublin	1993-12-27
-2961222	Thomastown Castle	Thomastown Castle		52.48972	-8.03222	S	EST	IE		M	26			0		79	Europe/Dublin	2010-08-14
-2961223	Thomastown	Thomastown		53.39639	-6.88417	P	PPL	IE		L	12			0		86	Europe/Dublin	2010-08-14
-2961224	Thomastown	Thomastown	Baile Mhic Andain,Baile Mhic Andáin,Thomastown	52.52667	-7.13722	P	PPL	IE		L	13			1603		52	Europe/Dublin	2010-08-14
-2961225	Thomastown	Thomastown	Thomastown,Thomastown Castle	52.49417	-8.02444	P	PPL	IE	IE	M	26			0		79	Europe/Dublin	2010-11-04
-2961226	Thomas Street	Thomas Street		53.46667	-8.21667	P	PPL	IE		C	24			0		76	Europe/Dublin	1993-12-27
-2961227	Tervoe House	Tervoe House		52.64944	-8.71139	S	EST	IE		M	16			0		3	Europe/Dublin	2010-08-14
-2961228	Terryglass	Terryglass	Terryglass	53.05028	-8.19889	P	PPL	IE		M	26			0		55	Europe/Dublin	2010-11-04
-2961229	Termon River	Termon River	Termon River	54.53333	-7.85	H	STM	IE		00				0		68	Europe/Dublin	1998-02-19
-2961230	Termon Hill	Termon Hill		54.10333	-10.09611	T	HLL	IE		C	20			0	105	2	Europe/Dublin	2010-08-14
-2961231	Termonfeckin	Termonfeckin	Tearmann Feichin,Tearmann Feichín,Termonfeckin	53.76333	-6.26778	P	PPL	IE		L	19			0		3	Europe/Dublin	2010-08-14
-2961232	Termon Cottage	Termon Cottage		53.04806	-9.06056	S	HSEC	IE		M	03			0		151	Europe/Dublin	2010-08-14
-2961233	Termoncarragh	Termoncarragh		54.25139	-10.06361	P	PPL	IE		C	20			0		57	Europe/Dublin	2010-08-14
-2961234	Termonbarry	Termonbarry		53.75	-7.91667	P	PPL	IE		00				0		66	Europe/Dublin	1993-12-27
-2961235	Terenure	Terenure	Roundtown,Terenure	53.30972	-6.28528	P	PPL	IE	IE	00				0		49	Europe/Dublin	2010-08-10
-2961236	Templetouhy	Templetouhy	Teampall Tuaithe,Templetouhy,Templetuohy	52.78722	-7.71972	P	PPL	IE	IE	M	26			0		147	Europe/Dublin	2010-11-04
-2961237	An Teampall Mór	An Teampall Mor	Templemore	52.79472	-7.83389	P	PPL	IE		M	26			2264		120	Europe/Dublin	2010-08-14
-2961238	Templehouse Lake	Templehouse Lake		54.10333	-8.58917	H	LK	IE		C	25			0		74	Europe/Dublin	2010-08-14
-2961239	Temple House	Temple House		54.11083	-8.59111	S	HSEC	IE		C	25			0		74	Europe/Dublin	2010-08-14
-2961240	Templebreedy	Templebreedy		51.78167	-8.31583	A	PRSH	IE		M	04			0		5	Europe/Dublin	2010-08-14
-2961241	Templeboy	Templeboy		54.24583	-8.8125	P	PPL	IE		C	25			0		43	Europe/Dublin	2010-08-14
-2961242	Templebodan	Templebodan		51.99861	-8.24583	P	PPL	IE		M	04			0		138	Europe/Dublin	2010-08-14
-2961243	Temple	Temple	Oriel Temple,Temple	53.78333	-6.46667	S	EST	IE	IE	00				0		152	Europe/Dublin	2010-08-10
-2961244	Temora House	Temora House		53.16667	-7.75	S	EST	IE		L	23			0		73	Europe/Dublin	2010-08-14
-2961245	Teltown House	Teltown House	Teltown,Teltown House	53.69667	-6.77861	S	BLDG	IE	IE	L	21			0		57	Europe/Dublin	2010-08-14
-2961246	Teeromoyle	Teeromoyle		51.97222	-10.07028	P	PPL	IE		M	11			0		170	Europe/Dublin	2010-08-14
-2961247	Teerelton	Teerelton		51.85139	-8.98444	P	PPL	IE		M	04			0		152	Europe/Dublin	2010-08-14
-2961248	Teeranearagh	Teeranearagh		51.86861	-10.26278	P	PPL	IE		M	11			0		263	Europe/Dublin	2010-08-14
-2961249	Teelin Bay	Teelin Bay	Teelin Bay,Teelin Harbour	54.63333	-8.63333	H	HBR	IE		U	06			0		-9999	Europe/Dublin	2010-08-10
-2961250	Teelin	Teelin		54.63472	-8.64167	P	PPL	IE		U	06			0		15	Europe/Dublin	2010-08-14
-2961251	Tedavnet	Tedavnet		54.29639	-7.01389	P	PPL	IE		U	22			0		138	Europe/Dublin	2010-08-14
-2961252	Tearaght Island	Tearaght Island	Inishteraght,Tearaght Island	52.07528	-10.65667	T	ISL	IE	IE	M	11			0		-9999	Europe/Dublin	2010-08-14
-2961253	River Tay	River Tay		52.125	-7.46222	H	STM	IE		M	27			0		-9999	Europe/Dublin	2010-08-14
-2961254	Lough Tay	Lough Tay	Loch Te,Loch Té,Lough Tay,Luggada Lake	53.10472	-6.26861	H	LK	IE	IE	L	31			0		342	Europe/Dublin	2010-08-14
-2961255	Tawnyinah	Tawnyinah		53.9	-8.76667	P	PPL	IE		C	20			0		135	Europe/Dublin	1993-12-27
-2961256	Tawny Bay	Tawny Bay		54.62167	-8.61861	H	BAY	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
-2961257	Tawnyard Lough	Tawnyard Lough		53.63333	-9.63333	H	LK	IE		C	20			0		74	Europe/Dublin	1993-12-27
-2961258	Tawny	Tawny	Tamney,Tawny	55.2	-7.68333	P	PPL	IE	IE	U	06			0		51	Europe/Dublin	2010-08-14
-2961259	Tawny	Tawny		54.62444	-8.60083	P	PPL	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
-2961260	Tawnawully Mountains	Tawnawully Mountains		54.73528	-7.98333	T	MTS	IE		U	06			0		180	Europe/Dublin	2010-08-14
-2961261	Tawin Island	Tawin Island	Tawin Island,West Tawin	53.21861	-9.03194	T	ISL	IE	IE	C	10			0		1	Europe/Dublin	2010-08-14
-2961262	Taurbeg	Taurbeg		52.23333	-9.13333	T	MT	IE		M	04			0		299	Europe/Dublin	1993-12-27
-2961263	Taur	Taur		52.23333	-9.11667	P	PPL	IE		M	04			0		291	Europe/Dublin	1993-12-27
-2961264	Tarsaghaunmore River	Tarsaghaunmore River		54.06361	-9.785	H	STM	IE		C	20			0		55	Europe/Dublin	2010-08-14
-2961265	Tarmon	Tarmon		52.53806	-9.37889	P	PPL	IE		M	11			0		76	Europe/Dublin	2010-08-14
-2961266	Tarbert House	Tarbert House		52.57833	-9.36833	S	EST	IE		M	11			0		1	Europe/Dublin	2010-08-14
-2961267	Tarbert	Tarbert	Tairbeart,Tarbert	52.57278	-9.37528	P	PPL	IE	IE	M	11			0		12	Europe/Dublin	2010-08-14
-2961268	Tara Hill	Tara Hill		52.69806	-6.21472	T	HLL	IE		L	30			0		56	Europe/Dublin	2010-08-14
-2961269	Tara Hall	Tara Hall		53.58	-6.60222	S	EST	IE		L	21			0		121	Europe/Dublin	2010-08-14
-2961270	Hill of Tara	Hill of Tara		53.57972	-6.61194	T	HLL	IE		L	21			0		135	Europe/Dublin	2010-08-14
-2961271	River Tar	River Tar		52.28333	-7.83333	H	STM	IE		00				0		48	Europe/Dublin	1993-12-27
-2961272	Lough Tap	Lough Tap		53.9	-7.98333	H	LK	IE		C	14			0		92	Europe/Dublin	1993-12-27
-2961273	Tanrego House	Tanrego House	Tanrego,Tanrego House	54.23056	-8.61222	S	HSEC	IE	IE	C	25			0		1	Europe/Dublin	2010-08-14
-2961274	Tankersley House	Tankersley House		52.82667	-6.38583	S	EST	IE		L	31			0		87	Europe/Dublin	2010-08-14
-2961275	Tang River	Tang River		53.53333	-7.83333	H	STM	IE		L	29			0		67	Europe/Dublin	1993-12-27
-2961276	Tang	Tang		53.53333	-7.78333	P	PPL	IE		L	29			0		67	Europe/Dublin	1993-12-27
-2961277	Lough Talt	Lough Talt		54.08389	-8.92139	H	LK	IE		C	25			0		182	Europe/Dublin	2010-08-14
-2961278	Tallyho Lodge	Tallyho Lodge		53.27	-8.69611	S	HSEC	IE		C	10			0		46	Europe/Dublin	2010-08-14
-2961279	Tallyho	Tallyho		52.81361	-6.36222	P	PPL	IE		L	31			0		170	Europe/Dublin	2010-08-14
-2961280	Tallow Road Station	Tallow Road Station	Tallow Road,Tallow Road Station	52.11667	-7.98333	S	RSTN	IE	IE	M	27			0		71	Europe/Dublin	2010-08-14
-2961281	Tallowbridge	Tallowbridge		52.10417	-8.00278	P	PPL	IE		M	27			0		32	Europe/Dublin	2010-08-14
-2961282	Tallow	Tallow	Tallow,Tulach an Iarainn	52.09278	-8.00806	P	PPL	IE		M	27			0		44	Europe/Dublin	2010-08-14
-2961283	Tallanstown	Tallanstown		53.92278	-6.54639	P	PPL	IE		L	19			0		36	Europe/Dublin	2010-08-14
-2961284	Tallaght	Tallaght	Tallaght	53.2859	-6.37344	P	PPL	IE	IE	L	07			64282		87	Europe/Dublin	2010-08-14
-2961285	Talbotstown House	Talbotstown House		53.22917	-6.45167	S	EST	IE		L	31			0		298	Europe/Dublin	2010-08-14
-2961286	Talbot Hall	Talbot Hall		52.38611	-6.9125	S	EST	IE		L	13			0		76	Europe/Dublin	2010-08-14
-2961287	Tahilla	Tahilla		51.83722	-9.83639	P	PPL	IE		M	11			0		62	Europe/Dublin	2010-08-14
-2961288	Tagoat	Tagoat		52.24278	-6.38028	P	PPL	IE		L	30			0		1	Europe/Dublin	2010-08-14
-2961289	Taghshinny	Taghshinny	Taghshinny	53.6	-7.71667	P	PPL	IE		L	18			0		76	Europe/Dublin	2010-08-10
-2961290	Taghsheenod	Taghsheenod		53.61667	-7.71667	P	PPL	IE		L	18			0		90	Europe/Dublin	1993-12-27
-2961291	Taghmon Castle	Taghmon Castle		53.6	-7.26667	S	BLDG	IE		L	29			0		118	Europe/Dublin	1993-12-27
-2961292	Taghmon	Taghmon	Taghmon,Teach Munna	52.32167	-6.6475	P	PPL	IE		L	30			0		73	Europe/Dublin	2010-08-14
-2961293	Tacumshin Lake	Tacumshin Lake	Tacumshin Lake,Tacumshin Lough,Tucumshin Lake	52.19528	-6.45306	H	BAY	IE	IE	L	30			0		-9999	Europe/Dublin	2010-08-14
-2961294	Lough Tacker	Lough Tacker		54.01667	-6.95	H	LK	IE		U	02			0		127	Europe/Dublin	2010-08-14
-2961295	Table Mountain	Table Mountain		53.01444	-6.48417	T	MT	IE		L	31			0	701	599	Europe/Dublin	2010-08-14
-2961296	Sybil Point	Sybil Point		52.17806	-10.47333	T	PT	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
-2961297	Swords	Swords	Sord,Swords	53.45972	-6.21806	P	PPL	IE		L	35			29816		6	Europe/Dublin	2010-11-04
-2961298	Swines Head	Swines Head		52.12972	-7.02667	T	CAPE	IE		M	27			0		-9999	Europe/Dublin	2010-08-14
-2961299	Swinford	Swinford	Beal Atha na Muice,Béal Átha na Muice,Swineford,Swinford	53.95	-8.95	P	PPL	IE		C	20			1241		68	Europe/Dublin	2010-08-14
-2961300	River Swilly	River Swilly		54.96056	-7.67778	H	STM	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
-2961301	Lough Swilly	Lough Swilly	Loch Suili,Loch Súilí,Lough Swilly,The Lake of Shadows	55.16667	-7.53333	H	INLT	IE		U	06			0		-9999	Europe/Dublin	2011-03-06
-2961302	The Sweep	The Sweep		52.21667	-7.23333	P	PPL	IE		M	27			0		49	Europe/Dublin	2010-08-14
-2961303	Swanlinbar	Swanlinbar	An Muileann Iarainn,Swanlinbar	54.19472	-7.70444	P	PPL	IE		U	02			0		74	Europe/Dublin	2010-08-14
-2961304	Swan	Swan		52.8875	-7.15972	P	PPL	IE		L	15			0		153	Europe/Dublin	2010-08-14
-2961305	Sutton	Sutton	Sutton	53.39056	-6.12167	P	PPL	IE		L	07			0		-9999	Europe/Dublin	2010-11-04
-2961306	Sunvale	Sunvale	Sun Ville,Sunvale	52.34611	-8.5175	S	EST	IE	IE	M	16			0		151	Europe/Dublin	2010-08-14
-2961307	Lough Sunderlin	Lough Sunderlin	Lough Sewdy,Lough Sunderlin	53.5	-7.66667	H	LK	IE		L	29			0		79	Europe/Dublin	2010-08-10
-2961308	Summerville	Summerville		53.8	-7.36667	P	PPL	IE		U	02			0		73	Europe/Dublin	1993-12-27
-2961309	Summerhill House	Summerhill House		53.47	-6.72556	S	EST	IE		L	21			0		78	Europe/Dublin	2010-08-14
-2961310	Summerhill House	Summerhill House		52.76306	-7.94278	S	EST	IE		M	26			0		107	Europe/Dublin	2010-08-14
-2961311	Summerhill House	Summerhill House	Summerhill House,Summerville	52.36778	-7.73889	S	EST	IE	IE	M	26			0		71	Europe/Dublin	2010-11-04
-2961312	Summerhill	Summerhill		53.47694	-6.73639	P	PPL	IE		L	21			0		77	Europe/Dublin	2010-08-14
-2961313	Summerhill	Summerhill		52.80528	-7.13722	P	PPL	IE		L	13			0		227	Europe/Dublin	2010-08-14
-2961314	Summer Cove	Summer Cove	Summer Cove,Summor Cove	51.70333	-8.50222	P	PPL	IE	IE	M	04			0		-9999	Europe/Dublin	2010-08-14
-2961315	Sullane River	Sullane River		51.88333	-8.93333	H	STM	IE		M	04			0		85	Europe/Dublin	2010-08-14
-2961316	Suir Mount	Suir Mount		52.29611	-7.79222	S	EST	IE		M	27			0		59	Europe/Dublin	2010-08-14
-2961317	Suir Island	Suir Island		52.35	-7.7	T	ISL	IE		M	27			0		132	Europe/Dublin	2010-08-14
-2961318	Suircastle House	Suircastle House		52.46167	-7.98972	S	HSEC	IE		M	26			0		73	Europe/Dublin	2010-08-14
-2961319	River Suir	River Suir	River Suir	52.27333	-6.99556	H	STM	IE		00				0		1	Europe/Dublin	2011-01-04
-2961320	Sugarloaf Mountain	Sugarloaf Mountain	Sugarloaf Mountain	51.72583	-9.63111	T	MT	IE		M	04			0		228	Europe/Dublin	2010-08-14
-2961321	Sugar Hill	Sugar Hill		52.43611	-9.16917	T	HLL	IE		M	11			0		312	Europe/Dublin	2010-08-14
-2961322	River Suck	River Suck		53.27222	-8.05306	H	STM	IE		00				0		55	Europe/Dublin	1998-08-18
-2961323	Sturrall	Sturrall		54.73667	-8.74417	T	CAPE	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
-2961324	Stuake	Stuake		51.98333	-8.76667	P	PPL	IE		M	04			0		171	Europe/Dublin	2010-08-14
-2961325	Stroove	Stroove		55.21667	-6.93333	P	PPL	IE		U	06			0		-9999	Europe/Dublin	1993-12-27
-2961326	Strokestown House	Strokestown House		53.76667	-8.1	S	EST	IE		C	24			0		71	Europe/Dublin	1993-12-27
-2961327	Strokestown	Strokestown	Beal na mBuilli,Béal na mBuillí,Strokestown	53.78333	-8.1	P	PPL	IE		C	24			0		72	Europe/Dublin	2010-08-14
-2961328	Street	Street		53.66667	-7.48333	P	PPL	IE		L	29			0		72	Europe/Dublin	1993-12-27
-2961329	Streek Head	Streek Head		51.47056	-9.70306	T	CAPE	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
-2961330	Streedagh Point	Streedagh Point		54.41194	-8.56722	T	PT	IE		C	25			0		1	Europe/Dublin	2010-08-14
-2961331	Streedagh House	Streedagh House		54.39778	-8.56389	S	HSEC	IE		C	25			0		1	Europe/Dublin	2010-08-14
-2961332	Streamstown Bay	Streamstown Bay		53.50917	-10.06833	H	BAY	IE		C	10			0		-9999	Europe/Dublin	2010-08-14
-2961333	Streamstown	Streamstown		53.52333	-10.04694	P	PPL	IE		C	10			0		76	Europe/Dublin	2010-08-14
-2961334	Streamstown	Streamstown		53.43333	-7.58333	P	PPL	IE		L	29			0		102	Europe/Dublin	1993-12-27
-2961335	Strawberryhill House	Strawberryhill House		53.23639	-7.88778	S	HSEC	IE		L	23			0		68	Europe/Dublin	2010-08-14
-2961336	Stratford	Stratford	Ath na Sraide,Stratford,Áth na Sráide	52.98583	-6.67778	P	PPL	IE		L	31			0		147	Europe/Dublin	2010-08-14
-2961337	Stranorlar	Stranorlar	Srath an Urlair,Srath an Urláir,Stranorlar	54.8	-7.76667	P	PPL	IE		U	06			0		58	Europe/Dublin	2010-08-14
-2961338	Strand	Strand		52.39556	-9.11056	P	PPL	IE		M	03			0		152	Europe/Dublin	2010-08-14
-2961339	Strancally House	Strancally House		52.01667	-7.85	S	BLDG	IE		M	04			0		71	Europe/Dublin	2010-08-14
-2961340	Strancally Castle	Strancally Castle		52.06861	-7.87694	S	EST	IE		M	27			0		36	Europe/Dublin	2010-08-14
-2961341	Straid River	Straid River		55.28333	-7.33333	H	STM	IE		U	06			0		40	Europe/Dublin	1993-12-27
-2961342	Straffan	Straffan		53.31556	-6.63472	P	PPL	IE		L	12			0		72	Europe/Dublin	2010-08-14
-2961343	Stradone House	Stradone House		53.98389	-7.25	S	EST	IE		U	02			0		134	Europe/Dublin	2010-08-14
-2961344	Stradone	Stradone	Sraith an Domhain,Stradone	53.98333	-7.23333	P	PPL	IE	IE	U	02			0		135	Europe/Dublin	2010-08-14
-2961345	Strade	Strade		53.91694	-9.13389	P	PPL	IE		C	20			0		38	Europe/Dublin	2010-08-14
-2961346	Stradbally River	Stradbally River	Bauteogue River,Stradbally River,Strade River,Straid River	53.03806	-7.08972	H	STM	IE	IE	L	15			0		72	Europe/Dublin	2010-08-14
-2961347	Stradbally Hall	Stradbally Hall		53	-7.16667	S	EST	IE		L	15			0		152	Europe/Dublin	2010-08-14
-2961348	Stradbally	Stradbally		53.21889	-8.88667	P	PPL	IE		C	10			0		2	Europe/Dublin	2010-08-14
-2961349	Stradbally	Stradbally	An Sraidbhaile,An Sráidbhaile,Stradbally	53.01556	-7.15278	P	PPL	IE		L	15			0		149	Europe/Dublin	2010-08-14
-2961350	Stradbally	Stradbally		52.24722	-10.06639	P	PPL	IE		M	11			0		81	Europe/Dublin	2010-08-14
-2961351	Stradbally	Stradbally	An tSraidbhaile,An tSráidbhaile,Stradbally	52.13	-7.46	P	PPL	IE		M	27			0		17	Europe/Dublin	2010-08-14
-2961352	Stowlin House	Stowlin House		53.18139	-8.21722	S	EST	IE		C	10			0		75	Europe/Dublin	2010-08-14
-2961353	Stookaruddan	Stookaruddan	Stockaruddan,Stookaruddan,Stookarudden	55.36972	-7.28222	T	ISLS	IE	IE	U	06			0		-9999	Europe/Dublin	2010-08-14
-2961354	Stonyford	Stonyford		52.53639	-7.22	P	PPL	IE		L	13			0		69	Europe/Dublin	2010-08-14
-2961355	Stonybatter	Stonybatter		52.76278	-6.45278	P	PPL	IE		L	31			0		159	Europe/Dublin	2010-08-14
-2961356	Stonetown	Stonetown		53.61667	-8.55	P	PPL	IE		C	10			0		76	Europe/Dublin	1993-12-27
-2961357	Stonepark	Stonepark		54.01028	-8.93722	P	PPL	IE		C	20			0		77	Europe/Dublin	2010-08-14
-2961358	Stonehall	Stonehall		52.60722	-8.87306	P	PPL	IE		M	16			0		22	Europe/Dublin	2010-08-14
-2961359	Stonefield	Stonefield		54.31	-9.82972	P	PPL	IE		C	20			0		141	Europe/Dublin	2010-08-14
-2961360	Stone Bridge	Stone Bridge		54.2	-7.16667	P	PPL	IE		U	22			0		73	Europe/Dublin	2010-08-14
-2961361	Stokestown	Stokestown	Stokestown,Stokestown Castle	52.36028	-6.98806	S	EST	IE	IE	L	30			0		13	Europe/Dublin	2010-08-14
-2961362	Stillorgan	Stillorgan		53.29049	-6.19487	P	PPL	IE		L	07			0		39	Europe/Dublin	2010-08-14
-2961363	Stephenstown House	Stephenstown House	Stephenstown,Stephenstown House	53.95806	-6.46639	S	EST	IE	IE	L	19			0		19	Europe/Dublin	2010-08-14
-2961364	Stepaside	Stepaside	Stepaside	53.2525	-6.21361	P	PPL	IE		L	07			0		140	Europe/Dublin	2010-11-04
-2961365	Station Island	Station Island		54.60833	-7.87139	T	ISL	IE		U	06			0		148	Europe/Dublin	2010-08-14
-2961366	Stamullin	Stamullin		53.62889	-6.26833	P	PPL	IE		L	21			0		48	Europe/Dublin	2010-08-14
-2961367	Stags of Broad Haven	Stags of Broad Haven	Stags,Stags of Broad Haven,The Stags	54.36639	-9.78778	T	RKS	IE	IE	C	20			0		-9999	Europe/Dublin	2010-08-14
-2961368	Stags of Bofin	Stags of Bofin		53.63194	-10.25917	T	RKS	IE		C	10			0		-9999	Europe/Dublin	2010-08-14
-2961369	The Stag Rocks	The Stag Rocks	The Stag Rocks,The Stags	55.07528	-8.47889	T	RKS	IE	IE	U	06			0		-9999	Europe/Dublin	2010-08-14
-2961370	Stacks Mountains	Stacks Mountains		52.31667	-9.56667	T	MTS	IE		M	11			0		286	Europe/Dublin	1993-12-27
-2961371	Stabannan	Stabannan	Stabannan,Stahannan	53.86472	-6.43583	P	PPL	IE	IE	L	19			0		6	Europe/Dublin	2010-08-14
-2961372	Sruwaddacon Bay	Sruwaddacon Bay	Sruwaddacon Bay,Sruwaddacon Creek	54.26667	-9.78333	H	BAY	IE		C	20			0		-9999	Europe/Dublin	2010-08-10
-2961373	Srahmore River	Srahmore River		53.95667	-9.58	H	STM	IE		C	20			0		98	Europe/Dublin	2010-08-14
-2961374	Srahmore	Srahmore		53.96028	-9.57083	P	PPL	IE		C	20			0		131	Europe/Dublin	2010-08-14
-2961375	Srahlaghy	Srahlaghy		54.235	-9.57361	P	PPL	IE		C	20			0		128	Europe/Dublin	2010-08-14
-2961376	Srahduggaun	Srahduggaun		54	-9.73333	P	PPL	IE		C	20			0		73	Europe/Dublin	1993-12-27
-2961377	Srah	Srah		54.1725	-9.93361	P	PPL	IE		C	20			0		5	Europe/Dublin	2010-08-14
-2961378	Srah	Srah		53.68333	-9.33333	P	PPL	IE		C	20			0		59	Europe/Dublin	1993-12-27
-2961379	Srah	Srah		53.28333	-7.75	P	PPL	IE		L	23			0		65	Europe/Dublin	2010-08-14
-2961380	Spring Valley	Spring Valley		53.47806	-6.71389	S	EST	IE		L	21			0		77	Europe/Dublin	2010-08-14
-2961381	Springfield Castle	Springfield Castle		52.35	-8.95	S	EST	IE		M	16			0		146	Europe/Dublin	1993-12-27
-2961382	Springfield	Springfield		53.05	-7.4	P	PPL	IE		L	15			0		138	Europe/Dublin	2010-08-14
-2961383	Springfield	Springfield		52.71556	-6.615	S	EST	IE		L	31			0		71	Europe/Dublin	2010-08-14
-2961384	Sporthouse Cross Roads	Sporthouse Cross Roads		52.19667	-7.17917	P	PPL	IE		M	27			0		77	Europe/Dublin	2010-08-14
-2961385	Spittle	Spittle		52.38	-8.3375	P	PPL	IE		M	16			0		152	Europe/Dublin	2010-08-14
-2961386	Spink	Spink		52.89944	-7.22611	P	PPL	IE		L	15			0		151	Europe/Dublin	2010-08-14
-2961387	Spike Island	Spike Island		51.83861	-8.28889	T	ISL	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
-2961388	Spiddal	Spiddal	An Spideal,An Spidéal,Spiddal,Spiddle	53.24667	-9.30278	P	PPL	IE		C	10			0		1	Europe/Dublin	2010-08-14
-2961389	Spear Vale	Spear Vale		53.91667	-7	P	PPL	IE		U	02			0		187	Europe/Dublin	1993-12-27
-2961390	Spanish Point	Spanish Point		52.84972	-9.44722	T	PT	IE		M	03			0		-9999	Europe/Dublin	2010-08-14
-2961391	Spancelhill	Spancelhill		52.86667	-8.9	P	PPL	IE		M	03			0		119	Europe/Dublin	1993-12-27
-2961392	Spa	Spa		52.28333	-9.78333	P	PPL	IE		M	11			0		39	Europe/Dublin	2010-08-14
-2961393	River Sow	River Sow		52.37778	-6.45139	H	STM	IE		L	30			0		4	Europe/Dublin	2010-08-14
-2961394	Sovereign Islands	Sovereign Islands	Big Sovereign,Sovereign Islands	51.67667	-8.45556	T	ISLS	IE	IE	M	04			0		-9999	Europe/Dublin	2010-08-14
-2961395	Sovereign Island	Sovereign Island	Little Sovereign,Sovereign Island	51.68389	-8.4425	T	ISL	IE	IE	M	04			0		-9999	Europe/Dublin	2010-08-14
-2961396	South Sound	South Sound		53.04167	-9.46583	H	SD	IE		M	03			0		-9999	Europe/Dublin	2010-08-14
-2961397	Southpark House	Southpark House		53.76667	-8.43333	S	EST	IE		C	24			0		77	Europe/Dublin	1993-12-27
-2961398	South Hill	South Hill		53.60861	-7.07167	S	EST	IE		L	29			0		109	Europe/Dublin	2010-08-14
-2961399	Sorrel House	Sorrel House		52.75	-9.23333	S	BLDG	IE		M	03			0		96	Europe/Dublin	1993-12-27
-2961400	Sorrelhill House	Sorrelhill House		52.83333	-7.75	S	EST	IE		M	26			0		150	Europe/Dublin	2010-08-14
-2961401	Sopwell Hall	Sopwell Hall		52.99194	-8.04806	S	EST	IE		M	26			0		119	Europe/Dublin	2010-08-14
-2961402	Soppog	Soppog		55.06472	-7.32111	P	PPL	IE		U	06			0		63	Europe/Dublin	2010-08-14
-2961403	Sonna House	Sonna House		53.56667	-7.46667	S	EST	IE		L	29			0		123	Europe/Dublin	1993-12-27
-2961404	Somerville House	Somerville House	Somerville,Somerville House	53.63139	-6.51167	S	EST	IE	IE	L	21			0		57	Europe/Dublin	2010-08-14
-2961405	Somerset House	Somerset House		53.24778	-8.22694	S	EST	IE		C	10			0		76	Europe/Dublin	2010-08-14
-2961406	Solsborough House	Solsborough House	Solsborough,Solsborough House	52.52861	-6.52	S	EST	IE	IE	L	30			0		64	Europe/Dublin	2010-08-14
-2961407	Snowhill House	Snowhill House		52.27278	-7.02028	S	EST	IE		L	13			0		1	Europe/Dublin	2010-08-14
-2961408	Sneem Harbour	Sneem Harbour		51.8	-9.88333	H	INLT	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
-2961409	Sneem	Sneem	An Snaidhm,An tSnaidhm,Sneem	51.83333	-9.9	P	PPL	IE		M	11			0		25	Europe/Dublin	2010-08-14
-2961410	Slieve Snaght	Slieve Snaght	Sliabh Sneachta,Slieve Snaght	55.19639	-7.33528	T	MT	IE		U	06			0	615	573	Europe/Dublin	2010-08-14
-2961411	Slieve Snaght	Slieve Snaght		54.98083	-8.11778	T	MT	IE		U	06			0		466	Europe/Dublin	2010-08-14
-2961412	Smithstown House	Smithstown House		52.98333	-9.26667	S	EST	IE		M	03			0		75	Europe/Dublin	1993-12-27
-2961413	Smithborough	Smithborough		54.22333	-7.09083	P	PPL	IE		U	22			0		74	Europe/Dublin	2010-08-14
-2961414	Smerwick Harbour	Smerwick Harbour		52.19222	-10.4025	H	HBR	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
-2961415	Smerwick	Smerwick		52.19444	-10.42333	P	PPL	IE		M	11			0		30	Europe/Dublin	2010-08-14
-2961416	Smearlagh River	Smearlagh River		52.43917	-9.42889	H	STM	IE		M	11			0		74	Europe/Dublin	2010-08-14
-2961417	Smarmore Castle	Smarmore Castle		53.81722	-6.56667	S	EST	IE		L	19			0		75	Europe/Dublin	2010-08-14
-2961418	Slyne Head	Slyne Head		53.40056	-10.23528	T	CAPE	IE		C	10			0		-9999	Europe/Dublin	2010-08-14
-2961419	Slugga	Slugga		54.30278	-9.86556	T	RK	IE		C	20			0		-9999	Europe/Dublin	2010-08-14
-2961420	Slish Wood	Slish Wood		54.23333	-8.38333	V	FRST	IE		C	25			0		149	Europe/Dublin	2010-08-14
-2961421	Sligo Bay	Sligo Bay		54.3	-8.7	H	BAY	IE		C	25			0		-9999	Europe/Dublin	1998-09-01
-2961422	Sligeach	Sligeach	Contae Shligigh,County Sligo,Sligo	54.25	-8.66667	A	ADM2	IE		C	25			58900		5	Europe/Dublin	2010-08-14
-2961423	Sligeach	Sligeach	Slajgou,Sligeach,Sligo,suraigo,Слайгоу,スライゴ	54.26969	-8.46943	P	PPLA2	IE		C	25			20228	13	5	Europe/Dublin	2010-08-14
-2961424	Slievetooey	Slievetooey		54.76278	-8.60722	T	MT	IE		U	06			0		329	Europe/Dublin	2010-08-14
-2961425	Slieveroe	Slieveroe		52.28056	-7.08667	P	PPL	IE		L	13			0		59	Europe/Dublin	2010-08-14
-2961426	Slievenamuck	Slievenamuck		52.4275	-8.23194	T	MT	IE		M	26			0		156	Europe/Dublin	2010-08-14
-2961427	Slievenamon	Slievenamon	Slievenaman,Slievenamon	52.42778	-7.56111	T	MT	IE		M	26			0	721	568	Europe/Dublin	2010-11-04
-2961428	Slievenakilla	Slievenakilla		54.15	-7.93333	P	PPL	IE		C	14			0		315	Europe/Dublin	1993-12-27
-2961429	Slievemore Point	Slievemore Point		54.01667	-10.05	T	PT	IE		C	20			0		73	Europe/Dublin	1993-12-27
-2961430	Slievemore	Slievemore		53.99611	-10.07056	P	PPLL	IE		C	20			0		149	Europe/Dublin	2010-08-14
-2961431	Slievemore	Slievemore		54.0075	-10.0625	T	MT	IE		C	20			0	671	269	Europe/Dublin	2010-08-14
-2961432	Slieve Miskish Mountains	Slieve Miskish Mountains	Slieve Miskish Mountains	51.66722	-9.95306	T	MTS	IE		M	04			0		188	Europe/Dublin	2010-08-14
-2961433	Slieve Mish Mountains	Slieve Mish Mountains	Slieve Mish Mountains	52.2	-9.76667	T	MTS	IE		M	11			0		224	Europe/Dublin	2010-08-14
-2961434	Slievekimalta	Slievekimalta	Keeper Hill,Slievekimalta	52.74972	-8.26028	T	MT	IE	IE	M	26			0		421	Europe/Dublin	2010-11-04
-2961435	Slieveglass	Slieveglass		52.27861	-10.20667	T	MT	IE		M	11			0		143	Europe/Dublin	2010-08-14
-2961436	Slievefelim Mountains	Slievefelim Mountains		52.67167	-8.3075	T	MTS	IE		M	16			0		315	Europe/Dublin	2010-08-14
-2961437	Slievecarran	Slievecarran		53.09583	-9.00639	T	MT	IE		M	03			0		154	Europe/Dublin	2010-08-14
-2961438	Slievecallan	Slievecallan		52.84056	-9.26861	T	MT	IE		M	03			0		279	Europe/Dublin	2010-08-14
-2961439	Slieveboy	Slieveboy		52.65639	-6.48861	T	MT	IE		L	30			0	422	266	Europe/Dublin	2010-08-14
-2961440	Slieve Bloom Mountains	Slieve Bloom Mountains	Slieve Bloom,Slieve Bloom Mountains	53.09333	-7.56722	T	MTS	IE		L	15			0		326	Europe/Dublin	2010-08-10
-2961441	Slievebane Bay	Slievebane Bay		55.36667	-7.33333	H	BAY	IE		U	06			0		1	Europe/Dublin	2010-08-14
-2961442	Slieve Aughty Mountains	Slieve Aughty Mountains	Slieve Aughty Mountains	53.04611	-8.51111	T	MTS	IE		C	10			0		151	Europe/Dublin	2010-08-14
-2961443	Slieveardagh Hills	Slieveardagh Hills	Slievardagh Region,Slieveardagh Hills	52.65278	-7.52056	T	HLLS	IE	IE	00				0		152	Europe/Dublin	2010-08-10
-2961444	Slevoir House	Slevoir House		53.06139	-8.18111	S	EST	IE		M	26			0		56	Europe/Dublin	2010-08-14
-2961445	Sleatygraigue	Sleatygraigue		52.84472	-6.97167	P	PPL	IE		L	15			0		39	Europe/Dublin	2010-08-14
-2961446	Slea Head	Slea Head		52.09639	-10.45917	T	CAPE	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
-2961447	Slate River	Slate River		53.195	-7.09417	H	STM	IE		L	23			0		75	Europe/Dublin	1999-02-24
-2961448	River Slaney	River Slaney		52.33806	-6.45306	H	STM	IE		L	30			0		-9999	Europe/Dublin	2010-08-14
-2961449	Slane Castle	Slane Castle		53.70944	-6.5825	S	EST	IE		L	21			0		37	Europe/Dublin	2010-08-14
-2961450	Slane	Slane	Baile Shlaine,Baile Shláine,Slane	53.71	-6.54333	P	PPL	IE		L	21			0		58	Europe/Dublin	2010-08-14
-2961451	Slaheny River	Slaheny River		51.9	-9.45	H	STM	IE		M	11			0		86	Europe/Dublin	1993-12-27
-2961452	Slade	Slade		52.1325	-6.90444	P	PPL	IE		L	30			0		-9999	Europe/Dublin	2010-08-14
-2961453	Skycur House	Skycur House	Skycur,Skycur House	53.22139	-8.23472	S	EST	IE	IE	C	10			0		76	Europe/Dublin	2010-08-14
-2961454	Skull Harbour	Skull Harbour		51.52528	-9.53833	H	HBR	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
-2961455	Skull	Skull	An Scoil,Schull,Skull	51.53333	-9.53333	P	PPL	IE		M	04			0		44	Europe/Dublin	2010-08-14
-2961456	Skreeny House	Skreeny House		54.315	-8.16722	S	RUIN	IE		C	14			0		76	Europe/Dublin	2010-08-14
-2961457	Skreen	Skreen		54.24333	-8.73111	P	PPL	IE		C	25			0		55	Europe/Dublin	2010-08-14
-2961458	Screen	Screen	Screen,Skreen	52.41361	-6.4125	P	PPL	IE	IE	L	30			0		22	Europe/Dublin	2010-08-14
-2961459	An Sciobairin	An Sciobairin	Skibbereen	51.55	-9.26667	P	PPL	IE		M	04			2098		98	Europe/Dublin	2010-08-14
-2961460	Skerries Islands	Skerries Islands		53.58333	-6.08333	T	ISLS	IE		00				0		-9999	Europe/Dublin	1993-12-27
-2961461	Skerries	Skerries	Na Sceiri,Na Sceirí,Skerries	53.58278	-6.10833	P	PPL	IE		L	35			10014		-9999	Europe/Dublin	2010-11-04
-2961462	Skenakilla Cross Roads	Skenakilla Cross Roads		52.19306	-8.51778	P	PPL	IE		M	04			0		76	Europe/Dublin	2010-08-14
-2961463	Skellig Rocks	Skellig Rocks	Skellig Rocks,The Skelligs	51.76667	-10.51667	T	RKS	IE	IE	M	11			0		-9999	Europe/Dublin	2010-08-14
-2961464	Skehanagh	Skehanagh		53.41389	-8.63417	P	PPL	IE		C	10			0		72	Europe/Dublin	2010-08-14
-2961465	Lough Skean	Lough Skean		54.06222	-8.21528	H	LK	IE		00				0		55	Europe/Dublin	1998-09-01
-2961466	Skeagh Lough Upper	Skeagh Lough Upper	Skeagh Lough,Skeagh Lough Upper	53.95	-7	H	LK	IE	IE	U	02			0		150	Europe/Dublin	2010-08-14
-2961467	Skeagh	Skeagh		51.58639	-9.35472	P	PPL	IE		M	04			0		79	Europe/Dublin	2010-08-14
-2961468	Skeaf House	Skeaf House		51.6775	-8.78111	S	EST	IE		M	04			0		75	Europe/Dublin	2010-08-14
-2961469	Lough Skannive	Lough Skannive		53.33083	-9.78722	H	LK	IE		C	10			0		65	Europe/Dublin	2010-08-14
-2961470	Sixmilebridge	Sixmilebridge	Droichead Abhann O gCearnaigh,Droíchead Abhann Ó gCearnaigh,Sixmilebridge	52.74139	-8.77417	P	PPL	IE		M	03			0		43	Europe/Dublin	2010-08-14
-2961471	Single Street	Single Street		54.48306	-8.26417	P	PPL	IE		U	06			0		1	Europe/Dublin	2010-08-14
-2961472	Silver Stream	Silver Stream		54.26667	-6.91667	P	PPL	IE		00				0		66	Europe/Dublin	1993-12-27
-2961473	Silver River	Silver River		53.2925	-7.62889	H	STM	IE		L	23			0		70	Europe/Dublin	2010-08-14
-2961474	Silver River	Silver River		53.24333	-7.79139	H	STM	IE		L	23			0		63	Europe/Dublin	2010-08-14
-2961475	Silvermines	Silvermines	Beal Atha Gabhann,Béal Átha Gabhann,Silvermines	52.79028	-8.23417	P	PPL	IE		M	38			0		188	Europe/Dublin	2010-11-04
-2961476	Silvermine Mountains	Silvermine Mountains	Silvermine Mountains,Silvermines Mountains	52.77583	-8.24889	T	MTS	IE	IE	M	26			0		345	Europe/Dublin	2010-11-04
-2961477	Silver Hill	Silver Hill		54.76944	-8.14722	T	MT	IE		U	06			0		423	Europe/Dublin	2010-08-14
-2961478	Lough Sillan	Lough Sillan		54.00222	-6.92222	H	LK	IE		U	02			0		149	Europe/Dublin	2010-08-14
-2961479	Siddan	Siddan		53.80972	-6.65639	P	PPL	IE		L	21			0		61	Europe/Dublin	2010-08-14
-2961480	Shrule Castle	Shrule Castle		52.87694	-6.95111	S	BLDG	IE		L	15			0		48	Europe/Dublin	2010-08-14
-2961481	Shrule	Shrule	Shrule,Shruthair,Sruthair	53.51681	-9.08902	P	PPL	IE		C	20			0		59	Europe/Dublin	2010-08-14
-2961482	Shronowen	Shronowen		52.50389	-9.45361	P	PPL	IE		M	11			0		69	Europe/Dublin	2010-08-14
-2961483	Shronell	Shronell		52.47222	-8.23472	P	PPL	IE		M	26			0		136	Europe/Dublin	2010-08-14
-2961484	Shrone	Shrone		52.525	-9.49	P	PPL	IE		M	11			0		57	Europe/Dublin	2010-08-14
-2961485	Shot Head	Shot Head		51.67667	-9.67611	T	CAPE	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
-2961486	Shiven River	Shiven River	Kingstown River,Shiven River	53.51667	-8.45	H	STM	IE		C	10			0		72	Europe/Dublin	2010-08-10
-2961487	Shiven River	Shiven River		53.5	-8.28333	H	STM	IE		00				0		69	Europe/Dublin	1993-12-27
-2961488	Shippool	Shippool	Shippool,Shippool Castle	51.75111	-8.62889	S	RUIN	IE	IE	M	04			0		72	Europe/Dublin	2010-08-14
-2961489	Shinrone	Shinrone	Shinrone,Sui an Roin,Suí an Róin	52.9825	-7.92444	P	PPL	IE	IE	L	23			0		84	Europe/Dublin	2010-08-14
-2961490	Lough Shindilla	Lough Shindilla		53.45	-9.56667	H	LK	IE		C	10			0		58	Europe/Dublin	1993-12-27
-2961491	Shillelagh	Shillelagh	Shillelagh,Siol Ealaigh,Síol Éalaigh	52.75389	-6.53722	P	PPL	IE	IE	L	31			0		76	Europe/Dublin	2010-08-14
-2961492	Sheskin Lodge	Sheskin Lodge		54.17028	-9.615	S	HSE	IE		C	20			0		146	Europe/Dublin	2010-08-14
-2961493	Sheshia	Sheshia		53.1	-9.06667	P	PPL	IE		M	03			0		57	Europe/Dublin	1993-12-27
-2961494	Sherky Island	Sherky Island		51.7975	-9.905	T	ISL	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
-2961495	Sherkin Island	Sherkin Island	Sherkin Island	51.4775	-9.42694	T	ISL	IE		M	04			0		1	Europe/Dublin	2010-08-14
-2961496	Sheriffhill	Sheriffhill		52.95	-6.80278	P	PPL	IE		L	12			0		143	Europe/Dublin	2010-08-14
-2961497	Shercock	Shercock	Searcog,Searcóg,Shercock	54	-6.9	P	PPL	IE	IE	U	02			0		153	Europe/Dublin	2010-08-14
-2961498	Shenicks Island	Shenicks Island		53.57472	-6.08444	T	ISL	IE		L	07			0		-9999	Europe/Dublin	2010-08-14
-2961499	Shelton Abbey	Shelton Abbey		52.815	-6.18278	S	EST	IE		L	31			0		43	Europe/Dublin	2010-08-14
-2961500	Shehy Mountain	Shehy Mountain		51.81778	-9.28722	T	MT	IE		M	04			0		334	Europe/Dublin	2010-08-14
-2961501	Sheffield	Sheffield	Sheffield,Sheffield House	53.00417	-7.26806	S	EST	IE	IE	L	15			0		150	Europe/Dublin	2010-08-14
-2961502	Sheep Haven	Sheep Haven	Cuan na gCaorach,Sheep Haven	55.2	-7.9	H	BAY	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
-2961503	Sheen River	Sheen River		51.86667	-9.56667	H	STM	IE		M	11			0		61	Europe/Dublin	1993-12-27
-2961504	Lough Sheelin	Lough Sheelin		53.8	-7.31667	H	LK	IE		L	21			0		73	Europe/Dublin	1993-12-27
-2961505	Sheehills House	Sheehills House		52.93278	-7.76861	S	EST	IE		M	26			0		135	Europe/Dublin	2010-08-14
-2961506	Sheeanamore	Sheeanamore		52.885	-6.37694	P	PPL	IE		L	31			0		269	Europe/Dublin	2010-08-14
-2961507	Shark Head	Shark Head	Shark Head,Stark Head	53.60167	-10.295	T	CAPE	IE	IE	C	10			0		-9999	Europe/Dublin	2010-08-14
-2961508	Shanvally	Shanvally		53.78333	-7.91667	P	PPL	IE		C	24			0		67	Europe/Dublin	1993-12-27
-2961509	Shantonagh	Shantonagh		54.05028	-6.85056	P	PPL	IE		U	22			0		147	Europe/Dublin	2010-08-14
-2961510	Shanow River	Shanow River		52.36667	-9.65	H	STM	IE		M	11			0		70	Europe/Dublin	1993-12-27
-2961511	Shannon View	Shannon View		52.61667	-8.98333	S	EST	IE		M	16			0		3	Europe/Dublin	1993-12-27
-2961512	Shannon Harbour	Shannon Harbour	Shannon Harbour	53.22056	-7.94833	P	PPL	IE		L	23			0		73	Europe/Dublin	2010-08-14
-2961513	Shannon Hall	Shannon Hall	Shannon Hall,Shannonvale House	52.90417	-8.28056	S	BLDG	IE	IE	M	26			0		51	Europe/Dublin	2010-11-04
-2961514	Shannongrove House	Shannongrove House	Shannongrove,Shannongrove House	52.66	-8.86417	S	EST	IE	IE	M	16			0		1	Europe/Dublin	2010-08-14
-2961515	Shannon Grove	Shannon Grove		53.19861	-8.04806	S	EST	IE		C	10			0		55	Europe/Dublin	2010-08-14
-2961516	Shannonbridge	Shannonbridge	Droichead na Sionainne,Shannonbridge	53.27778	-8.03722	P	PPL	IE		L	23			0		56	Europe/Dublin	2010-08-14
-2961517	River Shannon	River Shannon		52.58194	-9.68167	H	STM	IE		00				0		-9999	Europe/Dublin	1998-05-05
-2961518	Mouth of the Shannon	Mouth of the Shannon		52.50167	-9.81694	H	STMM	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
-2961519	Shannaghmore	Shannaghmore		53.6	-8.6	P	PPL	IE		C	10			0		76	Europe/Dublin	1993-12-27
-2961520	Shanlis Cross Roads	Shanlis Cross Roads	Shanlis,Shanlis Cross Roads	53.83778	-6.57111	P	PPL	IE	IE	L	19			0		49	Europe/Dublin	2010-08-14
-2961521	Shanlaragh	Shanlaragh		51.79556	-9.07889	P	PPL	IE		M	04			0		152	Europe/Dublin	2010-08-14
-2961522	Shankill Castle	Shankill Castle		52.68611	-7.02111	S	EST	IE		L	13			0		60	Europe/Dublin	2010-08-14
-2961523	Shankill	Shankill	Shankill	53.22611	-6.12444	P	PPL	IE		L	07			0		1	Europe/Dublin	2010-11-04
-2961524	Shanid Castle	Shanid Castle		52.55	-9.11667	S	BLDG	IE		M	16			0		117	Europe/Dublin	1993-12-27
-2961525	Shanganagh Junction	Shanganagh Junction		53.21667	-6.1	S	RSTN	IE		00				0		-9999	Europe/Dublin	1993-12-27
-2961526	Shanganagh Castle	Shanganagh Castle		53.22583	-6.11972	S	EST	IE		L	07			0		1	Europe/Dublin	2010-08-14
-2961527	Shanballymore	Shanballymore	An Seanbhaile Mor,An Seanbhaile Mór,Shanballymore	52.22028	-8.50139	P	PPL	IE		M	04			0		70	Europe/Dublin	2010-08-14
-2961528	Shanbally House	Shanbally House	Shanbally,Shanbally House	52.85722	-8.09167	S	EST	IE	IE	M	26			0		105	Europe/Dublin	2010-11-04
-2961529	Shanbally Castle	Shanbally Castle		52.29361	-8.04361	S	EST	IE		M	26			0		75	Europe/Dublin	2010-08-14
-2961530	Shanbally	Shanbally		51.8325	-8.3575	P	PPL	IE		M	04			0		11	Europe/Dublin	2010-08-14
-2961531	Shanagolden	Shanagolden	Seanghualainn,Shanagolden	52.5725	-9.1025	P	PPL	IE	IE	M	16			0		67	Europe/Dublin	2010-08-14
-2961532	Shanagh	Shanagh	Shanagh,Shunagh	51.58222	-8.71889	P	PPL	IE	IE	M	04			0		13	Europe/Dublin	2010-08-14
-2961533	Shanagarry	Shanagarry	Shanagarry	51.85444	-8.07083	P	PPL	IE		M	04			0		51	Europe/Dublin	2010-08-14
-2961534	Shallee River	Shallee River		52.87056	-8.99528	H	STM	IE		M	03			0		24	Europe/Dublin	2010-08-14
-2961535	Shaen House	Shaen House	Shaen,Shaen House	53.06667	-7.25	S	EST	IE	IE	L	15			0		141	Europe/Dublin	2010-08-14
-2961536	Shad Lough	Shad Lough		53.73333	-8.26667	H	LK	IE		C	24			0		76	Europe/Dublin	1993-12-27
-2961537	The Seven Stars	The Seven Stars		53.05722	-6.88028	L	LCTY	IE		L	12			0		108	Europe/Dublin	2010-08-14
-2961538	The Seven Hogs	The Seven Hogs	Magharee Islands,The Seven Hogs	52.32194	-10.03528	T	ISLS	IE	IE	M	11			0		-9999	Europe/Dublin	2010-08-14
-2961539	Seven Heads Bay	Seven Heads Bay		51.59444	-8.7	H	BAY	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
-2961540	Seven Heads	Seven Heads		51.56889	-8.7275	T	CAPE	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
-2961541	Seven Fathom Bank	Seven Fathom Bank		52.8	-6	H	BNK	IE		L	31			0		-9999	Europe/Dublin	1993-12-27
-2961542	Sevenchurches	Sevenchurches	Camaderry,Sevenchurches	53.02389	-6.39306	S	RUIN	IE	IE	L	31			0		588	Europe/Dublin	2010-08-14
-2961543	The Seven Arches	The Seven Arches	Seven Arches,The Seven Arches	55.21667	-7.6	S	CAVE	IE		U	06			0		-9999	Europe/Dublin	2010-08-10
-2961544	Seskinryan	Seskinryan		52.68222	-6.93167	P	PPL	IE		L	01			0		115	Europe/Dublin	2010-08-14
-2961545	Seskinrea	Seskinrea		52.76778	-7.06833	P	PPL	IE		L	01			0		191	Europe/Dublin	2010-08-14
-2961546	Seltannaveeny	Seltannaveeny	Seltannaveeny,Seltannavenny	54.1	-8.11667	P	PPL	IE		C	24			0		145	Europe/Dublin	2010-08-10
-2961547	Sellerna Bay	Sellerna Bay	Sellerna Bay,Sillerna Bay	53.55	-10.13333	H	BAY	IE		C	10			0		61	Europe/Dublin	2010-08-10
-2961548	Seershin	Seershin		53.26667	-9.21667	P	PPL	IE		C	10			0		57	Europe/Dublin	2010-08-14
-2961549	Seaweed Point	Seaweed Point		53.24889	-9.10944	T	PT	IE		C	10			0		-9999	Europe/Dublin	2010-08-14
-2961550	Seaview House	Seaview House	Seaview,Seaview House	52.02472	-7.58556	S	EST	IE	IE	M	27			0		2	Europe/Dublin	2010-08-14
-2961551	Seapark Point	Seapark Point		52.93333	-6.01667	T	PT	IE		L	31			0		-9999	Europe/Dublin	2010-08-14
-2961552	Sea Mount	Sea Mount		53.44278	-6.14	P	PPL	IE		L	07			0		1	Europe/Dublin	2010-08-14
-2961553	Seal Rocks	Seal Rocks		54.33667	-8.68722	T	RKS	IE		C	25			0		-9999	Europe/Dublin	2010-08-14
-2961554	Seafield House	Seafield House	Seafield,Seafield House	52.67417	-6.21444	S	EST	IE	IE	L	30			0		-9999	Europe/Dublin	2010-08-14
-2961555	Scurmore House	Scurmore House	Scarmore House,Scurmore House	54.19667	-9.11556	S	HSEC	IE	IE	C	25			0		3	Europe/Dublin	2010-08-14
-2961556	Lough Scur	Lough Scur	Lough Scur,Lough Seur	54.02667	-7.95222	H	LK	IE	IE	C	14			0		65	Europe/Dublin	2010-08-14
-2961557	Scullogue Gap	Scullogue Gap	Sculloge Gap,Scullogue Gap	52.57306	-6.7875	T	GAP	IE	IE	L	01			0		286	Europe/Dublin	2010-08-14
-2961558	Scullane Point	Scullane Point		51.49139	-9.21139	T	PT	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
-2961559	Scregg West	Scregg West		53.53333	-8.58333	P	PPL	IE		C	10			0		76	Europe/Dublin	1993-12-27
-2961560	Scregg House	Scregg House		53.55	-8.1	S	EST	IE		C	24			0		76	Europe/Dublin	1993-12-27
-2961561	Scregg East	Scregg East		53.53333	-8.56667	P	PPL	IE		C	10			0		76	Europe/Dublin	1993-12-27
-2961562	Screeb Lodge	Screeb Lodge	Screeb,Screeb Lodge	53.38694	-9.5525	S	HSEC	IE	IE	C	10			0		69	Europe/Dublin	2010-08-14
-2961563	Scramore Loughs	Scramore Loughs		54.3	-8.35	H	LKS	IE		00				0		284	Europe/Dublin	1993-12-27
-2961564	Scramoge	Scramoge		53.76667	-8.05	P	PPL	IE		C	24			0		76	Europe/Dublin	1993-12-27
-2961565	Scrahan	Scrahan		52.4	-9.36667	P	PPL	IE		M	11			0		143	Europe/Dublin	1993-12-27
-2961566	Scrabby	Scrabby		53.86667	-7.53333	P	PPL	IE		U	02			0		70	Europe/Dublin	1993-12-27
-2961567	Scotstown	Scotstown	Baile an Scotaigh,Scotstown	54.2775	-7.065	P	PPL	IE		U	22			0		81	Europe/Dublin	2010-08-14
-2961568	Scotshouse	Scotshouse		54.12194	-7.2475	P	PPL	IE		U	22			0		78	Europe/Dublin	2010-08-14
-2961569	Scilly	Scilly		51.70639	-8.52167	P	PPL	IE		M	04			0		1	Europe/Dublin	2010-08-14
-2961570	Scattery Island	Scattery Island		52.61222	-9.51944	T	ISL	IE		M	03			0		-9999	Europe/Dublin	2010-08-14
-2961571	Scartaglin	Scartaglin	Scartaglen,Scartaglin,Seartaglin	52.18333	-9.4	P	PPL	IE		M	11			0		149	Europe/Dublin	2010-08-10
-2961572	Scarriff Bay	Scarriff Bay	Scariff Bay,Scarriff Bay	52.90333	-8.48694	H	BAY	IE	IE	M	03			0		55	Europe/Dublin	2010-08-14
-2961573	River Scarriff	River Scarriff		52.9	-8.5	H	STM	IE		M	03			0		55	Europe/Dublin	1993-12-27
-2961574	Scarriff	Scarriff	An Scairbh,Scariff,Scarriff	52.89889	-8.50917	P	PPL	IE		M	03			0		82	Europe/Dublin	2010-08-14
-2961575	Scariff Island	Scariff Island	Great Hog Island,Scariff Island	51.73556	-10.25333	T	ISL	IE	IE	M	11			0		47	Europe/Dublin	2010-08-14
-2961576	Scardaun	Scardaun		53.65	-9	P	PPL	IE		C	20			0		120	Europe/Dublin	1993-12-27
-2961577	Lough Scannive	Lough Scannive		53.43528	-9.9525	H	LK	IE		C	10			0		81	Europe/Dublin	2010-08-14
-2961578	Scalp Mountain	Scalp Mountain		55.08917	-7.36611	T	MT	IE		U	06			0	484	352	Europe/Dublin	2010-08-14
-2961579	The Scalp	The Scalp	An Scailp,The Scalp	53.21611	-6.17944	T	GAP	IE	IE	00				0		151	Europe/Dublin	2010-08-10
-2961580	Scalp	Scalp		53.08333	-6.58333	P	PPL	IE		L	31			0		304	Europe/Dublin	2010-08-14
-2961581	Scalp	Scalp		52.99139	-8.48972	T	MT	IE		C	10			0		304	Europe/Dublin	2010-08-14
-2961582	Saundersville	Saundersville		52.96667	-6.68333	P	PPL	IE		L	31			0		156	Europe/Dublin	1993-12-27
-2961583	Saunders Court	Saunders Court		52.36611	-6.49333	S	EST	IE		L	30			0		1	Europe/Dublin	2010-08-14
-2961584	Sarsfieldscourt House	Sarsfieldscourt House	Sarsfieldcourt,Sarsfieldscourt House	51.95139	-8.4025	S	HSEC	IE	IE	M	04			0		89	Europe/Dublin	2010-08-14
-2961585	Sarnaght	Sarnaght		53.89056	-9.31389	P	PPL	IE		C	20			0		104	Europe/Dublin	2010-08-14
-2961586	Sarahville	Sarahville		52.16667	-7.46667	S	EST	IE		M	27			0		78	Europe/Dublin	1993-12-27
-2961587	Santry	Santry		53.39812	-6.25268	P	PPL	IE		L	07			0		12	Europe/Dublin	2010-08-14
-2961588	Sandymount	Sandymount		53.97139	-6.36194	P	PPL	IE		L	19			0		-9999	Europe/Dublin	2010-08-14
-2961589	Sandymount	Sandymount		53.335	-6.21139	P	PPL	IE		L	07			0		-9999	Europe/Dublin	2010-08-14
-2961590	Sandy Ford	Sandy Ford		52.85194	-6.46139	P	PPL	IE		L	31			0		289	Europe/Dublin	2010-08-14
-2961591	Sandy Cove	Sandy Cove		51.67694	-8.54917	P	PPL	IE		M	04			0		72	Europe/Dublin	2010-08-14
-2961592	Sandeel Bay	Sandeel Bay		52.1575	-6.87	H	BAY	IE		L	30			0		-9999	Europe/Dublin	2010-08-14
-2961593	Samphire Island	Samphire Island		52.27167	-9.865	T	ISL	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
-2961594	Saltmills	Saltmills		52.22194	-6.82667	P	PPL	IE		L	30			0		-9999	Europe/Dublin	2010-08-14
-2961595	Salt Hill	Salt Hill		53.26139	-9.06944	P	PPL	IE		C	10			0		1	Europe/Dublin	2010-08-14
-2961596	Salt Hill	Salt Hill		54.63111	-8.21111	S	EST	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
-2961597	Salterstown	Salterstown		53.87167	-6.30694	P	PPL	IE		L	19			0		1	Europe/Dublin	2010-08-14
-2961598	Saltee Islands	Saltee Islands	Saltee Islands	52.125	-6.59722	T	ISLS	IE		L	30			0		-9999	Europe/Dublin	2010-08-14
-2961599	Little Saltee	Little Saltee	Little Saltee,North Saltee,Saltee Island Little	52.13333	-6.61667	T	ISL	IE	IE	L	30			0		-9999	Europe/Dublin	2010-08-14
-2961600	Great Saltee	Great Saltee	Great Saltee,Saltee Island Great,South Saltee	52.11667	-6.61667	T	ISL	IE	IE	L	30			0		-9999	Europe/Dublin	2010-08-14
-2961601	Lough Salt	Lough Salt		55.08278	-7.80611	H	LK	IE		U	06			0		340	Europe/Dublin	2010-08-14
-2961602	Salrock	Salrock		53.6	-9.85	P	PPL	IE		C	10			0		144	Europe/Dublin	1993-12-27
-2961603	Sallymount House	Sallymount House	Sallymount,Sallymount House	53.12222	-6.70972	S	EST	IE	IE	L	12			0		151	Europe/Dublin	2010-08-14
-2961604	Sally Gap	Sally Gap	Sally Gap,Sully Gap	53.13611	-6.31306	T	GAP	IE	IE	L	31			0		460	Europe/Dublin	2010-08-14
-2961605	Sallybrook Station	Sallybrook Station	Sallybrook,Sallybrook Station	54.95	-7.56667	S	RSTN	IE		U	06			0		86	Europe/Dublin	2010-08-10
-2961606	Sallybrook	Sallybrook	Sallybrook	51.935	-8.38639	P	PPL	IE		M	04			0		76	Europe/Dublin	2010-08-14
-2961607	Sallins	Sallins	Na Sollain,Na Solláin,Sallins	53.24889	-6.66611	P	PPL	IE		L	12			3164		97	Europe/Dublin	2010-08-14
-2961608	Salisbury Lodge	Salisbury Lodge		53.65	-8	S	EST	IE		L	18			0		79	Europe/Dublin	1993-12-27
-2961609	Salia	Salia		53.95111	-9.94806	P	PPL	IE		C	20			0		26	Europe/Dublin	2010-08-14
-2961610	Saleen Harbour	Saleen Harbour	Saleen Bay,Saleen Harbour	54.18361	-10.03	H	HBR	IE	IE	C	20			0		-9999	Europe/Dublin	2010-08-14
-2961611	Saleen	Saleen		52.55861	-9.46444	P	PPL	IE		M	11			0		11	Europe/Dublin	2010-08-14
-2961612	Saleen	Saleen		51.86333	-8.16556	P	PPL	IE		M	04			0		74	Europe/Dublin	2010-08-14
-2961613	Saivnose River	Saivnose River		51.61278	-9.27	H	STM	IE		M	04			0		56	Europe/Dublin	2010-08-14
-2961614	Saint Thomas Island	Saint Thomas Island		52.69	-8.62	T	ISL	IE		M	03			0		2	Europe/Dublin	2010-08-14
-2961615	Saint Stephens Green Park	Saint Stephens Green Park		53.33784	-6.25813	L	PRK	IE		L	07			0		5	Europe/Dublin	2010-08-14
-2961616	Saints Island	Saints Island		54.61528	-7.88639	T	ISL	IE		U	06			0		152	Europe/Dublin	2010-08-14
-2961617	Patrickswell	Patrickswell	Patrickswell,Saint Patrickswell,Tobar Phadraig,Tobar Phádraig	52.59722	-8.70889	P	PPL	IE		M	16			0		55	Europe/Dublin	2010-08-14
-2961618	Saint Patricks Island	Saint Patricks Island		53.58833	-6.07389	T	ISL	IE		L	07			0		-9999	Europe/Dublin	2010-08-14
-2961619	Saint Mullins	Saint Mullins		52.49278	-6.92306	P	PPL	IE		L	01			0		45	Europe/Dublin	2010-08-14
-2961620	Saint Margarets House	Saint Margarets House		52.20083	-6.34472	S	BLDG	IE		L	30			0		-9999	Europe/Dublin	2010-08-14
-2961621	Saint Macdaras Island	Saint Macdaras Island	Macdara,Saint Macdaras Island	53.305	-9.91889	T	ISL	IE	IE	C	10			0		-9999	Europe/Dublin	2010-08-14
-2961622	Saint Johnstown	Saint Johnstown	Baile Suingean,Saint Johnston,Saint Johnstown	54.93333	-7.45	P	PPL	IE		U	06			0		1	Europe/Dublin	2010-08-14
-2961623	Saint Johns Port	Saint Johns Port		54.33333	-8.6	P	PPL	IE		C	25			0		-9999	Europe/Dublin	1993-12-27
-2961624	Saint John’s Point	Saint John's Point		54.56667	-8.46667	T	PT	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
-2961625	Saint Johns Lough	Saint Johns Lough		54.04028	-7.86167	H	LK	IE		C	14			0		70	Europe/Dublin	2010-08-14
-2961626	Saint Johns House	Saint Johns House		52.48833	-6.56944	S	EST	IE		L	30			0		51	Europe/Dublin	2010-08-14
-2961627	Saint Finans Bay	Saint Finans Bay	Saint Finans Bay,Saint Finian Bay,Saint Finnans Bay	51.81667	-10.36667	H	BAY	IE	IE	M	11			0		-9999	Europe/Dublin	2010-08-14
-2961628	Saint Edmonds	Saint Edmonds		52.38333	-6.48333	S	EST	IE		L	30			0		1	Europe/Dublin	2010-08-14
-2961629	Saint Doolaghs	Saint Doolaghs		53.41639	-6.18056	P	PPL	IE		L	07			0		3	Europe/Dublin	2010-08-14
-2961630	Saint Clerans	Saint Clerans	Saint Clerans,Saint Clernans	53.22667	-8.65778	S	EST	IE	IE	C	10			0		51	Europe/Dublin	2010-08-14
-2961631	Saint Catherines	Saint Catherines	Saint Catharine's,Saint Catharine’s,Saint Catherines	52.86667	-8.6	P	PPL	IE		M	03			0		76	Europe/Dublin	2010-08-10
-2961632	Saint Brendans House	Saint Brendans House		53.53333	-8.4	S	EST	IE		C	10			0		69	Europe/Dublin	1993-12-27
-2961633	Saint Brendans	Saint Brendans	Saint Bredan's,Saint Bredan’s,Saint Brendans	53.23417	-8.06083	S	EST	IE	IE	C	10			0		61	Europe/Dublin	2010-08-14
-2961634	Saint Anns Wells	Saint Anns Wells		53.23333	-6.35	P	PPL	IE		00				0		300	Europe/Dublin	2007-05-30
-2961635	Saint Anns Hill	Saint Anns Hill	Saint Ann's,Saint Anne's Hill,Saint Anne’s Hill,Saint Anns Hill,Saint Ann’s	51.93333	-8.6	P	PPL	IE	IE	M	04			0		68	Europe/Dublin	2010-08-14
-2961636	Saggart	Saggart	Saggart,Teach Sagard	53.28028	-6.44444	P	PPL	IE	IE	L	07			0		150	Europe/Dublin	2010-11-04
-2961637	Safe Harbour	Safe Harbour		53.53333	-8	H	COVE	IE		C	24			0		62	Europe/Dublin	1993-12-27
-2961638	Saddle Hill	Saddle Hill		54.34861	-8.12917	T	MT	IE		C	14			0	379	310	Europe/Dublin	2010-08-14
-2961639	Saddle Head	Saddle Head	Gubroenacoragh,Saddle Head	54.01222	-10.18889	T	CAPE	IE	IE	C	20			0		45	Europe/Dublin	2010-08-14
-2961640	Ryves Castle	Ryves Castle		52.42306	-8.36611	S	EST	IE		M	16			0		121	Europe/Dublin	2010-08-14
-2961641	Ryndville	Ryndville		53.43667	-6.82306	S	EST	IE		L	21			0		86	Europe/Dublin	2010-08-14
-2961642	Rylane Cross	Rylane Cross	Rylane,Rylane Cross	51.98333	-8.83333	P	PPL	IE	IE	M	04			0		191	Europe/Dublin	2010-08-14
-2961643	Rye Water	Rye Water	An Ri,Rye Water	53.365	-6.49111	H	STM	IE	IE	00				0		47	Europe/Dublin	2010-08-10
-2961644	Ryehill	Ryehill		53.39889	-8.69222	S	EST	IE		C	10			0		76	Europe/Dublin	2010-08-14
-2961645	Ryefield	Ryefield		53.78806	-7.05861	P	PPL	IE		U	02			0		126	Europe/Dublin	2010-08-14
-2961646	Rutland Island	Rutland Island		54.97667	-8.45722	T	ISL	IE		U	06			0		1	Europe/Dublin	2010-08-14
-2961647	Russborough House	Russborough House	Russborough,Russborough House	53.14111	-6.56806	S	HSEC	IE	IE	L	31			0		181	Europe/Dublin	2010-08-14
-2961648	Rushin House	Rushin House		53.01778	-7.49528	S	EST	IE		L	15			0		129	Europe/Dublin	2010-08-14
-2961649	Slieve Rushen	Slieve Rushen	Slieve Rushen	54.15	-7.63333	T	MT	IE		U	02			0		309	Europe/Dublin	1998-02-13
-2961650	Rushbrooke	Rushbrooke	Rushbrooke	51.85	-8.31667	P	PPL	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
-2961651	An Ros	An Ros	Rush	53.5223	-6.09308	P	PPL	IE		L	07			7294		1	Europe/Dublin	2010-08-14
-2961652	Runnamoat House	Runnamoat House	Runnamoat,Runnamoat House	53.68333	-8.31667	S	EST	IE		C	24			0		77	Europe/Dublin	2010-08-10
-2961653	Rue Point	Rue Point	Bankmore Point,Rue Point	54.43639	-8.64583	T	PT	IE	IE	C	25			0		-9999	Europe/Dublin	2010-08-14
-2961654	Ruan	Ruan		52.93056	-8.98972	P	PPL	IE		M	03			0		38	Europe/Dublin	2010-08-14
-2961655	Royaloak	Royaloak		52.7	-6.98667	P	PPL	IE		L	01			0		40	Europe/Dublin	2010-08-14
-2961656	Royal Canal	Royal Canal	An Chanail Rioga,Royal Canal	53.35	-6.23333	H	CNL	IE	IE	00				0		1	Europe/Dublin	2010-08-10
-2961657	Roy	Roy		54.08028	-9.94528	P	PPLL	IE		C	20			0		1	Europe/Dublin	2010-08-14
-2961658	Roxborough House	Roxborough House	Roxborough,Roxborough House	53.65	-8.18333	S	EST	IE		C	24			0		75	Europe/Dublin	2010-08-10
-2961659	Roxborough House	Roxborough House	Roxborough,Roxborough House	52.61306	-8.615	S	EST	IE	IE	M	16			0		56	Europe/Dublin	2010-08-14
-2961660	Roxborough	Roxborough		53.16694	-8.69528	S	EST	IE		C	10			0		76	Europe/Dublin	2010-08-14
-2961661	Rowls Aldworth	Rowls Aldworth		52.3	-9.01667	S	BLDG	IE		M	04			0		232	Europe/Dublin	1

<TRUNCATED>

[29/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/PackedQuadPrefixTree.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/PackedQuadPrefixTree.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/PackedQuadPrefixTree.java
new file mode 100644
index 0000000..6fe2bff
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/PackedQuadPrefixTree.java
@@ -0,0 +1,459 @@
+/*
+ * 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.prefix.tree;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.SpatialRelation;
+import com.spatial4j.core.shape.impl.RectangleImpl;
+import org.apache.lucene.util.BytesRef;
+
+/**
+ * Uses a compact binary representation of 8 bytes to encode a spatial quad trie.
+ *
+ * The binary representation is as follows:
+ * <pre>
+ * CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDL
+ *
+ * Where C = Cell bits (2 per quad)
+ *       D = Depth bits (5 with max of 29 levels)
+ *       L = isLeaf bit
+ * </pre>
+ *
+ * It includes a built-in "pruneLeafyBranches" setting (true by default) similar to
+ * {@link org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy#setPruneLeafyBranches(boolean)} although
+ * this one only prunes at the target detail level (where it has the most effect).  Usually you should disable RPT's
+ * prune, since it is very memory in-efficient.
+ *
+ * @lucene.experimental
+ */
+public class PackedQuadPrefixTree extends QuadPrefixTree {
+  public static final int MAX_LEVELS_POSSIBLE = 29;
+  protected static final byte[] QUAD = new byte[] {0x00, 0x01, 0x02, 0x03};
+
+  protected boolean leafyPrune = true;
+
+  /**
+   * Factory for creating {@link PackedQuadPrefixTree} instances with useful defaults.
+   */
+  public static class Factory extends QuadPrefixTree.Factory {
+    @Override
+    protected SpatialPrefixTree newSPT() {
+      return new PackedQuadPrefixTree(ctx, maxLevels != null ? maxLevels : MAX_LEVELS_POSSIBLE);
+    }
+  }
+
+  public PackedQuadPrefixTree(SpatialContext ctx, int maxLevels) {
+    super(ctx, maxLevels);
+    if (maxLevels > MAX_LEVELS_POSSIBLE) {
+      throw new IllegalArgumentException("maxLevels of " + maxLevels + " exceeds limit of " + MAX_LEVELS_POSSIBLE);
+    }
+  }
+
+  @Override
+  public String toString() {
+    return getClass().getSimpleName() + "(maxLevels:" + maxLevels + ",ctx:" + ctx + ",prune:" + leafyPrune + ")";
+  }
+
+  @Override
+  public Cell getWorldCell() {
+    return new PackedQuadCell(0x0L);
+  }
+
+  @Override
+  public Cell getCell(Point p, int level) {
+    List<Cell> cells = new ArrayList<>(1);
+    build(xmid, ymid, 0, cells, 0x0L, ctx.makePoint(p.getX(), p.getY()), level);
+    return cells.get(0);//note cells could be longer if p on edge
+  }
+
+  protected void build(double x, double y, int level, List<Cell> matches, long term, Shape shape, int maxLevel) {
+    double w = levelW[level] / 2;
+    double h = levelH[level] / 2;
+
+    // Z-Order
+    // http://en.wikipedia.org/wiki/Z-order_%28curve%29
+    checkBattenberg(QUAD[0], x - w, y + h, level, matches, term, shape, maxLevel);
+    checkBattenberg(QUAD[1], x + w, y + h, level, matches, term, shape, maxLevel);
+    checkBattenberg(QUAD[2], x - w, y - h, level, matches, term, shape, maxLevel);
+    checkBattenberg(QUAD[3], x + w, y - h, level, matches, term, shape, maxLevel);
+  }
+
+  protected void checkBattenberg(byte quad, double cx, double cy, int level, List<Cell> matches,
+                               long term, Shape shape, int maxLevel) {
+    // short-circuit if we find a match for the point (no need to continue recursion)
+    if (shape instanceof Point && !matches.isEmpty())
+      return;
+    double w = levelW[level] / 2;
+    double h = levelH[level] / 2;
+
+    SpatialRelation v = shape.relate(ctx.makeRectangle(cx - w, cx + w, cy - h, cy + h));
+
+    if (SpatialRelation.DISJOINT == v) {
+      return;
+    }
+
+    // set bits for next level
+    term |= (((long)(quad))<<(64-(++level<<1)));
+    // increment level
+    term = ((term>>>1)+1)<<1;
+
+    if (SpatialRelation.CONTAINS == v || (level >= maxLevel)) {
+      matches.add(new PackedQuadCell(term, v.transpose()));
+    } else {// SpatialRelation.WITHIN, SpatialRelation.INTERSECTS
+      build(cx, cy, level, matches, term, shape, maxLevel);
+    }
+  }
+
+  @Override
+  public Cell readCell(BytesRef term, Cell scratch) {
+    PackedQuadCell cell = (PackedQuadCell) scratch;
+    if (cell == null)
+      cell = (PackedQuadCell) getWorldCell();
+    cell.readCell(term);
+    return cell;
+  }
+
+  @Override
+  public CellIterator getTreeCellIterator(Shape shape, int detailLevel) {
+    if (detailLevel > maxLevels) {
+      throw new IllegalArgumentException("detailLevel:" + detailLevel +" exceed max: " + maxLevels);
+    }
+    return new PrefixTreeIterator(shape, (short) detailLevel);
+  }
+
+  public boolean isPruneLeafyBranches() {
+    return leafyPrune;
+  }
+
+  /** Like {@link org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy#setPruneLeafyBranches(boolean)}
+   * but more memory efficient and only applies to the detailLevel, where it has the most effect. */
+  public void setPruneLeafyBranches( boolean pruneLeafyBranches ) {
+    this.leafyPrune = pruneLeafyBranches;
+  }
+
+  /** See binary representation in the javadocs of {@link PackedQuadPrefixTree}. */
+  protected class PackedQuadCell extends QuadCell {
+    private long term;
+
+    PackedQuadCell(long term) {
+      super(null, 0, 0);
+      this.term = term;
+      this.b_off = 0;
+      this.bytes = longToByteArray(this.term);
+      this.b_len = 8;
+      readLeafAdjust();
+    }
+
+    PackedQuadCell(long term, SpatialRelation shapeRel) {
+      this(term);
+      this.shapeRel = shapeRel;
+    }
+
+    @Override
+    protected void readCell(BytesRef bytes) {
+      shapeRel = null;
+      shape = null;
+      this.bytes = bytes.bytes;
+      this.b_off = bytes.offset;
+      this.b_len = (short) bytes.length;
+      this.term = longFromByteArray(this.bytes, bytes.offset);
+      readLeafAdjust();
+    }
+
+    private final int getShiftForLevel(final int level) {
+      return 64 - (level<<1);
+    }
+
+    public boolean isEnd(final int level, final int shift) {
+      return (term != 0x0L && ((((0x1L<<(level<<1))-1)-(term>>>shift)) == 0x0L));
+    }
+
+    /**
+     * Get the next cell in the tree without using recursion. descend parameter requests traversal to the child nodes,
+     * setting this to false will step to the next sibling.
+     * Note: This complies with lexicographical ordering, once you've moved to the next sibling there is no backtracking.
+     */
+    public PackedQuadCell nextCell(boolean descend) {
+      final int level = getLevel();
+      final int shift = getShiftForLevel(level);
+      // base case: can't go further
+      if ( (!descend && isEnd(level, shift)) || isEnd(maxLevels, getShiftForLevel(maxLevels))) {
+        return null;
+      }
+      long newTerm;
+      final boolean isLeaf = (term&0x1L)==0x1L;
+      // if descend requested && we're not at the maxLevel
+      if ((descend && !isLeaf && (level != maxLevels)) || level == 0) {
+        // simple case: increment level bits (next level)
+        newTerm = ((term>>>1)+0x1L)<<1;
+      } else {  // we're not descending or we can't descend
+        newTerm = term + (0x1L<<shift);
+        // we're at the last sibling...force descend
+        if (((term>>>shift)&0x3L) == 0x3L) {
+          // adjust level for number popping up
+          newTerm = ((newTerm>>>1) - (Long.numberOfTrailingZeros(newTerm>>>shift)>>>1))<<1;
+        }
+      }
+      return new PackedQuadCell(newTerm);
+    }
+
+    @Override
+    protected void readLeafAdjust() {
+      isLeaf = ((0x1L)&term) == 0x1L;
+      if (getLevel() == getMaxLevels()) {
+        isLeaf = true;
+      }
+    }
+
+    @Override
+    public BytesRef getTokenBytesWithLeaf(BytesRef result) {
+      if (isLeaf) {
+        term |= 0x1L;
+      }
+      return getTokenBytesNoLeaf(result);
+    }
+
+    @Override
+    public BytesRef getTokenBytesNoLeaf(BytesRef result) {
+      if (result == null)
+        return new BytesRef(bytes, b_off, b_len);
+      result.bytes = longToByteArray(this.term);
+      result.offset = 0;
+      result.length = result.bytes.length;
+      return result;
+    }
+
+    @Override
+    public int compareToNoLeaf(Cell fromCell) {
+      PackedQuadCell b = (PackedQuadCell) fromCell;
+      final long thisTerm = (((0x1L)&term) == 0x1L) ? term-1 : term;
+      final long fromTerm = (((0x1L)&b.term) == 0x1L) ? b.term-1 : b.term;
+      final int result = Long.compareUnsigned(thisTerm, fromTerm);
+      assert Math.signum(result)
+          == Math.signum(compare(longToByteArray(thisTerm), 0, 8, longToByteArray(fromTerm), 0, 8)); // TODO remove
+      return result;
+    }
+
+    @Override
+    public int getLevel() {
+      int l = (int)((term >>> 1)&0x1FL);
+      return l;
+    }
+
+    @Override
+    protected Collection<Cell> getSubCells() {
+      List<Cell> cells = new ArrayList<>(4);
+      PackedQuadCell pqc = (new PackedQuadCell(((term&0x1)==0x1) ? this.term-1 : this.term))
+          .nextCell(true);
+      cells.add(pqc);
+      cells.add((pqc = pqc.nextCell(false)));
+      cells.add((pqc = pqc.nextCell(false)));
+      cells.add(pqc.nextCell(false));
+      return cells;
+    }
+
+    @Override
+    protected QuadCell getSubCell(Point p) {
+      return (PackedQuadCell) PackedQuadPrefixTree.this.getCell(p, getLevel() + 1);//not performant!
+    }
+
+    @Override
+    public boolean isPrefixOf(Cell c) {
+      PackedQuadCell cell = (PackedQuadCell)c;
+      return (this.term == 0x0L) || isInternalPrefix(cell);
+    }
+
+    protected boolean isInternalPrefix(PackedQuadCell c) {
+      final int shift = 64 - (getLevel()<<1);
+      return ((term>>>shift)-(c.term>>>shift)) == 0x0L;
+    }
+
+    protected long concat(byte postfix) {
+      // extra leaf bit
+      return this.term | (((long)(postfix))<<((getMaxLevels()-getLevel()<<1)+6));
+    }
+
+    /**
+     * Constructs a bounding box shape out of the encoded cell
+     */
+    @Override
+    protected Rectangle makeShape() {
+      double xmin = PackedQuadPrefixTree.this.xmin;
+      double ymin = PackedQuadPrefixTree.this.ymin;
+      int level = getLevel();
+
+      byte b;
+      for (short l=0, i=1; l<level; ++l, ++i) {
+        b = (byte) ((term>>>(64-(i<<1))) & 0x3L);
+
+        switch (b) {
+          case 0x00:
+            ymin += levelH[l];
+            break;
+          case 0x01:
+            xmin += levelW[l];
+            ymin += levelH[l];
+            break;
+          case 0x02:
+            break;//nothing really
+          case 0x03:
+            xmin += levelW[l];
+            break;
+          default:
+            throw new RuntimeException("unexpected quadrant");
+        }
+      }
+
+      double width, height;
+      if (level > 0) {
+        width = levelW[level - 1];
+        height = levelH[level - 1];
+      } else {
+        width = gridW;
+        height = gridH;
+      }
+      return new RectangleImpl(xmin, xmin + width, ymin, ymin + height, ctx);
+    }
+
+    private long fromBytes(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8) {
+      return ((long)b1 & 255L) << 56 | ((long)b2 & 255L) << 48 | ((long)b3 & 255L) << 40
+          | ((long)b4 & 255L) << 32 | ((long)b5 & 255L) << 24 | ((long)b6 & 255L) << 16
+          | ((long)b7 & 255L) << 8 | (long)b8 & 255L;
+    }
+
+    private byte[] longToByteArray(long value) {
+      byte[] result = new byte[8];
+      for(int i = 7; i >= 0; --i) {
+        result[i] = (byte)((int)(value & 255L));
+        value >>= 8;
+      }
+      return result;
+    }
+
+    private long longFromByteArray(byte[] bytes, int ofs) {
+      assert bytes.length >= 8;
+      return fromBytes(bytes[0+ofs], bytes[1+ofs], bytes[2+ofs], bytes[3+ofs],
+          bytes[4+ofs], bytes[5+ofs], bytes[6+ofs], bytes[7+ofs]);
+    }
+
+    /**
+     * Used for debugging, this will print the bits of the cell
+     */
+    @Override
+    public String toString() {
+      StringBuilder s = new StringBuilder(64);
+      final int numberOfLeadingZeros = Long.numberOfLeadingZeros(term);
+      for (int i = 0; i < numberOfLeadingZeros; i++) {
+        s.append('0');
+      }
+      if (term != 0)
+        s.append(Long.toBinaryString(term));
+      return s.toString();
+    }
+  } // PackedQuadCell
+
+  /** This is a streamlined version of TreeCellIterator, with built-in support to prune at detailLevel
+   * (but not recursively upwards). */
+  protected class PrefixTreeIterator extends CellIterator {
+    private Shape shape;
+    private PackedQuadCell thisCell;
+    private PackedQuadCell nextCell;
+
+    private short level;
+    private final short detailLevel;
+    private CellIterator pruneIter;
+
+    PrefixTreeIterator(Shape shape, short detailLevel) {
+      this.shape = shape;
+      this.thisCell = ((PackedQuadCell)(getWorldCell())).nextCell(true);
+      this.detailLevel = detailLevel;
+      this.nextCell = null;
+    }
+
+    @Override
+    public boolean hasNext() {
+      if (nextCell != null) {
+        return true;
+      }
+      SpatialRelation rel;
+      // loop until we're at the end of the quad tree or we hit a relation
+      while (thisCell != null) {
+        rel = thisCell.getShape().relate(shape);
+        if (rel == SpatialRelation.DISJOINT) {
+          thisCell = thisCell.nextCell(false);
+        } else { // within || intersects || contains
+          thisCell.setShapeRel(rel);
+          nextCell = thisCell;
+          if (rel == SpatialRelation.WITHIN) {
+            thisCell.setLeaf();
+            thisCell = thisCell.nextCell(false);
+          } else {  // intersects || contains
+            level = (short) (thisCell.getLevel());
+            if (level == detailLevel || pruned(rel)) {
+              thisCell.setLeaf();
+              if (shape instanceof Point) {
+                thisCell.setShapeRel(SpatialRelation.WITHIN);
+                thisCell = null;
+              } else {
+                thisCell = thisCell.nextCell(false);
+              }
+              break;
+            }
+            thisCell = thisCell.nextCell(true);
+          }
+          break;
+        }
+      }
+      return nextCell != null;
+    }
+
+    private boolean pruned(SpatialRelation rel) {
+      int leaves;
+      if (rel == SpatialRelation.INTERSECTS && leafyPrune && level == detailLevel - 1) {
+        for (leaves=0, pruneIter=thisCell.getNextLevelCells(shape); pruneIter.hasNext(); pruneIter.next(), ++leaves);
+        return leaves == 4;
+      }
+      return false;
+    }
+
+    @Override
+    public Cell next() {
+      if (nextCell == null) {
+        if (!hasNext()) {
+          throw new NoSuchElementException();
+        }
+      }
+      // overriding since this implementation sets thisCell in hasNext
+      Cell temp = nextCell;
+      nextCell = null;
+      return temp;
+    }
+
+    @Override
+    public void remove() {
+      //no-op
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java
new file mode 100644
index 0000000..48dac87
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java
@@ -0,0 +1,308 @@
+/*
+ * 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.prefix.tree;
+
+import java.io.PrintStream;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Locale;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.SpatialRelation;
+import org.apache.lucene.util.BytesRef;
+
+/**
+ * A {@link SpatialPrefixTree} which uses a
+ * <a href="http://en.wikipedia.org/wiki/Quadtree">quad tree</a> in which an
+ * indexed term will be generated for each cell, 'A', 'B', 'C', 'D'.
+ *
+ * @lucene.experimental
+ */
+public class QuadPrefixTree extends LegacyPrefixTree {
+
+  /**
+   * Factory for creating {@link QuadPrefixTree} instances with useful defaults
+   */
+  public static class Factory extends SpatialPrefixTreeFactory {
+
+    @Override
+    protected int getLevelForDistance(double degrees) {
+      QuadPrefixTree grid = new QuadPrefixTree(ctx, MAX_LEVELS_POSSIBLE);
+      return grid.getLevelForDistance(degrees);
+    }
+
+    @Override
+    protected SpatialPrefixTree newSPT() {
+      return new QuadPrefixTree(ctx,
+          maxLevels != null ? maxLevels : MAX_LEVELS_POSSIBLE);
+    }
+  }
+
+  public static final int MAX_LEVELS_POSSIBLE = 50;//not really sure how big this should be
+
+  public static final int DEFAULT_MAX_LEVELS = 12;
+  protected final double xmin;
+  protected final double xmax;
+  protected final double ymin;
+  protected final double ymax;
+  protected final double xmid;
+  protected final double ymid;
+
+  protected final double gridW;
+  public final double gridH;
+
+  final double[] levelW;
+  final double[] levelH;
+  final int[]    levelS; // side
+  final int[]    levelN; // number
+
+  public QuadPrefixTree(
+      SpatialContext ctx, Rectangle bounds, int maxLevels) {
+    super(ctx, maxLevels);
+    this.xmin = bounds.getMinX();
+    this.xmax = bounds.getMaxX();
+    this.ymin = bounds.getMinY();
+    this.ymax = bounds.getMaxY();
+
+    levelW = new double[maxLevels];
+    levelH = new double[maxLevels];
+    levelS = new int[maxLevels];
+    levelN = new int[maxLevels];
+
+    gridW = xmax - xmin;
+    gridH = ymax - ymin;
+    this.xmid = xmin + gridW/2.0;
+    this.ymid = ymin + gridH/2.0;
+    levelW[0] = gridW/2.0;
+    levelH[0] = gridH/2.0;
+    levelS[0] = 2;
+    levelN[0] = 4;
+
+    for (int i = 1; i < levelW.length; i++) {
+      levelW[i] = levelW[i - 1] / 2.0;
+      levelH[i] = levelH[i - 1] / 2.0;
+      levelS[i] = levelS[i - 1] * 2;
+      levelN[i] = levelN[i - 1] * 4;
+    }
+  }
+
+  public QuadPrefixTree(SpatialContext ctx) {
+    this(ctx, DEFAULT_MAX_LEVELS);
+  }
+
+  public QuadPrefixTree(
+      SpatialContext ctx, int maxLevels) {
+    this(ctx, ctx.getWorldBounds(), maxLevels);
+  }
+
+  @Override
+  public Cell getWorldCell() {
+    return new QuadCell(BytesRef.EMPTY_BYTES, 0, 0);
+  }
+
+  public void printInfo(PrintStream out) {
+    NumberFormat nf = NumberFormat.getNumberInstance(Locale.ROOT);
+    nf.setMaximumFractionDigits(5);
+    nf.setMinimumFractionDigits(5);
+    nf.setMinimumIntegerDigits(3);
+
+    for (int i = 0; i < maxLevels; i++) {
+      out.println(i + "]\t" + nf.format(levelW[i]) + "\t" + nf.format(levelH[i]) + "\t" +
+          levelS[i] + "\t" + (levelS[i] * levelS[i]));
+    }
+  }
+
+  @Override
+  public int getLevelForDistance(double dist) {
+    if (dist == 0)//short circuit
+      return maxLevels;
+    for (int i = 0; i < maxLevels-1; i++) {
+      //note: level[i] is actually a lookup for level i+1
+      if(dist > levelW[i] && dist > levelH[i]) {
+        return i+1;
+      }
+    }
+    return maxLevels;
+  }
+
+  @Override
+  public Cell getCell(Point p, int level) {
+    List<Cell> cells = new ArrayList<>(1);
+    build(xmid, ymid, 0, cells, new BytesRef(maxLevels+1), ctx.makePoint(p.getX(),p.getY()), level);
+    return cells.get(0);//note cells could be longer if p on edge
+  }
+
+  private void build(
+      double x,
+      double y,
+      int level,
+      List<Cell> matches,
+      BytesRef str,
+      Shape shape,
+      int maxLevel) {
+    assert str.length == level;
+    double w = levelW[level] / 2;
+    double h = levelH[level] / 2;
+
+    // Z-Order
+    // http://en.wikipedia.org/wiki/Z-order_%28curve%29
+    checkBattenberg('A', x - w, y + h, level, matches, str, shape, maxLevel);
+    checkBattenberg('B', x + w, y + h, level, matches, str, shape, maxLevel);
+    checkBattenberg('C', x - w, y - h, level, matches, str, shape, maxLevel);
+    checkBattenberg('D', x + w, y - h, level, matches, str, shape, maxLevel);
+
+    // possibly consider hilbert curve
+    // http://en.wikipedia.org/wiki/Hilbert_curve
+    // http://blog.notdot.net/2009/11/Damn-Cool-Algorithms-Spatial-indexing-with-Quadtrees-and-Hilbert-Curves
+    // if we actually use the range property in the query, this could be useful
+  }
+
+  protected void checkBattenberg(
+      char c,
+      double cx,
+      double cy,
+      int level,
+      List<Cell> matches,
+      BytesRef str,
+      Shape shape,
+      int maxLevel) {
+    assert str.length == level;
+    assert str.offset == 0;
+    double w = levelW[level] / 2;
+    double h = levelH[level] / 2;
+
+    int strlen = str.length;
+    Rectangle rectangle = ctx.makeRectangle(cx - w, cx + w, cy - h, cy + h);
+    SpatialRelation v = shape.relate(rectangle);
+    if (SpatialRelation.CONTAINS == v) {
+      str.bytes[str.length++] = (byte)c;//append
+      //str.append(SpatialPrefixGrid.COVER);
+      matches.add(new QuadCell(BytesRef.deepCopyOf(str), v.transpose()));
+    } else if (SpatialRelation.DISJOINT == v) {
+      // nothing
+    } else { // SpatialRelation.WITHIN, SpatialRelation.INTERSECTS
+      str.bytes[str.length++] = (byte)c;//append
+
+      int nextLevel = level+1;
+      if (nextLevel >= maxLevel) {
+        //str.append(SpatialPrefixGrid.INTERSECTS);
+        matches.add(new QuadCell(BytesRef.deepCopyOf(str), v.transpose()));
+      } else {
+        build(cx, cy, nextLevel, matches, str, shape, maxLevel);
+      }
+    }
+    str.length = strlen;
+  }
+
+  protected class QuadCell extends LegacyCell {
+
+    QuadCell(byte[] bytes, int off, int len) {
+      super(bytes, off, len);
+    }
+
+    QuadCell(BytesRef str, SpatialRelation shapeRel) {
+      this(str.bytes, str.offset, str.length);
+      this.shapeRel = shapeRel;
+    }
+
+    @Override
+    protected QuadPrefixTree getGrid() { return QuadPrefixTree.this; }
+
+    @Override
+    protected int getMaxLevels() { return maxLevels; }
+
+    @Override
+    protected Collection<Cell> getSubCells() {
+      BytesRef source = getTokenBytesNoLeaf(null);
+
+      List<Cell> cells = new ArrayList<>(4);
+      cells.add(new QuadCell(concat(source, (byte)'A'), null));
+      cells.add(new QuadCell(concat(source, (byte)'B'), null));
+      cells.add(new QuadCell(concat(source, (byte)'C'), null));
+      cells.add(new QuadCell(concat(source, (byte)'D'), null));
+      return cells;
+    }
+
+    protected BytesRef concat(BytesRef source, byte b) {
+      //+2 for new char + potential leaf
+      final byte[] buffer = Arrays.copyOfRange(source.bytes, source.offset, source.offset + source.length + 2);
+      BytesRef target = new BytesRef(buffer);
+      target.length = source.length;
+      target.bytes[target.length++] = b;
+      return target;
+    }
+
+    @Override
+    public int getSubCellsSize() {
+      return 4;
+    }
+
+    @Override
+    protected QuadCell getSubCell(Point p) {
+      return (QuadCell) QuadPrefixTree.this.getCell(p, getLevel() + 1);//not performant!
+    }
+
+    @Override
+    public Shape getShape() {
+      if (shape == null)
+        shape = makeShape();
+      return shape;
+    }
+
+    protected Rectangle makeShape() {
+      BytesRef token = getTokenBytesNoLeaf(null);
+      double xmin = QuadPrefixTree.this.xmin;
+      double ymin = QuadPrefixTree.this.ymin;
+
+      for (int i = 0; i < token.length; i++) {
+        byte c = token.bytes[token.offset + i];
+        switch (c) {
+          case 'A':
+            ymin += levelH[i];
+            break;
+          case 'B':
+            xmin += levelW[i];
+            ymin += levelH[i];
+            break;
+          case 'C':
+            break;//nothing really
+          case 'D':
+            xmin += levelW[i];
+            break;
+          default:
+            throw new RuntimeException("unexpected char: " + c);
+        }
+      }
+      int len = token.length;
+      double width, height;
+      if (len > 0) {
+        width = levelW[len-1];
+        height = levelH[len-1];
+      } else {
+        width = gridW;
+        height = gridH;
+      }
+      return ctx.makeRectangle(xmin, xmin + width, ymin, ymin + height);
+    }
+  }//QuadCell
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/SingletonCellIterator.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/SingletonCellIterator.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/SingletonCellIterator.java
new file mode 100644
index 0000000..177b431
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/SingletonCellIterator.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial.prefix.tree;
+
+/**
+ * A singleton (one Cell) instance of CellIterator.
+ *
+ * @lucene.internal
+ */
+class SingletonCellIterator extends CellIterator {
+
+  SingletonCellIterator(Cell cell) {
+    this.nextCell = cell;//preload nextCell
+  }
+
+  @Override
+  public boolean hasNext() {
+    thisCell = null;
+    return nextCell != null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTree.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTree.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTree.java
new file mode 100644
index 0000000..8ead954
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTree.java
@@ -0,0 +1,117 @@
+/*
+ * 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.prefix.tree;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.util.BytesRef;
+
+/**
+ * A spatial Prefix Tree, or Trie, which decomposes shapes into prefixed strings
+ * at variable lengths corresponding to variable precision.  Each string
+ * corresponds to a rectangular spatial region.  This approach is
+ * also referred to "Grids", "Tiles", and "Spatial Tiers".
+ * <p>
+ * Implementations of this class should be thread-safe and immutable once
+ * initialized.
+ *
+ * @lucene.experimental
+ */
+public abstract class SpatialPrefixTree {
+
+  protected final int maxLevels;
+
+  protected final SpatialContext ctx;
+
+  public SpatialPrefixTree(SpatialContext ctx, int maxLevels) {
+    assert maxLevels > 0;
+    this.ctx = ctx;
+    this.maxLevels = maxLevels;
+  }
+
+  public SpatialContext getSpatialContext() {
+    return ctx;
+  }
+
+  public int getMaxLevels() {
+    return maxLevels;
+  }
+
+  @Override
+  public String toString() {
+    return getClass().getSimpleName() + "(maxLevels:" + maxLevels + ",ctx:" + ctx + ")";
+  }
+
+  /**
+   * Returns the level of the largest grid in which its longest side is less
+   * than or equal to the provided distance (in degrees). Consequently {@code
+   * dist} acts as an error epsilon declaring the amount of detail needed in the
+   * grid, such that you can get a grid with just the right amount of
+   * precision.
+   *
+   * @param dist {@code >= 0}
+   * @return level [1 to maxLevels]
+   */
+  public abstract int getLevelForDistance(double dist);
+
+  /**
+   * Given a cell having the specified level, returns the distance from opposite
+   * corners. Since this might vary depending on where the cell is, this method
+   * may over-estimate.
+   *
+   * @param level [1 to maxLevels]
+   * @return {@code > 0}
+   */
+  public abstract double getDistanceForLevel(int level);
+
+  /**
+   * Returns the level 0 cell which encompasses all spatial data. Equivalent to {@link #readCell(BytesRef,Cell)}
+   * with no bytes.
+   */
+  public abstract Cell getWorldCell(); //another possible name: getTopCell
+
+  /**
+   * This creates a new Cell (or re-using {@code scratch} if provided), initialized to the state as read
+   * by the bytes.
+   * Warning: An implementation may refer to the same byte array (no copy). If {@link Cell#setLeaf()} is
+   * subsequently called, it would then modify these bytes.
+   */
+  public abstract Cell readCell(BytesRef term, Cell scratch);
+
+  /**
+   * Gets the intersecting cells for the specified shape, without exceeding
+   * detail level. If a cell is within the query shape then it's marked as a
+   * leaf and none of its children are added. For cells at detailLevel, they are marked as
+   * leaves too, unless it's a point.
+   * <p>
+   * IMPORTANT: Cells returned from the iterator can be re-used for cells at the same level. So you can't simply
+   * iterate to subsequent cells and still refer to the former cell nor the bytes returned from the former cell, unless
+   * you know the former cell is a parent.
+   *
+   * @param shape       the shape; possibly null but the caller should liberally call
+   *  {@code remove()} if so.
+   * @param detailLevel the maximum detail level to get cells for
+   * @return the matching cells
+   */
+  public CellIterator getTreeCellIterator(Shape shape, int detailLevel) {
+    if (detailLevel > maxLevels) {
+      throw new IllegalArgumentException("detailLevel > maxLevels");
+    }
+    return new TreeCellIterator(shape, detailLevel, getWorldCell());
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeFactory.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeFactory.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeFactory.java
new file mode 100644
index 0000000..b74dc93
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeFactory.java
@@ -0,0 +1,99 @@
+/*
+ * 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.prefix.tree;
+
+import java.util.Map;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.distance.DistanceUtils;
+
+/**
+ * Abstract Factory for creating {@link SpatialPrefixTree} instances with useful
+ * defaults and passed on configurations defined in a Map.
+ *
+ * @lucene.experimental
+ */
+public abstract class SpatialPrefixTreeFactory {
+
+  private static final double DEFAULT_GEO_MAX_DETAIL_KM = 0.001;//1m
+  public static final String PREFIX_TREE = "prefixTree";
+  public static final String MAX_LEVELS = "maxLevels";
+  public static final String MAX_DIST_ERR = "maxDistErr";
+
+  protected Map<String, String> args;
+  protected SpatialContext ctx;
+  protected Integer maxLevels;
+
+  /**
+   * The factory  is looked up via "prefixTree" in args, expecting "geohash" or "quad".
+   * If it's neither of these, then "geohash" is chosen for a geo context, otherwise "quad" is chosen.
+   */
+  public static SpatialPrefixTree makeSPT(Map<String,String> args, ClassLoader classLoader, SpatialContext ctx) {
+    SpatialPrefixTreeFactory instance;
+    String cname = args.get(PREFIX_TREE);
+    if (cname == null)
+      cname = ctx.isGeo() ? "geohash" : "quad";
+    if ("geohash".equalsIgnoreCase(cname))
+      instance = new GeohashPrefixTree.Factory();
+    else if ("quad".equalsIgnoreCase(cname))
+      instance = new QuadPrefixTree.Factory();
+    else if ("packedQuad".equalsIgnoreCase(cname))
+      instance = new PackedQuadPrefixTree.Factory();
+    else {
+      try {
+        Class<?> c = classLoader.loadClass(cname);
+        instance = (SpatialPrefixTreeFactory) c.newInstance();
+      } catch (Exception e) {
+        throw new RuntimeException(e);
+      }
+    }
+    instance.init(args,ctx);
+    return instance.newSPT();
+  }
+
+  protected void init(Map<String, String> args, SpatialContext ctx) {
+    this.args = args;
+    this.ctx = ctx;
+    initMaxLevels();
+  }
+
+  protected void initMaxLevels() {
+    String mlStr = args.get(MAX_LEVELS);
+    if (mlStr != null) {
+      maxLevels = Integer.valueOf(mlStr);
+      return;
+    }
+
+    double degrees;
+    String maxDetailDistStr = args.get(MAX_DIST_ERR);
+    if (maxDetailDistStr == null) {
+      if (!ctx.isGeo()) {
+        return;//let default to max
+      }
+      degrees = DistanceUtils.dist2Degrees(DEFAULT_GEO_MAX_DETAIL_KM, DistanceUtils.EARTH_MEAN_RADIUS_KM);
+    } else {
+      degrees = Double.parseDouble(maxDetailDistStr);
+    }
+    maxLevels = getLevelForDistance(degrees);
+  }
+
+  /** Calls {@link SpatialPrefixTree#getLevelForDistance(double)}. */
+  protected abstract int getLevelForDistance(double degrees);
+
+  protected abstract SpatialPrefixTree newSPT();
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/TreeCellIterator.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/TreeCellIterator.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/TreeCellIterator.java
new file mode 100644
index 0000000..3ec56ac
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/TreeCellIterator.java
@@ -0,0 +1,87 @@
+/*
+ * 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.prefix.tree;
+
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Shape;
+
+/**
+ * Navigates a {@link org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree} from a given cell (typically the world
+ * cell) down to a maximum number of configured levels, filtered by a given shape. Intermediate non-leaf cells are
+ * returned. It supports {@link #remove()} for skipping traversal of subcells of the current cell.
+ *
+ * @lucene.internal
+ */
+class TreeCellIterator extends CellIterator {
+  //This class uses a stack approach, which is more efficient than creating linked nodes. And it might more easily
+  // pave the way for re-using Cell & CellIterator at a given level in the future.
+
+  private final Shape shapeFilter;//possibly null
+  private final CellIterator[] iterStack;//starts at level 1
+  private int stackIdx;//-1 when done
+  private boolean descend;
+
+  public TreeCellIterator(Shape shapeFilter, int detailLevel, Cell parentCell) {
+    this.shapeFilter = shapeFilter;
+    assert parentCell.getLevel() == 0;
+    iterStack = new CellIterator[detailLevel];
+    iterStack[0] = parentCell.getNextLevelCells(shapeFilter);
+    stackIdx = 0;//always points to an iter (non-null)
+    //note: not obvious but needed to visit the first cell before trying to descend
+    descend = false;
+  }
+
+  @Override
+  public boolean hasNext() {
+    if (nextCell != null)
+      return true;
+    while (true) {
+      if (stackIdx == -1)//the only condition in which we return false
+        return false;
+      //If we can descend...
+      if (descend && !(stackIdx == iterStack.length - 1 || iterStack[stackIdx].thisCell().isLeaf())) {
+        CellIterator nextIter = iterStack[stackIdx].thisCell().getNextLevelCells(shapeFilter);
+        //push stack
+        iterStack[++stackIdx] = nextIter;
+      }
+      //Get sibling...
+      if (iterStack[stackIdx].hasNext()) {
+        nextCell = iterStack[stackIdx].next();
+        //at detailLevel
+        if (stackIdx == iterStack.length - 1 && !(shapeFilter instanceof Point)) //point check is a kludge
+          nextCell.setLeaf();//because at bottom
+        break;
+      }
+      //Couldn't get next; go up...
+      //pop stack
+      iterStack[stackIdx--] = null;
+      descend = false;//so that we don't re-descend where we just were
+    }
+    assert nextCell != null;
+    descend = true;//reset
+    return true;
+  }
+
+  @Override
+  public void remove() {
+    assert thisCell() != null && nextCell == null;
+    descend = false;
+  }
+
+  //TODO implement a smart nextFrom() that looks at the parent's bytes first
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/package-info.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/package-info.java
new file mode 100644
index 0000000..20a4a0e
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/package-info.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+/**
+ * This package is about SpatialPrefixTree and any supporting classes.
+ * A SpatialPrefixTree supports spatial indexing by index-time tokens
+ * where adding characters to a string gives greater resolution.
+ * <p>
+ * Potential Implementations include:
+ * <ul>
+ * <li>http://en.wikipedia.org/wiki/Quadtree
+ * <li>http://en.wikipedia.org/wiki/Geohash
+ * <li>http://healpix.jpl.nasa.gov/
+ * </ul>
+ */
+package org.apache.lucene.spatial.prefix.tree;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/SpatialArgs.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/SpatialArgs.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/SpatialArgs.java
new file mode 100644
index 0000000..0503072
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/SpatialArgs.java
@@ -0,0 +1,148 @@
+/*
+ * 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.query;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+
+/**
+ * Principally holds the query {@link Shape} and the {@link SpatialOperation}.
+ * It's used as an argument to some methods on {@link org.apache.lucene.spatial.SpatialStrategy}.
+ *
+ * @lucene.experimental
+ */
+public class SpatialArgs {
+
+  public static final double DEFAULT_DISTERRPCT = 0.025d;
+
+  private SpatialOperation operation;
+  private Shape shape;
+  private Double distErrPct;
+  private Double distErr;
+
+  public SpatialArgs(SpatialOperation operation, Shape shape) {
+    if (operation == null || shape == null)
+      throw new NullPointerException("operation and shape are required");
+    this.operation = operation;
+    this.shape = shape;
+  }
+
+  /**
+   * Computes the distance given a shape and the {@code distErrPct}.  The
+   * algorithm is the fraction of the distance from the center of the query
+   * shape to its closest bounding box corner.
+   *
+   * @param shape Mandatory.
+   * @param distErrPct 0 to 0.5
+   * @param ctx Mandatory
+   * @return A distance (in degrees).
+   */
+  public static double calcDistanceFromErrPct(Shape shape, double distErrPct, SpatialContext ctx) {
+    if (distErrPct < 0 || distErrPct > 0.5) {
+      throw new IllegalArgumentException("distErrPct " + distErrPct + " must be between [0 to 0.5]");
+    }
+    if (distErrPct == 0 || shape instanceof Point) {
+      return 0;
+    }
+    Rectangle bbox = shape.getBoundingBox();
+    //Compute the distance from the center to a corner.  Because the distance
+    // to a bottom corner vs a top corner can vary in a geospatial scenario,
+    // take the closest one (greater precision).
+    Point ctr = bbox.getCenter();
+    double y = (ctr.getY() >= 0 ? bbox.getMaxY() : bbox.getMinY());
+    double diagonalDist = ctx.getDistCalc().distance(ctr, bbox.getMaxX(), y);
+    return diagonalDist * distErrPct;
+  }
+
+  /**
+   * Gets the error distance that specifies how precise the query shape is. This
+   * looks at {@link #getDistErr()}, {@link #getDistErrPct()}, and {@code
+   * defaultDistErrPct}.
+   * @param defaultDistErrPct 0 to 0.5
+   * @return {@code >= 0}
+   */
+  public double resolveDistErr(SpatialContext ctx, double defaultDistErrPct) {
+    if (distErr != null)
+      return distErr;
+    double distErrPct = (this.distErrPct != null ? this.distErrPct : defaultDistErrPct);
+    return calcDistanceFromErrPct(shape, distErrPct, ctx);
+  }
+
+  /** Check if the arguments make sense -- throw an exception if not */
+  public void validate() throws IllegalArgumentException {
+    if (distErr != null && distErrPct != null)
+      throw new IllegalArgumentException("Only distErr or distErrPct can be specified.");
+  }
+
+  @Override
+  public String toString() {
+    return SpatialArgsParser.writeSpatialArgs(this);
+  }
+
+  //------------------------------------------------
+  // Getters & Setters
+  //------------------------------------------------
+
+  public SpatialOperation getOperation() {
+    return operation;
+  }
+
+  public void setOperation(SpatialOperation operation) {
+    this.operation = operation;
+  }
+
+  public Shape getShape() {
+    return shape;
+  }
+
+  public void setShape(Shape shape) {
+    this.shape = shape;
+  }
+
+  /**
+   * A measure of acceptable error of the shape as a fraction.  This effectively
+   * inflates the size of the shape but should not shrink it.
+   *
+   * @return 0 to 0.5
+   * @see #calcDistanceFromErrPct(com.spatial4j.core.shape.Shape, double,
+   *      com.spatial4j.core.context.SpatialContext)
+   */
+  public Double getDistErrPct() {
+    return distErrPct;
+  }
+
+  public void setDistErrPct(Double distErrPct) {
+    if (distErrPct != null)
+      this.distErrPct = distErrPct;
+  }
+
+  /**
+   * The acceptable error of the shape.  This effectively inflates the
+   * size of the shape but should not shrink it.
+   *
+   * @return {@code >= 0}
+   */
+  public Double getDistErr() {
+    return distErr;
+  }
+
+  public void setDistErr(Double distErr) {
+    this.distErr = distErr;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/SpatialArgsParser.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/SpatialArgsParser.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/SpatialArgsParser.java
new file mode 100644
index 0000000..81612ff
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/SpatialArgsParser.java
@@ -0,0 +1,146 @@
+/*
+ * 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.query;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.exception.InvalidShapeException;
+import com.spatial4j.core.shape.Shape;
+
+import java.text.ParseException;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * Parses a string that usually looks like "OPERATION(SHAPE)" into a {@link SpatialArgs}
+ * object. The set of operations supported are defined in {@link SpatialOperation}, such
+ * as "Intersects" being a common one. The shape portion is defined by WKT {@link com.spatial4j.core.io.WktShapeParser},
+ * but it can be overridden/customized via {@link #parseShape(String, com.spatial4j.core.context.SpatialContext)}.
+ * There are some optional name-value pair parameters that follow the closing parenthesis.  Example:
+ * <pre>
+ *   Intersects(ENVELOPE(-10,-8,22,20)) distErrPct=0.025
+ * </pre>
+ * <p>
+ * In the future it would be good to support something at least semi-standardized like a
+ * variant of <a href="http://docs.geoserver.org/latest/en/user/filter/ecql_reference.html#spatial-predicate">
+ *   [E]CQL</a>.
+ *
+ * @lucene.experimental
+ */
+public class SpatialArgsParser {
+
+  public static final String DIST_ERR_PCT = "distErrPct";
+  public static final String DIST_ERR = "distErr";
+
+  /** Writes a close approximation to the parsed input format. */
+  static String writeSpatialArgs(SpatialArgs args) {
+    StringBuilder str = new StringBuilder();
+    str.append(args.getOperation().getName());
+    str.append('(');
+    str.append(args.getShape().toString());
+    if (args.getDistErrPct() != null)
+      str.append(" distErrPct=").append(String.format(Locale.ROOT, "%.2f%%", args.getDistErrPct() * 100d));
+    if (args.getDistErr() != null)
+      str.append(" distErr=").append(args.getDistErr());
+    str.append(')');
+    return str.toString();
+  }
+
+  /**
+   * Parses a string such as "Intersects(ENVELOPE(-10,-8,22,20)) distErrPct=0.025".
+   *
+   * @param v   The string to parse. Mandatory.
+   * @param ctx The spatial context. Mandatory.
+   * @return Not null.
+   * @throws IllegalArgumentException if the parameters don't make sense or an add-on parameter is unknown
+   * @throws ParseException If there is a problem parsing the string
+   * @throws InvalidShapeException When the coordinates are invalid for the shape
+   */
+  public SpatialArgs parse(String v, SpatialContext ctx) throws ParseException, InvalidShapeException {
+    int idx = v.indexOf('(');
+    int edx = v.lastIndexOf(')');
+
+    if (idx < 0 || idx > edx) {
+      throw new ParseException("missing parens: " + v, -1);
+    }
+
+    SpatialOperation op = SpatialOperation.get(v.substring(0, idx).trim());
+
+    String body = v.substring(idx + 1, edx).trim();
+    if (body.length() < 1) {
+      throw new ParseException("missing body : " + v, idx + 1);
+    }
+
+    Shape shape = parseShape(body, ctx);
+    SpatialArgs args = newSpatialArgs(op, shape);
+
+    if (v.length() > (edx + 1)) {
+      body = v.substring(edx + 1).trim();
+      if (body.length() > 0) {
+        Map<String, String> aa = parseMap(body);
+        readNameValuePairs(args, aa);
+        if (!aa.isEmpty()) {
+          throw new IllegalArgumentException("unused parameters: " + aa);
+        }
+      }
+    }
+    args.validate();
+    return args;
+  }
+
+  protected SpatialArgs newSpatialArgs(SpatialOperation op, Shape shape) {
+    return new SpatialArgs(op, shape);
+  }
+
+  protected void readNameValuePairs(SpatialArgs args, Map<String, String> nameValPairs) {
+    args.setDistErrPct(readDouble(nameValPairs.remove(DIST_ERR_PCT)));
+    args.setDistErr(readDouble(nameValPairs.remove(DIST_ERR)));
+  }
+
+  protected Shape parseShape(String str, SpatialContext ctx) throws ParseException {
+    //return ctx.readShape(str);//still in Spatial4j 0.4 but will be deleted
+    return ctx.readShapeFromWkt(str);
+  }
+
+  protected static Double readDouble(String v) {
+    return v == null ? null : Double.valueOf(v);
+  }
+
+  protected static boolean readBool(String v, boolean defaultValue) {
+    return v == null ? defaultValue : Boolean.parseBoolean(v);
+  }
+
+  /** Parses "a=b c=d f" (whitespace separated) into name-value pairs. If there
+   * is no '=' as in 'f' above then it's short for f=f. */
+  protected static Map<String, String> parseMap(String body) {
+    Map<String, String> map = new HashMap<>();
+    StringTokenizer st = new StringTokenizer(body, " \n\t");
+    while (st.hasMoreTokens()) {
+      String a = st.nextToken();
+      int idx = a.indexOf('=');
+      if (idx > 0) {
+        String k = a.substring(0, idx);
+        String v = a.substring(idx + 1);
+        map.put(k, v);
+      } else {
+        map.put(a, a);
+      }
+    }
+    return map;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/SpatialOperation.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/SpatialOperation.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/SpatialOperation.java
new file mode 100644
index 0000000..7d750ac
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/SpatialOperation.java
@@ -0,0 +1,179 @@
+/*
+ * 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.query;
+
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.SpatialRelation;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * A predicate that compares a stored geometry to a supplied geometry. It's enum-like. For more
+ * explanation of each predicate, consider looking at the source implementation
+ * of {@link #evaluate(com.spatial4j.core.shape.Shape, com.spatial4j.core.shape.Shape)}. It's important
+ * to be aware that Lucene-spatial makes no distinction of shape boundaries, unlike many standardized
+ * definitions. Nor does it make dimensional distinctions (e.g. line vs polygon).
+ * You can lookup a predicate by "Covers" or "Contains", for example, and you will get the
+ * same underlying predicate implementation.
+ *
+ * @see <a href="http://en.wikipedia.org/wiki/DE-9IM">DE-9IM at Wikipedia, based on OGC specs</a>
+ * @see <a href="http://edndoc.esri.com/arcsde/9.1/general_topics/understand_spatial_relations.htm">
+ *   ESRIs docs on spatial relations</a>
+ *
+ * @lucene.experimental
+ */
+public abstract class SpatialOperation implements Serializable {
+  //TODO rename to SpatialPredicate. Use enum?  LUCENE-5771
+
+  // Private registry
+  private static final Map<String, SpatialOperation> registry = new HashMap<>();//has aliases
+  private static final List<SpatialOperation> list = new ArrayList<>();
+
+  // Geometry Operations
+
+  /** Bounding box of the *indexed* shape, then {@link #Intersects}. */
+  public static final SpatialOperation BBoxIntersects = new SpatialOperation("BBoxIntersects") {
+    @Override
+    public boolean evaluate(Shape indexedShape, Shape queryShape) {
+      return indexedShape.getBoundingBox().relate(queryShape).intersects();
+    }
+  };
+  /** Bounding box of the *indexed* shape, then {@link #IsWithin}. */
+  public static final SpatialOperation BBoxWithin     = new SpatialOperation("BBoxWithin") {
+    {
+      register("BBoxCoveredBy");//alias -- the better name
+    }
+    @Override
+    public boolean evaluate(Shape indexedShape, Shape queryShape) {
+      Rectangle bbox = indexedShape.getBoundingBox();
+      return bbox.relate(queryShape) == SpatialRelation.WITHIN || bbox.equals(queryShape);
+    }
+  };
+  /** Meets the "Covers" OGC definition (boundary-neutral). */
+  public static final SpatialOperation Contains       = new SpatialOperation("Contains") {
+    {
+      register("Covers");//alias -- the better name
+    }
+    @Override
+    public boolean evaluate(Shape indexedShape, Shape queryShape) {
+      return indexedShape.relate(queryShape) == SpatialRelation.CONTAINS || indexedShape.equals(queryShape);
+    }
+  };
+  /** Meets the "Intersects" OGC definition. */
+  public static final SpatialOperation Intersects     = new SpatialOperation("Intersects") {
+    @Override
+    public boolean evaluate(Shape indexedShape, Shape queryShape) {
+      return indexedShape.relate(queryShape).intersects();
+    }
+  };
+  /** Meets the "Equals" OGC definition. */
+  public static final SpatialOperation IsEqualTo      = new SpatialOperation("Equals") {
+    {
+      register("IsEqualTo");//alias (deprecated)
+    }
+    @Override
+    public boolean evaluate(Shape indexedShape, Shape queryShape) {
+      return indexedShape.equals(queryShape);
+    }
+  };
+  /** Meets the "Disjoint" OGC definition. */
+  public static final SpatialOperation IsDisjointTo   = new SpatialOperation("Disjoint") {
+    {
+      register("IsDisjointTo");//alias (deprecated)
+    }
+    @Override
+    public boolean evaluate(Shape indexedShape, Shape queryShape) {
+      return ! indexedShape.relate(queryShape).intersects();
+    }
+  };
+  /** Meets the "CoveredBy" OGC definition (boundary-neutral). */
+  public static final SpatialOperation IsWithin       = new SpatialOperation("Within") {
+    {
+      register("IsWithin");//alias (deprecated)
+      register("CoveredBy");//alias -- the more appropriate name.
+    }
+    @Override
+    public boolean evaluate(Shape indexedShape, Shape queryShape) {
+      return indexedShape.relate(queryShape) == SpatialRelation.WITHIN || indexedShape.equals(queryShape);
+    }
+  };
+  /** Almost meets the "Overlaps" OGC definition, but boundary-neutral (boundary==interior). */
+  public static final SpatialOperation Overlaps       = new SpatialOperation("Overlaps") {
+    @Override
+    public boolean evaluate(Shape indexedShape, Shape queryShape) {
+      return indexedShape.relate(queryShape) == SpatialRelation.INTERSECTS;//not Contains or Within or Disjoint
+    }
+  };
+
+  private final String name;
+
+  protected SpatialOperation(String name) {
+    this.name = name;
+    register(name);
+    list.add( this );
+  }
+
+  protected void register(String name) {
+    registry.put(name, this);
+    registry.put(name.toUpperCase(Locale.ROOT), this);
+  }
+
+  public static SpatialOperation get( String v ) {
+    SpatialOperation op = registry.get( v );
+    if( op == null ) {
+      op = registry.get(v.toUpperCase(Locale.ROOT));
+    }
+    if( op == null ) {
+      throw new IllegalArgumentException("Unknown Operation: " + v );
+    }
+    return op;
+  }
+
+  public static List<SpatialOperation> values() {
+    return list;
+  }
+
+  public static boolean is( SpatialOperation op, SpatialOperation ... tst ) {
+    for( SpatialOperation t : tst ) {
+      if( op == t ) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Returns whether the relationship between indexedShape and queryShape is
+   * satisfied by this operation.
+   */
+  public abstract boolean evaluate(Shape indexedShape, Shape queryShape);
+
+  public String getName() {
+    return name;
+  }
+
+  @Override
+  public String toString() {
+    return name;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/UnsupportedSpatialOperation.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/UnsupportedSpatialOperation.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/UnsupportedSpatialOperation.java
new file mode 100644
index 0000000..d6cb152
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/UnsupportedSpatialOperation.java
@@ -0,0 +1,28 @@
+/*
+ * 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.query;
+
+/**
+ * Exception thrown when the {@link org.apache.lucene.spatial.SpatialStrategy} cannot implement the requested operation.
+ * @lucene.experimental
+ */
+public class UnsupportedSpatialOperation extends UnsupportedOperationException {
+
+  public UnsupportedSpatialOperation(SpatialOperation op) {
+    super(op.getName());
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/package-info.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/package-info.java
new file mode 100644
index 0000000..a7946a4
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/query/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Spatial Query options useful for client side requests
+ */
+package org.apache.lucene.spatial.query;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java
new file mode 100644
index 0000000..a6c575b
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java
@@ -0,0 +1,278 @@
+/*
+ * 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.serialized;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.util.Map;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.io.BinaryCodec;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.document.BinaryDocValuesField;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.index.BinaryDocValues;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.search.Explanation;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.RandomAccessWeight;
+import org.apache.lucene.search.TwoPhaseIterator;
+import org.apache.lucene.search.Weight;
+import org.apache.lucene.spatial.SpatialStrategy;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.util.DistanceToShapeValueSource;
+import org.apache.lucene.spatial.util.ShapePredicateValueSource;
+import org.apache.lucene.util.Bits;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.BytesRefBuilder;
+
+
+/**
+ * A SpatialStrategy based on serializing a Shape stored into BinaryDocValues.
+ * This is not at all fast; it's designed to be used in conjunction with another index based
+ * SpatialStrategy that is approximated (like {@link org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy})
+ * to add precision or eventually make more specific / advanced calculations on the per-document
+ * geometry.
+ * The serialization uses Spatial4j's {@link com.spatial4j.core.io.BinaryCodec}.
+ *
+ * @lucene.experimental
+ */
+public class SerializedDVStrategy extends SpatialStrategy {
+
+  /**
+   * A cache heuristic for the buf size based on the last shape size.
+   */
+  //TODO do we make this non-volatile since it's merely a heuristic?
+  private volatile int indexLastBufSize = 8 * 1024;//8KB default on first run
+
+  /**
+   * Constructs the spatial strategy with its mandatory arguments.
+   */
+  public SerializedDVStrategy(SpatialContext ctx, String fieldName) {
+    super(ctx, fieldName);
+  }
+
+  @Override
+  public Field[] createIndexableFields(Shape shape) {
+    int bufSize = Math.max(128, (int) (this.indexLastBufSize * 1.5));//50% headroom over last
+    ByteArrayOutputStream byteStream = new ByteArrayOutputStream(bufSize);
+    final BytesRef bytesRef = new BytesRef();//receiver of byteStream's bytes
+    try {
+      ctx.getBinaryCodec().writeShape(new DataOutputStream(byteStream), shape);
+      //this is a hack to avoid redundant byte array copying by byteStream.toByteArray()
+      byteStream.writeTo(new FilterOutputStream(null/*not used*/) {
+        @Override
+        public void write(byte[] b, int off, int len) throws IOException {
+          bytesRef.bytes = b;
+          bytesRef.offset = off;
+          bytesRef.length = len;
+        }
+      });
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+    this.indexLastBufSize = bytesRef.length;//cache heuristic
+    return new Field[]{new BinaryDocValuesField(getFieldName(), bytesRef)};
+  }
+
+  @Override
+  public ValueSource makeDistanceValueSource(Point queryPoint, double multiplier) {
+    //TODO if makeShapeValueSource gets lifted to the top; this could become a generic impl.
+    return new DistanceToShapeValueSource(makeShapeValueSource(), queryPoint, multiplier, ctx);
+  }
+
+  /**
+   * Returns a Query that should be used in a random-access fashion.
+   * Use in another manner will be SLOW.
+   */
+  @Override
+  public Query makeQuery(SpatialArgs args) {
+    ValueSource shapeValueSource = makeShapeValueSource();
+    ShapePredicateValueSource predicateValueSource = new ShapePredicateValueSource(
+        shapeValueSource, args.getOperation(), args.getShape());
+    return new PredicateValueSourceQuery(predicateValueSource);
+  }
+
+  /**
+   * Provides access to each shape per document as a ValueSource in which
+   * {@link org.apache.lucene.queries.function.FunctionValues#objectVal(int)} returns a {@link
+   * Shape}.
+   */ //TODO raise to SpatialStrategy
+  public ValueSource makeShapeValueSource() {
+    return new ShapeDocValueSource(getFieldName(), ctx.getBinaryCodec());
+  }
+
+  /** Warning: don't iterate over the results of this query; it's designed for use in a random-access fashion
+   * by {@link TwoPhaseIterator}.
+   */
+  static class PredicateValueSourceQuery extends Query {
+    private final ValueSource predicateValueSource;//we call boolVal(doc)
+
+    public PredicateValueSourceQuery(ValueSource predicateValueSource) {
+      this.predicateValueSource = predicateValueSource;
+    }
+
+    @Override
+    public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
+      return new RandomAccessWeight(this) {
+        @Override
+        protected Bits getMatchingDocs(LeafReaderContext context) throws IOException {
+          final FunctionValues predFuncValues = predicateValueSource.getValues(null, context);
+          return new Bits() {
+            @Override
+            public boolean get(int index) {
+              return predFuncValues.boolVal(index);
+            }
+
+            @Override
+            public int length() {
+              return context.reader().maxDoc();
+            }
+          };
+        }
+      };
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (this == o) return true;
+      if (super.equals(o) == false) return false;
+
+      PredicateValueSourceQuery that = (PredicateValueSourceQuery) o;
+
+      if (!predicateValueSource.equals(that.predicateValueSource)) return false;
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      return super.hashCode() + 31 * predicateValueSource.hashCode();
+    }
+
+    @Override
+    public String toString(String field) {
+      return "PredicateValueSourceQuery(" +
+               predicateValueSource.toString() +
+             ")";
+    }
+  }//PredicateValueSourceQuery
+
+  /**
+   * Implements a ValueSource by deserializing a Shape in from BinaryDocValues using BinaryCodec.
+   * @see #makeShapeValueSource()
+   */
+  static class ShapeDocValueSource extends ValueSource {
+
+    private final String fieldName;
+    private final BinaryCodec binaryCodec;//spatial4j
+
+    private ShapeDocValueSource(String fieldName, BinaryCodec binaryCodec) {
+      this.fieldName = fieldName;
+      this.binaryCodec = binaryCodec;
+    }
+
+    @Override
+    public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
+      final BinaryDocValues docValues = readerContext.reader().getBinaryDocValues(fieldName);
+
+      return new FunctionValues() {
+        int bytesRefDoc = -1;
+        BytesRefBuilder bytesRef = new BytesRefBuilder();
+
+        boolean fillBytes(int doc) {
+          if (bytesRefDoc != doc) {
+            bytesRef.copyBytes(docValues.get(doc));
+            bytesRefDoc = doc;
+          }
+          return bytesRef.length() != 0;
+        }
+
+        @Override
+        public boolean exists(int doc) {
+          return fillBytes(doc);
+        }
+
+        @Override
+        public boolean bytesVal(int doc, BytesRefBuilder target) {
+          target.clear();
+          if (fillBytes(doc)) {
+            target.copyBytes(bytesRef);
+            return true;
+          } else {
+            return false;
+          }
+        }
+
+        @Override
+        public Object objectVal(int docId) {
+          if (!fillBytes(docId))
+            return null;
+          DataInputStream dataInput = new DataInputStream(
+              new ByteArrayInputStream(bytesRef.bytes(), 0, bytesRef.length()));
+          try {
+            return binaryCodec.readShape(dataInput);
+          } catch (IOException e) {
+            throw new RuntimeException(e);
+          }
+        }
+
+        @Override
+        public Explanation explain(int doc) {
+          return Explanation.match(Float.NaN, toString(doc));
+        }
+
+        @Override
+        public String toString(int doc) {
+          return description() + "=" + objectVal(doc);//TODO truncate?
+        }
+
+      };
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+
+      ShapeDocValueSource that = (ShapeDocValueSource) o;
+
+      if (!fieldName.equals(that.fieldName)) return false;
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int result = fieldName.hashCode();
+      return result;
+    }
+
+    @Override
+    public String description() {
+      return "shapeDocVal(" + fieldName + ")";
+    }
+  }//ShapeDocValueSource
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/serialized/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/serialized/package-info.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/serialized/package-info.java
new file mode 100644
index 0000000..8f88a73
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/serialized/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Strategies that serialize the shape (non-indexed).
+ */
+package org.apache.lucene.spatial.serialized;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/spatial4j/Geo3dShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/spatial4j/Geo3dShape.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/spatial4j/Geo3dShape.java
new file mode 100644
index 0000000..7a3078a
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/spatial4j/Geo3dShape.java
@@ -0,0 +1,185 @@
+/*
+ * 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.spatial4j;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.distance.DistanceUtils;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.SpatialRelation;
+import com.spatial4j.core.shape.impl.RectangleImpl;
+import org.apache.lucene.geo3d.LatLonBounds;
+import org.apache.lucene.geo3d.GeoArea;
+import org.apache.lucene.geo3d.GeoAreaFactory;
+import org.apache.lucene.geo3d.GeoPoint;
+import org.apache.lucene.geo3d.GeoShape;
+import org.apache.lucene.geo3d.PlanetModel;
+
+/**
+ * A Spatial4j Shape wrapping a {@link GeoShape} ("Geo3D") -- a 3D planar geometry based Spatial4j Shape implementation.
+ * Geo3D implements shapes on the surface of a sphere or ellipsoid.
+ *
+ * @lucene.experimental
+ */
+public class Geo3dShape implements Shape {
+  /** The required size of this adjustment depends on the actual planetary model chosen.
+   * This value is big enough to account for WGS84. */
+  protected static final double ROUNDOFF_ADJUSTMENT = 0.05;
+
+  public final SpatialContext ctx;
+  public final GeoShape shape;
+  public final PlanetModel planetModel;
+
+  private volatile Rectangle boundingBox = null; // lazy initialized
+
+  public Geo3dShape(final GeoShape shape, final SpatialContext ctx) {
+    this(PlanetModel.SPHERE, shape, ctx);
+  }
+
+  public Geo3dShape(final PlanetModel planetModel, final GeoShape shape, final SpatialContext ctx) {
+    if (!ctx.isGeo()) {
+      throw new IllegalArgumentException("SpatialContext.isGeo() must be true");
+    }
+    this.ctx = ctx;
+    this.planetModel = planetModel;
+    this.shape = shape;
+  }
+
+  @Override
+  public SpatialContext getContext() {
+    return ctx;
+  }
+
+  @Override
+  public SpatialRelation relate(Shape other) {
+    if (other instanceof Rectangle)
+      return relate((Rectangle)other);
+    else if (other instanceof Point)
+      return relate((Point)other);
+    else
+      throw new RuntimeException("Unimplemented shape relationship determination: " + other.getClass());
+  }
+
+  protected SpatialRelation relate(Rectangle r) {
+    // Construct the right kind of GeoArea first
+    GeoArea geoArea = GeoAreaFactory.makeGeoArea(planetModel,
+        r.getMaxY() * DistanceUtils.DEGREES_TO_RADIANS,
+        r.getMinY() * DistanceUtils.DEGREES_TO_RADIANS,
+        r.getMinX() * DistanceUtils.DEGREES_TO_RADIANS,
+        r.getMaxX() * DistanceUtils.DEGREES_TO_RADIANS);
+    int relationship = geoArea.getRelationship(shape);
+    if (relationship == GeoArea.WITHIN)
+      return SpatialRelation.WITHIN;
+    else if (relationship == GeoArea.CONTAINS)
+      return SpatialRelation.CONTAINS;
+    else if (relationship == GeoArea.OVERLAPS)
+      return SpatialRelation.INTERSECTS;
+    else if (relationship == GeoArea.DISJOINT)
+      return SpatialRelation.DISJOINT;
+    else
+      throw new RuntimeException("Unknown relationship returned: "+relationship);
+  }
+
+  protected SpatialRelation relate(Point p) {
+    // Create a GeoPoint
+    GeoPoint point = new GeoPoint(planetModel, p.getY()* DistanceUtils.DEGREES_TO_RADIANS, p.getX()* DistanceUtils.DEGREES_TO_RADIANS);
+    if (shape.isWithin(point)) {
+      // Point within shape
+      return SpatialRelation.CONTAINS;
+    }
+    return SpatialRelation.DISJOINT;
+  }
+
+
+
+  @Override
+  public Rectangle getBoundingBox() {
+    Rectangle bbox = this.boundingBox;//volatile read once
+    if (bbox == null) {
+      LatLonBounds bounds = new LatLonBounds();
+      shape.getBounds(bounds);
+      double leftLon;
+      double rightLon;
+      if (bounds.checkNoLongitudeBound()) {
+        leftLon = -180.0;
+        rightLon = 180.0;
+      } else {
+        leftLon = bounds.getLeftLongitude().doubleValue() * DistanceUtils.RADIANS_TO_DEGREES;
+        rightLon = bounds.getRightLongitude().doubleValue() * DistanceUtils.RADIANS_TO_DEGREES;
+      }
+      double minLat;
+      if (bounds.checkNoBottomLatitudeBound()) {
+        minLat = -90.0;
+      } else {
+        minLat = bounds.getMinLatitude().doubleValue() * DistanceUtils.RADIANS_TO_DEGREES;
+      }
+      double maxLat;
+      if (bounds.checkNoTopLatitudeBound()) {
+        maxLat = 90.0;
+      } else {
+        maxLat = bounds.getMaxLatitude().doubleValue() * DistanceUtils.RADIANS_TO_DEGREES;
+      }
+      bbox = new RectangleImpl(leftLon, rightLon, minLat, maxLat, ctx).getBuffered(ROUNDOFF_ADJUSTMENT, ctx);
+      this.boundingBox = bbox;
+    }
+    return bbox;
+  }
+
+  @Override
+  public boolean hasArea() {
+    return true;
+  }
+
+  @Override
+  public double getArea(SpatialContext ctx) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public Point getCenter() {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public Shape getBuffered(double distance, SpatialContext ctx) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public boolean isEmpty() {
+    return false;
+  }
+
+  @Override
+  public String toString() {
+    return "Geo3dShape{planetmodel=" + planetModel + ", shape=" + shape + '}';
+  }
+
+  @Override
+  public boolean equals(Object other) {
+    if (!(other instanceof Geo3dShape))
+      return false;
+    Geo3dShape tr = (Geo3dShape)other;
+    return tr.ctx.equals(ctx) && tr.planetModel.equals(planetModel) && tr.shape.equals(shape);
+  }
+
+  @Override
+  public int hashCode() {
+    return planetModel.hashCode() + shape.hashCode();
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/spatial4j/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/spatial4j/package-info.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/spatial4j/package-info.java
new file mode 100644
index 0000000..7815318
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/spatial4j/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+/** Spatial4j stuff that ideally belongs in Spatial4j (isn't related to Lucene). */
+package org.apache.lucene.spatial.spatial4j;
\ No newline at end of file


[20/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/DateNRStrategyTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/DateNRStrategyTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/DateNRStrategyTest.java
new file mode 100644
index 0000000..7cd4723
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/DateNRStrategyTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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.prefix;
+
+import java.io.IOException;
+import java.util.Calendar;
+
+import com.carrotsearch.randomizedtesting.annotations.Repeat;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.spatial.prefix.tree.DateRangePrefixTree;
+import org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomBoolean;
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween;
+
+public class DateNRStrategyTest extends RandomSpatialOpStrategyTestCase {
+
+  static final int ITERATIONS = 10;
+
+  DateRangePrefixTree tree;
+
+  long randomCalWindowMs;
+
+  @Before
+  public void setUp() throws Exception {
+    super.setUp();
+    tree = DateRangePrefixTree.INSTANCE;
+    if (randomBoolean()) {
+      strategy = new NumberRangePrefixTreeStrategy(tree, "dateRange");
+    } else {
+      //Test the format that existed <= Lucene 5.0
+      strategy = new NumberRangePrefixTreeStrategy(tree, "dateRange") {
+        @Override
+        protected CellToBytesRefIterator newCellToBytesRefIterator() {
+          return new CellToBytesRefIterator50();
+        }
+      };
+    }
+    Calendar tmpCal = tree.newCal();
+    int randomCalWindowField = randomIntBetween(1, Calendar.ZONE_OFFSET - 1);//we're not allowed to add zone offset
+    tmpCal.add(randomCalWindowField, 2_000);
+    randomCalWindowMs = Math.max(2000L, tmpCal.getTimeInMillis());
+  }
+
+  @Test
+  @Repeat(iterations = ITERATIONS)
+  public void testIntersects() throws IOException {
+    testOperationRandomShapes(SpatialOperation.Intersects);
+  }
+
+  @Test
+  @Repeat(iterations = ITERATIONS)
+  public void testWithin() throws IOException {
+    testOperationRandomShapes(SpatialOperation.IsWithin);
+  }
+
+  @Test
+  @Repeat(iterations = ITERATIONS)
+  public void testContains() throws IOException {
+    testOperationRandomShapes(SpatialOperation.Contains);
+  }
+
+  @Test
+  public void testWithinSame() throws IOException {
+    final Calendar cal = tree.newCal();
+    testOperation(
+        tree.toShape(cal),
+        SpatialOperation.IsWithin,
+        tree.toShape(cal), true);//is within itself
+  }
+
+  @Test
+  public void testWorld() throws IOException {
+    testOperation(
+        tree.toShape(tree.newCal()),//world matches everything
+        SpatialOperation.Contains,
+        tree.toShape(randomCalendar()), true);
+  }
+
+  @Test
+  public void testBugInitIterOptimization() throws Exception {
+    //bug due to fast path initIter() optimization
+    testOperation(
+        tree.parseShape("[2014-03-27T23 TO 2014-04-01T01]"),
+        SpatialOperation.Intersects,
+        tree.parseShape("[2014-04 TO 2014-04-01T02]"), true);
+  }
+
+  @Override
+  protected Shape randomIndexedShape() {
+    Calendar cal1 = randomCalendar();
+    UnitNRShape s1 = tree.toShape(cal1);
+    if (rarely()) {
+      return s1;
+    }
+    try {
+      Calendar cal2 = randomCalendar();
+      UnitNRShape s2 = tree.toShape(cal2);
+      if (cal1.compareTo(cal2) < 0) {
+        return tree.toRangeShape(s1, s2);
+      } else {
+        return tree.toRangeShape(s2, s1);
+      }
+    } catch (IllegalArgumentException e) {
+      assert e.getMessage().startsWith("Differing precision");
+      return s1;
+    }
+  }
+
+  private Calendar randomCalendar() {
+    Calendar cal = tree.newCal();
+    cal.setTimeInMillis(random().nextLong() % randomCalWindowMs);
+    try {
+      tree.clearFieldsAfter(cal, random().nextInt(Calendar.FIELD_COUNT+1)-1);
+    } catch (AssertionError e) {
+      if (!e.getMessage().equals("Calendar underflow"))
+        throw e;
+    }
+    return cal;
+  }
+
+  @Override
+  protected Shape randomQueryShape() {
+    return randomIndexedShape();
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/HeatmapFacetCounterTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/HeatmapFacetCounterTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/HeatmapFacetCounterTest.java
new file mode 100644
index 0000000..124af79
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/HeatmapFacetCounterTest.java
@@ -0,0 +1,252 @@
+/*
+ * 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.prefix;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.carrotsearch.randomizedtesting.annotations.Repeat;
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.context.SpatialContextFactory;
+import com.spatial4j.core.distance.DistanceUtils;
+import com.spatial4j.core.shape.Circle;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.SpatialRelation;
+import com.spatial4j.core.shape.impl.RectangleImpl;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TotalHitCountCollector;
+import org.apache.lucene.spatial.StrategyTestCase;
+import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.util.Bits;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.carrotsearch.randomizedtesting.RandomizedTest.atMost;
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween;
+
+public class HeatmapFacetCounterTest extends StrategyTestCase {
+
+  SpatialPrefixTree grid;
+
+  int cellsValidated;
+  int cellValidatedNonZero;
+
+  @Before
+  public void setUp() throws Exception {
+    super.setUp();
+    cellsValidated = cellValidatedNonZero = 0;
+    ctx = SpatialContext.GEO;
+    grid = new QuadPrefixTree(ctx, randomIntBetween(1, 8));
+    strategy = new RecursivePrefixTreeStrategy(grid, getTestClass().getSimpleName());
+    if (rarely()) {
+      ((PrefixTreeStrategy) strategy).setPointsOnly(true);
+    }
+  }
+
+  @After
+  public void after() {
+    log.info("Validated " + cellsValidated + " cells, " + cellValidatedNonZero + " non-zero");
+  }
+
+  @Test
+  public void testStatic() throws IOException {
+    //Some specific tests (static, not random).
+    adoc("0", ctx.makeRectangle(179.8, -170, -90, -80));//barely crosses equator
+    adoc("1", ctx.makePoint(-180, -85));//a pt within the above rect
+    adoc("2", ctx.makePoint(172, -85));//a pt to left of rect
+    commit();
+
+    validateHeatmapResultLoop(ctx.makeRectangle(+170, +180, -90, -85), 1, 100);
+    validateHeatmapResultLoop(ctx.makeRectangle(-180, -160, -89, -50), 1, 100);
+    validateHeatmapResultLoop(ctx.makeRectangle(179, 179, -89, -50), 1, 100);//line
+    // We could test anything and everything at this point... I prefer we leave that to random testing and then
+    // add specific tests if we find a bug.
+  }
+
+  @Test
+  public void testQueryCircle() throws IOException {
+    //overwrite setUp; non-geo bounds is more straight-forward; otherwise 88,88 would actually be practically north,
+    final SpatialContextFactory spatialContextFactory = new SpatialContextFactory();
+    spatialContextFactory.geo = false;
+    spatialContextFactory.worldBounds = new RectangleImpl(-90, 90, -90, 90, null);
+    ctx = spatialContextFactory.newSpatialContext();
+    final int LEVEL = 4;
+    grid = new QuadPrefixTree(ctx, LEVEL);
+    strategy = new RecursivePrefixTreeStrategy(grid, getTestClass().getSimpleName());
+    Circle circle = ctx.makeCircle(0, 0, 89);
+    adoc("0", ctx.makePoint(88, 88));//top-right, inside bbox of circle but not the circle
+    adoc("1", ctx.makePoint(0, 0));//clearly inside; dead center in fact
+    commit();
+    final HeatmapFacetCounter.Heatmap heatmap = HeatmapFacetCounter.calcFacets(
+        (PrefixTreeStrategy) strategy, indexSearcher.getTopReaderContext(), null,
+        circle, LEVEL, 1000);
+    //assert that only one point is found, not 2
+    boolean foundOne = false;
+    for (int count : heatmap.counts) {
+      switch (count) {
+        case 0: break;
+        case 1:
+          assertFalse(foundOne);//this is the first
+          foundOne = true;
+          break;
+        default:
+          fail("counts should be 0 or 1: " + count);
+      }
+    }
+    assertTrue(foundOne);
+  }
+
+  /** Recursively facet & validate at higher resolutions until we've seen enough. We assume there are
+   * some non-zero cells. */
+  private void validateHeatmapResultLoop(Rectangle inputRange, int facetLevel, int cellCountRecursThreshold)
+      throws IOException {
+    if (facetLevel > grid.getMaxLevels()) {
+      return;
+    }
+    final int maxCells = 10_000;
+    final HeatmapFacetCounter.Heatmap heatmap = HeatmapFacetCounter.calcFacets(
+        (PrefixTreeStrategy) strategy, indexSearcher.getTopReaderContext(), null, inputRange, facetLevel, maxCells);
+    int preNonZero = cellValidatedNonZero;
+    validateHeatmapResult(inputRange, facetLevel, heatmap);
+    assert cellValidatedNonZero - preNonZero > 0;//we validated more non-zero cells
+    if (heatmap.counts.length < cellCountRecursThreshold) {
+      validateHeatmapResultLoop(inputRange, facetLevel + 1, cellCountRecursThreshold);
+    }
+  }
+
+  @Test
+  @Repeat(iterations = 20)
+  public void testRandom() throws IOException {
+    // Tests using random index shapes & query shapes. This has found all sorts of edge case bugs (e.g. dateline,
+    // cell border, overflow(?)).
+
+    final int numIndexedShapes = 1 + atMost(9);
+    List<Shape> indexedShapes = new ArrayList<>(numIndexedShapes);
+    for (int i = 0; i < numIndexedShapes; i++) {
+      indexedShapes.add(randomIndexedShape());
+    }
+
+    //Main index loop:
+    for (int i = 0; i < indexedShapes.size(); i++) {
+      Shape shape = indexedShapes.get(i);
+      adoc("" + i, shape);
+
+      if (random().nextInt(10) == 0)
+        commit();//intermediate commit, produces extra segments
+    }
+    //delete some documents randomly
+    for (int id = 0; id < indexedShapes.size(); id++) {
+      if (random().nextInt(10) == 0) {
+        deleteDoc("" + id);
+        indexedShapes.set(id, null);
+      }
+    }
+
+    commit();
+
+    // once without dateline wrap
+    final Rectangle rect = randomRectangle();
+    queryHeatmapRecursive(usually() ? ctx.getWorldBounds() : rect, 1);
+    // and once with dateline wrap
+    if (rect.getWidth() > 0) {
+      double shift = random().nextDouble() % rect.getWidth();
+      queryHeatmapRecursive(ctx.makeRectangle(
+              DistanceUtils.normLonDEG(rect.getMinX() - shift),
+              DistanceUtils.normLonDEG(rect.getMaxX() - shift),
+              rect.getMinY(), rect.getMaxY()),
+          1);
+    }
+  }
+
+  /** Build heatmap, validate results, then descend recursively to another facet level. */
+  private boolean queryHeatmapRecursive(Rectangle inputRange, int facetLevel) throws IOException {
+    if (!inputRange.hasArea()) {
+      // Don't test line inputs. It's not that we don't support it but it is more challenging to test if per-chance it
+      // coincides with a grid line due due to edge overlap issue for some grid implementations (geo & quad).
+      return false;
+    }
+    Bits filter = null; //FYI testing filtering of underlying PrefixTreeFacetCounter is done in another test
+    //Calculate facets
+    final int maxCells = 10_000;
+    final HeatmapFacetCounter.Heatmap heatmap = HeatmapFacetCounter.calcFacets(
+        (PrefixTreeStrategy) strategy, indexSearcher.getTopReaderContext(), filter, inputRange, facetLevel, maxCells);
+
+    validateHeatmapResult(inputRange, facetLevel, heatmap);
+
+    boolean foundNonZeroCount = false;
+    for (int count : heatmap.counts) {
+      if (count > 0) {
+        foundNonZeroCount = true;
+        break;
+      }
+    }
+
+    //Test again recursively to higher facetLevel (more detailed cells)
+    if (foundNonZeroCount && cellsValidated <= 500 && facetLevel != grid.getMaxLevels() && inputRange.hasArea()) {
+      for (int i = 0; i < 5; i++) {//try multiple times until we find non-zero counts
+        if (queryHeatmapRecursive(randomRectangle(inputRange), facetLevel + 1)) {
+          break;//we found data here so we needn't try again
+        }
+      }
+    }
+    return foundNonZeroCount;
+  }
+
+  private void validateHeatmapResult(Rectangle inputRange, int facetLevel, HeatmapFacetCounter.Heatmap heatmap)
+      throws IOException {
+    final Rectangle heatRect = heatmap.region;
+    assertTrue(heatRect.relate(inputRange) == SpatialRelation.CONTAINS || heatRect.equals(inputRange));
+    final double cellWidth = heatRect.getWidth() / heatmap.columns;
+    final double cellHeight = heatRect.getHeight() / heatmap.rows;
+    for (int c = 0; c < heatmap.columns; c++) {
+      for (int r = 0; r < heatmap.rows; r++) {
+        final int facetCount = heatmap.getCount(c, r);
+        double x = DistanceUtils.normLonDEG(heatRect.getMinX() + c * cellWidth + cellWidth / 2);
+        double y = DistanceUtils.normLatDEG(heatRect.getMinY() + r * cellHeight + cellHeight / 2);
+        Point pt =  ctx.makePoint(x, y);
+        assertEquals(countMatchingDocsAtLevel(pt, facetLevel), facetCount);
+      }
+    }
+  }
+
+  private int countMatchingDocsAtLevel(Point pt, int facetLevel) throws IOException {
+    // we use IntersectsPrefixTreeFilter directly so that we can specify the level to go to exactly.
+    RecursivePrefixTreeStrategy strategy = (RecursivePrefixTreeStrategy) this.strategy;
+    Query filter = new IntersectsPrefixTreeQuery(
+        pt, strategy.getFieldName(), grid, facetLevel, grid.getMaxLevels());
+    final TotalHitCountCollector collector = new TotalHitCountCollector();
+    indexSearcher.search(filter, collector);
+    cellsValidated++;
+    if (collector.getTotalHits() > 0) {
+      cellValidatedNonZero++;
+    }
+    return collector.getTotalHits();
+  }
+
+  private Shape randomIndexedShape() {
+    if (((PrefixTreeStrategy) strategy).isPointsOnly() || random().nextBoolean()) {
+      return randomPoint();
+    } else {
+      return randomRectangle();
+    }
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/JtsPolygonTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/JtsPolygonTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/JtsPolygonTest.java
new file mode 100644
index 0000000..09fb3a9
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/JtsPolygonTest.java
@@ -0,0 +1,117 @@
+/*
+ * 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.prefix;
+
+import com.spatial4j.core.context.SpatialContextFactory;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.Field.Store;
+import org.apache.lucene.document.TextField;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.spatial.StrategyTestCase;
+import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.junit.Test;
+
+import java.text.ParseException;
+import java.util.HashMap;
+
+public class JtsPolygonTest extends StrategyTestCase {
+
+  private static final double LUCENE_4464_distErrPct = SpatialArgs.DEFAULT_DISTERRPCT;//DEFAULT 2.5%
+
+  public JtsPolygonTest() {
+    try {
+      HashMap<String, String> args = new HashMap<>();
+      args.put("spatialContextFactory",
+          "com.spatial4j.core.context.jts.JtsSpatialContextFactory");
+      ctx = SpatialContextFactory.makeSpatialContext(args, getClass().getClassLoader());
+    } catch (NoClassDefFoundError e) {
+      assumeTrue("This test requires JTS jar: "+e, false);
+    }
+
+    GeohashPrefixTree grid = new GeohashPrefixTree(ctx, 11);//< 1 meter == 11 maxLevels
+    this.strategy = new RecursivePrefixTreeStrategy(grid, getClass().getSimpleName());
+    ((RecursivePrefixTreeStrategy)this.strategy).setDistErrPct(LUCENE_4464_distErrPct);//1% radius (small!)
+  }
+
+  @Test
+  /** LUCENE-4464 */
+  public void testCloseButNoMatch() throws Exception {
+    getAddAndVerifyIndexedDocuments("LUCENE-4464.txt");
+    SpatialArgs args = q(
+        "POLYGON((-93.18100824442227 45.25676372469945," +
+            "-93.23182001200654 45.21421290799412," +
+            "-93.16315546122038 45.23742639412364," +
+            "-93.18100824442227 45.25676372469945))",
+        LUCENE_4464_distErrPct);
+    SearchResults got = executeQuery(strategy.makeQuery(args), 100);
+    assertEquals(1, got.numFound);
+    assertEquals("poly2", got.results.get(0).document.get("id"));
+    //did not find poly 1 !
+  }
+
+  private SpatialArgs q(String shapeStr, double distErrPct) throws ParseException {
+    Shape shape = ctx.readShapeFromWkt(shapeStr);
+    SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, shape);
+    args.setDistErrPct(distErrPct);
+    return args;
+  }
+
+  /**
+   * A PrefixTree pruning optimization gone bad.
+   * See <a href="https://issues.apache.org/jira/browse/LUCENE-4770">LUCENE-4770</a>.
+   */
+  @Test
+  public void testBadPrefixTreePrune() throws Exception {
+
+    Shape area = ctx.readShapeFromWkt("POLYGON((-122.83 48.57, -122.77 48.56, -122.79 48.53, -122.83 48.57))");
+
+    SpatialPrefixTree trie = new QuadPrefixTree(ctx, 12);
+    TermQueryPrefixTreeStrategy strategy = new TermQueryPrefixTreeStrategy(trie, "geo");
+    Document doc = new Document();
+    doc.add(new TextField("id", "1", Store.YES));
+
+    Field[] fields = strategy.createIndexableFields(area, 0.025);
+    for (Field field : fields) {
+      doc.add(field);
+    }
+    addDocument(doc);
+
+    Point upperleft = ctx.makePoint(-122.88, 48.54);
+    Point lowerright = ctx.makePoint(-122.82, 48.62);
+
+    Query query = strategy.makeQuery(new SpatialArgs(SpatialOperation.Intersects, ctx.makeRectangle(upperleft, lowerright)));
+    commit();
+
+    TopDocs search = indexSearcher.search(query, 10);
+    ScoreDoc[] scoreDocs = search.scoreDocs;
+    for (ScoreDoc scoreDoc : scoreDocs) {
+      System.out.println(indexSearcher.doc(scoreDoc.doc));
+    }
+
+    assertEquals(1, search.totalHits);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/NumberRangeFacetsTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/NumberRangeFacetsTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/NumberRangeFacetsTest.java
new file mode 100644
index 0000000..11e1d18
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/NumberRangeFacetsTest.java
@@ -0,0 +1,275 @@
+/*
+ * 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.prefix;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.List;
+
+import com.carrotsearch.randomizedtesting.annotations.Repeat;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.queries.TermsQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.SimpleCollector;
+import org.apache.lucene.spatial.StrategyTestCase;
+import org.apache.lucene.spatial.prefix.NumberRangePrefixTreeStrategy.Facets;
+import org.apache.lucene.spatial.prefix.tree.Cell;
+import org.apache.lucene.spatial.prefix.tree.CellIterator;
+import org.apache.lucene.spatial.prefix.tree.DateRangePrefixTree;
+import org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree;
+import org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape;
+import org.apache.lucene.util.Bits;
+import org.apache.lucene.util.FixedBitSet;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomInt;
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween;
+
+public class NumberRangeFacetsTest extends StrategyTestCase {
+
+  DateRangePrefixTree tree;
+
+  int randomCalWindowField;
+  long randomCalWindowMs;
+
+  @Before
+  public void setUp() throws Exception {
+    super.setUp();
+    tree = DateRangePrefixTree.INSTANCE;
+    strategy = new NumberRangePrefixTreeStrategy(tree, "dateRange");
+    Calendar tmpCal = tree.newCal();
+    randomCalWindowField = randomIntBetween(1, Calendar.ZONE_OFFSET - 1);//we're not allowed to add zone offset
+    tmpCal.add(randomCalWindowField, 2_000);
+    randomCalWindowMs = Math.max(2000L, tmpCal.getTimeInMillis());
+  }
+
+  @Repeat(iterations = 20)
+  @Test
+  public void test() throws IOException {
+    //generate test data
+    List<Shape> indexedShapes = new ArrayList<>();
+    final int numIndexedShapes = random().nextInt(15);
+    for (int i = 0; i < numIndexedShapes; i++) {
+      indexedShapes.add(randomShape());
+    }
+
+    //Main index loop:
+    for (int i = 0; i < indexedShapes.size(); i++) {
+      Shape shape = indexedShapes.get(i);
+      adoc(""+i, shape);
+
+      if (random().nextInt(10) == 0)
+        commit();//intermediate commit, produces extra segments
+    }
+
+    //delete some documents randomly
+    for (int id = 0; id < indexedShapes.size(); id++) {
+      if (random().nextInt(10) == 0) {
+        deleteDoc(""+id);
+        indexedShapes.set(id, null);
+      }
+    }
+
+    commit();
+
+    //Main query loop:
+    for (int queryIdx = 0; queryIdx < 10; queryIdx++) {
+      preQueryHavoc();
+
+      // We need to have a facet range window to do the facets between (a start time & end time). We randomly
+      // pick a date, decide the level we want to facet on, and then pick a right end time that is up to 2 thousand
+      // values later.
+      int calFieldFacet = randomCalWindowField - 1;
+      if (calFieldFacet > 1 && rarely()) {
+        calFieldFacet--;
+      }
+      final Calendar leftCal = randomCalendar();
+      leftCal.add(calFieldFacet, -1 * randomInt(1000));
+      Calendar rightCal = (Calendar) leftCal.clone();
+      rightCal.add(calFieldFacet, randomInt(2000));
+      // Pick facet detail level based on cal field.
+      int detailLevel = tree.getTreeLevelForCalendarField(calFieldFacet);
+      if (detailLevel < 0) {//no exact match
+        detailLevel = -1 * detailLevel;
+      }
+
+      //Randomly pick a filter/acceptDocs
+      Bits topAcceptDocs = null;
+      List<Integer> acceptFieldIds = new ArrayList<>();
+      if (usually()) {
+        //get all possible IDs into a list, random shuffle it, then randomly choose how many of the first we use to
+        // replace the list.
+        for (int i = 0; i < indexedShapes.size(); i++) {
+          if (indexedShapes.get(i) == null) { // we deleted this one
+            continue;
+          }
+          acceptFieldIds.add(i);
+        }
+        Collections.shuffle(acceptFieldIds, random());
+        acceptFieldIds = acceptFieldIds.subList(0, randomInt(acceptFieldIds.size()));
+        if (!acceptFieldIds.isEmpty()) {
+          List<Term> terms = new ArrayList<>();
+          for (Integer acceptDocId : acceptFieldIds) {
+            terms.add(new Term("id", acceptDocId.toString()));
+          }
+
+          topAcceptDocs = searchForDocBits(new TermsQuery(terms));
+        }
+      }
+
+      //Lets do it!
+      NumberRangePrefixTree.NRShape facetRange = tree.toRangeShape(tree.toShape(leftCal), tree.toShape(rightCal));
+      Facets facets = ((NumberRangePrefixTreeStrategy) strategy)
+          .calcFacets(indexSearcher.getTopReaderContext(), topAcceptDocs, facetRange, detailLevel);
+
+      //System.out.println("Q: " + queryIdx + " " + facets);
+
+      //Verify results. We do it by looping over indexed shapes and reducing the facet counts.
+      Shape facetShapeRounded = facetRange.roundToLevel(detailLevel);
+      for (int indexedShapeId = 0; indexedShapeId < indexedShapes.size(); indexedShapeId++) {
+        if (topAcceptDocs != null && !acceptFieldIds.contains(indexedShapeId)) {
+          continue;// this doc was filtered out via acceptDocs
+        }
+        Shape indexedShape = indexedShapes.get(indexedShapeId);
+        if (indexedShape == null) {//was deleted
+          continue;
+        }
+        Shape indexedShapeRounded = ((NumberRangePrefixTree.NRShape) indexedShape).roundToLevel(detailLevel);
+        if (!indexedShapeRounded.relate(facetShapeRounded).intersects()) { // no intersection at all
+          continue;
+        }
+        // walk the cells
+        final CellIterator cellIterator = tree.getTreeCellIterator(indexedShape, detailLevel);
+        while (cellIterator.hasNext()) {
+          Cell cell = cellIterator.next();
+          if (!cell.getShape().relate(facetShapeRounded).intersects()) {
+            cellIterator.remove();//no intersection; prune
+            continue;
+          }
+          assert cell.getLevel() <= detailLevel;
+
+          if (cell.getLevel() == detailLevel) {
+            //count it
+            UnitNRShape shape = (UnitNRShape) cell.getShape();
+            final UnitNRShape parentShape = shape.getShapeAtLevel(detailLevel - 1);//get parent
+            final Facets.FacetParentVal facetParentVal = facets.parents.get(parentShape);
+            assertNotNull(facetParentVal);
+            int index = shape.getValAtLevel(shape.getLevel());
+            assertNotNull(facetParentVal.childCounts);
+            assert facetParentVal.childCounts[index] > 0;
+            facetParentVal.childCounts[index]--;
+
+          } else if (cell.isLeaf()) {
+            //count it, and remove/prune.
+            if (cell.getLevel() < detailLevel - 1) {
+              assert facets.topLeaves > 0;
+              facets.topLeaves--;
+            } else {
+              UnitNRShape shape = (UnitNRShape) cell.getShape();
+              final UnitNRShape parentShape = shape.getShapeAtLevel(detailLevel - 1);//get parent
+              final Facets.FacetParentVal facetParentVal = facets.parents.get(parentShape);
+              assertNotNull(facetParentVal);
+              assert facetParentVal.parentLeaves > 0;
+              facetParentVal.parentLeaves--;
+            }
+
+            cellIterator.remove();
+          }
+        }
+      }
+      // At this point; all counts should be down to zero.
+      assertTrue(facets.topLeaves == 0);
+      for (Facets.FacetParentVal facetParentVal : facets.parents.values()) {
+        assertTrue(facetParentVal.parentLeaves == 0);
+        if (facetParentVal.childCounts != null) {
+          for (int childCount : facetParentVal.childCounts) {
+            assertTrue(childCount == 0);
+          }
+        }
+      }
+
+    }
+  }
+
+  private Bits searchForDocBits(Query query) throws IOException {
+    FixedBitSet bitSet = new FixedBitSet(indexSearcher.getIndexReader().maxDoc());
+    indexSearcher.search(query,
+        new SimpleCollector() {
+          int leafDocBase;
+          @Override
+          public void collect(int doc) throws IOException {
+            bitSet.set(leafDocBase + doc);
+          }
+
+          @Override
+          protected void doSetNextReader(LeafReaderContext context) throws IOException {
+            leafDocBase = context.docBase;
+          }
+
+          @Override
+          public boolean needsScores() {
+            return false;
+          }
+        });
+    return bitSet;
+  }
+
+  private void preQueryHavoc() {
+    if (strategy instanceof RecursivePrefixTreeStrategy) {
+      RecursivePrefixTreeStrategy rpts = (RecursivePrefixTreeStrategy) strategy;
+      int scanLevel = randomInt(rpts.getGrid().getMaxLevels());
+      rpts.setPrefixGridScanLevel(scanLevel);
+    }
+  }
+
+  protected Shape randomShape() {
+    Calendar cal1 = randomCalendar();
+    UnitNRShape s1 = tree.toShape(cal1);
+    if (rarely()) {
+      return s1;
+    }
+    try {
+      Calendar cal2 = randomCalendar();
+      UnitNRShape s2 = tree.toShape(cal2);
+      if (cal1.compareTo(cal2) < 0) {
+        return tree.toRangeShape(s1, s2);
+      } else {
+        return tree.toRangeShape(s2, s1);
+      }
+    } catch (IllegalArgumentException e) {
+      assert e.getMessage().startsWith("Differing precision");
+      return s1;
+    }
+  }
+
+  private Calendar randomCalendar() {
+    Calendar cal = tree.newCal();
+    cal.setTimeInMillis(random().nextLong() % randomCalWindowMs);
+    try {
+      tree.clearFieldsAfter(cal, random().nextInt(Calendar.FIELD_COUNT+1)-1);
+    } catch (AssertionError e) {
+      if (!e.getMessage().equals("Calendar underflow"))
+        throw e;
+    }
+    return cal;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpFuzzyPrefixTree50Test.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpFuzzyPrefixTree50Test.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpFuzzyPrefixTree50Test.java
new file mode 100644
index 0000000..e932fe9
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpFuzzyPrefixTree50Test.java
@@ -0,0 +1,31 @@
+/*
+ * 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.prefix;
+
+/** Test RandomSpatialOpFuzzyPrefixTreeTest using the PrefixTree index format found in 5.0 and prior. */
+public class RandomSpatialOpFuzzyPrefixTree50Test extends RandomSpatialOpFuzzyPrefixTreeTest {
+
+  protected RecursivePrefixTreeStrategy newRPT() {
+    return new RecursivePrefixTreeStrategy(this.grid, getClass().getSimpleName()) {
+      @Override
+      protected CellToBytesRefIterator newCellToBytesRefIterator() {
+        return new CellToBytesRefIterator50();
+      }
+    };
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpFuzzyPrefixTreeTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpFuzzyPrefixTreeTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpFuzzyPrefixTreeTest.java
new file mode 100644
index 0000000..8db131c
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpFuzzyPrefixTreeTest.java
@@ -0,0 +1,533 @@
+/*
+ * 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.prefix;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.carrotsearch.randomizedtesting.annotations.Repeat;
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.context.SpatialContextFactory;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.ShapeCollection;
+import com.spatial4j.core.shape.SpatialRelation;
+import com.spatial4j.core.shape.impl.RectangleImpl;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.StoredField;
+import org.apache.lucene.document.StringField;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.spatial.StrategyTestCase;
+import org.apache.lucene.spatial.prefix.tree.Cell;
+import org.apache.lucene.spatial.prefix.tree.CellIterator;
+import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.PackedQuadPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.junit.Test;
+
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomBoolean;
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomInt;
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween;
+import static com.spatial4j.core.shape.SpatialRelation.CONTAINS;
+import static com.spatial4j.core.shape.SpatialRelation.DISJOINT;
+import static com.spatial4j.core.shape.SpatialRelation.INTERSECTS;
+import static com.spatial4j.core.shape.SpatialRelation.WITHIN;
+
+/** Randomized PrefixTree test that considers the fuzziness of the
+ * results introduced by grid approximation. */
+public class RandomSpatialOpFuzzyPrefixTreeTest extends StrategyTestCase {
+
+  static final int ITERATIONS = 10;
+
+  protected SpatialPrefixTree grid;
+  private SpatialContext ctx2D;
+
+  public void setupGrid(int maxLevels) throws IOException {
+    if (randomBoolean())
+      setupQuadGrid(maxLevels, randomBoolean());
+    else
+      setupGeohashGrid(maxLevels);
+    setupCtx2D(ctx);
+
+    // set prune independently on strategy & grid randomly; should work
+    ((RecursivePrefixTreeStrategy)strategy).setPruneLeafyBranches(randomBoolean());
+    if (this.grid instanceof PackedQuadPrefixTree) {
+      ((PackedQuadPrefixTree) this.grid).setPruneLeafyBranches(randomBoolean());
+    }
+
+    if (maxLevels == -1 && rarely()) {
+      ((PrefixTreeStrategy) strategy).setPointsOnly(true);
+    }
+
+    log.info("Strategy: " + strategy.toString());
+  }
+
+  private void setupCtx2D(SpatialContext ctx) {
+    if (!ctx.isGeo())
+      ctx2D = ctx;
+    //A non-geo version of ctx.
+    SpatialContextFactory ctxFactory = new SpatialContextFactory();
+    ctxFactory.geo = false;
+    ctxFactory.worldBounds = ctx.getWorldBounds();
+    ctx2D = ctxFactory.newSpatialContext();
+  }
+
+  private void setupQuadGrid(int maxLevels, boolean packedQuadPrefixTree) {
+    //non-geospatial makes this test a little easier (in gridSnap), and using boundary values 2^X raises
+    // the prospect of edge conditions we want to test, plus makes for simpler numbers (no decimals).
+    SpatialContextFactory factory = new SpatialContextFactory();
+    factory.geo = false;
+    factory.worldBounds = new RectangleImpl(0, 256, -128, 128, null);
+    this.ctx = factory.newSpatialContext();
+    //A fairly shallow grid, and default 2.5% distErrPct
+    if (maxLevels == -1)
+      maxLevels = randomIntBetween(1, 8);//max 64k cells (4^8), also 256*256
+    if (packedQuadPrefixTree) {
+      this.grid = new PackedQuadPrefixTree(ctx, maxLevels);
+    } else {
+      this.grid = new QuadPrefixTree(ctx, maxLevels);
+    }
+    this.strategy = newRPT();
+  }
+
+  public void setupGeohashGrid(int maxLevels) {
+    this.ctx = SpatialContext.GEO;
+    //A fairly shallow grid, and default 2.5% distErrPct
+    if (maxLevels == -1)
+      maxLevels = randomIntBetween(1, 3);//max 16k cells (32^3)
+    this.grid = new GeohashPrefixTree(ctx, maxLevels);
+    this.strategy = newRPT();
+  }
+
+  protected RecursivePrefixTreeStrategy newRPT() {
+    return new RecursivePrefixTreeStrategy(this.grid, getClass().getSimpleName());
+  }
+
+  @Test
+  @Repeat(iterations = ITERATIONS)
+  public void testIntersects() throws IOException {
+    setupGrid(-1);
+    doTest(SpatialOperation.Intersects);
+  }
+
+  @Test
+  @Repeat(iterations = ITERATIONS)
+  public void testWithin() throws IOException {
+    setupGrid(-1);
+    doTest(SpatialOperation.IsWithin);
+  }
+
+  @Test
+  @Repeat(iterations = ITERATIONS)
+  public void testContains() throws IOException {
+    setupGrid(-1);
+    doTest(SpatialOperation.Contains);
+  }
+
+  /** See LUCENE-5062, {@link ContainsPrefixTreeQuery#multiOverlappingIndexedShapes}. */
+  @Test
+  public void testContainsPairOverlap() throws IOException {
+    setupQuadGrid(3, randomBoolean());
+    adoc("0", new ShapePair(ctx.makeRectangle(0, 33, -128, 128), ctx.makeRectangle(33, 128, -128, 128), true));
+    commit();
+    Query query = strategy.makeQuery(new SpatialArgs(SpatialOperation.Contains,
+        ctx.makeRectangle(0, 128, -16, 128)));
+    SearchResults searchResults = executeQuery(query, 1);
+    assertEquals(1, searchResults.numFound);
+  }
+
+  @Test
+  public void testWithinDisjointParts() throws IOException {
+    setupQuadGrid(7, randomBoolean());
+    //one shape comprised of two parts, quite separated apart
+    adoc("0", new ShapePair(ctx.makeRectangle(0, 10, -120, -100), ctx.makeRectangle(220, 240, 110, 125), false));
+    commit();
+    //query surrounds only the second part of the indexed shape
+    Query query = strategy.makeQuery(new SpatialArgs(SpatialOperation.IsWithin,
+        ctx.makeRectangle(210, 245, 105, 128)));
+    SearchResults searchResults = executeQuery(query, 1);
+    //we shouldn't find it because it's not completely within
+    assertTrue(searchResults.numFound == 0);
+  }
+
+  @Test /** LUCENE-4916 */
+  public void testWithinLeafApproxRule() throws IOException {
+    setupQuadGrid(2, randomBoolean());//4x4 grid
+    //indexed shape will simplify to entire right half (2 top cells)
+    adoc("0", ctx.makeRectangle(192, 204, -128, 128));
+    commit();
+
+    ((RecursivePrefixTreeStrategy) strategy).setPrefixGridScanLevel(randomInt(2));
+
+    //query does NOT contain it; both indexed cells are leaves to the query, and
+    // when expanded to the full grid cells, the top one's top row is disjoint
+    // from the query and thus not a match.
+    assertTrue(executeQuery(strategy.makeQuery(
+        new SpatialArgs(SpatialOperation.IsWithin, ctx.makeRectangle(38, 192, -72, 56))
+    ), 1).numFound==0);//no-match
+
+    //this time the rect is a little bigger and is considered a match. It's
+    // an acceptable false-positive because of the grid approximation.
+    assertTrue(executeQuery(strategy.makeQuery(
+        new SpatialArgs(SpatialOperation.IsWithin, ctx.makeRectangle(38, 192, -72, 80))
+    ), 1).numFound==1);//match
+  }
+
+  @Test
+  public void testShapePair() {
+    ctx = SpatialContext.GEO;
+    setupCtx2D(ctx);
+
+    Shape leftShape = new ShapePair(ctx.makeRectangle(-74, -56, -8, 1), ctx.makeRectangle(-180, 134, -90, 90), true);
+    Shape queryShape = ctx.makeRectangle(-180, 180, -90, 90);
+    assertEquals(SpatialRelation.WITHIN, leftShape.relate(queryShape));
+  }
+
+  //Override so we can index parts of a pair separately, resulting in the detailLevel
+  // being independent for each shape vs the whole thing
+  @Override
+  protected Document newDoc(String id, Shape shape) {
+    Document doc = new Document();
+    doc.add(new StringField("id", id, Field.Store.YES));
+    if (shape != null) {
+      Collection<Shape> shapes;
+      if (shape instanceof ShapePair) {
+        shapes = new ArrayList<>(2);
+        shapes.add(((ShapePair)shape).shape1);
+        shapes.add(((ShapePair)shape).shape2);
+      } else {
+        shapes = Collections.singleton(shape);
+      }
+      for (Shape shapei : shapes) {
+        for (Field f : strategy.createIndexableFields(shapei)) {
+          doc.add(f);
+        }
+      }
+      if (storeShape)//just for diagnostics
+        doc.add(new StoredField(strategy.getFieldName(), shape.toString()));
+    }
+    return doc;
+  }
+
+  @SuppressWarnings("fallthrough")
+  private void doTest(final SpatialOperation operation) throws IOException {
+    //first show that when there's no data, a query will result in no results
+    {
+      Query query = strategy.makeQuery(new SpatialArgs(operation, randomRectangle()));
+      SearchResults searchResults = executeQuery(query, 1);
+      assertEquals(0, searchResults.numFound);
+    }
+
+    final boolean biasContains = (operation == SpatialOperation.Contains);
+
+    //Main index loop:
+    Map<String, Shape> indexedShapes = new LinkedHashMap<>();
+    Map<String, Shape> indexedShapesGS = new LinkedHashMap<>();//grid snapped
+    final int numIndexedShapes = randomIntBetween(1, 6);
+    boolean indexedAtLeastOneShapePair = false;
+    final boolean pointsOnly = ((PrefixTreeStrategy) strategy).isPointsOnly();
+    for (int i = 0; i < numIndexedShapes; i++) {
+      String id = "" + i;
+      Shape indexedShape;
+      int R = random().nextInt(12);
+      if (R == 0) {//1 in 12
+        indexedShape = null;
+      } else if (R == 1 || pointsOnly) {//1 in 12
+        indexedShape = randomPoint();//just one point
+      } else if (R <= 4) {//3 in 12
+        //comprised of more than one shape
+        indexedShape = randomShapePairRect(biasContains);
+        indexedAtLeastOneShapePair = true;
+      } else {
+        indexedShape = randomRectangle();//just one rect
+      }
+
+      indexedShapes.put(id, indexedShape);
+      indexedShapesGS.put(id, gridSnap(indexedShape));
+
+      adoc(id, indexedShape);
+
+      if (random().nextInt(10) == 0)
+        commit();//intermediate commit, produces extra segments
+
+    }
+    //delete some documents randomly
+    Iterator<String> idIter = indexedShapes.keySet().iterator();
+    while (idIter.hasNext()) {
+      String id = idIter.next();
+      if (random().nextInt(10) == 0) {
+        deleteDoc(id);
+        idIter.remove();
+        indexedShapesGS.remove(id);
+      }
+    }
+
+    commit();
+
+    //Main query loop:
+    final int numQueryShapes = atLeast(20);
+    for (int i = 0; i < numQueryShapes; i++) {
+      int scanLevel = randomInt(grid.getMaxLevels());
+      ((RecursivePrefixTreeStrategy) strategy).setPrefixGridScanLevel(scanLevel);
+
+      final Shape queryShape;
+      switch (randomInt(10)) {
+        case 0: queryShape = randomPoint(); break;
+// LUCENE-5549
+//TODO debug: -Dtests.method=testWithin -Dtests.multiplier=3 -Dtests.seed=5F5294CE2E075A3E:AAD2F0F79288CA64
+//        case 1:case 2:case 3:
+//          if (!indexedAtLeastOneShapePair) { // avoids ShapePair.relate(ShapePair), which isn't reliable
+//            queryShape = randomShapePairRect(!biasContains);//invert biasContains for query side
+//            break;
+//          }
+
+        case 4:
+          //choose an existing indexed shape
+          if (!indexedShapes.isEmpty()) {
+            Shape tmp = indexedShapes.values().iterator().next();
+            if (tmp instanceof Point || tmp instanceof Rectangle) {//avoids null and shapePair
+              queryShape = tmp;
+              break;
+            }
+          }//else fall-through
+
+        default: queryShape = randomRectangle();
+      }
+      final Shape queryShapeGS = gridSnap(queryShape);
+
+      final boolean opIsDisjoint = operation == SpatialOperation.IsDisjointTo;
+
+      //Generate truth via brute force:
+      // We ensure true-positive matches (if the predicate on the raw shapes match
+      //  then the search should find those same matches).
+      // approximations, false-positive matches
+      Set<String> expectedIds = new LinkedHashSet<>();//true-positives
+      Set<String> secondaryIds = new LinkedHashSet<>();//false-positives (unless disjoint)
+      for (Map.Entry<String, Shape> entry : indexedShapes.entrySet()) {
+        String id = entry.getKey();
+        Shape indexedShapeCompare = entry.getValue();
+        if (indexedShapeCompare == null)
+          continue;
+        Shape queryShapeCompare = queryShape;
+
+        if (operation.evaluate(indexedShapeCompare, queryShapeCompare)) {
+          expectedIds.add(id);
+          if (opIsDisjoint) {
+            //if no longer intersect after buffering them, for disjoint, remember this
+            indexedShapeCompare = indexedShapesGS.get(id);
+            queryShapeCompare = queryShapeGS;
+            if (!operation.evaluate(indexedShapeCompare, queryShapeCompare))
+              secondaryIds.add(id);
+          }
+        } else if (!opIsDisjoint) {
+          //buffer either the indexed or query shape (via gridSnap) and try again
+          if (operation == SpatialOperation.Intersects) {
+            indexedShapeCompare = indexedShapesGS.get(id);
+            queryShapeCompare = queryShapeGS;
+            //TODO Unfortunately, grid-snapping both can result in intersections that otherwise
+            // wouldn't happen when the grids are adjacent. Not a big deal but our test is just a
+            // bit more lenient.
+          } else if (operation == SpatialOperation.Contains) {
+            indexedShapeCompare = indexedShapesGS.get(id);
+          } else if (operation == SpatialOperation.IsWithin) {
+            queryShapeCompare = queryShapeGS;
+          }
+          if (operation.evaluate(indexedShapeCompare, queryShapeCompare))
+            secondaryIds.add(id);
+        }
+      }
+
+      //Search and verify results
+      SpatialArgs args = new SpatialArgs(operation, queryShape);
+      if (queryShape instanceof ShapePair)
+        args.setDistErrPct(0.0);//a hack; we want to be more detailed than gridSnap(queryShape)
+      Query query = strategy.makeQuery(args);
+      SearchResults got = executeQuery(query, 100);
+      Set<String> remainingExpectedIds = new LinkedHashSet<>(expectedIds);
+      for (SearchResult result : got.results) {
+        String id = result.getId();
+        boolean removed = remainingExpectedIds.remove(id);
+        if (!removed && (!opIsDisjoint && !secondaryIds.contains(id))) {
+          fail("Shouldn't match", id, indexedShapes, indexedShapesGS, queryShape);
+        }
+      }
+      if (opIsDisjoint)
+        remainingExpectedIds.removeAll(secondaryIds);
+      if (!remainingExpectedIds.isEmpty()) {
+        String id = remainingExpectedIds.iterator().next();
+        fail("Should have matched", id, indexedShapes, indexedShapesGS, queryShape);
+      }
+    }
+  }
+
+  private Shape randomShapePairRect(boolean biasContains) {
+    Rectangle shape1 = randomRectangle();
+    Rectangle shape2 = randomRectangle();
+    return new ShapePair(shape1, shape2, biasContains);
+  }
+
+  private void fail(String label, String id, Map<String, Shape> indexedShapes, Map<String, Shape> indexedShapesGS, Shape queryShape) {
+    System.err.println("Ig:" + indexedShapesGS.get(id) + " Qg:" + gridSnap(queryShape));
+    fail(label + " I#" + id + ":" + indexedShapes.get(id) + " Q:" + queryShape);
+  }
+
+//  private Rectangle inset(Rectangle r) {
+//    //typically inset by 1 (whole numbers are easy to read)
+//    double d = Math.min(1.0, grid.getDistanceForLevel(grid.getMaxLevels()) / 4);
+//    return ctx.makeRectangle(r.getMinX() + d, r.getMaxX() - d, r.getMinY() + d, r.getMaxY() - d);
+//  }
+
+  protected Shape gridSnap(Shape snapMe) {
+    if (snapMe == null)
+      return null;
+    if (snapMe instanceof ShapePair) {
+      ShapePair me = (ShapePair) snapMe;
+      return new ShapePair(gridSnap(me.shape1), gridSnap(me.shape2), me.biasContainsThenWithin);
+    }
+    if (snapMe instanceof Point) {
+      snapMe = snapMe.getBoundingBox();
+    }
+    //The next 4 lines mimic PrefixTreeStrategy.createIndexableFields()
+    double distErrPct = ((PrefixTreeStrategy) strategy).getDistErrPct();
+    double distErr = SpatialArgs.calcDistanceFromErrPct(snapMe, distErrPct, ctx);
+    int detailLevel = grid.getLevelForDistance(distErr);
+    CellIterator cells = grid.getTreeCellIterator(snapMe, detailLevel);
+
+    //calc bounding box of cells.
+    List<Shape> cellShapes = new ArrayList<>(1024);
+    while (cells.hasNext()) {
+      Cell cell = cells.next();
+      if (!cell.isLeaf())
+        continue;
+      cellShapes.add(cell.getShape());
+    }
+    return new ShapeCollection<>(cellShapes, ctx).getBoundingBox();
+  }
+
+  /**
+   * An aggregate of 2 shapes. Unfortunately we can't simply use a ShapeCollection because:
+   * (a) ambiguity between CONTAINS and WITHIN for equal shapes, and
+   * (b) adjacent pairs could as a whole contain the input shape.
+   * The tests here are sensitive to these matters, although in practice ShapeCollection
+   * is fine.
+   */
+  private class ShapePair extends ShapeCollection<Shape> {
+
+    final Shape shape1, shape2;
+    final Shape shape1_2D, shape2_2D;//not geo (bit of a hack)
+    final boolean biasContainsThenWithin;
+
+    public ShapePair(Shape shape1, Shape shape2, boolean containsThenWithin) {
+      super(Arrays.asList(shape1, shape2), RandomSpatialOpFuzzyPrefixTreeTest.this.ctx);
+      this.shape1 = shape1;
+      this.shape2 = shape2;
+      this.shape1_2D = toNonGeo(shape1);
+      this.shape2_2D = toNonGeo(shape2);
+      biasContainsThenWithin = containsThenWithin;
+    }
+
+    private Shape toNonGeo(Shape shape) {
+      if (!ctx.isGeo())
+        return shape;//already non-geo
+      if (shape instanceof Rectangle) {
+        Rectangle rect = (Rectangle) shape;
+        if (rect.getCrossesDateLine()) {
+          return new ShapePair(
+              ctx2D.makeRectangle(rect.getMinX(), 180, rect.getMinY(), rect.getMaxY()),
+              ctx2D.makeRectangle(-180, rect.getMaxX(), rect.getMinY(), rect.getMaxY()),
+              biasContainsThenWithin);
+        } else {
+          return ctx2D.makeRectangle(rect.getMinX(), rect.getMaxX(), rect.getMinY(), rect.getMaxY());
+        }
+      }
+      //no need to do others; this addresses the -180/+180 ambiguity corner test problem
+      return shape;
+    }
+
+    @Override
+    public SpatialRelation relate(Shape other) {
+      SpatialRelation r = relateApprox(other);
+      if (r == DISJOINT)
+        return r;
+      if (r == CONTAINS)
+        return r;
+      if (r == WITHIN && !biasContainsThenWithin)
+        return r;
+
+      //See if the correct answer is actually Contains, when the indexed shapes are adjacent,
+      // creating a larger shape that contains the input shape.
+      boolean pairTouches = shape1.relate(shape2).intersects();
+      if (!pairTouches)
+        return r;
+      //test all 4 corners
+      // Note: awkwardly, we use a non-geo context for this because in geo, -180 & +180 are the same place, which means
+      //  that "other" might wrap the world horizontally and yet all its corners could be in shape1 (or shape2) even
+      //  though shape1 is only adjacent to the dateline. I couldn't think of a better way to handle this.
+      Rectangle oRect = (Rectangle)other;
+      if (cornerContainsNonGeo(oRect.getMinX(), oRect.getMinY())
+          && cornerContainsNonGeo(oRect.getMinX(), oRect.getMaxY())
+          && cornerContainsNonGeo(oRect.getMaxX(), oRect.getMinY())
+          && cornerContainsNonGeo(oRect.getMaxX(), oRect.getMaxY()) )
+        return CONTAINS;
+      return r;
+    }
+
+    private boolean cornerContainsNonGeo(double x, double y) {
+      Shape pt = ctx2D.makePoint(x, y);
+      return shape1_2D.relate(pt).intersects() || shape2_2D.relate(pt).intersects();
+    }
+
+    private SpatialRelation relateApprox(Shape other) {
+      if (biasContainsThenWithin) {
+        if (shape1.relate(other) == CONTAINS || shape1.equals(other)
+            || shape2.relate(other) == CONTAINS || shape2.equals(other)) return CONTAINS;
+
+        if (shape1.relate(other) == WITHIN && shape2.relate(other) == WITHIN) return WITHIN;
+
+      } else {
+        if ((shape1.relate(other) == WITHIN || shape1.equals(other))
+            && (shape2.relate(other) == WITHIN || shape2.equals(other))) return WITHIN;
+
+        if (shape1.relate(other) == CONTAINS || shape2.relate(other) == CONTAINS) return CONTAINS;
+      }
+
+      if (shape1.relate(other).intersects() || shape2.relate(other).intersects())
+        return INTERSECTS;//might actually be 'CONTAINS' if the pair are adjacent but we handle that later
+      return DISJOINT;
+    }
+
+    @Override
+    public String toString() {
+      return "ShapePair(" + shape1 + " , " + shape2 + ")";
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpStrategyTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpStrategyTestCase.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpStrategyTestCase.java
new file mode 100644
index 0000000..87f1071
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/RandomSpatialOpStrategyTestCase.java
@@ -0,0 +1,141 @@
+/*
+ * 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.prefix;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.spatial.StrategyTestCase;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.query.SpatialOperation;
+
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomInt;
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween;
+
+/** Base test harness, ideally for SpatialStrategy impls that have exact results
+ * (not grid approximated), hence "not fuzzy".
+ */
+public abstract class RandomSpatialOpStrategyTestCase extends StrategyTestCase {
+
+  //Note: this is partially redundant with StrategyTestCase.runTestQuery & testOperation
+
+  protected void testOperationRandomShapes(final SpatialOperation operation) throws IOException {
+
+    final int numIndexedShapes = randomIntBetween(1, 6);
+    List<Shape> indexedShapes = new ArrayList<>(numIndexedShapes);
+    for (int i = 0; i < numIndexedShapes; i++) {
+      indexedShapes.add(randomIndexedShape());
+    }
+
+    final int numQueryShapes = atLeast(20);
+    List<Shape> queryShapes = new ArrayList<>(numQueryShapes);
+    for (int i = 0; i < numQueryShapes; i++) {
+      queryShapes.add(randomQueryShape());
+    }
+
+    testOperation(operation, indexedShapes, queryShapes, true/*havoc*/);
+  }
+
+  protected void testOperation(final SpatialOperation operation,
+                               List<Shape> indexedShapes, List<Shape> queryShapes, boolean havoc) throws IOException {
+    //first show that when there's no data, a query will result in no results
+    {
+      Query query = strategy.makeQuery(new SpatialArgs(operation, randomQueryShape()));
+      SearchResults searchResults = executeQuery(query, 1);
+      assertEquals(0, searchResults.numFound);
+    }
+
+    //Main index loop:
+    for (int i = 0; i < indexedShapes.size(); i++) {
+      Shape shape = indexedShapes.get(i);
+      adoc(""+i, shape);
+
+      if (havoc && random().nextInt(10) == 0)
+        commit();//intermediate commit, produces extra segments
+    }
+    if (havoc) {
+      //delete some documents randomly
+      for (int id = 0; id < indexedShapes.size(); id++) {
+        if (random().nextInt(10) == 0) {
+          deleteDoc(""+id);
+          indexedShapes.set(id, null);
+        }
+      }
+    }
+
+    commit();
+
+    //Main query loop:
+    for (int queryIdx = 0; queryIdx < queryShapes.size(); queryIdx++) {
+      final Shape queryShape = queryShapes.get(queryIdx);
+
+      if (havoc)
+        preQueryHavoc();
+
+      //Generate truth via brute force:
+      // We ensure true-positive matches (if the predicate on the raw shapes match
+      //  then the search should find those same matches).
+      Set<String> expectedIds = new LinkedHashSet<>();//true-positives
+      for (int id = 0; id < indexedShapes.size(); id++) {
+        Shape indexedShape = indexedShapes.get(id);
+        if (indexedShape == null)
+          continue;
+        if (operation.evaluate(indexedShape, queryShape)) {
+          expectedIds.add(""+id);
+        }
+      }
+
+      //Search and verify results
+      SpatialArgs args = new SpatialArgs(operation, queryShape);
+      Query query = strategy.makeQuery(args);
+      SearchResults got = executeQuery(query, 100);
+      Set<String> remainingExpectedIds = new LinkedHashSet<>(expectedIds);
+      for (SearchResult result : got.results) {
+        String id = result.getId();
+        if (!remainingExpectedIds.remove(id)) {
+          fail("qIdx:" + queryIdx + " Shouldn't match", id, indexedShapes, queryShape, operation);
+        }
+      }
+      if (!remainingExpectedIds.isEmpty()) {
+        String id = remainingExpectedIds.iterator().next();
+        fail("qIdx:" + queryIdx + " Should have matched", id, indexedShapes, queryShape, operation);
+      }
+    }
+  }
+
+  private void fail(String label, String id, List<Shape> indexedShapes, Shape queryShape, SpatialOperation operation) {
+    fail("[" + operation + "] " + label
+        + " I#" + id + ":" + indexedShapes.get(Integer.parseInt(id)) + " Q:" + queryShape);
+  }
+
+  protected void preQueryHavoc() {
+    if (strategy instanceof RecursivePrefixTreeStrategy) {
+      RecursivePrefixTreeStrategy rpts = (RecursivePrefixTreeStrategy) strategy;
+      int scanLevel = randomInt(rpts.getGrid().getMaxLevels());
+      rpts.setPrefixGridScanLevel(scanLevel);
+    }
+  }
+
+  protected abstract Shape randomIndexedShape();
+
+  protected abstract Shape randomQueryShape();
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java
new file mode 100644
index 0000000..a53d52d
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java
@@ -0,0 +1,122 @@
+/*
+ * 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.prefix;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.distance.DistanceUtils;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.spatial.SpatialMatchConcern;
+import org.apache.lucene.spatial.StrategyTestCase;
+import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+public class TestRecursivePrefixTreeStrategy extends StrategyTestCase {
+
+  private int maxLength;
+
+  //Tests should call this first.
+  private void init(int maxLength) {
+    this.maxLength = maxLength;
+    this.ctx = SpatialContext.GEO;
+    GeohashPrefixTree grid = new GeohashPrefixTree(ctx, maxLength);
+    this.strategy = new RecursivePrefixTreeStrategy(grid, getClass().getSimpleName());
+  }
+
+  @Test
+  public void testFilterWithVariableScanLevel() throws IOException {
+    init(GeohashPrefixTree.getMaxLevelsPossible());
+    getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS);
+
+    //execute queries for each prefix grid scan level
+    for(int i = 0; i <= maxLength; i++) {
+      ((RecursivePrefixTreeStrategy)strategy).setPrefixGridScanLevel(i);
+      executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_Intersects_BBox);
+    }
+  }
+
+  @Test
+  public void testOneMeterPrecision() {
+    init(GeohashPrefixTree.getMaxLevelsPossible());
+    GeohashPrefixTree grid = (GeohashPrefixTree) ((RecursivePrefixTreeStrategy) strategy).getGrid();
+    //DWS: I know this to be true.  11 is needed for one meter
+    double degrees = DistanceUtils.dist2Degrees(0.001, DistanceUtils.EARTH_MEAN_RADIUS_KM);
+    assertEquals(11, grid.getLevelForDistance(degrees));
+  }
+
+  @Test
+  public void testPrecision() throws IOException{
+    init(GeohashPrefixTree.getMaxLevelsPossible());
+
+    Point iPt = ctx.makePoint(2.8028712999999925, 48.3708044);//lon, lat
+    addDocument(newDoc("iPt", iPt));
+    commit();
+
+    Point qPt = ctx.makePoint(2.4632387000000335, 48.6003516);
+
+    final double KM2DEG = DistanceUtils.dist2Degrees(1, DistanceUtils.EARTH_MEAN_RADIUS_KM);
+    final double DEG2KM = 1 / KM2DEG;
+
+    final double DIST = 35.75;//35.7499...
+    assertEquals(DIST, ctx.getDistCalc().distance(iPt, qPt) * DEG2KM, 0.001);
+
+    //distErrPct will affect the query shape precision. The indexed precision
+    // was set to nearly zilch via init(GeohashPrefixTree.getMaxLevelsPossible());
+    final double distErrPct = 0.025; //the suggested default, by the way
+    final double distMult = 1+distErrPct;
+
+    assertTrue(35.74*distMult >= DIST);
+    checkHits(q(qPt, 35.74 * KM2DEG, distErrPct), 1, null);
+
+    assertTrue(30*distMult < DIST);
+    checkHits(q(qPt, 30 * KM2DEG, distErrPct), 0, null);
+
+    assertTrue(33*distMult < DIST);
+    checkHits(q(qPt, 33 * KM2DEG, distErrPct), 0, null);
+
+    assertTrue(34*distMult < DIST);
+    checkHits(q(qPt, 34 * KM2DEG, distErrPct), 0, null);
+  }
+
+  private SpatialArgs q(Point pt, double distDEG, double distErrPct) {
+    Shape shape = ctx.makeCircle(pt, distDEG);
+    SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects,shape);
+    args.setDistErrPct(distErrPct);
+    return args;
+  }
+
+  private void checkHits(SpatialArgs args, int assertNumFound, int[] assertIds) {
+    SearchResults got = executeQuery(strategy.makeQuery(args), 100);
+    assertEquals("" + args, assertNumFound, got.numFound);
+    if (assertIds != null) {
+      Set<Integer> gotIds = new HashSet<>();
+      for (SearchResult result : got.results) {
+        gotIds.add(Integer.valueOf(result.document.get("id")));
+      }
+      for (int assertId : assertIds) {
+        assertTrue("has "+assertId,gotIds.contains(assertId));
+      }
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestTermQueryPrefixGridStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestTermQueryPrefixGridStrategy.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestTermQueryPrefixGridStrategy.java
new file mode 100644
index 0000000..1a912c0
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/TestTermQueryPrefixGridStrategy.java
@@ -0,0 +1,63 @@
+/*
+ * 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.prefix;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.StoredField;
+import org.apache.lucene.document.StringField;
+import org.apache.lucene.spatial.SpatialTestCase;
+import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
+import org.apache.lucene.spatial.query.SpatialArgsParser;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+
+public class TestTermQueryPrefixGridStrategy extends SpatialTestCase {
+
+  @Test
+  public void testNGramPrefixGridLosAngeles() throws IOException {
+    SpatialContext ctx = SpatialContext.GEO;
+    TermQueryPrefixTreeStrategy prefixGridStrategy = new TermQueryPrefixTreeStrategy(new QuadPrefixTree(ctx), "geo");
+
+    Shape point = ctx.makePoint(-118.243680, 34.052230);
+
+    Document losAngeles = new Document();
+    losAngeles.add(new StringField("name", "Los Angeles", Field.Store.YES));
+    for (Field field : prefixGridStrategy.createIndexableFields(point)) {
+      losAngeles.add(field);
+    }
+    losAngeles.add(new StoredField(prefixGridStrategy.getFieldName(), point.toString()));//just for diagnostics
+
+    addDocumentsAndCommit(Arrays.asList(losAngeles));
+
+    // This won't work with simple spatial context...
+    SpatialArgsParser spatialArgsParser = new SpatialArgsParser();
+    // TODO... use a non polygon query
+//    SpatialArgs spatialArgs = spatialArgsParser.parse(
+//        "Intersects(POLYGON((-127.00390625 39.8125,-112.765625 39.98828125,-111.53515625 31.375,-125.94921875 30.14453125,-127.00390625 39.8125)))",
+//        new SimpleSpatialContext());
+
+//    Query query = prefixGridStrategy.makeQuery(spatialArgs, fieldInfo);
+//    SearchResults searchResults = executeQuery(query, 1);
+//    assertEquals(1, searchResults.numFound);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTreeTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTreeTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTreeTest.java
new file mode 100644
index 0000000..74a989e
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTreeTest.java
@@ -0,0 +1,175 @@
+/*
+ * 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.prefix.tree;
+
+import java.text.ParseException;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.SpatialRelation;
+import org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.LuceneTestCase;
+
+public class DateRangePrefixTreeTest extends LuceneTestCase {
+
+  private DateRangePrefixTree tree = DateRangePrefixTree.INSTANCE;
+
+  public void testRoundTrip() throws Exception {
+    Calendar cal = tree.newCal();
+
+    assertEquals("*", tree.toString(cal));
+
+    //test no underflow
+    assertTrue(tree.toShape(new int[]{0}, 1).toString().startsWith("-"));
+
+    //Some arbitrary date
+    cal.set(2014, Calendar.MAY, 9);
+    roundTrip(cal);
+    assertEquals("2014-05-09",tree.toString(cal));
+
+    //Earliest date
+    cal.setTimeInMillis(Long.MIN_VALUE);
+    roundTrip(cal);
+
+    //Farthest date
+    cal.setTimeInMillis(Long.MAX_VALUE);
+    roundTrip(cal);
+
+    //1BC is "0000".
+    cal.clear();
+    cal.set(Calendar.ERA, GregorianCalendar.BC);
+    cal.set(Calendar.YEAR, 1);
+    roundTrip(cal);
+    assertEquals("0000", tree.toString(cal));
+    //adding a "+" parses to the same; and a trailing 'Z' is fine too
+    assertEquals(cal, tree.parseCalendar("+0000Z"));
+
+    //2BC is "-0001"
+    cal.clear();
+    cal.set(Calendar.ERA, GregorianCalendar.BC);
+    cal.set(Calendar.YEAR, 2);
+    roundTrip(cal);
+    assertEquals("-0001", tree.toString(cal));
+
+    //1AD is "0001"
+    cal.clear();
+    cal.set(Calendar.YEAR, 1);
+    roundTrip(cal);
+    assertEquals("0001", tree.toString(cal));
+
+    //test random
+    cal.setTimeInMillis(random().nextLong());
+    roundTrip(cal);
+  }
+
+  //copies from DateRangePrefixTree
+  private static final int[] CAL_FIELDS = {
+      Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH,
+      Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND};
+
+  private void roundTrip(Calendar calOrig) throws ParseException {
+    Calendar cal = (Calendar) calOrig.clone();
+    String lastString = null;
+    while (true) {
+      String calString = tree.toString(cal);
+      assert lastString == null || calString.length() < lastString.length();
+      //test parseCalendar
+      assertEquals(cal, tree.parseCalendar(calString));
+
+      //to Shape and back to Cal
+      UnitNRShape shape = tree.toShape(cal);
+      Calendar cal2 = tree.toCalendar(shape);
+      assertEquals(calString, tree.toString(cal2));
+
+      if (!calString.equals("*")) {//not world cell
+        //to Term and back to Cell
+        Cell cell = (Cell) shape;
+        BytesRef term = cell.getTokenBytesNoLeaf(null);
+        Cell cell2 = tree.readCell(BytesRef.deepCopyOf(term), null);
+        assertEquals(calString, cell, cell2);
+        Calendar cal3 = tree.toCalendar((UnitNRShape) cell2.getShape());
+        assertEquals(calString, tree.toString(cal3));
+
+        // setLeaf comparison
+        cell2.setLeaf();
+        BytesRef termLeaf = cell2.getTokenBytesWithLeaf(null);
+        assertTrue(term.compareTo(termLeaf) < 0);
+        assertEquals(termLeaf.length, term.length + 1);
+        assertEquals(0, termLeaf.bytes[termLeaf.offset + termLeaf.length - 1]);
+        assertTrue(cell.isPrefixOf(cell2));
+      }
+
+      //end of loop; decide if should loop again with lower precision
+      final int calPrecField = tree.getCalPrecisionField(cal);
+      if (calPrecField == -1)
+        break;
+      int fieldIdx = Arrays.binarySearch(CAL_FIELDS, calPrecField);
+      assert fieldIdx >= 0;
+      int prevPrecField = (fieldIdx == 0 ? -1 : CAL_FIELDS[--fieldIdx]);
+      try {
+        tree.clearFieldsAfter(cal, prevPrecField);
+      } catch (AssertionError e) {
+        if (e.getMessage().equals("Calendar underflow"))
+          return;
+        throw e;
+      }
+      lastString = calString;
+    }
+  }
+
+  public void testShapeRelations() throws ParseException {
+    //note: left range is 264000 at the thousand year level whereas right value is exact year
+    assertEquals(SpatialRelation.WITHIN,
+        tree.parseShape("[-264000 TO -264000-11-20]").relate(tree.parseShape("-264000")));
+
+    Shape shapeA = tree.parseShape("[3122-01-23 TO 3122-11-27]");
+    Shape shapeB = tree.parseShape("[3122-08 TO 3122-11]");
+    assertEquals(SpatialRelation.INTERSECTS, shapeA.relate(shapeB));
+
+    shapeA = tree.parseShape("3122");
+    shapeB = tree.parseShape("[* TO 3122-10-31]");
+    assertEquals(SpatialRelation.INTERSECTS, shapeA.relate(shapeB));
+
+    shapeA = tree.parseShape("[3122-05-28 TO 3122-06-29]");
+    shapeB = tree.parseShape("[3122 TO 3122-04]");
+    assertEquals(SpatialRelation.DISJOINT, shapeA.relate(shapeB));
+  }
+
+  public void testShapeRangeOptimizer() throws ParseException {
+    assertEquals("[2014-08 TO 2014-09]", tree.parseShape("[2014-08-01 TO 2014-09-30]").toString());
+
+    assertEquals("2014", tree.parseShape("[2014-01-01 TO 2014-12-31]").toString());
+
+    assertEquals("2014",    tree.parseShape("[2014-01 TO 2014]").toString());
+    assertEquals("2014-01", tree.parseShape("[2014 TO 2014-01]").toString());
+    assertEquals("2014-12", tree.parseShape("[2014-12 TO 2014]").toString());
+
+    assertEquals("[2014 TO 2014-04-06]", tree.parseShape("[2014-01 TO 2014-04-06]").toString());
+
+    assertEquals("*", tree.parseShape("[* TO *]").toString());
+
+    assertEquals("2014-08-01", tree.parseShape("[2014-08-01 TO 2014-08-01]").toString());
+
+    assertEquals("[2014 TO 2014-09-15]", tree.parseShape("[2014 TO 2014-09-15]").toString());
+
+    assertEquals("[* TO 2014-09-15]", tree.parseShape("[* TO 2014-09-15]").toString());
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeTest.java
new file mode 100644
index 0000000..403b8d1
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeTest.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial.prefix.tree;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.Field.Store;
+import org.apache.lucene.document.TextField;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.spatial.SpatialTestCase;
+import org.apache.lucene.spatial.prefix.TermQueryPrefixTreeStrategy;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SpatialPrefixTreeTest extends SpatialTestCase {
+
+  //TODO plug in others and test them
+  private SpatialContext ctx;
+  private SpatialPrefixTree trie;
+
+  @Override
+  @Before
+  public void setUp() throws Exception {
+    super.setUp();
+    ctx = SpatialContext.GEO;
+  }
+
+  @Test
+  public void testCellTraverse() {
+    trie = new GeohashPrefixTree(ctx,4);
+
+    Cell prevC = null;
+    Cell c = trie.getWorldCell();
+    assertEquals(0, c.getLevel());
+    assertEquals(ctx.getWorldBounds(), c.getShape());
+    while (c.getLevel() < trie.getMaxLevels()) {
+      prevC = c;
+      List<Cell> subCells = new ArrayList<>();
+      CellIterator subCellsIter = c.getNextLevelCells(null);
+      while (subCellsIter.hasNext()) {
+        subCells.add(subCellsIter.next());
+      }
+      c = subCells.get(random().nextInt(subCells.size()-1));
+
+      assertEquals(prevC.getLevel()+1,c.getLevel());
+      Rectangle prevNShape = (Rectangle) prevC.getShape();
+      Shape s = c.getShape();
+      Rectangle sbox = s.getBoundingBox();
+      assertTrue(prevNShape.getWidth() > sbox.getWidth());
+      assertTrue(prevNShape.getHeight() > sbox.getHeight());
+    }
+  }
+  /**
+   * A PrefixTree pruning optimization gone bad, applicable when optimize=true.
+   * See <a href="https://issues.apache.org/jira/browse/LUCENE-4770">LUCENE-4770</a>.
+   */
+  @Test
+  public void testBadPrefixTreePrune() throws Exception {
+
+    trie = new QuadPrefixTree(ctx, 12);
+    TermQueryPrefixTreeStrategy strategy = new TermQueryPrefixTreeStrategy(trie, "geo");
+    Document doc = new Document();
+    doc.add(new TextField("id", "1", Store.YES));
+
+    Shape area = ctx.makeRectangle(-122.82, -122.78, 48.54, 48.56);
+
+    Field[] fields = strategy.createIndexableFields(area, 0.025);
+    for (Field field : fields) {
+      doc.add(field);
+    }
+    addDocument(doc);
+
+    Point upperleft = ctx.makePoint(-122.88, 48.54);
+    Point lowerright = ctx.makePoint(-122.82, 48.62);
+
+    Query query = strategy.makeQuery(new SpatialArgs(SpatialOperation.Intersects, ctx.makeRectangle(upperleft, lowerright)));
+
+    commit();
+
+    TopDocs search = indexSearcher.search(query, 10);
+    ScoreDoc[] scoreDocs = search.scoreDocs;
+    for (ScoreDoc scoreDoc : scoreDocs) {
+      System.out.println(indexSearcher.doc(scoreDoc.doc));
+    }
+
+    assertEquals(1, search.totalHits);
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/query/SpatialArgsParserTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/query/SpatialArgsParserTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/query/SpatialArgsParserTest.java
new file mode 100644
index 0000000..93b95f3
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/query/SpatialArgsParserTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.query;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Rectangle;
+import org.apache.lucene.util.LuceneTestCase;
+import org.junit.Test;
+
+import java.text.ParseException;
+
+//Tests SpatialOperation somewhat too
+public class SpatialArgsParserTest extends LuceneTestCase {
+
+  private SpatialContext ctx = SpatialContext.GEO;
+
+  //The args parser is only dependent on the ctx for IO so I don't care to test
+  // with other implementations.
+
+  @Test
+  public void testArgsParser() throws Exception {
+    SpatialArgsParser parser = new SpatialArgsParser();
+
+    String arg = SpatialOperation.IsWithin + "(Envelope(-10, 10, 20, -20))";
+    SpatialArgs out = parser.parse(arg, ctx);
+    assertEquals(SpatialOperation.IsWithin, out.getOperation());
+    Rectangle bounds = (Rectangle) out.getShape();
+    assertEquals(-10.0, bounds.getMinX(), 0D);
+    assertEquals(10.0, bounds.getMaxX(), 0D);
+
+    // Disjoint should not be scored
+    arg = SpatialOperation.IsDisjointTo + " (Envelope(-10,-20,20,10))";
+    out = parser.parse(arg, ctx);
+    assertEquals(SpatialOperation.IsDisjointTo, out.getOperation());
+
+    // spatial operations need args
+    expectThrows(Exception.class, () -> {
+      parser.parse(SpatialOperation.IsDisjointTo + "[ ]", ctx);
+    });
+
+    // unknown operation
+    expectThrows(Exception.class, () -> {
+      parser.parse("XXXX(Envelope(-10, 10, 20, -20))", ctx);
+    });
+
+    assertAlias(SpatialOperation.IsWithin, "CoveredBy");
+    assertAlias(SpatialOperation.IsWithin, "COVEREDBY");
+    assertAlias(SpatialOperation.IsWithin, "coveredBy");
+    assertAlias(SpatialOperation.IsWithin, "Within");
+    assertAlias(SpatialOperation.IsEqualTo, "Equals");
+    assertAlias(SpatialOperation.IsDisjointTo, "disjoint");
+    assertAlias(SpatialOperation.Contains, "Covers");
+  }
+
+  private void assertAlias(SpatialOperation op, final String name) throws ParseException {
+    String arg;
+    SpatialArgs out;
+    arg = name + "(Point(0 0))";
+    out = new SpatialArgsParser().parse(arg, ctx);
+    assertEquals(op, out.getOperation());
+  }
+
+}


[09/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test-files/data/states-poly.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test-files/data/states-poly.txt b/lucene/spatial/src/test-files/data/states-poly.txt
deleted file mode 100644
index 6164ae0..0000000
--- a/lucene/spatial/src/test-files/data/states-poly.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-#id	name	shape	
-HI	Hawaii	MULTIPOLYGON (((-160.07380334546815 22.00417734795773, -160.0497093454457 21.988164347942817, -160.0898583454831 21.915870347875487, -160.17013734555786 21.867596347830528, -160.20225934558778 21.795308347763203, -160.24240634562517 21.803280347770627, -160.2263363456102 21.891592347852875, -160.121962345513 21.96397834792029, -160.07380334546815 22.00417734795773)), ((-159.33517434478023 21.94834334790573, -159.43954534487744 21.86807134783097, -159.57602134500453 21.88413634784593, -159.64024734506435 21.94836534790575, -159.7365923451541 21.9644203479207, -159.8008143452139 22.036666347987985, -159.71250634513166 22.14905934809266, -159.57601234500453 22.213179348152376, -159.39136734483256 22.229120348167225, -159.34319534478772 22.197016348137325, -159.29502534474284 22.12481234807008, -159.32713034477274 22.044639347995414, -159.33517434478023 21.94834334790573)), ((-157.67333034323252 21.298027347300074, -157.68137134324002 21.273942347277643, -157.7215013432774 21.
 281971347285122, -157.8258713433746 21.249863347255218, -157.89813434344188 21.330144347329988, -157.94630634348675 21.30606134730756, -158.0988333436288 21.290008347292606, -158.13095134365872 21.354232347352422, -158.23531834375592 21.47465234746457, -158.24334234376337 21.538879347524386, -158.26743134378583 21.58704234756924, -158.11489434364375 21.579016347561765, -158.04262634357644 21.675350347651484, -157.98642834352412 21.699433347673914, -157.91417934345682 21.6352083476141, -157.84995934339702 21.506758347494472, -157.80981534335962 21.43450534742718, -157.76164334331477 21.45858734744961, -157.7134723432699 21.386335347382317, -157.67333034323252 21.298027347300074)), ((-156.71787234234267 21.137419347150498, -156.76604834238753 21.065176347083217, -156.88648434249973 21.049134347068275, -157.0711323426717 21.105331347120615, -157.28789734287355 21.081250347098187, -157.3039483428885 21.137448347150524, -157.24774734283616 21.161530347172953, -157.2316943428212 21.233776
 347240237, -157.16747134276142 21.19364034720286, -157.00690334261185 21.18561034719538, -156.9925463425985 21.195420347204514, -156.958733342567 21.209693347217808, -156.94334634255267 21.172778347183428, -156.91424234252557 21.167372347178393, -156.9102143425218 21.158045347169708, -156.71787234234267 21.137419347150498)), ((-157.03905034264181 20.92870734695612, -156.91058634252215 20.92871834695613, -156.80620534242496 20.840418346873893, -156.81422534243242 20.792252346829034, -156.88648734249972 20.736049346776692, -156.9667653425745 20.728020346769213, -156.99086334259692 20.792237346829022, -156.98282634258945 20.832377346866405, -157.05509834265675 20.88053834691126, -157.03905034264181 20.92870734695612)), ((-156.1960453418567 20.631649346679463, -156.27631734193145 20.583484346634606, -156.3967353420436 20.567427346619652, -156.436879342081 20.623621346671985, -156.46097234210342 20.727981346769177, -156.49307434213333 20.792204346828992, -156.52519334216322 20.7761493468
 14037, -156.63758634226792 20.808261346843945, -156.69378234232025 20.91262434694114, -156.65363634228285 21.016985347038336, -156.59743934223053 21.04106434706076, -156.52519134216323 20.984870347008425, -156.47702234211837 20.896565346926185, -156.35660334200622 20.944726346971038, -156.2602633419165 20.928671346956087, -156.0113923416847 20.800225346836463, -155.9873173416623 20.752061346791606, -156.04351134171463 20.655732346701893, -156.13180934179687 20.623623346671987, -156.1960453418567 20.631649346679463)), ((-155.66619234136323 18.92178634508703, -155.7785853414679 19.01009234516927, -155.85886134154265 19.01010134516928, -155.90703134158753 19.130513345281422, -155.87492734155762 19.371358345505726, -155.94717834162492 19.4837503456104, -155.97125834164734 19.628252345744976, -156.04352434171466 19.78078334588703, -155.97930134165483 19.820922345924416, -155.88295834156511 19.933312346029084, -155.82676134151276 20.005563346096373, -155.83478634152024 20.06175734614871, 
 -155.89097834157258 20.174149346253383, -155.85885834154266 20.270479346343098, -155.73844234143053 20.206256346283283, -155.56182634126603 20.134007346216, -155.20055034092957 19.99752834608889, -155.09618534083236 19.877114345976747, -155.07210634080994 19.724585345834694, -154.97576334072022 19.740643345849648, -154.97576234072022 19.652335345767405, -154.79109634054822 19.53996034566275, -154.81518734057067 19.459676345587976, -154.92758134067535 19.41951834555058, -155.01588134075757 19.331211345468336, -155.1523723408847 19.266992345408525, -155.30489934102675 19.23487834537862, -155.52167834122864 19.122484345273943, -155.5377293412436 19.04221034519918, -155.66619234136323 18.92178634508703)))	
-WA	Washington	MULTIPOLYGON (((-122.40201531038355 48.22521637237797, -122.4628553104402 48.22836337238091, -122.45441931043234 48.128492372287894, -122.36133331034566 48.06009737222419, -122.51451131048832 48.133973372293, -122.54207431051398 48.21046037236424, -122.5091303104833 48.25379337240459, -122.40440431038577 48.24659437239789, -122.37832031036149 48.28972137243805, -122.56436631053475 48.414246372554025, -122.66703231063036 48.41289537255277, -122.69941331066052 48.4943283726286, -122.60817831057555 48.51882437265142, -122.52322831049644 48.45840337259515, -122.47383331045043 48.46219537259868, -122.50529931047973 48.55944437268925, -122.4295453104092 48.59939737272646, -122.48779831046343 48.63857037276294, -122.52655831049954 48.71172437283107, -122.51685331049049 48.757921372874094, -122.69740431065864 48.80301537291609, -122.75424231071159 48.90998837301572, -122.82242131077507 48.95072537305366, -122.74394031070199 48.95580837305839, -122.76511931072172 48.99974637309
 931, -120.85705930894468 48.99983037309939, -118.84360330706951 48.999898373099455, -118.20035430647044 48.999908373099466, -117.43858030576098 48.999918373099476, -117.03204930538237 48.999931373099486, -117.02911130537964 48.838075372948744, -117.03886830538872 48.04618637221124, -117.03747230538742 47.9710923721413, -117.04179430539145 47.36144137157352, -117.04239230539201 47.25850137147765, -117.04096830539069 47.11931937134803, -117.04192630539157 46.53660137080533, -117.03855830538843 46.42798037070417, -117.04447030539394 46.38857437066747, -117.06418430541231 46.34869837063033, -117.02797330537858 46.33542737061797, -117.00164230535405 46.30244837058726, -116.97272530532712 46.24930937053777, -116.96749030532226 46.19755437048957, -116.9294263052868 46.1654833704597, -116.9616373053168 46.09727437039618, -116.98721130534062 46.0785093703787, -116.95772330531315 46.06568737036676, -116.91913230527722 45.995175370301084, -117.4816633058011 45.99983437030543, -117.602826305913
 95 46.00026837030583, -117.98267730626772 45.99988037030547, -117.99252730627688 46.0016393703071, -118.98213330719852 45.99905837030471, -119.03222130724518 45.96627437027417, -119.14025030734578 45.92570837023639, -119.17874230738164 45.922351370233265, -119.30276330749714 45.932662370242866, -119.37944130756856 45.91761037022885, -119.4388613076239 45.91426837022574, -119.51222030769222 45.8992003702117, -119.58929430776399 45.91331537022485, -119.62211630779456 45.899410370211896, -119.67844530784703 45.852539370168245, -119.83355630799147 45.84160937015807, -119.86973530802518 45.83169837014884, -119.9943203081412 45.81114037012969, -120.06864830821043 45.78020237010088, -120.1559083082917 45.76126137008324, -120.20744530833969 45.71978437004461, -120.28363530841065 45.71658337004163, -120.44338330855942 45.6892793700162, -120.49915630861136 45.695630370022116, -120.57008230867743 45.74091837006429, -120.62375730872742 45.743610370066804, -120.65840330875969 45.73261237005656, 
 -120.69699430879562 45.71050937003597, -120.86141930894875 45.66518636999376, -120.90793730899208 45.6354773699661, -120.94857330902992 45.65031636997991, -120.96847830904846 45.6451543699751, -121.033482309109 45.65284436998227, -121.07353030914629 45.64661036997646, -121.12520430919443 45.60705936993963, -121.17431630924017 45.60051636993353, -121.19205430925669 45.61324236994538, -121.20330830926716 45.657287369986406, -121.21427130927736 45.66564536999419, -121.27639130933522 45.67834037000601, -121.31997730937582 45.696642370023056, -121.36781430942037 45.699686370025894, -121.42202930947087 45.690603370017435, -121.44255230948997 45.6949673700215, -121.52905430957054 45.71956737004441, -121.70641730973571 45.688793370015745, -121.7586943097844 45.68971637001661, -121.81104130983316 45.70068337002682, -121.88828330990509 45.67685637000463, -121.92682030994098 45.642028369972195, -121.97265930998367 45.63577636996637, -122.00001131000914 45.61782436994965, -122.08203731008555 45
 .590504369924204, -122.24492231023724 45.54811236988473, -122.30315031029147 45.54309236988006, -122.35645731034111 45.56617136990155, -122.43715431041628 45.56477936990025, -122.56542931053573 45.59481836992823, -122.65120931061563 45.606830369939416, -122.69632331065765 45.63104536996197, -122.76054131071746 45.649397369979056, -122.77255131072863 45.72768537005197, -122.76428831072094 45.760568370082595, -122.78800931074304 45.800343370119634, -122.78451631073978 45.8504493701663, -122.78407331073936 45.867886370182546, -122.80622331076 45.90407237021624, -122.8077413107614 45.94389037025333, -122.87541731082445 46.0271833703309, -122.89975731084711 46.07932937037946, -122.97416931091641 46.110483370408474, -123.05059631098759 46.155736370450626, -123.11855431105087 46.17931037047258, -123.17619631110456 46.18358637047656, -123.2124373111383 46.17000637046391, -123.24879931117218 46.14402037043971, -123.30471731122425 46.14473737044038, -123.4707733113789 46.27502337056171, -123.
 62007631151795 46.25866537054648, -123.7254593116161 46.28542337057141, -123.88577131176541 46.2404383705295, -123.99332931186558 46.31027437059455, -124.07910731194546 46.267259370554484, -124.0655103119328 46.639745370901394, -124.02304331189325 46.58354137084905, -124.0130023118839 46.383680370662915, -123.84145131172413 46.404343370682156, -123.94069331181655 46.481115370753656, -123.89356731177267 46.51107937078156, -123.95771231183241 46.61722537088042, -123.92647031180331 46.67306037093242, -123.84096631172368 46.71828837097454, -123.8955423117745 46.7449863709994, -124.04315831191198 46.71585537097228, -124.09104931195658 46.72902237098454, -124.10206731196683 46.78946937104083, -124.13882731200107 46.89998537114376, -124.10576031197029 46.908148371151356, -124.10473831196933 46.874145371119695, -124.02880831189862 46.823767371072776, -124.04692931191549 46.887253371131905, -123.81265531169731 46.963965371203344, -123.99586431186793 46.97638537121491, -124.03439431190381 47.
 031033371265806, -124.11236131197643 47.042675371276644, -124.16203631202269 46.92961237117135, -124.19273331205127 47.16698237139242, -124.23142531208731 47.275070371493086, -124.31942731216927 47.34923837156216, -124.34908031219689 47.526910371727624, -124.37360531221972 47.6387633718318, -124.48403531232259 47.80825537198965, -124.60668531243681 47.87373537205063, -124.73276931255424 48.149989372307914, -124.70520931252857 48.23199637238429, -124.71717531253971 48.37755737251986, -124.56354731239662 48.35727837250097, -123.99121531186361 48.15916137231646, -123.39685731131007 48.11103037227163, -123.12322231105523 48.14873337230675, -122.92159431086745 48.09417937225594, -122.92484431087047 48.066796372230435, -122.84111131079248 48.13313637229222, -122.76888231072522 48.14399437230233, -122.80293131075693 48.08532137224769, -122.66156031062528 47.91715737209107, -122.65358531061784 47.86443137204197, -122.7458703107038 47.80898837199034, -122.7898013107447 47.80254837198434, -12
 2.80951731076306 47.85707537203512, -122.85880431080896 47.827328372007415, -122.89936331084674 47.672517371863236, -122.9827443109244 47.605474371800796, -123.11391531104655 47.45627337166184, -123.15406031108395 47.348547371561516, -123.01047131095021 47.35302737156569, -122.83324731078517 47.43846437164525, -123.03620631097418 47.3560513715685, -123.11268531104541 47.37156937158295, -123.026336310965 47.51593637171741, -122.91696931086314 47.6146063718093, -122.75294231071038 47.66068837185222, -122.72306231068254 47.75689937194182, -122.61116231057832 47.85000837202854, -122.61321731058024 47.9361893721088, -122.5318883105045 47.90946137208391, -122.4735883104502 47.754980371940036, -122.62150931058797 47.69696837188601, -122.58646031055532 47.57119137176887, -122.55526231052627 47.58350537178033, -122.54270231051457 47.52273437172374, -122.50446131047896 47.50721637170929, -122.55844631052923 47.398363371607914, -122.5441253105159 47.373927371585154, -122.588254310557 47.333929
 371547896, -122.55315631052432 47.28333237150078, -122.5805303105498 47.251387371471026, -122.61154631057869 47.29339837151015, -122.60691431057438 47.2705713714889, -122.69974431066083 47.29208537150893, -122.62875431059472 47.39855337160809, -122.6374363106028 47.39858037160811, -122.74154931069975 47.341450371554906, -122.76970831072599 47.26615637148478, -122.71980131067951 47.22313137144471, -122.7612383107181 47.162496371388244, -122.82510831077758 47.234826371455604, -122.77333531072937 47.3373603715511, -122.80218431075623 47.360740371572874, -122.88037331082904 47.299233371515584, -123.11543631104797 47.207981371430606, -123.08120031101609 47.09005837132078, -123.03134831096966 47.10077437133076, -122.92315031086889 47.04796337128157, -122.79004831074494 47.125859371354125, -122.72818631068732 47.082441371313685, -122.70007931066114 47.09832537132848, -122.5918063105603 47.18006037140459, -122.53076331050346 47.28745637150462, -122.54658831051819 47.31627637153146, -122.424
 09431040412 47.25947237147855, -122.39284331037501 47.27772237149556, -122.44160431042042 47.301125371517344, -122.42083731040108 47.31884437153385, -122.32537631031218 47.34432337155758, -122.31973831030692 47.39011537160023, -122.3926333103748 47.5102423717121, -122.38222031036511 47.59540937179142, -122.41481531039547 47.664180371855466, -122.39449231037653 47.77417637195791, -122.30292231029125 47.95021437212186, -122.23012131022347 47.96911337213946, -122.21699231021123 48.007439372175156, -122.36833331035217 48.12814137228757, -122.40201531038355 48.22521637237797)), ((-122.96797831091064 48.44379437258154, -123.09523331102915 48.47942237261472, -123.15972031108922 48.521842372654234, -123.1698993110987 48.56256437269215, -123.14105331107183 48.62364737274905, -123.10372131103706 48.60837737273482, -123.01209531095174 48.557477372687416, -123.00869831094857 48.53371937266529, -122.96798031091063 48.526933372658974, -123.0222713109612 48.513359372646335, -123.01888331095805 48.
 48960537262421, -122.96797831091064 48.44379437258154)), ((-122.73318731069197 48.27664737242587, -122.66561231062904 48.396777372537755, -122.60438431057202 48.40478937254522, -122.52575031049878 48.32104337246722, -122.52864831050148 48.28351037243227, -122.62350931058984 48.29635037244422, -122.73203431069089 48.22541437237816, -122.61092531057811 48.20632137236038, -122.54620231051783 48.07685837223981, -122.49621231047126 48.09407137225584, -122.37999431036303 48.03214637219817, -122.35540031034013 47.963886372134596, -122.38696131036953 47.90454937207933, -122.44278831042152 47.91805637209191, -122.47161631044837 47.987509372156595, -122.54496131051667 47.967531372137984, -122.60862831057597 48.0314303721975, -122.69555431065692 48.18118537233697, -122.76877831072511 48.21881837237201, -122.73318731069197 48.27664737242587)))	
-MT	Montana	MULTIPOLYGON (((-111.47542530020736 44.702162369096875, -111.48080430021237 44.691416369086866, -111.46069230019364 44.67002336906694, -111.45826530019139 44.652555369050674, -111.47016830020247 44.640710369039645, -111.50769030023741 44.63768836903683, -111.50174730023188 44.615971369016606, -111.51452630024379 44.59319736899539, -111.49290430022364 44.55118936895627, -111.46282730019563 44.549942368955115, -111.45932530019238 44.53792136894391, -111.48257330021403 44.53614336894226, -111.49024130022117 44.528697368935326, -111.56723130029286 44.55286636895784, -111.60524830032827 44.54298936894864, -111.68486230040241 44.55075236895587, -111.71699730043235 44.53376036894004, -111.76691830047884 44.51882536892613, -111.79260830050276 44.518462368925796, -111.80783730051695 44.503982368912304, -111.87250230057717 44.556265368961, -111.9403863006404 44.54972636895491, -111.97781830067525 44.52967636893624, -112.02361330071791 44.53504336894123, -112.02707730072113 44.52284
 336892987, -112.0593673007512 44.528611368935245, -112.09989730078895 44.518231368925576, -112.12419030081158 44.52825336893491, -112.19965830088186 44.531449368937885, -112.21776330089872 44.53849536894445, -112.2303983009105 44.559491368964004, -112.25667530093496 44.55997236896445, -112.28234130095886 44.54170236894744, -112.3425073010149 44.52510036893197, -112.3405773010131 44.49718036890597, -112.36758330103825 44.44927036886135, -112.42075330108777 44.44928436886136, -112.45851930112295 44.46883436887957, -112.50183930116329 44.462997368874134, -112.53932430119819 44.47749736888764, -112.65318930130424 44.48080236889072, -112.71432630136118 44.49693536890574, -112.73371230137924 44.48432036889399, -112.77986330142222 44.47392236888431, -112.79622830143747 44.45801136886949, -112.82669130146583 44.4210843688351, -112.8187103014584 44.394819368810644, -112.81739630145718 44.36420236878213, -112.84427530148221 44.35363936877229, -112.8707813015069 44.36997836878751, -112.8873073
 0152228 44.3928523688088, -112.93828130156976 44.407192368822166, -112.98524930161349 44.435540368848564, -113.01201430163843 44.43771536885059, -113.00665830163344 44.45261536886447, -113.02030930164615 44.48177636889163, -113.00771330163442 44.51061236891848, -113.03782130166246 44.532959368939295, -113.03966030166417 44.55629436896103, -113.08303730170456 44.582681368985604, -113.0542893016778 44.62428936902435, -113.07314430169536 44.67552536907207, -113.0989563017194 44.69591636909106, -113.10170330172195 44.715173369108996, -113.12743130174591 44.73737936912967, -113.13827430175601 44.761439369152086, -113.24033830185107 44.81184136919902, -113.25715430186673 44.81048636919776, -113.31868030192403 44.78022836916958, -113.34063130194447 44.779000369168436, -113.35002430195323 44.80756836919504, -113.42137930201967 44.833699369219374, -113.4455733020422 44.851239369235714, -113.49619130208936 44.930670369309695, -113.48734830208112 44.93957436931798, -113.46341330205883 44.94077
 53693191, -113.44876530204519 44.94952236932725, -113.44102930203798 44.99819436937258, -113.45885330205458 45.02744936939982, -113.4554353020514 45.04334936941463, -113.48630530208014 45.058321369428576, -113.49015930208374 45.071219369440584, -113.52060930211209 45.08206336945069, -113.51022530210243 45.107835369474685, -113.55227230214157 45.10754936947443, -113.57437630216216 45.117711369483885, -113.57158430215956 45.13454536949956, -113.59409930218054 45.14974236951372, -113.6009283021869 45.18099236954282, -113.6455923022285 45.206790369566846, -113.69012030226996 45.26228136961853, -113.68870930226865 45.27778836963297, -113.73908030231556 45.32153036967371, -113.74131030231763 45.38238636973038, -113.77502630234903 45.41017236975626, -113.78566230235894 45.44563336978929, -113.76916830234359 45.47770736981916, -113.7723043023465 45.507054369846486, -113.78093330235454 45.51686536985562, -113.83371530240369 45.514908369853806, -113.8037543023758 45.583729369917904, -113.8224
 8530239323 45.600636369933646, -113.85202730242075 45.609562369941955, -113.90330530246851 45.61349136994562, -113.90219930246748 45.63725336996775, -113.92353230248735 45.65512436998439, -113.9266983024903 45.67121136999937, -113.96414430252517 45.67937837000698, -113.97114930253169 45.69737637002374, -114.00947230256737 45.68633237001346, -114.01987830257707 45.67237837000046, -114.0109903025688 45.65251136998196, -114.01803230257535 45.64077336997103, -114.05651530261119 45.62514436995647, -114.08296730263582 45.58637836992037, -114.11813930266858 45.571127369906165, -114.13204830268154 45.55038236988685, -114.17266730271938 45.54392436988083, -114.19480830273999 45.52791736986592, -114.24199830278394 45.53529036987278, -114.24788030278941 45.502945369842664, -114.26223930280278 45.485859369826755, -114.32643430286257 45.457424369800265, -114.35024630288476 45.46338336980582, -114.3714573029045 45.485740369826644, -114.41905130294883 45.499008369839, -114.43355530296233 45.527633
 369865654, -114.46270830298948 45.54784736988448, -114.49659130302105 45.54664936988337, -114.52739230304974 45.55819336989411, -114.56092430308095 45.54874036988531, -114.54095830306237 45.5963973699297, -114.56467830308446 45.62427136995566, -114.50174130302585 45.65239336998185, -114.5107063030342 45.674057370002025, -114.49756130302194 45.69440137002097, -114.5349763030568 45.7229963700476, -114.5419583030633 45.74599937006903, -114.56354230308341 45.7623983700843, -114.51737530304041 45.81006737012869, -114.49916430302343 45.842683370159065, -114.47380330299983 45.83946837015607, -114.44323130297136 45.85262137016832, -114.4075253029381 45.84645337016258, -114.39283830292442 45.87088637018533, -114.41353030294368 45.91065137022237, -114.42946030295852 45.92147737023245, -114.40529030293601 45.95397937026272, -114.41244730294268 45.97197337027948, -114.48445530300975 45.98980637029609, -114.47452930300051 46.009765370314675, -114.49432130301894 46.02341037032738, -114.4657563029
 9233 46.05081537035291, -114.45602930298327 46.082229370382166, -114.47737030300314 46.107357370405566, -114.50656830303033 46.11614237041375, -114.51894430304186 46.136063370432296, -114.50961330303318 46.15741737045219, -114.4670183029935 46.15526237045018, -114.44087930296917 46.168969370462946, -114.43955330296792 46.22025437051071, -114.47283330299892 46.243783370532626, -114.47379530299982 46.25296137054117, -114.4317953029607 46.28471137057074, -114.40979630294021 46.39291137067151, -114.3970173029283 46.399545370677686, -114.38402530291621 46.428179370704356, -114.41071530294107 46.48737137075948, -114.36046830289428 46.50612537077694, -114.35011530288463 46.51738937078744, -114.3433193028783 46.58788137085309, -114.32471230286097 46.62283937088564, -114.33468530287027 46.65422737091488, -114.3840173029162 46.66159637092174, -114.44153630296978 46.645715370906956, -114.48471830301 46.62357437088633, -114.54039130306184 46.637891370899666, -114.61082630312744 46.6290483708914
 25, -114.64474030315901 46.66082437092102, -114.6450383031593 46.67092137093043, -114.6259263031415 46.6871073709455, -114.67388730318616 46.734721370989845, -114.69843130320902 46.733760370988946, -114.74810530325529 46.695132370952976, -114.78291930328771 46.70304037096034, -114.77783230328296 46.755717371009396, -114.79403030329806 46.76653137101947, -114.8407923033416 46.77553837102786, -114.86660330336565 46.797045371047886, -114.90232530339892 46.799433371050114, -114.94840930344184 46.85244637109949, -114.94056630343454 46.89088837113529, -114.92412530341922 46.90716537115044, -114.96473030345703 46.92521337116725, -115.00157430349134 46.95880937119854, -115.03733430352466 46.963001371202445, -115.0556383035417 46.97335837121209, -115.08133630356564 47.02652437126161, -115.13550730361608 47.06355037129609, -115.14868430362836 47.09174237132235, -115.17249630365053 47.09757037132778, -115.1930733036697 47.124026371352414, -115.29623430376577 47.17955037140412, -115.32522830379
 278 47.245150371465215, -115.34366130380994 47.25502237147441, -115.40820730387006 47.26359337148239, -115.42664130388722 47.274374371492435, -115.50193030395735 47.281644371499205, -115.52306430397702 47.29198237150884, -115.55552030400725 47.33461337154854, -115.59953630404824 47.3700033715815, -115.6387823040848 47.38004437159085, -115.66647730411059 47.399167371608655, -115.75032630418868 47.42247537163037, -115.75010530418848 47.43396637164106, -115.73248130417207 47.445303371651626, -115.65608730410091 47.44918037165523, -115.64318530408889 47.45779337166326, -115.64014230408605 47.4752353716795, -115.69277030413508 47.489540371692826, -115.70152230414323 47.520893371722025, -115.7428293041817 47.533691371733944, -115.69208830413444 47.590721371787055, -115.6982843041402 47.616080371810675, -115.73406730417354 47.63987937183283, -115.73366530417316 47.69555437188469, -115.77572730421232 47.70973237189789, -115.79053730422612 47.744838371930584, -115.83674230426917 47.756281371
 94124, -115.84932430428088 47.80518237198679, -115.86980930429996 47.82745237200753, -115.90392130433173 47.841074372020216, -115.93784230436331 47.86712437204447, -115.99893230442021 47.92514037209851, -116.02531630444479 47.964939372135575, -116.05349230447102 47.976191372146054, -116.0554973044729 48.208483372362394, -116.05669230447401 48.498665372632644, -116.06353130448036 48.9999503730995, -114.7293253032378 48.99997037309952, -114.06346330261766 48.999977373099526, -112.18838730087137 48.999992373099545, -111.28267930002785 49.00001137309956, -110.75079729953251 49.000005373099555, -109.50073729836829 49.000005373099555, -108.25067529720408 49.00000937309956, -107.1881212962145 49.00001737309957, -106.12557929522494 49.00002137309957, -105.06303429423536 49.00002137309957, -104.062991293304 49.00002637309957, -104.05231729329405 48.645824372769695, -104.05211129329386 48.39101937253239, -104.04842529329044 48.0000813721683, -104.04730729328939 47.40001737160945, -104.0459262
 932881 47.333832371547814, -104.04743729328952 46.64294737090437, -104.04670529328884 46.54253937081086, -104.04783629328989 46.28088137056717, -104.04890629329088 45.942993370252495, -104.04951729329144 45.883052370196665, -104.04385129328617 45.212875369572515, -104.04307229328545 44.997805369372216, -104.05984229330106 44.99733636937178, -105.04179629421559 45.00107636937526, -105.08500329425583 44.999817369374085, -106.02115029512768 44.997213369371664, -106.25923129534941 44.99616236937068, -107.89437429687226 44.99977336937405, -108.25923829721206 45.00011536937437, -108.62525629755294 44.99759336937201, -109.79938529864643 44.999522369373814, -109.99552929882911 45.00279336937686, -110.39276029919905 44.998625369372974, -110.42964929923342 44.992285369367075, -111.05342829981436 44.99569536937025, -111.05161629981266 44.664490369061795, -111.0515602998126 44.473323368883754, -111.09463029985272 44.48612436889567, -111.12891829988466 44.500757368909305, -111.13435929988972 44.
 52790236893458, -111.17024229992315 44.54518636895068, -111.17876429993107 44.564851368968995, -111.21950729996902 44.57317036897675, -111.23423329998273 44.60256236900412, -111.2197972999693 44.61798136901848, -111.22397129997319 44.62690836902679, -111.27066530001667 44.64221236904105, -111.27020830001624 44.673802369070465, -111.29566830003995 44.68293836907897, -111.3154753000584 44.7051933690997, -111.31922130006188 44.72786436912081, -111.34997730009053 44.72617736911924, -111.37230930011133 44.745087369136854, -111.38495930012311 44.73769436912997, -111.39508430013254 44.70886936910313, -111.44363230017775 44.71317936910714, -111.47542530020736 44.702162369096875)))	
-ME	Maine	MULTIPOLYGON (((-69.77727626137293 44.07414836851199, -69.85992826144991 44.00000136844294, -69.7915282613862 43.75608536821577, -69.8303922614224 43.727986368189605, -69.85178526144233 43.74432836820482, -69.84615526143709 43.84234436829611, -69.88679126147493 43.87671336832811, -69.90313226149014 43.790732368248044, -69.97290326155513 43.768847368227654, -69.9995002615799 43.78620736824382, -69.9873702615686 43.845738368299266, -70.02640326160495 43.84560136829914, -70.15662826172624 43.78981036824718, -70.23579826179997 43.68579636815031, -70.22223926178734 43.57724036804921, -70.34161026189851 43.53490836800978, -70.36592526192116 43.430303367912366, -70.45697726200596 43.349470367837085, -70.53894126208229 43.33571836782427, -70.66567226220032 43.09105036759641, -70.81866826234281 43.12187136762512, -70.83054826235387 43.15917436765986, -70.81320726233773 43.235222367730685, -70.90108626241957 43.28102036777334, -70.90580126242396 43.30206936779294, -70.96969926248347 
 43.36638036785283, -70.97909926249223 43.39618436788059, -70.96148326247581 43.43812636791965, -70.97079126248448 43.47021136794953, -70.95927826247376 43.51638836799253, -70.96426826247841 43.53198936800707, -70.94961926246476 43.548953368022865, -70.95652426247119 43.56414336803701, -70.97387426248736 43.571830368044175, -70.9844422624972 43.79116336824844, -71.00859626251969 44.28214636870571, -71.02872626253844 44.66853836906556, -71.08750926259319 45.301469369655024, -70.95938226247385 45.338865369689856, -70.87644426239662 45.22544536958422, -70.84287526236535 45.2781373696333, -70.81266626233722 45.35467836970458, -70.82913226235256 45.39072636973815, -70.7969672623226 45.42517236977023, -70.63492926217168 45.391967369739305, -70.71991026225083 45.51295436985198, -70.55227026209471 45.66066436998955, -70.39638326194952 45.72204637004671, -70.416214261968 45.79030937011029, -70.25396426181689 45.89900437021152, -70.24746426181083 45.944619370254, -70.31029526186934 45.96878237
 027651, -70.28002226184115 46.05315437035509, -70.30484926186428 46.06665837036766, -70.22932526179395 46.13743437043358, -70.28349626184439 46.19024937048276, -70.1910582617583 46.33483937061742, -70.04660726162378 46.42611537070243, -70.01414426159354 46.57059837083699, -69.98497726156637 46.69136537094947, -69.23029626086353 47.4533343716591, -69.04697626069279 47.42203037162995, -69.03671426068324 47.25736137147659, -68.89487226055114 47.182256371406645, -68.51467326019704 47.296964371513475, -68.3912572600821 47.28509737150242, -68.33481426002953 47.35737437156973, -68.23080725993267 47.352148371564866, -67.79101125952309 47.06100337129372, -67.7802892595131 45.947062370256276, -67.75561525949011 45.91658037022789, -67.79457125952639 45.878475370192405, -67.75936725949362 45.8277983701452, -67.8030532595343 45.7945083701142, -67.80343325953466 45.6781133700058, -67.75295525948763 45.65928936998827, -67.71803425945512 45.68129937000877, -67.6151402593593 45.60519936993789, -67.4
 3930125919553 45.59256136992612, -67.4160842591739 45.50355436984323, -67.50410625925588 45.48581636982671, -67.4185552591762 45.3758523697243, -67.47795025923152 45.28028036963529, -67.43943525919565 45.18958436955082, -67.34560525910827 45.122252369488116, -67.27409525904167 45.18278336954449, -67.16590525894091 45.15626436951979, -67.1506612589267 45.121990369487875, -67.06535825884727 44.959295369336346, -67.14670625892303 44.904581369285395, -66.96927125875777 44.82865536921469, -67.00771925879359 44.780625369169954, -67.200364258973 44.65378136905181, -67.30846825907368 44.653521369051575, -67.38851025914822 44.69140036908685, -67.57099325931817 44.59833336900017, -67.61883825936273 44.540239368946075, -67.8112192595419 44.5540093689589, -67.858560259586 44.5360773689422, -67.90004225962463 44.45239936886426, -67.96834225968823 44.4712283688818, -67.96343625968366 44.505327368913555, -67.98652325970517 44.48481236889445, -68.01639325973298 44.384956368801454, -68.074379259787 
 44.38137436879812, -68.13626425984462 44.47523736888554, -68.24561425994646 44.49064836889988, -68.3637652600565 44.4313863688447, -68.42857126011685 44.465306368876284, -68.55218626023198 44.39904936881458, -68.53007526021139 44.28983636871287, -68.55942726023872 44.25988736868497, -68.74031026040718 44.34633036876548, -68.81285126047474 44.32743236874788, -68.8137682604756 44.41399036882849, -68.74134826040816 44.50728536891538, -68.74527926041182 44.552320368957325, -68.82355226048472 44.60890636901003, -68.82381326048495 44.664089369061415, -68.86060926051923 44.61097036901195, -68.80790326047014 44.56965436897347, -68.81167826047366 44.494593368903566, -68.95917926061102 44.43033136884371, -68.9850282606351 44.27111236869543, -69.02148226066905 44.24409336867026, -69.07445826071839 44.06906636850726, -69.21914026085314 43.94678736839337, -69.29365026092252 43.94219036838909, -69.3464542609717 44.01596936845781, -69.39448826101643 44.02512836846634, -69.48323326109909 43.8871603
 68337845, -69.5893262611979 43.84486236829845, -69.66445326126787 43.85222436830531, -69.65524526125928 43.98025036842454, -69.61293226121988 44.03361236847424, -69.72063526132018 43.93797936838517, -69.74852826134617 43.893375368343634, -69.72467126132395 43.784477368242214, -69.75035926134787 43.761704368221004, -69.77767326137331 43.79127036824854, -69.80001326139411 44.02686636846796, -69.76675526136314 44.04773236848739, -69.77727626137293 44.07414836851199)), ((-68.387921260079 44.377253368794285, -68.35025426004391 44.398951368814494, -68.35544926004876 44.428857368842344, -68.23870925994004 44.43756336885045, -68.16476925987118 44.33449536875446, -68.3047052600015 44.290031368713045, -68.32071126001641 44.22507936865256, -68.40289026009295 44.27080136869514, -68.387921260079 44.377253368794285)))	
-ND	North Dakota	MULTIPOLYGON (((-98.73043728833767 45.93827137024809, -99.00683328859509 45.93955537024929, -99.7173452892568 45.94276137025227, -99.87578328940435 45.94354737025301, -100.51440628999912 45.94038837025006, -102.00277529138528 45.942505370252036, -102.9463972922641 45.94166537025126, -102.99482329230919 45.94111537025074, -104.04890629329088 45.942993370252495, -104.04783629328989 46.28088137056717, -104.04670529328884 46.54253937081086, -104.04743729328952 46.64294737090437, -104.0459262932881 47.333832371547814, -104.04730729328939 47.40001737160945, -104.04842529329044 48.0000813721683, -104.05211129329386 48.39101937253239, -104.05231729329405 48.645824372769695, -104.062991293304 49.00002637309957, -102.93795929225622 49.00002637309957, -102.02226429140342 49.000015373099565, -101.50043729091743 49.000020373099574, -100.18790828969505 49.00000237309955, -99.53356628908564 49.00000837309956, -99.0004032885891 49.00000637309955, -97.93786728759953 48.99999237309954
 5, -97.22943628693976 48.999987373099536, -97.21636928692759 48.931830373036064, -97.17572728688974 48.87375737298198, -97.17120428688553 48.83598037294679, -97.1804222868941 48.81553737292775, -97.16471228687948 48.81036837292294, -97.17394428688807 48.801514372914696, -97.14751628686346 48.781170372895744, -97.13924628685575 48.76354237287933, -97.14789828686382 48.75565337287198, -97.13250228684947 48.747218372864126, -97.13480628685163 48.72623837284459, -97.11010128682861 48.708583372828144, -97.1167392868348 48.695243372815725, -97.09716928681657 48.67452937279643, -97.1076302868263 48.629946372754915, -97.12744428684476 48.62979437275477, -97.12295828684059 48.62076837274636, -97.14471828686085 48.61402437274008, -97.14081228685721 48.586905372714824, -97.1581922868734 48.583640372711784, -97.15212728686775 48.572856372701736, -97.16794328688249 48.56226337269187, -97.14661828686262 48.54953737268002, -97.1604352868755 48.545078372675874, -97.15553728687092 48.53839837266965,
  -97.13938528685588 48.534648372666155, -97.14832728686422 48.51795137265061, -97.13459428685142 48.51731437265001, -97.14361328685983 48.43810937257625, -97.1196332868375 48.43710237257531, -97.12260128684025 48.416110372555764, -97.1516472868673 48.41961237255902, -97.14982328686561 48.40999137255006, -97.12912428684633 48.4078853725481, -97.15881928687399 48.38820637252977, -97.135205286852 48.38441037252623, -97.13378628685068 48.3724543725151, -97.15039628686614 48.3632153725065, -97.1311232868482 48.361491372504894, -97.13713628685379 48.32599137247183, -97.11259128683093 48.319926372466185, -97.1326342868496 48.31096937245784, -97.11475128683294 48.303618372451, -97.11372128683199 48.294882372442856, -97.13051328684763 48.29304037244114, -97.11268328683101 48.286147372434726, -97.11171428683012 48.277876372427016, -97.13665528685334 48.264483372414546, -97.12378428684136 48.259173372409606, -97.12755428684487 48.23352337238571, -97.10923528682781 48.22804937238061, -97.139754
 28685623 48.22175537237475, -97.11089928682935 48.20760537236157, -97.13082828684792 48.20374237235798, -97.13727528685392 48.19506337234989, -97.13629128685301 48.17522737233142, -97.13744328685408 48.16776937232447, -97.11606528683417 48.15922337231652, -97.13651328685322 48.14839837230643, -97.12091828683869 48.1427743723012, -97.12187328683957 48.11636937227661, -97.0990302868183 48.10097237226226, -97.09272128681243 48.07034437223374, -97.06707128678855 48.04816437221308, -97.04805328677082 47.95492437212624, -97.01533128674035 47.917890372091755, -97.02056628674522 47.87556937205234, -97.0003402867264 47.87019737204734, -96.97723128670486 47.82802937200807, -96.98389328671108 47.809661371990956, -96.9578302866868 47.79444037197678, -96.93201228666275 47.763506371947976, -96.92365928665498 47.71409437190196, -96.8894252866231 47.67392537186454, -96.87333528660811 47.61525537180991, -96.85221728658844 47.601151371796774, -96.85866428659445 47.56297837176122, -96.84918828658562 4
 7.54456837174408, -96.86068728659633 47.521356371722455, -96.85161528658789 47.50061937170314, -96.86668428660191 47.46153737166674, -96.8558272865918 47.43675337164366, -96.86724828660245 47.41308737162162, -96.85000528658638 47.408936371617756, -96.8398272865769 47.38411737159464, -96.85063128658696 47.36095437157307, -96.83846128657564 47.34224337155564, -96.84674728658335 47.3146023715299, -96.83771428657494 47.2938843715106, -96.84962328658602 47.25684337147611, -96.83706528657433 47.240458371460846, -96.82649128656448 47.17006337139529, -96.83916428657629 47.15188637137836, -96.81915128655764 47.09260437132315, -96.82696428656492 47.07883237131033, -96.82260828656086 47.033932371268506, -96.83529628657269 47.010231371246434, -96.82453128656266 47.003436371240106, -96.81677228655543 46.96977937120876, -96.79342528653369 46.96964137120863, -96.80188728654157 46.95584337119578, -96.78971028653022 46.948202371188664, -96.78792528652856 46.93218437117375, -96.76306828650542 46.9362
 61371177544, -96.75691128649969 46.92278037116499, -96.77806128651937 46.86734937111336, -96.76825028651024 46.84486137109242, -96.7971972865372 46.812033371061844, -96.78038228652154 46.76231237101554, -96.78155628652263 46.70704437096407, -96.79369528653393 46.67880437093777, -96.79024628653073 46.6297733708921, -96.78431728652521 46.624112370886834, -96.77104128651284 46.59998337086436, -96.75122728649438 46.58861937085378, -96.74031628648423 46.4894323707614, -96.71489428646055 46.46871837074211, -96.70968228645569 46.42716837070341, -96.68822828643572 46.41221837068949, -96.65210128640207 46.35943337064033, -96.61486128636739 46.3508123706323, -96.60207428635547 46.33632437061881, -96.59818328635185 46.23868237052787, -96.58645628634093 46.2154133705062, -96.58789028634227 46.191918370484316, -96.57116628632669 46.17717437047059, -96.55193128630877 46.09552937039455, -96.57621528633139 46.0212793703254, -96.56180228631797 45.947683370256854, -96.56692128632274 45.93411037024421
 , -97.23331028694336 45.936502370246444, -97.97872228763758 45.93082237024116, -98.0147092876711 45.93149837024178, -98.73043728833767 45.93827137024809)))	
-SD	South Dakota	MULTIPOLYGON (((-102.78838429211693 42.99530336750724, -103.00587529231949 42.99935436751102, -103.50146429278104 42.99861836751033, -104.05619929329767 43.00306236751447, -104.05915729330043 43.47913436795784, -104.05791429329928 43.50371236798073, -104.05947929330073 43.852906368305945, -104.05973129330096 44.14582536857875, -104.06103629330218 44.18182536861227, -104.05946529330072 44.57435236897784, -104.05984229330106 44.99733636937178, -104.04307229328545 44.997805369372216, -104.04385129328617 45.212875369572515, -104.04951729329144 45.883052370196665, -104.04890629329088 45.942993370252495, -102.99482329230919 45.94111537025074, -102.9463972922641 45.94166537025126, -102.00277529138528 45.942505370252036, -100.51440628999912 45.94038837025006, -99.87578328940435 45.94354737025301, -99.7173452892568 45.94276137025227, -99.00683328859509 45.93955537024929, -98.73043728833767 45.93827137024809, -98.0147092876711 45.93149837024178, -97.97872228763758 45.930822370
 24116, -97.23331028694336 45.936502370246444, -96.56692128632274 45.93411037024421, -96.58795528634232 45.81785437013595, -96.60461028635784 45.80826437012701, -96.65739128640699 45.738970370062475, -96.83279628657036 45.65068736998026, -96.85499028659102 45.609122369941545, -96.84308728657994 45.584090369918236, -96.76924628651116 45.5174783698562, -96.7380322864821 45.45819536980099, -96.69316928644032 45.4106383697567, -96.60508428635828 45.39652436974355, -96.53254928629073 45.37513236972363, -96.47759228623954 45.328509369680205, -96.45760228622093 45.298850369652584, -96.45449628621803 45.27519536963055, -96.4560802862195 44.97199436934818, -96.45521728621871 44.801347369189244, -96.45671828622011 44.62880836902856, -96.45510628621861 44.53834336894431, -96.45739728622074 44.19906136862833, -96.45660228621999 43.848741368302065, -96.46045428622358 43.49971836797701, -96.59831528635198 43.499849367977134, -96.58379628633845 43.48192036796044, -96.5891132863434 43.43553936791724
 4, -96.55770828631415 43.40072736788482, -96.52505328628375 43.38422536786945, -96.52289428628174 43.356966367844066, -96.5405632862982 43.307659367798145, -96.5791312863341 43.29007436778177, -96.57072228632627 43.26361236775712, -96.5595672863159 43.25326336774748, -96.5669912863228 43.23963336773479, -96.558605286315 43.22548936772162, -96.48724528624854 43.217909367714554, -96.47311428623537 43.20908236770634, -96.45150528621525 43.12630836762925, -96.46080528622392 43.08787236759345, -96.46209428622511 43.075582367582, -96.47957328624139 43.06188436756925, -96.52001028627905 43.051508367559585, -96.4990202862595 43.01205036752283, -96.51714828627638 42.986458367499, -96.51493528627432 42.952382367467266, -96.54426328630164 42.913866367431396, -96.53751128629536 42.896906367415596, -96.55621128631276 42.846660367368806, -96.57312628632852 42.83434736735734, -96.58764528634204 42.8353813673583, -96.60087528635437 42.799558367324934, -96.63298028638427 42.776835367303775, -96.6407
 0928639146 42.74860336727748, -96.62654028637826 42.70835436724, -96.56303928631912 42.66851336720289, -96.54116528629875 42.66240536719721, -96.51284428627237 42.629755367166794, -96.48849828624971 42.580480367120906, -96.50094228626129 42.57388536711476, -96.48933728625049 42.56402836710558, -96.48024328624201 42.51713036706191, -96.43939428620396 42.48924036703593, -96.49470128625548 42.488459367035205, -96.5472152863044 42.52049936706504, -96.58475328633935 42.51828736706298, -96.60546728635863 42.50723636705269, -96.62929428638083 42.52269336706709, -96.6366722863877 42.5507313670932, -96.71405928645977 42.61230236715054, -96.7152732864609 42.62190736715949, -96.69459628644165 42.64116336717742, -96.6990602864458 42.657715367192836, -96.72265828646778 42.66859236720296, -96.7993442865392 42.67001936720429, -96.81043728654953 42.68134136721484, -96.81014028654926 42.70408436723602, -96.9082342866406 42.73169936726174, -96.97077328669886 42.721147367251916, -96.97786928670547 42.
 72730836725765, -96.97000328669814 42.75206536728071, -96.97959328670707 42.758313367286526, -97.01513928674018 42.759542367287665, -97.13046928684759 42.773923367301066, -97.16142228687642 42.798619367324065, -97.21183128692336 42.81257336733706, -97.2244432869351 42.84120236736372, -97.24318928695256 42.85182636737362, -97.27145728697889 42.85001436737193, -97.3114142870161 42.86177136738288, -97.38930628708864 42.86743336738815, -97.45726328715193 42.85044336737233, -97.48315928717605 42.857157367378576, -97.50613228719745 42.86013636738136, -97.57065428725754 42.847990367370045, -97.63497028731744 42.86128536738242, -97.68575228736474 42.83683736735966, -97.72525028740152 42.85800836737937, -97.77218628744522 42.846164367368345, -97.79702828746836 42.849597367371544, -97.8186432874885 42.86658736738737, -97.88865928755371 42.855807367377324, -97.88994128755489 42.831271367354475, -97.92947728759172 42.7923243673182, -97.96355828762346 42.773690367300844, -97.99514428765288 42.76
 681236729444, -98.03314028768825 42.769192367296654, -98.12182028777084 42.80836036733314, -98.12311728777206 42.820223367344184, -98.14486928779232 42.83579436735869, -98.1678262878137 42.839571367362204, -98.31033928794642 42.881794367401525, -98.39120428802174 42.92013536743723, -98.45744428808342 42.93716036745309, -98.49765128812088 42.991778367503954, -99.25397128882526 42.99238936750453, -99.53279028908491 42.992335367504474, -100.19814228970458 42.99109536750332, -101.23173729066718 42.98684336749936, -102.08670129146344 42.98988736750219, -102.78838429211693 42.99530336750724)))	
-WY	Wyoming	MULTIPOLYGON (((-104.05361529329527 41.69821836629923, -104.05550029329702 41.56422236617444, -104.05401229329564 41.3880853660104, -104.0517052932935 41.003211365651964, -104.93449329411565 40.99428936564365, -105.2787972944363 40.99634936564557, -106.20347129529748 41.00008536564905, -106.3291252954145 41.001289365650166, -106.86543829591398 40.99845736564753, -107.30405129632247 41.00013336564909, -107.91867129689489 41.00337536565211, -109.04831429794694 40.998433365647514, -110.00216529883528 40.997599365646735, -110.06318529889211 40.997892365647004, -111.0510222998121 40.99658336564579, -111.05165129981269 41.25842536588965, -111.05106829981216 41.57859236618782, -111.04869729980994 41.99620336657675, -111.04678029980816 42.50325236704899, -111.04921529981043 43.01988336753013, -111.04749829980882 43.28473436777679, -111.04677129980816 43.515528367991735, -111.05040529981153 43.98255336842669, -111.0515602998126 44.473323368883754, -111.05161629981266 44.6644903690
 61795, -111.05342829981436 44.99569536937025, -110.42964929923342 44.992285369367075, -110.39276029919905 44.998625369372974, -109.99552929882911 45.00279336937686, -109.79938529864643 44.999522369373814, -108.62525629755294 44.99759336937201, -108.25923829721206 45.00011536937437, -107.89437429687226 44.99977336937405, -106.25923129534941 44.99616236937068, -106.02115029512768 44.997213369371664, -105.08500329425583 44.999817369374085, -105.04179629421559 45.00107636937526, -104.05984229330106 44.99733636937178, -104.05946529330072 44.57435236897784, -104.06103629330218 44.18182536861227, -104.05973129330096 44.14582536857875, -104.05947929330073 43.852906368305945, -104.05791429329928 43.50371236798073, -104.05915729330043 43.47913436795784, -104.05619929329767 43.00306236751447, -104.05621929329769 42.61466936715274, -104.05351329329517 41.99981536658012, -104.05361529329527 41.69821836629923)))	
-WI	Wisconsin	MULTIPOLYGON (((-87.74855527810999 44.961616369338515, -87.83999227819515 44.92732336930658, -87.8310202781868 44.8733463692563, -87.98579127833094 44.72047436911393, -87.98318227832851 44.67726536907369, -88.01328827835654 44.63911836903816, -87.97575827832159 44.595814368997836, -88.0130212783563 44.622234369022436, -88.04041727838181 44.57144936897514, -87.96622827831271 44.53549636894166, -87.92640827827563 44.539139368945044, -87.86878227822197 44.61690636901747, -87.7642262781246 44.64404836904275, -87.72382127808696 44.68928736908488, -87.6144642779851 44.833047369218775, -87.55278727792768 44.851335369235805, -87.55167227792663 44.82302336920944, -87.4337472778168 44.89109636927283, -87.36745927775507 44.81156736919877, -87.31446527770572 44.79471836918307, -87.37307027776029 44.67691836907336, -87.47352827785386 44.533946368940214, -87.53748927791342 44.32785136874827, -87.51732227789465 44.17575436860662, -87.64437027801297 44.09783036853405, -87.7261222780891
 1 43.893904368344124, -87.70273027806732 43.673176368138556, -87.78604527814491 43.54629736802039, -87.80295927816066 43.458714367938825, -87.87533227822807 43.358592367845574, -87.88983427824157 43.19721636769529, -87.86006927821386 43.07587536758228, -87.89198327824357 43.02577436753562, -87.83643827819185 42.96459236747864, -87.81984927817639 42.84156336736406, -87.75680327811767 42.77754636730444, -87.79150927815 42.66664236720115, -87.79738227815547 42.48915236703585, -88.19479027852559 42.489631367036296, -88.2979892786217 42.49198836703849, -88.70662327900227 42.48967136703634, -88.76505827905669 42.4909223670375, -88.93918727921886 42.49087936703746, -89.35955927961037 42.49791736704401, -89.4006132796486 42.49750236704362, -89.8347392800529 42.50346836704918, -89.92369128013574 42.504115367049785, -90.42010328059807 42.50836536705374, -90.63845628080142 42.509363367054675, -90.62570728078956 42.52856236707255, -90.63921928080214 42.55571436709784, -90.66438028082557 42.5713
 9136711244, -90.69479128085389 42.63792836717441, -90.74561028090122 42.65700136719217, -90.89254528103807 42.678240367211956, -90.91940928106308 42.68067736721422, -90.99918228113738 42.70705836723879, -91.06616828119977 42.744913367274044, -91.08203028121454 42.783365367309855, -91.09342828122514 42.871440367391884, -91.1391212812677 42.9258933674426, -91.1522142812799 43.00131636751284, -91.15975228128691 43.08118236758722, -91.16857128129513 43.08288836758881, -91.16135428128841 43.14757636764905, -91.06905228120245 43.2578983677518, -91.0664282812 43.28068336777302, -91.07849828121125 43.31329736780339, -91.17704828130303 43.35394636784125, -91.19824328132277 43.37051336785668, -91.21091628133458 43.42405136790654, -91.23590328135784 43.464684367944386, -91.22356628134635 43.500808367978024, -91.24055828136218 43.54871236802264, -91.23299028135513 43.59889036806938, -91.25838928137878 43.67732236814242, -91.25891628137927 43.722395368184394, -91.251105281372 43.788075368245565,
  -91.29194828141004 43.847190368300616, -91.37335728148585 43.94719136839375, -91.42590228153479 43.98561936842954, -91.52842028163028 44.034215368474804, -91.56916228166821 44.034955368475494, -91.6017862816986 44.04082236848096, -91.65223328174558 44.066895368505236, -91.75321928183963 44.137227368570734, -91.84874428192859 44.191187368620994, -91.8886942819658 44.25749536868275, -91.92234928199714 44.28834136871147, -91.92275428199753 44.31752036873865, -91.93886828201254 44.33911136875876, -91.97238628204374 44.36448736878239, -92.09133328215452 44.415589368829984, -92.20613728226144 44.43839436885122, -92.24910028230146 44.45621636886782, -92.29668728234577 44.49218236890132, -92.32047828236793 44.540491368946306, -92.34087228238693 44.5528353689578, -92.5092152825437 44.575159368978596, -92.60897328263661 44.61029236901132, -92.63036728265654 44.64265236904146, -92.73714528275598 44.713594369107525, -92.80558428281972 44.746160369137854, -92.76102828277823 44.83537136922094, -
 92.76426328278124 44.862234369245954, -92.77187128278833 44.899496369280655, -92.75392628277162 44.915002369295095, -92.74976828276773 44.93565536931433, -92.7671262827839 45.00100536937519, -92.76299128278005 45.02211936939486, -92.7967622828115 45.06561036943536, -92.74542228276368 45.1130043694795, -92.74493528276324 45.15642236951994, -92.76258328277967 45.18661236954806, -92.755419282773 45.21237636957205, -92.74659328276478 45.297603369651426, -92.70738428272827 45.318201369670604, -92.6848692827073 45.3630763697124, -92.64875128267366 45.395466369742564, -92.64497528267015 45.43945236978353, -92.6548172826793 45.45522136979822, -92.68542128270781 45.470053369812035, -92.72815428274761 45.54724236988392, -92.7621752827793 45.56426336989977, -92.83503728284715 45.56340236989897, -92.87683128288607 45.57883636991335, -92.88539728289405 45.64495536997492, -92.86001928287041 45.71056237003602, -92.83363628284584 45.73089037005495, -92.77910728279507 45.763340370085174, -92.7487622
 827668 45.837302370154056, -92.73409728275314 45.84498037016121, -92.7062402827272 45.89095837020403, -92.66620828268992 45.91570337022708, -92.55267228258418 45.9512693702602, -92.52397728255745 45.98258337028936, -92.46234528250005 45.98119737028807, -92.42499928246528 46.02550437032933, -92.36496328240936 46.01624837032071, -92.34622528239191 46.022596370326625, -92.32737228237436 46.056878370358554, -92.28937028233896 46.07323137037378, -92.28894428233856 46.15660037045143, -92.28868528233832 46.415984370692996, -92.287271282337 46.658786370919124, -92.20915428226425 46.64687237090803, -92.09597028215885 46.74262737099721, -92.00415728207334 46.68380037094242, -91.92146128199632 46.680134370939, -91.55577328165575 46.75686037101046, -90.86173028100937 46.95247937119265, -90.77448628092812 46.92023537116262, -90.77744528093086 46.88312237112805, -90.92624428106944 46.58550337085087, -90.73071428088734 46.64569637090693, -90.54087728071055 46.58752637085276, -90.40820028058698 46.
 568610370835145, -90.38552528056586 46.53965737080817, -90.31370828049899 46.55156337081927, -90.30239328048845 46.544296370812496, -90.30018128048638 46.52505137079457, -90.26978528045808 46.52248037079218, -90.25840128044747 46.508789370779425, -90.21152628040382 46.50629537077711, -90.16139128035712 46.44238037071758, -90.14179728033888 46.39389937067243, -90.11517728031409 46.36515537064566, -90.1116592803108 46.34042937062263, -89.9251362801371 46.30402537058873, -89.09980627936845 46.14564237044122, -88.9853012792618 46.10039137039908, -88.92519527920582 46.07360137037413, -88.80439727909332 46.026804370330545, -88.79381527908347 46.036360370339445, -88.77748027906826 46.032614370335956, -88.7730172790641 46.02114737032528, -88.72640927902069 46.02958137033313, -88.70360527899946 46.01892337032321, -88.67738427897504 46.020144370324346, -88.64366927894363 45.99338837029943, -88.6155022789174 45.99412037030011, -88.59753627890068 46.01551637032003, -88.57535727888002 46.0089593
 70313924, -88.54835827885486 46.019300370323556, -88.51561327882438 46.01860937032291, -88.49408327880433 46.01296037031766, -88.48381427879475 45.99915137030479, -88.45431927876729 46.00076037030629, -88.40352227871998 45.98342237029014, -88.3699382786887 45.994587370300536, -88.32132327864343 45.96671237027458, -88.29915227862278 45.96194437027014, -88.25716827858368 45.9670553702749, -88.2149922785444 45.94790137025706, -88.18019427851199 45.95351637026229, -88.15043827848427 45.93629337024625, -88.11139027844791 45.926287370236935, -88.09385027843157 45.920615370231644, -88.09576427843336 45.89180337020481, -88.0654212784051 45.8736423701879, -88.12178627845759 45.8348783701518, -88.12994927846519 45.81940237013738, -88.08873427842681 45.791532370111426, -88.05163927839226 45.78611237010638, -87.99007027833493 45.795046370114704, -87.96917927831547 45.76644837008807, -87.87362927822647 45.750699370073406, -87.84236227819736 45.722418370047066, -87.80155327815935 45.7113913700367
 9, -87.80115627815898 45.70132437002742, -87.77747327813692 45.684101370011376, -87.78094527814017 45.67591537000375, -87.81705427817379 45.66539036999395, -87.81993827817648 45.65445036998376, -87.7760452781356 45.613200369945346, -87.7750752781347 45.600387369933415, -87.78631227814516 45.56851936990373, -87.82860227818455 45.5685913699038, -87.8051412781627 45.544525369881384, -87.78938527814802 45.499067369839054, -87.81361427817059 45.466460369808686, -87.86026727821404 45.44509836978879, -87.84953127820404 45.40611736975249, -87.88361027823578 45.36585436971499, -87.8739742782268 45.36208536971148, -87.86853527822174 45.37207236972078, -87.86209627821574 45.370165369719004, -87.84128227819636 45.34614936969663, -87.82800827818399 45.35832136970797, -87.76003827812069 45.352897369702916, -87.68959827805509 45.39126936973865, -87.64368427801233 45.36185636971126, -87.64536227801389 45.34816936969852, -87.70447127806894 45.27220536962777, -87.70514227806956 45.247086369604375, -8
 7.71966827808309 45.23677136959477, -87.72162827808492 45.211672369571396, -87.7362002780985 45.19907236955966, -87.7296692780924 45.17660436953874, -87.67281427803945 45.14067236950527, -87.66488627803207 45.10905436947583, -87.5812762779542 45.0946403694624, -87.61852127798889 45.05680736942716, -87.62033527799058 44.99199736936681, -87.74855527810999 44.961616369338515)), ((-87.034524277445 45.290405369644716, -86.98625327740005 45.2986573696524, -86.96771227738277 45.24027736959803, -86.99573427740887 45.218411369577666, -87.04511227745486 45.249019369606174, -87.02544827743655 45.149974369513934, -87.07987627748724 45.14730736951145, -87.04490127745467 45.09551336946321, -87.0876782774945 45.09217836946011, -87.08390027749098 45.05328536942389, -87.11255727751768 45.06476336943457, -87.17869227757927 44.982806369358244, -87.16878827757004 44.93332336931216, -87.20565027760438 44.873239369256204, -87.3111232777026 44.79877336918685, -87.37873727776558 44.83774236922314, -87.4054
 1927779043 44.91120036929156, -87.3421612777315 45.01521336938843, -87.28348427767686 45.05261936942327, -87.2309152776279 45.1750633695373, -87.17791327757854 45.154973369518586, -87.06606427747438 45.29646236965036, -87.034524277445 45.290405369644716)))	
-ID	Idaho	MULTIPOLYGON (((-117.02629530537702 43.67903136814401, -117.02379430537468 43.753701368213555, -117.0371173053871 43.8001423682568, -117.02762630537825 43.83156736828607, -117.0105053053623 43.83976936829371, -117.01622030536763 43.852972368306006, -116.98577030533927 43.85935136831195, -116.97814830533218 43.8734693683251, -116.97814130533217 43.90444136835394, -116.95971630531501 43.92857736837642, -116.96795730532268 43.96319536840866, -116.93359330529069 44.01420236845617, -116.97681730533094 44.07389436851176, -116.96344330531849 44.09029836852703, -116.94688630530305 44.093025368529574, -116.9022543052615 44.1463133685792, -116.91305130527155 44.17730436860806, -116.98187130533564 44.19784236862719, -116.9761273053303 44.22518236865265, -116.99270730534573 44.24706336867303, -117.0303523053808 44.249336368675145, -117.05202730540098 44.23155636865859, -117.08138730542832 44.243846368670035, -117.10056030544618 44.26707836869167, -117.11269230545747 44.26980536869421, 
 -117.14327930548598 44.25063236867636, -117.17072330551153 44.25333236867887, -117.21357230555142 44.2847193687081, -117.21745530555505 44.30066536872295, -117.20160230554029 44.33943836875906, -117.23692130557318 44.38998236880613, -117.21722130555483 44.427855368841406, -117.22441030556152 44.47298736888344, -117.20396230554249 44.485785368895364, -117.18739130552706 44.511805368919596, -117.14516030548772 44.534655368940875, -117.14394030548658 44.55928736896381, -117.13050430547406 44.572523368976135, -117.07935430542643 44.68933636908493, -117.06651330541447 44.697557369092586, -117.03957230538938 44.749115369140604, -116.95149430530736 44.776035369165676, -116.90962030526836 44.82894036921495, -116.89736730525695 44.84855536923321, -116.86707630522874 44.86860836925189, -116.83539630519923 44.92014436929989, -116.84755630521056 44.954850369332206, -116.83139630519551 44.97263336934877, -116.84815930521111 44.97174136934794, -116.85588730521832 44.9799653693556, -116.8480973052
 1106 45.0000423693743, -116.85451330521704 45.016945369390044, -116.80730730517307 45.049755369420595, -116.78721030515436 45.075752369444814, -116.77809230514586 45.0994803694669, -116.76126830513019 45.10630036947326, -116.73658530510721 45.13730736950214, -116.68881330506271 45.26235036961859, -116.6722653050473 45.335410369686635, -116.56577230494813 45.45986336980254, -116.55450330493763 45.49364736983401, -116.4785513048669 45.56605836990144, -116.47041830485932 45.60625736993888, -116.51491530490075 45.664491369993115, -116.5282753049132 45.71072837003618, -116.56063230494334 45.74742437007035, -116.65439830503067 45.78063037010128, -116.7031803050761 45.819169370137175, -116.77370730514178 45.81976337013772, -116.79126230515813 45.84586737016203, -116.85647230521886 45.9035973702158, -116.89819730525772 45.98051637028743, -116.91913230527722 45.995175370301084, -116.95772330531315 46.06568737036676, -116.98721130534062 46.0785093703787, -116.9616373053168 46.09727437039618, 
 -116.9294263052868 46.1654833704597, -116.96749030532226 46.19755437048957, -116.97272530532712 46.24930937053777, -117.00164230535405 46.30244837058726, -117.02797330537858 46.33542737061797, -117.06418430541231 46.34869837063033, -117.04447030539394 46.38857437066747, -117.03855830538843 46.42798037070417, -117.04192630539157 46.53660137080533, -117.04096830539069 47.11931937134803, -117.04239230539201 47.25850137147765, -117.04179430539145 47.36144137157352, -117.03747230538742 47.9710923721413, -117.03886830538872 48.04618637221124, -117.02911130537964 48.838075372948744, -117.03204930538237 48.999931373099486, -116.06353130448036 48.9999503730995, -116.05669230447401 48.498665372632644, -116.0554973044729 48.208483372362394, -116.05349230447102 47.976191372146054, -116.02531630444479 47.964939372135575, -115.99893230442021 47.92514037209851, -115.93784230436331 47.86712437204447, -115.90392130433173 47.841074372020216, -115.86980930429996 47.82745237200753, -115.84932430428088 
 47.80518237198679, -115.83674230426917 47.75628137194124, -115.79053730422612 47.744838371930584, -115.77572730421232 47.70973237189789, -115.73366530417316 47.69555437188469, -115.73406730417354 47.63987937183283, -115.6982843041402 47.616080371810675, -115.69208830413444 47.590721371787055, -115.7428293041817 47.533691371733944, -115.70152230414323 47.520893371722025, -115.69277030413508 47.489540371692826, -115.64014230408605 47.4752353716795, -115.64318530408889 47.45779337166326, -115.65608730410091 47.44918037165523, -115.73248130417207 47.445303371651626, -115.75010530418848 47.43396637164106, -115.75032630418868 47.42247537163037, -115.66647730411059 47.399167371608655, -115.6387823040848 47.38004437159085, -115.59953630404824 47.3700033715815, -115.55552030400725 47.33461337154854, -115.52306430397702 47.29198237150884, -115.50193030395735 47.281644371499205, -115.42664130388722 47.274374371492435, -115.40820730387006 47.26359337148239, -115.34366130380994 47.25502237147441
 , -115.32522830379278 47.245150371465215, -115.29623430376577 47.17955037140412, -115.1930733036697 47.124026371352414, -115.17249630365053 47.09757037132778, -115.14868430362836 47.09174237132235, -115.13550730361608 47.06355037129609, -115.08133630356564 47.02652437126161, -115.0556383035417 46.97335837121209, -115.03733430352466 46.963001371202445, -115.00157430349134 46.95880937119854, -114.96473030345703 46.92521337116725, -114.92412530341922 46.90716537115044, -114.94056630343454 46.89088837113529, -114.94840930344184 46.85244637109949, -114.90232530339892 46.799433371050114, -114.86660330336565 46.797045371047886, -114.8407923033416 46.77553837102786, -114.79403030329806 46.76653137101947, -114.77783230328296 46.755717371009396, -114.78291930328771 46.70304037096034, -114.74810530325529 46.695132370952976, -114.69843130320902 46.733760370988946, -114.67388730318616 46.734721370989845, -114.6259263031415 46.6871073709455, -114.6450383031593 46.67092137093043, -114.644740303159
 01 46.66082437092102, -114.61082630312744 46.629048370891425, -114.54039130306184 46.637891370899666, -114.48471830301 46.62357437088633, -114.44153630296978 46.645715370906956, -114.3840173029162 46.66159637092174, -114.33468530287027 46.65422737091488, -114.32471230286097 46.62283937088564, -114.3433193028783 46.58788137085309, -114.35011530288463 46.51738937078744, -114.36046830289428 46.50612537077694, -114.41071530294107 46.48737137075948, -114.38402530291621 46.428179370704356, -114.3970173029283 46.399545370677686, -114.40979630294021 46.39291137067151, -114.4317953029607 46.28471137057074, -114.47379530299982 46.25296137054117, -114.47283330299892 46.243783370532626, -114.43955330296792 46.22025437051071, -114.44087930296917 46.168969370462946, -114.4670183029935 46.15526237045018, -114.50961330303318 46.15741737045219, -114.51894430304186 46.136063370432296, -114.50656830303033 46.11614237041375, -114.47737030300314 46.107357370405566, -114.45602930298327 46.082229370382166
 , -114.46575630299233 46.05081537035291, -114.49432130301894 46.02341037032738, -114.47452930300051 46.009765370314675, -114.48445530300975 45.98980637029609, -114.41244730294268 45.97197337027948, -114.40529030293601 45.95397937026272, -114.42946030295852 45.92147737023245, -114.41353030294368 45.91065137022237, -114.39283830292442 45.87088637018533, -114.4075253029381 45.84645337016258, -114.44323130297136 45.85262137016832, -114.47380330299983 45.83946837015607, -114.49916430302343 45.842683370159065, -114.51737530304041 45.81006737012869, -114.56354230308341 45.7623983700843, -114.5419583030633 45.74599937006903, -114.5349763030568 45.7229963700476, -114.49756130302194 45.69440137002097, -114.5107063030342 45.674057370002025, -114.50174130302585 45.65239336998185, -114.56467830308446 45.62427136995566, -114.54095830306237 45.5963973699297, -114.56092430308095 45.54874036988531, -114.52739230304974 45.55819336989411, -114.49659130302105 45.54664936988337, -114.46270830298948 45.5
 4784736988448, -114.43355530296233 45.527633369865654, -114.41905130294883 45.499008369839, -114.3714573029045 45.485740369826644, -114.35024630288476 45.46338336980582, -114.32643430286257 45.457424369800265, -114.26223930280278 45.485859369826755, -114.24788030278941 45.502945369842664, -114.24199830278394 45.53529036987278, -114.19480830273999 45.52791736986592, -114.17266730271938 45.54392436988083, -114.13204830268154 45.55038236988685, -114.11813930266858 45.571127369906165, -114.08296730263582 45.58637836992037, -114.05651530261119 45.62514436995647, -114.01803230257535 45.64077336997103, -114.0109903025688 45.65251136998196, -114.01987830257707 45.67237837000046, -114.00947230256737 45.68633237001346, -113.97114930253169 45.69737637002374, -113.96414430252517 45.67937837000698, -113.9266983024903 45.67121136999937, -113.92353230248735 45.65512436998439, -113.90219930246748 45.63725336996775, -113.90330530246851 45.61349136994562, -113.85202730242075 45.609562369941955, -113.
 82248530239323 45.600636369933646, -113.8037543023758 45.583729369917904, -113.83371530240369 45.514908369853806, -113.78093330235454 45.51686536985562, -113.7723043023465 45.507054369846486, -113.76916830234359 45.47770736981916, -113.78566230235894 45.44563336978929, -113.77502630234903 45.41017236975626, -113.74131030231763 45.38238636973038, -113.73908030231556 45.32153036967371, -113.68870930226865 45.27778836963297, -113.69012030226996 45.26228136961853, -113.6455923022285 45.206790369566846, -113.6009283021869 45.18099236954282, -113.59409930218054 45.14974236951372, -113.57158430215956 45.13454536949956, -113.57437630216216 45.117711369483885, -113.55227230214157 45.10754936947443, -113.51022530210243 45.107835369474685, -113.52060930211209 45.08206336945069, -113.49015930208374 45.071219369440584, -113.48630530208014 45.058321369428576, -113.4554353020514 45.04334936941463, -113.45885330205458 45.02744936939982, -113.44102930203798 44.99819436937258, -113.44876530204519 44.
 94952236932725, -113.46341330205883 44.9407753693191, -113.48734830208112 44.93957436931798, -113.49619130208936 44.930670369309695, -113.4455733020422 44.851239369235714, -113.42137930201967 44.833699369219374, -113.35002430195323 44.80756836919504, -113.34063130194447 44.779000369168436, -113.31868030192403 44.78022836916958, -113.25715430186673 44.81048636919776, -113.24033830185107 44.81184136919902, -113.13827430175601 44.761439369152086, -113.12743130174591 44.73737936912967, -113.10170330172195 44.715173369108996, -113.0989563017194 44.69591636909106, -113.07314430169536 44.67552536907207, -113.0542893016778 44.62428936902435, -113.08303730170456 44.582681368985604, -113.03966030166417 44.55629436896103, -113.03782130166246 44.532959368939295, -113.00771330163442 44.51061236891848, -113.02030930164615 44.48177636889163, -113.00665830163344 44.45261536886447, -113.01201430163843 44.43771536885059, -112.98524930161349 44.435540368848564, -112.93828130156976 44.407192368822166, 
 -112.88730730152228 44.3928523688088, -112.8707813015069 44.36997836878751, -112.84427530148221 44.35363936877229, -112.81739630145718 44.36420236878213, -112.8187103014584 44.394819368810644, -112.82669130146583 44.4210843688351, -112.79622830143747 44.45801136886949, -112.77986330142222 44.47392236888431, -112.73371230137924 44.48432036889399, -112.71432630136118 44.49693536890574, -112.65318930130424 44.48080236889072, -112.53932430119819 44.47749736888764, -112.50183930116329 44.462997368874134, -112.45851930112295 44.46883436887957, -112.42075330108777 44.44928436886136, -112.36758330103825 44.44927036886135, -112.3405773010131 44.49718036890597, -112.3425073010149 44.52510036893197, -112.28234130095886 44.54170236894744, -112.25667530093496 44.55997236896445, -112.2303983009105 44.559491368964004, -112.21776330089872 44.53849536894445, -112.19965830088186 44.531449368937885, -112.12419030081158 44.52825336893491, -112.09989730078895 44.518231368925576, -112.0593673007512 44.52
 8611368935245, -112.02707730072113 44.52284336892987, -112.02361330071791 44.53504336894123, -111.97781830067525 44.52967636893624, -111.9403863006404 44.54972636895491, -111.87250230057717 44.556265368961, -111.80783730051695 44.503982368912304, -111.79260830050276 44.518462368925796, -111.76691830047884 44.51882536892613, -111.71699730043235 44.53376036894004, -111.68486230040241 44.55075236895587, -111.60524830032827 44.54298936894864, -111.56723130029286 44.55286636895784, -111.49024130022117 44.528697368935326, -111.48257330021403 44.53614336894226, -111.45932530019238 44.53792136894391, -111.46282730019563 44.549942368955115, -111.49290430022364 44.55118936895627, -111.51452630024379 44.59319736899539, -111.50174730023188 44.615971369016606, -111.50769030023741 44.63768836903683, -111.47016830020247 44.640710369039645, -111.45826530019139 44.652555369050674, -111.46069230019364 44.67002336906694, -111.48080430021237 44.691416369086866, -111.47542530020736 44.702162369096875, -
 111.44363230017775 44.71317936910714, -111.39508430013254 44.70886936910313, -111.38495930012311 44.73769436912997, -111.37230930011133 44.745087369136854, -111.34997730009053 44.72617736911924, -111.31922130006188 44.72786436912081, -111.3154753000584 44.7051933690997, -111.29566830003995 44.68293836907897, -111.27020830001624 44.673802369070465, -111.27066530001667 44.64221236904105, -111.22397129997319 44.62690836902679, -111.2197972999693 44.61798136901848, -111.23423329998273 44.60256236900412, -111.21950729996902 44.57317036897675, -111.17876429993107 44.564851368968995, -111.17024229992315 44.54518636895068, -111.13435929988972 44.52790236893458, -111.12891829988466 44.500757368909305, -111.09463029985272 44.48612436889567, -111.0515602998126 44.473323368883754, -111.05040529981153 43.98255336842669, -111.04677129980816 43.515528367991735, -111.04749829980882 43.28473436777679, -111.04921529981043 43.01988336753013, -111.04678029980816 42.50325236704899, -111.04869729980994 4
 1.99620336657675, -111.49458630022521 42.000171366580446, -112.10051430078953 42.00230036658243, -112.14711630083293 41.999054366579415, -112.98957530161753 42.00114636658136, -114.03907230259495 41.995391366576, -114.26947130280954 41.995924366576496, -115.02486330351303 41.99650636657704, -115.94754430437234 41.99459936657526, -116.99231330534536 41.99479436657545, -117.0188643053701 41.99479436657545, -117.02629530537702 43.67903136814401)))	
-VT	Vermont	MULTIPOLYGON (((-73.25806026461467 42.74605836727511, -73.26927526462511 42.747481367276436, -73.29616926465016 42.80354936732866, -73.27958326463471 42.8371033673599, -73.27600526463138 42.940294367456005, -73.25007126460723 43.31085436780112, -73.23839126459634 43.512832367989226, -73.25998426461646 43.55938236803258, -73.29140226464573 43.57503336804716, -73.28173626463672 43.593187368064065, -73.29410426464824 43.619653368088706, -73.30353426465702 43.62471436809342, -73.36368526471304 43.61499836808437, -73.38811426473579 43.569143368041665, -73.41832026476392 43.582479368054095, -73.42296026476825 43.63211436810032, -73.37098926471984 43.71428136817684, -73.35666926470651 43.75655836821622, -73.35899726470868 43.77842736823658, -73.38474026473266 43.80450836826087, -73.37512126472369 43.88597736833674, -73.40533426475183 43.9148073683636, -73.41740626476307 43.98819736843194, -73.40825126475454 44.0182223684599, -73.43600026478039 44.04567936848548, -73.435215264779
 66 44.063897368502445, -73.40875726475501 44.10661036854222, -73.4078652647542 44.136227368569806, -73.38206226473015 44.17210736860322, -73.37733226472575 44.20124736863036, -73.30532526465869 44.26014236868521, -73.32978826468147 44.367390368785095, -73.29999526465373 44.40553336882061, -73.29331926464751 44.43285336884606, -73.33445226468581 44.54432836894988, -73.34781226469826 44.55397136895886, -73.37129626472013 44.579167368982326, -73.38182526472994 44.61980736902018, -73.37013626471905 44.63434936903372, -73.3730972647218 44.6612763690588, -73.35815126470789 44.680368369076575, -73.37315826472187 44.724236369117435, -73.32678626467867 44.79929336918734, -73.36905426471805 44.819118369205796, -73.38230626473039 44.847933369232635, -73.33641426468765 44.93260436931149, -73.350758264701 44.98197336935747, -73.34472326469538 45.006138369379975, -73.18854626454993 45.00848636938216, -72.54723126395265 45.005370369379264, -71.90186826335162 45.0073403693811, -71.50537226298235 45
 .0133513693867, -71.54092726301546 44.976563369352434, -71.51697726299317 44.94369636932182, -71.50636526298328 44.899671369280824, -71.57510126304729 44.81601936920291, -71.58350126305511 44.77919736916862, -71.63113326309947 44.741710369133706, -71.60767826307763 44.67786236907425, -71.58874926306 44.650599369048855, -71.5680272630407 44.6374463690366, -71.55410226302773 44.59658936899855, -71.53679126301161 44.57893136898211, -71.5922882630633 44.55120336895628, -71.5914412630625 44.5388743689448, -71.57524326304743 44.52580536893263, -71.58661926305801 44.49453736890351, -71.61422326308373 44.47450736888486, -71.63655426310453 44.47673136888693, -71.64770926311492 44.46917436887989, -71.656399263123 44.440137368852845, -71.67688426314209 44.42134236883534, -71.76657026322562 44.39824836881384, -71.79772926325462 44.384172368800726, -71.82119726327649 44.35036036876923, -71.83481626328917 44.3441993687635, -71.92836126337629 44.33611236875596, -71.9389052633861 44.32578636874635,
  -71.99443326343783 44.32754836874799, -72.03549526347607 44.299434368721805, -72.05956626349848 44.26149436868647, -72.04439026348435 44.23437936866122, -72.05928226349822 44.1821763686126, -72.04472426348467 44.15643536858863, -72.03492026347553 44.12074636855539, -72.04951526348913 44.100452368536494, -72.03244726347323 44.096099368532435, -72.03472826347536 44.08337436852058, -72.07691926351464 44.03204036847278, -72.08520426352236 44.00892436845125, -72.10990926354538 43.9892293684329, -72.11280826354808 43.97651536842106, -72.09171126352842 43.95799136840381, -72.11320426354844 43.93916636838628, -72.12164926355631 43.909217368358384, -72.17008926360141 43.878917368330164, -72.18483626361515 43.80169036825825, -72.20609226363494 43.764635368223736, -72.21912326364708 43.75069236821075, -72.2600552636852 43.73530036819642, -72.30404026372616 43.69853036816217, -72.33308526375322 43.59736436806796, -72.37349826379085 43.57237436804468, -72.39499826381088 43.517554367993625, -72.
 38251526379925 43.48462936796296, -72.39624826381204 43.410156367893606, -72.41213926382684 43.37712536786284, -72.39762826381333 43.351006367838515, -72.41023126382507 43.323404367812806, -72.40241926381779 43.307382367797885, -72.43559826384869 43.23225336772792, -72.45239826386434 43.15602236765692, -72.43760526385056 43.1162703676199, -72.44346426385601 43.079039367585224, -72.46175226387305 43.046504367554924, -72.45715926386877 42.99960336751124, -72.47334126388384 42.9761433674894, -72.50426326391263 42.965584367479565, -72.5202172639275 42.9516723674666, -72.52481026393178 42.91261436743023, -72.55342826395842 42.860643367381826, -72.53891726394491 42.80773336733255, -72.51306826392084 42.789259367315346, -72.50726926391545 42.768732367296224, -72.47932226388942 42.761588367289576, -72.46217126387344 42.74684036727584, -72.45577026386748 42.725852367256294, -72.92299726430262 42.73736436726702, -73.01969526439268 42.74039636726984, -73.25806026461467 42.74605836727511)))	
-MN	Minnesota	MULTIPOLYGON (((-91.73036628181835 43.49957136797688, -92.07753228214168 43.49915336797649, -92.45316928249152 43.499462367976776, -92.55800828258914 43.50025936797752, -93.02721128302613 43.501278367978465, -93.05438028305143 43.50145736797863, -93.50083028346722 43.50048836797773, -93.65369928360958 43.500762367977984, -93.97395028390784 43.50029836797755, -94.24678728416194 43.4989483679763, -94.45523828435608 43.498102367975505, -94.8598392847329 43.5000303679773, -94.92046428478936 43.49937136797669, -95.39655828523276 43.50033436797759, -95.46477528529628 43.499541367976846, -95.86691228567081 43.49894436797629, -96.0610392858516 43.49853336797591, -96.46045428622358 43.49971836797701, -96.45660228621999 43.848741368302065, -96.45739728622074 44.19906136862833, -96.45510628621861 44.53834336894431, -96.45671828622011 44.62880836902856, -96.45521728621871 44.801347369189244, -96.4560802862195 44.97199436934818, -96.45449628621803 45.27519536963055, -96.457602286220
 93 45.298850369652584, -96.47759228623954 45.328509369680205, -96.53254928629073 45.37513236972363, -96.60508428635828 45.39652436974355, -96.69316928644032 45.4106383697567, -96.7380322864821 45.45819536980099, -96.76924628651116 45.5174783698562, -96.84308728657994 45.584090369918236, -96.85499028659102 45.609122369941545, -96.83279628657036 45.65068736998026, -96.65739128640699 45.738970370062475, -96.60461028635784 45.80826437012701, -96.58795528634232 45.81785437013595, -96.56692128632274 45.93411037024421, -96.56180228631797 45.947683370256854, -96.57621528633139 46.0212793703254, -96.55193128630877 46.09552937039455, -96.57116628632669 46.17717437047059, -96.58789028634227 46.191918370484316, -96.58645628634093 46.2154133705062, -96.59818328635185 46.23868237052787, -96.60207428635547 46.33632437061881, -96.61486128636739 46.3508123706323, -96.65210128640207 46.35943337064033, -96.68822828643572 46.41221837068949, -96.70968228645569 46.42716837070341, -96.71489428646055 46.46
 871837074211, -96.74031628648423 46.4894323707614, -96.75122728649438 46.58861937085378, -96.77104128651284 46.59998337086436, -96.78431728652521 46.624112370886834, -96.79024628653073 46.6297733708921, -96.79369528653393 46.67880437093777, -96.78155628652263 46.70704437096407, -96.78038228652154 46.76231237101554, -96.7971972865372 46.812033371061844, -96.76825028651024 46.84486137109242, -96.77806128651937 46.86734937111336, -96.75691128649969 46.92278037116499, -96.76306828650542 46.936261371177544, -96.78792528652856 46.93218437117375, -96.78971028653022 46.948202371188664, -96.80188728654157 46.95584337119578, -96.79342528653369 46.96964137120863, -96.81677228655543 46.96977937120876, -96.82453128656266 47.003436371240106, -96.83529628657269 47.010231371246434, -96.82260828656086 47.033932371268506, -96.82696428656492 47.07883237131033, -96.81915128655764 47.09260437132315, -96.83916428657629 47.15188637137836, -96.82649128656448 47.17006337139529, -96.83706528657433 47.2404583
 71460846, -96.84962328658602 47.25684337147611, -96.83771428657494 47.2938843715106, -96.84674728658335 47.3146023715299, -96.83846128657564 47.34224337155564, -96.85063128658696 47.36095437157307, -96.8398272865769 47.38411737159464, -96.85000528658638 47.408936371617756, -96.86724828660245 47.41308737162162, -96.8558272865918 47.43675337164366, -96.86668428660191 47.46153737166674, -96.85161528658789 47.50061937170314, -96.86068728659633 47.521356371722455, -96.84918828658562 47.54456837174408, -96.85866428659445 47.56297837176122, -96.85221728658844 47.601151371796774, -96.87333528660811 47.61525537180991, -96.8894252866231 47.67392537186454, -96.92365928665498 47.71409437190196, -96.93201228666275 47.763506371947976, -96.9578302866868 47.79444037197678, -96.98389328671108 47.809661371990956, -96.97723128670486 47.82802937200807, -97.0003402867264 47.87019737204734, -97.02056628674522 47.87556937205234, -97.01533128674035 47.917890372091755, -97.04805328677082 47.95492437212624, 
 -97.06707128678855 48.04816437221308, -97.09272128681243 48.07034437223374, -97.0990302868183 48.10097237226226, -97.12187328683957 48.11636937227661, -97.12091828683869 48.1427743723012, -97.13651328685322 48.14839837230643, -97.11606528683417 48.15922337231652, -97.13744328685408 48.16776937232447, -97.13629128685301 48.17522737233142, -97.13727528685392 48.19506337234989, -97.13082828684792 48.20374237235798, -97.11089928682935 48.20760537236157, -97.13975428685623 48.22175537237475, -97.10923528682781 48.22804937238061, -97.12755428684487 48.23352337238571, -97.12378428684136 48.259173372409606, -97.13665528685334 48.264483372414546, -97.11171428683012 48.277876372427016, -97.11268328683101 48.286147372434726, -97.13051328684763 48.29304037244114, -97.11372128683199 48.294882372442856, -97.11475128683294 48.303618372451, -97.1326342868496 48.31096937245784, -97.11259128683093 48.319926372466185, -97.13713628685379 48.32599137247183, -97.1311232868482 48.361491372504894, -97.1503
 9628686614 48.3632153725065, -97.13378628685068 48.3724543725151, -97.135205286852 48.38441037252623, -97.15881928687399 48.38820637252977, -97.12912428684633 48.4078853725481, -97.14982328686561 48.40999137255006, -97.1516472868673 48.41961237255902, -97.12260128684025 48.416110372555764, -97.1196332868375 48.43710237257531, -97.14361328685983 48.43810937257625, -97.13459428685142 48.51731437265001, -97.14832728686422 48.51795137265061, -97.13938528685588 48.534648372666155, -97.15553728687092 48.53839837266965, -97.1604352868755 48.545078372675874, -97.14661828686262 48.54953737268002, -97.16794328688249 48.56226337269187, -97.15212728686775 48.572856372701736, -97.1581922868734 48.583640372711784, -97.14081228685721 48.586905372714824, -97.14471828686085 48.61402437274008, -97.12295828684059 48.62076837274636, -97.12744428684476 48.62979437275477, -97.1076302868263 48.629946372754915, -97.09716928681657 48.67452937279643, -97.1167392868348 48.695243372815725, -97.11010128682861 4
 8.708583372828144, -97.13480628685163 48.72623837284459, -97.13250228684947 48.747218372864126, -97.14789828686382 48.75565337287198, -97.13924628685575 48.76354237287933, -97.14751628686346 48.781170372895744, -97.17394428688807 48.801514372914696, -97.16471228687948 48.81036837292294, -97.1804222868941 48.81553737292775, -97.17120428688553 48.83598037294679, -97.17572728688974 48.87375737298198, -97.21636928692759 48.931830373036064, -97.22943628693976 48.999987373099536, -96.40691528617373 48.999982373099535, -95.27665728512109 48.99999137309954, -95.15775028501035 48.99999637309955, -95.15186728500487 49.37173037344575, -94.83203928470701 49.33080637340764, -94.68125028456657 48.87716137298514, -94.69443228457885 48.77761537289244, -94.57031228446326 48.71367637283289, -94.43063428433317 48.7107853728302, -94.29233728420436 48.70771137282733, -94.23082728414708 48.65198737277544, -93.84390428378673 48.62473737275006, -93.81268528375766 48.52540837265755, -93.78110628372825 48.51
 159037264468, -93.51413928347961 48.534271372665806, -93.46533928343416 48.54952037268001, -93.45776928342711 48.592710372720234, -93.30423628328413 48.637163372761634, -93.09144228308595 48.62658437275178, -92.94692628295135 48.62835537275343, -92.7290002827484 48.54021137267134, -92.6418202826672 48.54034937267147, -92.62638028265282 48.50282437263652, -92.69882128272029 48.49472137262897, -92.70664328272757 48.460370372596984, -92.49752928253282 48.44007237257807, -92.45634528249447 48.40216937254277, -92.47332228251028 48.357499372501174, -92.37011628241416 48.22077937237384, -92.27691828232736 48.24434037239578, -92.30027228234911 48.29831137244605, -92.27613128232663 48.35231937249635, -92.12596228218678 48.3667563725098, -92.03518328210222 48.355508372499315, -91.9795342820504 48.25039837240143, -91.78881528187279 48.20614537236021, -91.71193828180118 48.19677537235149, -91.70373128179354 48.11483537227518, -91.56877528166785 48.104457372265514, -91.57156228167045 48.04357137
 22088, -91.23944628136114 48.08129837224394, -91.02714828116342 48.19533937235015, -90.86449528101194 48.25419837240497, -90.74336528089913 48.088443372250595, -90.5674552807353 48.12169937228157, -90.55683528072541 48.092750372254606, -90.1452702803421 48.11277037227325, -90.02670028023168 48.08607937224839, -89.98702028019473 48.023556372190164, -89.90038928011404 47.99250537216125, -89.74931027997334 48.0264843721929, -89.53067327976972 48.00165637216977, -89.62564527985818 47.9925613721613, -89.63637327986817 47.95939037213041, -89.99967728020651 47.82456437200484, -90.50963328068146 47.70993837189809, -91.02147528115815 47.4610583716663, -91.46865728157461 47.12493537135326, -91.8009692818841 46.927086371169, -92.08849228215188 46.79189737104309, -92.21462428226934 46.668204370927896, -92.30314828235178 46.66657537092638, -92.287271282337 46.658786370919124, -92.28868528233832 46.415984370692996, -92.28894428233856 46.15660037045143, -92.28937028233896 46.07323137037378, -92.32
 737228237436 46.056878370358554, -92.34622528239191 46.022596370326625, -92.36496328240936 46.01624837032071, -92.42499928246528 46.02550437032933, -92.46234528250005 45.98119737028807, -92.52397728255745 45.98258337028936, -92.55267228258418 45.9512693702602, -92.66620828268992 45.91570337022708, -92.7062402827272 45.89095837020403, -92.73409728275314 45.84498037016121, -92.7487622827668 45.837302370154056, -92.77910728279507 45.763340370085174, -92.83363628284584 45.73089037005495, -92.86001928287041 45.71056237003602, -92.88539728289405 45.64495536997492, -92.87683128288607 45.57883636991335, -92.83503728284715 45.56340236989897, -92.7621752827793 45.56426336989977, -92.72815428274761 45.54724236988392, -92.68542128270781 45.470053369812035, -92.6548172826793 45.45522136979822, -92.64497528267015 45.43945236978353, -92.64875128267366 45.395466369742564, -92.6848692827073 45.3630763697124, -92.70738428272827 45.318201369670604, -92.74659328276478 45.297603369651426, -92.7554192827
 73 45.21237636957205, -92.76258328277967 45.18661236954806, -92.74493528276324 45.15642236951994, -92.74542228276368 45.1130043694795, -92.7967622828115 45.06561036943536, -92.76299128278005 45.02211936939486, -92.7671262827839 45.00100536937519, -92.74976828276773 44.93565536931433, -92.75392628277162 44.915002369295095, -92.77187128278833 44.899496369280655, -92.76426328278124 44.862234369245954, -92.76102828277823 44.83537136922094, -92.80558428281972 44.746160369137854, -92.73714528275598 44.713594369107525, -92.63036728265654 44.64265236904146, -92.60897328263661 44.61029236901132, -92.5092152825437 44.575159368978596, -92.34087228238693 44.5528353689578, -92.32047828236793 44.540491368946306, -92.29668728234577 44.49218236890132, -92.24910028230146 44.45621636886782, -92.20613728226144 44.43839436885122, -92.09133328215452 44.415589368829984, -91.97238628204374 44.36448736878239, -91.93886828201254 44.33911136875876, -91.92275428199753 44.31752036873865, -91.92234928199714 44.
 28834136871147, -91.8886942819658 44.25749536868275, -91.84874428192859 44.191187368620994, -91.75321928183963 44.137227368570734, -91.65223328174558 44.066895368505236, -91.6017862816986 44.04082236848096, -91.56916228166821 44.034955368475494, -91.52842028163028 44.034215368474804, -91.42590228153479 43.98561936842954, -91.37335728148585 43.94719136839375, -91.29194828141004 43.847190368300616, -91.251105281372 43.788075368245565, -91.25891628137927 43.722395368184394, -91.25838928137878 43.67732236814242, -91.23299028135513 43.59889036806938, -91.24055828136218 43.54871236802264, -91.22356628134635 43.500808367978024, -91.61109928170727 43.50062636797786, -91.73036628181835 43.49957136797688)))	
-OR	Oregon	MULTIPOLYGON (((-121.441509309489 41.99433436657502, -122.28470531027429 42.000764366581, -123.22210231114731 42.00219136658233, -123.51320431141842 41.99783336657828, -123.81914631170335 41.99294836657373, -124.20644431206405 41.997648366578105, -124.35224631219984 42.09867736667219, -124.41506231225834 42.245894366809296, -124.43781831227955 42.429608366980396, -124.39176331223663 42.55302736709534, -124.40107831224532 42.62269936716022, -124.55961731239297 42.83245736735557, -124.4853463123238 42.955454367470125, -124.386772312232 43.261589367755235, -124.40607631224998 43.3001973677912, -124.27399431212697 43.45910536793919, -124.22600431208227 43.60500436807507, -124.15832531201923 43.85711836830987, -124.11831931198198 44.269515368693945, -124.05440531192245 44.6621393690596, -124.07556831194216 44.81473836920172, -124.00757231187885 45.03610336940788, -123.95660731183138 45.292965369647106, -123.98056031185368 45.485084369826026, -123.93667431181281 45.5079663698473
 4, -123.8921083117713 45.47405036981576, -123.85950731174094 45.499082369839066, -123.9534153118284 45.568528369903746, -123.936076

<TRUNCATED>

[27/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test-files/data/countries-bbox.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test-files/data/countries-bbox.txt b/lucene/spatial-extras/src/test-files/data/countries-bbox.txt
new file mode 100644
index 0000000..ac3a4fd
--- /dev/null
+++ b/lucene/spatial-extras/src/test-files/data/countries-bbox.txt
@@ -0,0 +1,249 @@
+#id	name	shape
+FLK	Falkland Is.	ENVELOPE(-61.148055, -57.733200, -51.249455, -52.343055)
+GUF	French Guiana	ENVELOPE(-54.603782, -51.648055, 5.755418, 2.113473)
+GUY	Guyana	ENVELOPE(-61.389727, -56.470636, 8.535273, 1.186873)
+PCN	Pitcairn Is.	ENVELOPE(-130.105055, -128.286118, -24.325836, -25.082227)
+SGS	South Georgia & the South Sandwich Is.	ENVELOPE(-38.023755, -26.241391, -53.989727, -58.498609)
+SHN	St. Helena	ENVELOPE(-5.792782, -5.645282, -15.903755, -16.021946)
+SUR	Suriname	ENVELOPE(-58.071400, -53.986118, 6.001809, 1.836245)
+TTO	Trinidad & Tobago	ENVELOPE(-61.921600, -60.520836, 11.345554, 10.040345)
+VEN	Venezuela	ENVELOPE(-73.378064, -59.803055, 12.197500, 0.649164)
+ASM	American Samoa	ENVELOPE(-170.823227, -170.561873, -14.254309, -14.375555)
+COK	Cook Is.	ENVELOPE(-165.848345, -157.703764, -10.881318, -21.940836)
+PYF	French Polynesia	ENVELOPE(-151.497773, -138.809755, -8.778191, -17.870836)
+UMI	Jarvis I.	ENVELOPE(-160.045164, -160.009464, -0.374309, -0.398055)
+NIU	Niue	ENVELOPE(-169.952236, -169.781555, -18.963336, -19.145555)
+WSM	Samoa	ENVELOPE(-172.780027, -171.429200, -13.460555, -14.057500)
+TKL	Tokelau	ENVELOPE(-171.862718, -171.843764, -9.170627, -9.218891)
+TON	Tonga	ENVELOPE(-175.360000, -173.906827, -18.568055, -21.268064)
+WLF	Wallis & Futuna	ENVELOPE(-178.190273, -176.121936, -13.214864, -14.323891)
+ARG	Argentina	ENVELOPE(-73.582300, -53.650009, -21.780518, -55.051673)
+BOL	Bolivia	ENVELOPE(-69.656191, -57.521118, -9.679191, -22.901109)
+BRA	Brazil	ENVELOPE(-74.004591, -34.792918, 5.272709, -33.741118)
+CHL	Chile	ENVELOPE(-109.446109, -66.420627, -17.505282, -55.902227)
+ECU	Ecuador	ENVELOPE(-91.663891, -75.216846, 1.437782, -5.000309)
+PRY	Paraguay	ENVELOPE(-62.643773, -54.243900, -19.296809, -27.584727)
+PER	Peru	ENVELOPE(-81.355146, -68.673909, -0.036873, -18.348546)
+URY	Uruguay	ENVELOPE(-58.438609, -53.098300, -30.096673, -34.943818)
+UMI	Baker I.	ENVELOPE(-176.467655, -176.455855, 0.222573, 0.215282)
+CAN	Canada	ENVELOPE(-141.002991, -52.617364, 83.113873, 41.675554)
+GTM	Guatemala	ENVELOPE(-92.246782, -88.214736, 17.821109, 13.745836)
+UMI	Howland I.	ENVELOPE(-176.643082, -176.631091, 0.808609, 0.790282)
+UMI	Johnston Atoll	ENVELOPE(-169.538936, -169.523927, 16.730273, 16.724164)
+MEX	Mexico	ENVELOPE(-118.404164, -86.738618, 32.718454, 14.550545)
+UMI	Midway Is.	ENVELOPE(-177.395845, -177.360545, 28.221518, 28.184154)
+BRB	Barbados	ENVELOPE(-59.659446, -59.427082, 13.337082, 13.050554)
+DMA	Dominica	ENVELOPE(-61.491391, -61.250700, 15.631945, 15.198054)
+GRD	Grenada	ENVELOPE(-61.785182, -61.596391, 12.237154, 11.996945)
+GLP	Guadeloupe	ENVELOPE(-61.796109, -61.187082, 16.512918, 15.870000)
+MTQ	Martinique	ENVELOPE(-61.231536, -60.816946, 14.880136, 14.402773)
+LCA	St. Lucia	ENVELOPE(-61.079582, -60.878064, 14.109309, 13.709445)
+SPM	St. Pierre & Miquelon	ENVELOPE(-56.397782, -56.145500, 47.135827, 46.747191)
+VCT	St. Vincent & the Grenadines	ENVELOPE(-61.280146, -61.120282, 13.383191, 13.130282)
+ABW	Aruba	ENVELOPE(-70.059664, -69.874864, 12.627773, 12.411109)
+BMU	Bermuda	ENVELOPE(-64.823064, -64.676809, 32.379509, 32.260554)
+DOM	Dominican Republic	ENVELOPE(-72.003064, -68.322927, 19.930827, 17.604164)
+HTI	Haiti	ENVELOPE(-74.467791, -71.629182, 20.091454, 18.022782)
+JAM	Jamaica	ENVELOPE(-78.373900, -76.221118, 18.522500, 17.697218)
+ANT	Netherlands Antilles	ENVELOPE(-69.163618, -68.192927, 12.383891, 12.020554)
+BHS	The Bahamas	ENVELOPE(-78.978900, -72.738891, 26.929164, 20.915273)
+TCA	Turks & Caicos Is.	ENVELOPE(-72.031464, -71.127573, 21.957773, 21.429918)
+BLZ	Belize	ENVELOPE(-89.216400, -87.779591, 18.489900, 15.889854)
+CYM	Cayman Is.	ENVELOPE(-81.400836, -81.093064, 19.354164, 19.265000)
+COL	Colombia	ENVELOPE(-81.720146, -66.870455, 12.590273, -4.236873)
+CRI	Costa Rica	ENVELOPE(-85.911391, -82.561400, 11.212845, 8.025673)
+CUB	Cuba	ENVELOPE(-84.952927, -74.131255, 23.194027, 19.821945)
+SLV	El Salvador	ENVELOPE(-90.108064, -87.694673, 14.431982, 13.156391)
+HND	Honduras	ENVELOPE(-89.350491, -83.131855, 16.435827, 12.985173)
+NIC	Nicaragua	ENVELOPE(-87.689827, -83.131855, 15.022218, 10.709691)
+PAN	Panama	ENVELOPE(-83.030291, -77.198336, 9.620136, 7.206109)
+AIA	Anguilla	ENVELOPE(-63.167782, -62.972709, 18.272982, 18.164445)
+ATG	Antigua & Barbuda	ENVELOPE(-61.891109, -61.666946, 17.724300, 16.989718)
+VGB	British Virgin Is.	ENVELOPE(-64.698482, -64.324527, 18.504854, 18.383891)
+MSR	Montserrat	ENVELOPE(-62.236946, -62.138891, 16.812354, 16.671391)
+PRI	Puerto Rico	ENVELOPE(-67.266400, -65.301118, 18.519445, 17.922218)
+KNA	St. Kitts & Nevis	ENVELOPE(-62.862782, -62.622509, 17.410136, 17.208882)
+VIR	Virgin Is.	ENVELOPE(-65.023509, -64.562573, 18.387673, 17.676664)
+FRO	Faroe Is.	ENVELOPE(-7.433473, -6.389718, 62.357500, 61.388327)
+GRL	Greenland	ENVELOPE(-73.053609, -12.157637, 83.623600, 59.790273)
+XGK	Guernsey	ENVELOPE(-2.668609, -2.500973, 49.508191, 49.422491)
+ISL	Iceland	ENVELOPE(-24.538400, -13.499446, 66.536100, 63.390000)
+IRL	Ireland	ENVELOPE(-10.474727, -6.013055, 55.379991, 51.445545)
+XIM	Isle of Man	ENVELOPE(-4.787155, -4.308682, 54.416382, 54.055545)
+SJM	Jan Mayen	ENVELOPE(-9.119909, -7.928509, 71.180818, 70.803863)
+XJE	Jersey	ENVELOPE(-2.247364, -2.015000, 49.261109, 49.167773)
+GBR	United Kingdom	ENVELOPE(-8.171664, 1.749445, 60.843327, 49.955273)
+CPV	Cape Verde	ENVELOPE(-25.360555, -22.666109, 17.192364, 14.811109)
+CIV	Cote d'Ivoire	ENVELOPE(-8.606382, -2.487782, 10.735254, 4.344718)
+GHA	Ghana	ENVELOPE(-3.248891, 1.202782, 11.155691, 4.727082)
+GIB	Gibraltar	ENVELOPE(-5.356173, -5.334509, 36.163309, 36.112073)
+LBR	Liberia	ENVELOPE(-11.492327, -7.368400, 8.512782, 4.343609)
+MAR	Morocco	ENVELOPE(-13.174964, -1.011809, 35.919164, 27.664236)
+PRT	Portugal	ENVELOPE(-31.289027, -6.190455, 42.150673, 32.637500)
+ESP	Spain	ENVELOPE(-18.169864, 4.316945, 43.764300, 27.637500)
+ESH	Western Sahara	ENVELOPE(-17.101527, -8.666391, 27.666954, 20.764100)
+BFA	Burkina Faso	ENVELOPE(-5.520837, 2.397927, 15.082773, 9.395691)
+GIN	Guinea	ENVELOPE(-15.080837, -7.653373, 12.677500, 7.193927)
+GNB	Guinea-Bissau	ENVELOPE(-16.717773, -13.643891, 12.684718, 10.925100)
+MLI	Mali	ENVELOPE(-12.244837, 4.251391, 25.000273, 10.142154)
+MRT	Mauritania	ENVELOPE(-17.075555, -4.806109, 27.290454, 14.725636)
+SEN	Senegal	ENVELOPE(-17.532782, -11.369927, 16.690618, 12.301745)
+SLE	Sierra Leone	ENVELOPE(-13.295609, -10.264309, 9.997500, 6.923609)
+GMB	The Gambia	ENVELOPE(-16.821664, -13.798609, 13.826391, 13.059973)
+DJI	Djibouti	ENVELOPE(41.759854, 43.420409, 12.708327, 10.942218)
+ERI	Eritrea	ENVELOPE(36.443282, 43.121382, 17.994882, 12.363891)
+ETH	Ethiopia	ENVELOPE(32.991800, 47.988245, 14.883609, 3.406664)
+MNG	Mongolia	ENVELOPE(87.761100, 119.931509, 52.142773, 41.586654)
+SDN	Sudan	ENVELOPE(21.829100, 38.607500, 22.232218, 3.493391)
+UGA	Uganda	ENVELOPE(29.574300, 35.009718, 4.222782, -1.476109)
+ISR	Gaza Strip	ENVELOPE(34.216663, 34.558891, 31.596100, 31.216545)
+IRQ	Iraq	ENVELOPE(38.794700, 48.560691, 37.383673, 29.061664)
+ISR	Israel	ENVELOPE(34.267582, 35.681109, 33.270273, 29.486709)
+JOR	Jordan	ENVELOPE(34.960418, 39.301109, 33.377591, 29.188891)
+KAZ	Kazakhstan	ENVELOPE(46.499163, 87.348209, 55.442627, 40.594436)
+NOR	Norway	ENVELOPE(4.789582, 31.073536, 71.154709, 57.987918)
+RUS	Russia	ENVELOPE(-180.000000, 180.000000, 81.851927, 41.196582)
+SWE	Sweden	ENVELOPE(11.113336, 24.167009, 69.060300, 55.339164)
+ISR	West Bank	ENVELOPE(34.888191, 35.570609, 32.546391, 31.350691)
+DZA	Algeria	ENVELOPE(-8.667218, 11.986473, 37.089854, 18.976391)
+AND	Andorra	ENVELOPE(1.421391, 1.781718, 42.655964, 42.436382)
+CMR	Cameroon	ENVELOPE(8.502363, 16.207000, 13.085000, 1.654164)
+CAF	Central African Republic	ENVELOPE(14.418891, 27.459718, 11.000836, 2.221264)
+LBY	Libya	ENVELOPE(9.311391, 25.151663, 33.171136, 19.499064)
+MCO	Monaco	ENVELOPE(7.390900, 7.439291, 43.768300, 43.727545)
+TUN	Tunisia	ENVELOPE(7.492218, 11.581663, 37.340409, 30.234391)
+BEN	Benin	ENVELOPE(0.776663, 3.855000, 12.396654, 6.218718)
+TCD	Chad	ENVELOPE(13.461945, 24.002745, 23.450554, 7.458536)
+GNQ	Equatorial Guinea	ENVELOPE(8.424163, 11.353891, 3.763336, 0.930154)
+KIR	Kiribati	ENVELOPE(-157.581700, 172.947509, 2.033054, 1.335991)
+NER	Niger	ENVELOPE(0.166663, 15.996663, 23.522309, 11.693273)
+NGA	Nigeria	ENVELOPE(2.692500, 14.649654, 13.891500, 4.272845)
+STP	Sao Tome & Principe	ENVELOPE(6.465136, 7.463473, 1.701245, 0.018336)
+TGO	Togo	ENVELOPE(-0.149764, 1.797800, 11.138536, 6.100545)
+ALB	Albania	ENVELOPE(19.288536, 21.053327, 42.660345, 39.645000)
+BIH	Bosnia & Herzegovina	ENVELOPE(15.740591, 19.619782, 45.265945, 42.565827)
+HRV	Croatia	ENVELOPE(13.504791, 19.425000, 46.535827, 42.399991)
+ITA	Italy	ENVELOPE(6.623963, 18.514445, 47.094582, 36.649164)
+MKD	Macedonia	ENVELOPE(20.458818, 23.030973, 42.358954, 40.855891)
+MLT	Malta	ENVELOPE(14.329100, 14.570000, 35.991936, 35.800000)
+SMR	San Marino	ENVELOPE(12.406945, 12.511109, 43.986873, 43.898682)
+SMN	Serbia & Montenegro	ENVELOPE(18.453327, 23.005000, 46.181109, 41.849000)
+VTC	Vatican City	ENVELOPE(12.444473, 12.457718, 41.908391, 41.900891)
+BGR	Bulgaria	ENVELOPE(22.365273, 28.605136, 44.224718, 41.243045)
+CYP	Cyprus	ENVELOPE(32.269863, 34.586036, 35.688609, 34.640273)
+EGY	Egypt	ENVELOPE(24.706800, 36.895827, 31.646945, 21.994164)
+GEO	Georgia	ENVELOPE(40.002963, 46.710818, 43.584718, 41.048045)
+GRC	Greece	ENVELOPE(19.640000, 28.238045, 41.747773, 34.930545)
+LBN	Lebanon	ENVELOPE(35.100827, 36.623745, 34.647500, 33.062082)
+SYR	Syria	ENVELOPE(35.614463, 42.378327, 37.290545, 32.313609)
+TUR	Turkey	ENVELOPE(25.665827, 44.820545, 42.109991, 35.818445)
+AUT	Austria	ENVELOPE(9.533573, 17.166382, 49.018745, 46.407491)
+CZE	Czech Republic	ENVELOPE(12.093700, 18.852218, 51.052491, 48.581382)
+DNK	Denmark	ENVELOPE(8.092918, 15.149163, 57.745973, 54.561936)
+HUN	Hungary	ENVELOPE(16.111800, 22.894800, 48.576173, 45.748327)
+POL	Poland	ENVELOPE(14.147636, 24.143473, 54.836036, 49.002918)
+SVK	Slovakia	ENVELOPE(16.844718, 22.558054, 49.600827, 47.737500)
+SVN	Slovenia	ENVELOPE(13.383473, 16.607873, 46.876245, 45.425818)
+SJM	Svalbard	ENVELOPE(10.487918, 33.637500, 80.764163, 74.343045)
+BEL	Belgium	ENVELOPE(2.541663, 6.398200, 51.501245, 49.508882)
+FRA	France	ENVELOPE(-4.790282, 9.562218, 51.091109, 41.364927)
+DEU	Germany	ENVELOPE(5.865000, 15.033818, 55.056527, 47.274718)
+LIE	Liechtenstein	ENVELOPE(9.474636, 9.633891, 47.274545, 47.057454)
+LUX	Luxembourg	ENVELOPE(5.734445, 6.524027, 50.181809, 49.448464)
+NLD	Netherlands	ENVELOPE(3.370863, 7.210973, 53.465827, 50.753882)
+CHE	Switzerland	ENVELOPE(5.967009, 10.488209, 47.806664, 45.829436)
+USA	United States	ENVELOPE(-178.216555, 179.775936, 71.351436, 18.925482)
+BLR	Belarus	ENVELOPE(23.165400, 32.740054, 56.167491, 51.251845)
+EST	Estonia	ENVELOPE(21.837354, 28.194091, 59.664718, 57.522636)
+FIN	Finland	ENVELOPE(19.511391, 31.581963, 70.088609, 59.806800)
+LVA	Latvia	ENVELOPE(20.968609, 28.235963, 58.083254, 55.674836)
+LTU	Lithuania	ENVELOPE(20.942836, 26.813054, 56.449854, 53.890336)
+MDA	Moldova	ENVELOPE(26.634991, 30.128709, 48.468318, 45.448645)
+ROM	Romania	ENVELOPE(20.261027, 29.672218, 48.263882, 43.623309)
+UKR	Ukraine	ENVELOPE(22.151445, 40.178745, 52.378600, 44.379154)
+IND	India	ENVELOPE(68.144227, 97.380536, 35.505618, 6.745827)
+MDV	Maldives	ENVELOPE(72.863391, 73.637272, 7.027773, -0.641664)
+OMN	Oman	ENVELOPE(51.999291, 59.847082, 26.368709, 16.642782)
+SOM	Somalia	ENVELOPE(40.988609, 51.411318, 11.979164, -1.674873)
+LKA	Sri Lanka	ENVELOPE(79.696091, 81.891663, 9.828191, 5.918054)
+TKM	Turkmenistan	ENVELOPE(51.250182, 66.670882, 42.796173, 35.145991)
+UZB	Uzbekistan	ENVELOPE(55.997491, 73.167545, 45.570591, 37.184991)
+YEM	Yemen	ENVELOPE(42.555973, 54.473473, 18.999345, 12.144718)
+ARM	Armenia	ENVELOPE(43.454163, 46.620536, 41.297054, 38.841145)
+AZE	Azerbaijan	ENVELOPE(44.778863, 51.677009, 42.710754, 38.262809)
+BHR	Bahrain	ENVELOPE(50.453327, 50.796391, 26.288891, 25.571945)
+IRN	Iran	ENVELOPE(44.034954, 63.330273, 39.779154, 25.075973)
+KWT	Kuwait	ENVELOPE(46.546945, 48.416591, 30.084164, 28.538882)
+QAT	Qatar	ENVELOPE(50.751936, 51.615827, 26.152500, 24.556045)
+SAU	Saudi Arabia	ENVELOPE(34.572145, 55.666109, 32.154945, 16.377500)
+ARE	United Arab Emirates	ENVELOPE(51.583327, 56.381663, 26.083882, 22.633327)
+AFG	Afghanistan	ENVELOPE(60.504163, 74.915736, 38.471982, 29.406109)
+KGZ	Kyrgyzstan	ENVELOPE(69.249500, 80.281582, 43.216900, 39.195473)
+NPL	Nepal	ENVELOPE(80.052200, 88.194554, 30.424718, 26.368364)
+PAK	Pakistan	ENVELOPE(60.866300, 77.823927, 37.060791, 23.688045)
+TJK	Tajikistan	ENVELOPE(67.364700, 75.187482, 41.049254, 36.671845)
+BGD	Bangladesh	ENVELOPE(88.043872, 92.669345, 26.626136, 20.744818)
+BTN	Bhutan	ENVELOPE(88.751936, 92.114218, 28.325000, 26.703609)
+BRN	Brunei	ENVELOPE(114.095082, 115.360263, 5.053054, 4.018191)
+CHN	China	ENVELOPE(73.620045, 134.768463, 53.553745, 18.168882)
+JPN	Japan	ENVELOPE(123.678863, 145.812409, 45.486382, 24.251391)
+PRK	North Korea	ENVELOPE(124.323954, 130.697418, 43.006100, 37.671382)
+PLW	Palau	ENVELOPE(134.452482, 134.658872, 7.729445, 7.305254)
+PHL	Philippines	ENVELOPE(116.950000, 126.598036, 19.391109, 5.049164)
+KOR	South Korea	ENVELOPE(126.099018, 129.586872, 38.625245, 33.192209)
+KHM	Cambodia	ENVELOPE(102.346509, 107.636382, 14.708618, 10.422736)
+LAO	Laos	ENVELOPE(100.091372, 107.695254, 22.499927, 13.926664)
+MYS	Malaysia	ENVELOPE(99.641936, 119.275818, 7.352918, 0.852782)
+MMR	Myanmar	ENVELOPE(92.204991, 101.169427, 28.546527, 9.839582)
+SGP	Singapore	ENVELOPE(103.640945, 103.997945, 1.445282, 1.259027)
+THA	Thailand	ENVELOPE(97.347272, 105.639291, 20.454582, 5.633473)
+VNM	Vietnam	ENVELOPE(102.140745, 109.464845, 23.324164, 8.559236)
+GUM	Guam	ENVELOPE(144.634154, 144.953309, 13.652291, 13.235000)
+MHL	Marshall Is.	ENVELOPE(162.324963, 171.378063, 14.594027, 5.600273)
+FSM	Micronesia	ENVELOPE(158.120100, 163.042891, 6.977636, 5.261664)
+MNP	Northern Mariana Is.	ENVELOPE(145.572682, 145.818082, 15.268191, 14.908054)
+UMI	Wake I.	ENVELOPE(166.608981, 166.662200, 19.324582, 19.279445)
+BWA	Botswana	ENVELOPE(19.996109, 29.373618, -17.782082, -26.875555)
+BDI	Burundi	ENVELOPE(28.985000, 30.853191, -2.301564, -4.448055)
+ATF	French Southern & Antarctic Lands	ENVELOPE(51.650836, 70.567491, -46.327645, -49.725009)
+HMD	Heard I. & McDonald Is.	ENVELOPE(73.234709, 73.773882, -52.965145, -53.199445)
+KEN	Kenya	ENVELOPE(33.907218, 41.905163, 4.622500, -4.669618)
+RWA	Rwanda	ENVELOPE(28.854445, 30.893263, -1.054446, -2.825491)
+TZA	Tanzania	ENVELOPE(29.340827, 40.436809, -0.997218, -11.740418)
+ZMB	Zambia	ENVELOPE(21.996391, 33.702282, -8.191664, -18.074918)
+ZWE	Zimbabwe	ENVELOPE(25.237918, 33.071591, -15.616527, -22.414764)
+ATA	Antarctica	ENVELOPE(-180.000000, 180.000000, -60.503336, -90.000000)
+NOR	Bouvet I.	ENVELOPE(3.342363, 3.484163, -54.383609, -54.462782)
+COM	Comoros	ENVELOPE(43.214027, 44.530418, -11.366946, -12.383055)
+REU	Juan De Nova I.	ENVELOPE(42.723818, 42.760900, -17.052018, -17.076118)
+LSO	Lesotho	ENVELOPE(27.013973, 29.455554, -28.570691, -30.650527)
+MWI	Malawi	ENVELOPE(32.681873, 35.920963, -9.376673, -17.135282)
+MOZ	Mozambique	ENVELOPE(30.213018, 40.846109, -10.471109, -26.860282)
+ZAF	South Africa	ENVELOPE(16.483327, 37.892218, -22.136391, -46.969727)
+SWZ	Swaziland	ENVELOPE(30.798336, 32.133400, -25.728336, -27.316391)
+AGO	Angola	ENVELOPE(11.731245, 24.084445, -4.388991, -18.016391)
+COG	Congo	ENVELOPE(11.140663, 18.643609, 3.711109, -5.015000)
+ZAR	Congo, DRC	ENVELOPE(12.214554, 31.302773, 5.380691, -13.458055)
+FJI	Fiji	ENVELOPE(-180.000000, 180.000000, -16.153473, -19.162782)
+GAB	Gabon	ENVELOPE(8.700836, 14.519582, 2.317900, -3.925282)
+NAM	Namibia	ENVELOPE(11.716391, 25.264427, -16.954173, -28.961873)
+NZL	New Zealand	ENVELOPE(-176.848755, 178.841063, -34.414718, -52.578055)
+IOT	British Indian Ocean Territory	ENVELOPE(72.357900, 72.494282, -7.233473, -7.436246)
+REU	Glorioso Is.	ENVELOPE(47.279091, 47.303054, -11.554100, -11.577782)
+MDG	Madagascar	ENVELOPE(43.236827, 50.501391, -11.945555, -25.588336)
+MUS	Mauritius	ENVELOPE(57.306309, 63.495754, -19.673336, -20.520555)
+MYT	Mayotte	ENVELOPE(45.039163, 45.293345, -12.662500, -12.992500)
+REU	Reunion	ENVELOPE(55.220554, 55.853054, -20.856527, -21.373891)
+SYC	Seychelles	ENVELOPE(46.205691, 55.540554, -4.551664, -9.463055)
+CXR	Christmas I.	ENVELOPE(105.629000, 105.751900, -10.384082, -10.510973)
+CCK	Cocos Is.	ENVELOPE(96.817491, 96.864845, -12.130418, -12.199446)
+IDN	Indonesia	ENVELOPE(95.210945, 141.007018, 5.913473, -10.929655)
+TLS	Timor Leste	ENVELOPE(124.046100, 127.308591, -8.140000, -9.463627)
+AUS	Australia	ENVELOPE(112.907209, 158.960372, -10.135691, -54.753891)
+NRU	Nauru	ENVELOPE(166.904418, 166.957045, -0.493336, -0.552218)
+NCL	New Caledonia	ENVELOPE(163.982745, 168.130509, -20.087918, -22.673891)
+NFK	Norfolk I.	ENVELOPE(167.910945, 167.998872, -29.000555, -29.081109)
+PNG	Papua New Guinea	ENVELOPE(140.858854, 155.966845, -1.355282, -11.642500)
+SLB	Solomon Is.	ENVELOPE(155.671300, 166.931836, -6.605518, -11.845836)
+TUV	Tuvalu	ENVELOPE(176.295254, 179.232281, -6.089446, -8.561291)
+VUT	Vanuatu	ENVELOPE(166.521636, 169.893863, -13.707218, -20.254173)


[12/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test-files/data/countries-poly.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test-files/data/countries-poly.txt b/lucene/spatial/src/test-files/data/countries-poly.txt
deleted file mode 100644
index 8192df2..0000000
--- a/lucene/spatial/src/test-files/data/countries-poly.txt
+++ /dev/null
@@ -1,249 +0,0 @@
-#id	name	shape	
-FLK	Falkland Is.	MULTIPOLYGON (((-59.348063887634126 -52.34305496492924, -59.37944588766335 -52.32778196491501, -59.57444588784496 -52.21528196481024, -59.71611788797689 -52.11737296471905, -59.56667288783771 -51.91749996453291, -59.51805488779243 -51.87528196449359, -59.2883358875785 -51.746944964374066, -59.221254887516025 -51.71709096434626, -59.13306388743389 -51.69444496432517, -59.055554887361694 -51.691672964322585, -59.03087288733872 -51.7643819643903, -59.04139088734851 -51.81520896443764, -59.00083588731074 -51.8100089644328, -58.99472688730505 -51.80667296442969, -58.9826458872938 -51.79534496441914, -59.02389988733222 -51.67694496430887, -59.07833588738292 -51.631954964266974, -59.168263887466665 -51.585281964223505, -59.10860888741111 -51.513890964157014, -59.08416388738834 -51.53722696417875, -59.06986388737502 -51.557363964197506, -59.039308887346564 -51.58396396422228, -59.01430888732328 -51.575835964214704, -58.989445887300135 -51.50417296414796, -59.0461088873529 -
 51.47889096412442, -59.074726887379555 -51.469863964116016, -59.08472688738887 -51.41166396406181, -58.99110888730168 -51.40555496405612, -58.868754887187734 -51.37007296402307, -58.88430888720221 -51.33083596398653, -58.84861788716897 -51.291390963949794, -58.75403588708089 -51.32639096398239, -58.69667288702746 -51.336672963991965, -58.614508886950944 -51.3294089639852, -58.57972688691855 -51.30944496396661, -58.5444458868857 -51.30569996396312, -58.4673638868139 -51.307363963964676, -58.41250888676282 -51.32340896397962, -58.34361788669865 -51.36903596402211, -58.32459088668094 -51.416081964065924, -58.36194588671573 -51.44445496409235, -58.44389088679205 -51.45361796410088, -58.45917288680627 -51.43020896407908, -58.47597288682192 -51.39999996405095, -58.49610888684067 -51.39631796404752, -58.55028188689113 -51.43361796408225, -58.51833588686138 -51.47610896412183, -58.49889088684327 -51.50028196414434, -58.420563886770324 -51.556672964196856, -58.36249988671625 -51.567217964206
 684, -58.33583588669141 -51.56667296420617, -58.28167288664096 -51.606808964243555, -58.241390886603455 -51.65014496428391, -58.21743588658114 -51.65069996428443, -58.18278188654887 -51.60917296424575, -58.188899886554566 -51.585281964223505, -58.2572268866182 -51.53055496417254, -58.31409988667117 -51.50041796414447, -58.345554886700455 -51.509099964152554, -58.27479988663457 -51.413754964063756, -58.25028188661173 -51.40097296405185, -58.21736388658107 -51.39528196404655, -57.94445488632691 -51.371808964024694, -57.91541788629986 -51.37528196402793, -57.89680888628253 -51.3841729640362, -57.873890886261194 -51.4016729640525, -57.768054886162616 -51.50403596414784, -57.77291788616715 -51.54375496418483, -57.81389988620532 -51.54972696419039, -57.87861788626559 -51.54610896418702, -57.90472688628991 -51.543335964184436, -57.93028188631371 -51.539999964181334, -57.95360888633543 -51.53486396417655, -57.9794458863595 -51.52389096416633, -58.00417288638252 -51.50778196415133, -58.03541
 788641162 -51.50209096414603, -58.138963886508066 -51.54986396419052, -58.109308886480434 -51.570563964209796, -58.039235886415184 -51.59014496422803, -58.0087548863868 -51.59319996423088, -57.983545886363316 -51.58805496422609, -57.87694588626404 -51.60000896423722, -57.79764588619018 -51.61180896424821, -57.77528188616935 -51.621735964257454, -57.733199886130166 -51.69444496432517, -57.83444588622446 -51.723617964352336, -57.973890886354326 -51.74860896437561, -58.0324998864089 -51.7575089643839, -58.1119458864829 -51.76333596438933, -58.19778188656284 -51.761944964388036, -58.249172886610694 -51.7573999643838, -58.21389088657784 -51.78110896440588, -58.17361788654033 -51.796672964420374, -58.200008886564916 -51.793890964417784, -58.24680888660849 -51.79333596441727, -58.35833588671237 -51.82666396444831, -58.33778188669322 -51.83278196445401, -58.31514588667214 -51.83444496445556, -58.28528188664433 -51.82722696444883, -58.234726886597244 -51.83278196445401, -58.39291788674457 -5
 1.89583596451273, -58.4199998867698 -51.90069996451726, -58.60639088694339 -51.90028196451687, -58.76812688709401 -51.89125496450846, -58.88945488720701 -51.84472696446513, -58.90917288722537 -51.83583596445685, -58.92347288723869 -51.820281964442366, -58.935554887249936 -51.80125496442464, -58.96243588727498 -51.81764496443991, -58.97382688728558 -51.85146396447141, -58.926672887241665 -51.87806396449618, -58.82389088714595 -51.91528196453084, -58.720626887049775 -51.94784496456116, -58.63396388696907 -51.96451796457669, -58.60389088694106 -52.001399964611046, -58.64694588698116 -52.067217964672345, -58.6802818870122 -52.090835964694335, -58.734726887062905 -52.046672964653204, -58.78791788711244 -52.03417296464156, -58.82500888714699 -52.047226964653724, -58.856526887176344 -52.0688909646739, -58.918890887234426 -52.099999964702874, -58.981108887292365 -52.06958196467454, -59.03333588734101 -52.02444496463251, -59.14236388744254 -51.985281964596034, -59.251672887544345 -51.9911089
 6460146, -59.29430888758405 -52.0097269646188, -59.279654887570416 -52.02493596463297, -59.24444588753762 -52.01944496462785, -59.21959088751447 -52.0234729646316, -59.19180888748859 -52.029444964637165, -59.12222688742379 -52.063335964668724, -59.03625488734373 -52.1408359647409, -59.05069988735718 -52.217499964812305, -59.0720908873771 -52.231535964825376, -59.19389088749054 -52.206672964802216, -59.24083588753426 -52.18639096478333, -59.29249988758238 -52.157499964756425, -59.37951788766341 -52.11923596472079, -59.44979088772887 -52.1467359647464, -59.428408887708954 -52.21389096480894, -59.38444588766801 -52.22722696482136, -59.343472887629844 -52.25215496484458, -59.33805488762479 -52.324444964911905, -59.348063887634126 -52.34305496492924)), ((-60.34528188856285 -51.86083596448013, -60.310835888530775 -51.81139096443408, -60.25749988848111 -51.77486396440007, -60.222781888448765 -51.7877819644121, -60.18284588841158 -51.75785496438422, -60.178481888407504 -51.71222696434173, -
 60.201117888428584 -51.70333596433345, -60.22749988845317 -51.70028196433061, -60.35610888857293 -51.711317964340886, -60.38556388860037 -51.744726964372, -60.445281888655984 -51.76249996438855, -60.5561178887592 -51.77555496440071, -60.63437288883209 -51.72499996435363, -60.638408888835855 -51.67972696431146, -60.61389088881302 -51.671108964303436, -60.57722688877887 -51.68528196431664, -60.55722688876024 -51.69306396432388, -60.52472688872997 -51.69944496432983, -60.48861788869634 -51.702781964332935, -60.45722688866711 -51.70222696433242, -60.43625488864758 -51.697090964327636, -60.39939088861324 -51.67999996431172, -60.36472688858096 -51.66749996430008, -60.34389088856156 -51.66528196429801, -60.248890888473085 -51.665554964298266, -60.163608888393654 -51.67111796430344, -60.29444588851551 -51.59861796423592, -60.40444588861796 -51.55139096419194, -60.390626888605084 -51.4922909641369, -60.40391788861746 -51.46865496411488, -60.448126888658635 -51.44507296409292, -60.50555488871
 211 -51.43652696408496, -60.55500888875818 -51.437435964085815, -60.62201788882058 -51.41152696406168, -60.643617888840694 -51.358054964011885, -60.60694588880655 -51.34861796400309, -60.48360888869168 -51.38528196403724, -60.39744588861143 -51.42349996407283, -60.333617888551984 -51.45555496410269, -60.3133358885331 -51.46333596410993, -60.25583588847955 -51.48111796412649, -60.22264588844864 -51.486672964131664, -60.12722688835977 -51.49472696413917, -59.992363888234166 -51.46562696411207, -60.04291788828125 -51.45069996409816, -60.0624998882995 -51.42083596407035, -60.023199888262894 -51.38125496403349, -59.89417288814272 -51.37236396402521, -59.87028188812047 -51.38110896403335, -59.825835888079084 -51.40722696405768, -59.82389088807727 -51.43322696408189, -59.777781888034326 -51.44694496409467, -59.750835888009235 -51.44917296409674, -59.5136178877883 -51.46194496410864, -59.45861788773708 -51.45806396410502, -59.39535488767817 -51.43104496407986, -59.41667288769801 -51.4141729
 6406414, -59.442154887721756 -51.40479096405541, -59.44889088772803 -51.35833596401214, -59.399799887682306 -51.33764496399287, -59.21167288750709 -51.40819996405858, -59.39833588768094 -51.60264496423967, -59.431945887712246 -51.62333596425894, -59.454235887733006 -51.62104496425681, -59.57778188784806 -51.68833596431948, -59.67361788793731 -51.771663964397085, -59.83167288808451 -51.8933359645104, -59.93194588817791 -51.968608964580504, -59.953054888197556 -51.98306396459397, -60.06486388830169 -51.940563964554386, -60.18999988841824 -51.97833596458956, -60.27250888849508 -52.04361796465036, -60.26451788848763 -52.07089996467577, -60.280554888502564 -52.09611796469925, -60.31444588853414 -52.1294449647303, -60.368054888584055 -52.15917296475798, -60.598617888798785 -52.24222696483533, -60.62458188882297 -52.243199964836236, -60.657363888853496 -52.22778196482188, -60.73528188892607 -52.17778196477531, -60.86278188904481 -52.119444964720984, -60.98083588915476 -52.06195496466744, -
 60.91111788908982 -52.03110896463871, -60.82020888900516 -52.033754964641176, -60.75041788894016 -52.00659996461589, -60.813408888998836 -51.99264496460289, -60.84403588902735 -51.9619449645743, -60.76611788895478 -51.95583596456861, -60.70722688889994 -51.96167296457404, -60.67583588887071 -51.968890964580766, -60.64110888883836 -51.975008964586465, -60.53389088873851 -51.97749996458879, -60.45972688866944 -51.97083596458258, -60.43972688865081 -51.96208196457442, -60.40649988861986 -51.92409996453905, -60.42444588863658 -51.911944964527734, -60.44944588865987 -51.88305496450083, -60.45403588866414 -51.80583596442891, -60.44034588865139 -51.782844964407495, -60.38125488859636 -51.76653596439231, -60.363199888579544 -51.8064639644295, -60.37610888859156 -51.83459096445569, -60.34528188856285 -51.86083596448013)), ((-60.99305488916613 -51.96583596457792, -61.02944588920003 -51.94722696456059, -61.112154889277065 -51.89541796451234, -61.14805488931049 -51.84639096446668, -61.139163889
 30221 -51.835281964456335, -61.12264588928683 -51.821390964443395, -61.01306388918478 -51.779726964404595, -60.99917288917183 -51.77847296440343, -60.96805488914285 -51.78110896440588, -60.938545889115375 -51.80680896442982, -60.945554889121894 -51.81917296444133, -60.95667288913225 -51.826117964447796, -60.994172889167174 -51.83861796445944, -61.01389088918555 -51.84806396446824, -61.03076388920125 -51.86590896448486, -61.01639988918788 -51.869726964488414, -60.97278188914726 -51.86028196447962, -60.94944588912553 -51.853335964473146, -60.92694588910457 -51.84528196446565, -60.9072268890862 -51.836390964457365, -60.89083588907094 -51.825835964447535, -60.87528188905645 -51.83999996446073, -60.86847288905011 -51.906108964522296, -60.88110888906188 -51.93444496454869, -60.91222688909086 -51.94389096455748, -60.96805488914285 -51.95972696457223, -60.99305488916613 -51.96583596457792)), ((-60.28526388850696 -51.37564496402826, -60.27944588850154 -51.36361796401706, -60.28917288851059 -
 51.28583596394462, -60.299172888519905 -51.274444963934016, -60.29097288851227 -51.26652696392664, -60.273199888495725 -51.26514496392535, -60.07944588831528 -51.30083596395859, -60.06806388830468 -51.3074999639648, -60.0483358882863 -51.33333596398886, -60.05278188829044 -51.34667296400128, -60.11360888834709 -51.40680896405729, -60.24986388847398 -51.403199964053925, -60.268335888491194 -51.39805496404914, -60.285135888506844 -51.38403596403608, -60.28526388850696 -51.37564496402826)), ((-59.791390888047005 -51.24945496391074, -59.73194588799164 -51.2530639639141, -59.58361788785349 -51.25750896391824, -59.48319988775998 -51.26389096392418, -59.47306388775054 -51.26778196392781, -59.45083588772984 -51.30555496396299, -59.44555488772491 -51.320281963976704, -59.467781887745616 -51.335281963990674, -59.50833588778339 -51.33749996399274, -59.53833588781133 -51.33749996399274, -59.55749988782918 -51.336672963991965, -59.57361788784418 -51.33361796398912, -59.802363888057215 -51.274590
 96393415, -59.81110888806536 -51.26972696392962, -59.80514588805981 -51.25499996391591, -59.791390888047005 -51.24945496391074)))	
-GUF	French Guiana	MULTIPOLYGON (((-54.60378188321566 2.3291910859882705, -54.499172883118234 2.3650000860216096, -54.420563883045034 2.434718086086548, -54.365908882994134 2.49660008614417, -54.35195488298113 2.5238910861695985, -54.32180888295305 2.5984730862390535, -54.31513588294685 2.629164086267636, -54.25695488289266 2.7188910863512064, -54.222917882860955 2.755554086385345, -54.20459088284389 2.775000086403452, -54.19528188283522 2.796245086423241, -54.16083588280314 2.9536090865697986, -54.176117882817366 3.043891086653886, -54.19574588283565 3.096200086702595, -54.2084728828475 3.124309086728772, -54.206117882845305 3.14528208674831, -54.187226882827716 3.1948640867944818, -54.11875488276395 3.27778208687171, -54.09445488274132 3.2950000868877396, -54.07110888271957 3.3127820869043063, -54.00110888265438 3.4483360870305546, -53.986117882640414 3.601527087173224, -53.99778188265128 3.626945087196887, -54.12764588277223 3.788609087347453, -54.14639088278969 3.7977820873559978
 , -54.18868188282907 3.808745087366205, -54.29028188292369 3.9338910874827633, -54.36076388298933 4.042427087583846, -54.365008882993294 4.163609087696699, -54.39389088302019 4.237218087765257, -54.43139988305512 4.369164087888137, -54.44023588306335 4.410645087926767, -54.45180888307412 4.512364088021499, -54.442917883065846 4.530691088038566, -54.42326388304754 4.5643090880698765, -54.42209088304645 4.601527088104547, -54.439726883062875 4.669164088167534, -54.47333588309418 4.734582088228464, -54.47778188309832 4.7541640882466965, -54.47610888309676 4.867773088352507, -54.45528188307736 5.004027088479404, -54.448063883070645 5.0241640884981535, -54.4086178830339 5.08055408855067, -54.37889088300622 5.112218088580164, -54.347781882977245 5.148336088613803, -54.317326882948876 5.208627088669942, -54.28348188291736 5.254864088713006, -54.244999882881515 5.2850000887410715, -54.19333588283341 5.315273088769274, -54.17069988281233 5.342218088794368, -54.16668188280859 5.34740008879919
 1, -54.1398638827836 5.357782088808861, -54.091663882738715 5.3919450888406715, -54.06959088271816 5.4180540888649915, -54.058199882707555 5.437364088882973, -54.006735882659626 5.5447910889830325, -54.003890882656975 5.575691089011798, -54.0111178826637 5.605973089040006, -54.00569988265866 5.641527089073122, -53.99222688264611 5.673054089102479, -53.981672882636275 5.690554089118777, -53.93972688259721 5.7447180891692255, -53.91139088257083 5.750282089174405, -53.858608882521665 5.755418089179187, -53.7508358824213 5.731391089156816, -53.63667288231497 5.673054089102479, -53.52236388220851 5.60471808903884, -53.49917288218691 5.58028208901608, -53.49433588218241 5.572345089008692, -53.48360888217242 5.56805408900469, -53.40833588210232 5.548891088986849, -53.30278188200401 5.52305408896278, -53.18639088189562 5.499164088940532, -53.084445881800676 5.483336088925796, -52.97319988169707 5.473054088916214, -52.93778188166408 5.458336088902513, -52.88652688161635 5.420282088867069, -5
 2.799726881535506 5.341945088794105, -52.78750888152413 5.321945088775479, -52.736390881476524 5.260554088718308, -52.611117881359846 5.129445088596199, -52.56750888131924 5.096664088565674, -52.42222688118393 4.99250008846866, -52.330699881098695 4.948891088428056, -52.28972688106053 4.938400088418277, -52.06444588085073 4.733891088227821, -52.02347288081256 4.685691088182921, -51.99694588078785 4.6430540881432165, -51.985281880776995 4.613609088115794, -51.97805488077026 4.586945088090957, -51.95625488074995 4.492364088002873, -51.950835880744904 4.456664087969628, -51.950835880744904 4.423891087939111, -51.96041788075385 4.400136087916977, -52.001254880791876 4.368891087887889, -52.029035880817744 4.352364087872488, -52.04069988082861 4.334582087855935, -51.99194588078319 4.348191087868599, -51.951181880745224 4.372636087891365, -51.92819988072384 4.400836087917639, -51.923617880719576 4.4270820879420825, -51.92639088072215 4.465282087977656, -51.929308880724875 4.486809087997699
 , -51.931399880726815 4.529164088037149, -51.931399880726815 4.570000088075176, -51.92444588072033 4.620973088122653, -51.91555488071205 4.646527088146456, -51.900008880697584 4.66180908816068, -51.8615998806618 4.659309088158352, -51.794445880599255 4.605554088108292, -51.76701788057372 4.5376360880450335, -51.75917288056641 4.500282088010252, -51.75639088056383 4.477218087988774, -51.75249988056021 4.455282087968342, -51.74417288055244 4.4211090879365145, -51.71389088052425 4.3129180878357545, -51.70249988051364 4.287082087811697, -51.6744458804875 4.253336087780269, -51.65569988047005 4.225418087754264, -51.648472880463316 4.200282087730855, -51.64805488046292 4.167218087700064, -51.65222688046683 4.1372180876721245, -51.66104588047503 4.081109087619865, -51.6744458804875 4.049445087590371, -51.68406388049647 4.034164087576144, -51.70417288051519 4.026109087568642, -51.728335880537685 4.01583608755908, -51.7538908805615 4.000554087544842, -51.77180888057819 3.9834730875289353, -5
 1.78361788058919 3.961109087508106, -51.79389088059875 3.916664087466714, -51.81232688061593 3.876818087429612, -51.906390880703526 3.7908360873495326, -51.927081880722795 3.7769450873365855, -51.98104588077305 3.7000000872649252, -51.9900088807814 3.657500087225344, -51.995835880786814 3.6258360871958644, -52.1002818808841 3.448891087031072, -52.16528188094463 3.342218086931723, -52.226745881001875 3.253054086848678, -52.24965488102322 3.2437450868400077, -52.27360888104552 3.2410450868375023, -52.34493588111195 3.157400086759594, -52.353054881119505 3.1316640867356256, -52.34486388111188 3.0884730866954015, -52.35195488111849 3.0400000866502523, -52.37917288114383 2.9741640865889423, -52.40861788117125 2.9222180865405676, -52.46417288122299 2.8133360864391648, -52.519726881274735 2.697782086331543, -52.55278188130552 2.6212450862602594, -52.539863881293485 2.586391086227806, -52.54222688129569 2.565554086208394, -52.563754881315745 2.522082086167913, -52.59445488134433 2.473891086
 1230323, -52.67562688141993 2.3741640860301487, -52.78945488152594 2.3033360859641903, -52.88278188161286 2.22471808589097, -52.89646388162561 2.2068090858742835, -52.95472688167986 2.176182085845767, -52.99430888171672 2.175691085845301, -53.054863881773116 2.1869450858557826, -53.06959088178684 2.2030540858707894, -53.087363881803384 2.2194450858860506, -53.11180888182615 2.222500085888896, -53.196108881904664 2.21360908588062, -53.23917288194477 2.2083360858757146, -53.2261088819326 2.26444508592796, -53.296535881998196 2.3190090859787773, -53.319863882019916 2.3479820860057714, -53.340563882039206 2.3496540860073196, -53.34833588204644 2.3227090859822255, -53.45861788214914 2.2575000859214924, -53.52778188221356 2.249509085914056, -53.7016638823755 2.3102820859706554, -53.72153588239401 2.3417360859999548, -53.74610888241689 2.3709730860271776, -53.77680888244548 2.3645820860212297, -53.79944588246657 2.3523640860098425, -53.91028188256979 2.2772180859398645, -53.92806388258636 
 2.2527820859171044, -53.93263588259062 2.2280540858940725, -54.10965488275548 2.113473085787362, -54.32055488295188 2.1615270858321196, -54.4646548830861 2.211736085878883, -54.51861788313634 2.2575000859214924, -54.527226883144365 2.2893090859511176, -54.541326883157495 2.3152090859752406, -54.57389088318783 2.3252820859846253, -54.59361788320619 2.329718085988759, -54.60378188321566 2.3291910859882705)))	
-GUY	Guyana	MULTIPOLYGON (((-58.1726178865394 6.812218090163412, -58.154935886522935 6.828191090178279, -58.03889088641486 6.815554090166515, -57.98639088636597 6.790554090143232, -57.966672886347595 6.775418090129136, -57.94333588632587 6.750554090105979, -57.92778188631138 6.731664090088387, -57.91445488629897 6.711109090069243, -57.897917886283565 6.689864090049454, -57.88250888626922 6.674164090034836, -57.757781886153055 6.570000089937821, -57.64069988604402 6.485136089858784, -57.5943088860008 6.4345820898117125, -57.5213908859329 6.290345089677373, -57.519190885930854 6.270764089659139, -57.498617885911685 6.338682089722397, -57.469717885884776 6.34027308972388, -57.363617885785956 6.290000089677051, -57.33667288576086 6.2747180896628265, -57.261117885690496 6.2113910896038504, -57.22028188565247 6.169164089564518, -57.194308885628274 6.1393090895367095, -57.17778188561289 6.108336089507873, -57.16236388559852 6.056945089460001, -57.13576388557375 5.954100089364232, -57.175281
 88561056 5.637500089069363, -57.182781885617544 5.600691089035081, -57.195563885629454 5.568891089005476, -57.24850888567876 5.486109088928373, -57.27159988570027 5.384864088834078, -57.2994458857262 5.359718088810666, -57.32444588574948 5.303609088758407, -57.282781885710676 5.226391088686498, -57.26222688569153 5.22166408868209, -57.23520888566637 5.259945088717743, -57.20750888564058 5.223609088683901, -57.19104588562524 5.172009088635846, -57.231526885662944 5.146454088612046, -57.25055488568066 5.172636088636423, -57.27209088570072 5.177082088640574, -57.292363885719595 5.166245088630475, -57.321945885747155 5.075973088546405, -57.32722688575207 5.026109088499965, -57.41709088583576 4.989445088465814, -57.4736178858884 4.989164088465557, -57.61098188601633 4.992218088468405, -57.63417288603793 5.000282088475913, -57.67625488607713 5.011527088486389, -57.84111788623066 4.927782088408392, -57.901390886286805 4.855554088341123, -57.92333588630724 4.821945088309818, -57.92486388630
 866 4.796391088286029, -57.909026886293915 4.777782088268694, -57.88778188627413 4.7683360882599, -57.84035488622996 4.669027088167411, -57.8469458862361 4.6288910881300325, -57.902781886288096 4.503609088013349, -57.94861788633078 4.349164087869511, -57.9491728863313 4.317218087839763, -57.954517886336276 4.288336087812866, -58.00278188638123 4.239718087767585, -58.039172886415116 4.211391087741205, -58.0618088864362 4.180136087712086, -58.071399886445136 4.15569108768932, -58.04375488641939 4.001527087545753, -58.01639988639391 3.9636090875104344, -57.96889088634967 3.9291640874783553, -57.95041788633246 3.913191087463474, -57.93194588631526 3.8906910874425193, -57.876672886263776 3.8091640873665966, -57.86749988625523 3.7908360873495326, -57.85945488624775 3.771664087331672, -57.84930888623829 3.7388910873011554, -57.84597288623519 3.692636087258066, -57.83848188622821 3.6693090872363427, -57.8166728862079 3.6502820872186277, -57.76056388615565 3.624164087194302, -57.740835886137
 276 3.613745087184597, -57.66861788607001 3.5383360871143736, -57.65444588605682 3.518609087095996, -57.63840888604189 3.457009087038628, -57.65778188605992 3.4138910869984755, -57.642226886045435 3.3563910869449245, -57.61041788601581 3.3600000869482756, -57.53055488594143 3.3463910869356113, -57.42945488584728 3.3472180869363797, -57.304172885730594 3.380418086967296, -57.28354588571139 3.318682086909803, -57.29249988571972 3.2673640868620026, -57.28999988571739 3.181391086781943, -57.28361788571145 3.140973086744296, -57.255008885684816 3.103609086709497, -57.22028188565247 3.0650000866735354, -57.210281885643155 3.035836086646384, -57.207217885640304 3.004236086616956, -57.213335885646 2.878891086500218, -57.20083588563436 2.8228450864480124, -57.11688188555617 2.757191086386868, -56.94472688539584 2.4830540861315598, -56.917781885370744 2.428054086080337, -56.853890885311245 2.283336085945564, -56.810563885270895 2.1933360858617448, -56.77499988523776 2.1408360858128503, -56.68
 209088515124 2.0267640857066027, -56.64611788511773 2.028054085707808, -56.579726885055905 2.0273640857071626, -56.55597288503378 2.020554085700823, -56.47736388496057 1.9620820856463723, -56.470635884954305 1.944500085629997, -56.52555488500545 1.9225000856094994, -56.57791788505422 1.9216640856087253, -56.59499988507012 1.9322180856185582, -56.628199885101054 1.9394450856252803, -56.73500888520053 1.9141000856016746, -56.75209088521643 1.896945085585699, -56.77069088523376 1.8756270855658528, -56.87389088532987 1.8916640855807856, -57.00389088545094 1.9229180856098935, -57.050835885494664 1.9522180856371847, -57.06083588550398 1.984164085666933, -57.07423588551646 2.015764085696361, -57.10020888554064 2.0227820857029, -57.163063885599186 1.9966640856785745, -57.199172885632805 1.9711090856547742, -57.235345885666504 1.9497910856349279, -57.27667288570498 1.979509085662599, -57.298190885725035 1.9819450856648615, -57.33194588575647 1.9722180856558111, -57.42549088584359 1.901391085
 5898501, -57.42805488584597 1.8712450855617675, -57.450908885867264 1.8111090855057626, -57.512363885924486 1.730836085431008, -57.52806388593912 1.7158360854170382, -57.55930888596821 1.6997180854020257, -57.63333588603716 1.6927820853955637, -57.65361788605604 1.6966640853991777, -57.68749988608759 1.707500085409265, -57.72249988612019 1.7175000854185782, -57.75944588615461 1.717845085418901, -57.87610888626325 1.6650000853696838, -57.97249988635302 1.6134730853217008, -57.98291788636273 1.5723640852834109, -58.00715488638531 1.5156910852306282, -58.127781886497644 1.5177820852325823, -58.26833588662855 1.570554085281728, -58.29722688665545 1.5827820852931183, -58.387290886739336 1.4778450851953835, -58.50229088684644 1.454673085173809, -58.46930888681571 1.3584730850842135, -58.46764588681417 1.3376360850648013, -58.47514588682115 1.3140270850428237, -58.51961788686258 1.2696180850014542, -58.57249988691183 1.2752820850067366, -58.69299088702404 1.2847180850155269, -58.7088908870
 3885 1.2629180849952206, -58.722917887051906 1.2323640849667612, -58.751945887078946 1.209582084945552, -58.810699887133666 1.1868730849244002, -58.8363998871576 1.1902820849275741, -58.86959088718851 1.2050000849412754, -58.89840888721535 1.2311090849655955, -58.89736388721437 1.261836084994215, -58.92486388723998 1.2993090850291082, -58.95750888727039 1.3144450850432037, -58.97278188728461 1.3197180850481232, -59.104726887407494 1.3447180850714062, -59.24396388753718 1.3865270851103446, -59.41445488769595 1.5633360852750116, -59.48361788776036 1.6505540853562337, -59.50750888778262 1.6875000853906386, -59.6054178878738 1.7194450854203893, -59.64576388791137 1.735136085435002, -59.675281887938866 1.7670820854647644, -59.653617887918685 1.8022180854974863, -59.632472887899 1.8422360855347506, -59.7263178879864 1.854164085545861, -59.74902688800755 1.8613910855525972, -59.75625488801428 1.908891085596835, -59.743617888002504 2.0727820857494663, -59.727017887987046 2.241245085906357, 
 -59.73549088799494 2.2847180859468494, -59.79319988804869 2.297782085959014, -59.84972688810133 2.330554085989533, -59.893263888141874 2.3641000860207697, -59.901672888149704 2.384445086039719, -59.88889088813781 2.407082086060811, -59.89278188814143 2.4544450861049114, -59.925563888171965 2.567782086210471, -59.9541728881986 2.616391086255746, -59.98847288823055 2.688191086322604, -59.98278188822525 2.860282086482883, -59.97889088822163 2.899164086519093, -59.96278188820662 3.025836086637071, -59.949717888194456 3.071945086680003, -59.90472688815255 3.2041640868031465, -59.869726888119956 3.2763910868704187, -59.85611788810728 3.2977820868903365, -59.83569988808827 3.322082086912971, -59.810835888065114 3.3595820869478956, -59.81444588806848 3.498745087077495, -59.831945888084775 3.5241640871011697, -59.786117888042085 3.620554087190939, -59.6655548879298 3.711391087275544, -59.56860888783952 3.8994450874506725, -59.58167288785168 3.9988910875432992, -59.70861788796991 4.1706910877
 0329, -59.722226887982586 4.191391087722579, -59.73110888799086 4.219164087748439, -59.73083588799061 4.293336087817522, -59.675281887938866 4.373336087892028, -59.67444588793809 4.385136087903007, -59.71722688797793 4.414164087930047, -59.79111788804674 4.456109087969111, -59.94180888818708 4.508054088017488, -59.96778188821128 4.501945088011794, -60.045281888283455 4.4940270880044295, -60.13069988836301 4.509718088019042, -60.14847288837956 4.52000008802861, -60.152226888383055 4.5733360880782925, -60.12389088835667 4.596664088100013, -60.09152688832653 4.600691088103758, -60.07209088830842 4.618473088120325, -60.02583588826535 4.707218088202978, -60.02056388826044 4.734445088228327, -60.00583588824672 4.8369450883237874, -59.983063888225516 5.022500088496599, -60.013890888254224 5.11000008857809, -60.080872888316605 5.161509088626062, -60.081945888317605 5.1730540886368175, -60.09833588833287 5.217218088677953, -60.114581888348 5.245691088704461, -60.202363888429744 5.27270908872
 9627, -60.24999988847412 5.2584730887163715, -60.268408888491265 5.235282088694774, -60.317845888537306 5.197636088659706, -60.54639088875015 5.191391088653901, -60.5738268887757 5.197154088659261, -60.597426888797685 5.211945088673033, -60.689445888883384 5.216109088676916, -60.730372888921494 5.2048000886663885, -60.748890888938746 5.222500088682864, -60.781108888968745 5.2583360887162485, -60.86028188904248 5.348054088799799, -61.11610888928074 5.63471808906678, -61.38972688953557 5.940000089351088, -61.37345488952042 5.960973089370626, -61.3378908894873 5.972782089381624, -61.32306388947349 5.992500089399982, -61.282817889436004 6.056336089459435, -61.270281889424325 6.086391089487435, -61.26278188941734 6.107782089507353, -61.160145889321754 6.1825000895769335, -61.1386178893017 6.29916408968559, -61.140008889303004 6.408609089787518, -61.19652688935564 6.533682089904005, -61.20472688936327 6.5779180899452, -61.174445889335075 6.658745090020474, -61.12510888928912 6.71477309007
 2654, -61.05472688922357 6.72889109008581, -61.03597288920611 6.719718090077265, -60.93965488911641 6.724582090081796, -60.89368188907359 6.765000090119429, -60.81611788900135 6.788336090141172, -60.71917288891106 6.759027090113875, -60.69778188889114 6.766664090120983, -60.676390888871225 6.790000090142712, -60.66499988886062 6.80750009015901, -60.63778188883526 6.834927090184564, -60.590835888791545 6.85083609019938, -60.526945888732044 6.87471809022162, -60.498890888705915 6.8877820902337845, -60.463617888673056 6.906664090251368, -60.40833588862158 6.947500090289395, -60.29125488851254 7.056600090391015, -60.28139088850335 7.090000090422109, -60.278054888500236 7.118745090448883, -60.309035888529095 7.143473090471915, -60.33667288855483 7.155282090482913, -60.36049088857702 7.176245090502434, -60.45611788866607 7.195836090520686, -60.50576388871231 7.17270909049914, -60.51499988872092 7.142982090471463, -60.5380638887424 7.124445090454188, -60.61749988881638 7.19444509051938, -6
 0.6308358888288 7.221945090544992, -60.63423588883197 7.254309090575134, -60.61861788881741 7.2840270906028195, -60.595354888795754 7.30610909062338, -60.59139088879206 7.336391090651588, -60.6099998888094 7.381945090694003, -60.66083588885674 7.447218090754802, -60.688263888882275 7.453473090760625, -60.714026888906275 7.500973090804862, -60.71666388890873 7.540000090841204, -60.691108888884926 7.567082090866435, -60.662090888857904 7.566527090865918, -60.58875488878961 7.639309090933693, -60.57458188877641 7.7152090910043825, -60.533335888737994 7.803891091086982, -60.51319988871924 7.818191091100289, -60.31972688853905 7.877500091155525, -60.25754588848115 7.921573091196578, -60.23722688846222 7.946391091219695, -60.12486388835757 8.028327091296006, -60.09360888832846 8.041245091308028, -60.03778188827647 8.037009091304085, -60.0111818882517 8.059236091324792, -59.98701788822919 8.1469820914065, -59.9797268882224 8.174864091432468, -59.94618188819116 8.199991091455871, -59.922226
 88816885 8.211109091466227, -59.88889088813781 8.218609091473212, -59.83285488808562 8.231527091485248, -59.80305488805786 8.2833360915335, -59.81209088806628 8.306109091554703, -59.88611788813522 8.40083609164293, -59.98111788822369 8.518327091752354, -59.99028188823223 8.535273091768133, -59.95819988820236 8.514027091748346, -59.92930888817544 8.48416409172053, -59.902572888150544 8.445764091684765, -59.88945488813833 8.421664091662322, -59.87250888812255 8.397218091639559, -59.85583588810702 8.379445091622998, -59.83167288808451 8.361664091606443, -59.78625488804222 8.340973091587173, -59.76472688802217 8.349027091594678, -59.77930888803574 8.380973091624426, -59.764208888021685 8.407364091649, -59.6683358879324 8.360000091604888, -59.6508358879161 8.349445091595058, -59.35583588764136 8.173891091431571, -59.15472688745406 8.05639109132214, -59.12930888743038 8.040000091306865, -59.109445887411894 8.018473091286822, -59.09347288739701 7.987009091257519, -59.07583588738059 7.96916
 40912408985, -58.94389088725771 7.851109091130951, -58.80694588713017 7.730554091018675, -58.76889088709473 7.679718090971335, -58.751399887078435 7.6361090909307165, -58.71736388704673 7.59437309089185, -58.6419458869765 7.569445090868626, -58.48528188683059 7.368609090681588, -58.46854588681501 7.337573090652683, -58.465563886812234 7.135836090464807, -58.46666388681325 7.115000090445392, -58.4815268868271 7.009927090347546, -58.497508886841985 6.989445090328459, -58.51074588685431 6.980254090319903, -58.53709088687884 6.96069109030168, -58.55569988689618 6.937500090280082, -58.56305488690302 6.916391090260433, -58.59403588693188 6.801809090153711, -58.598608886936134 6.774309090128099, -58.60917288694597 6.656664090018538, -58.619090886955206 6.489491089862852, -58.637090886971976 6.421945089799934, -58.600726886938105 6.413945089792492, -58.59333588693123 6.420000089798123, -58.58132688692004 6.464973089840015, -58.574026886913245 6.509864089881816, -58.57278188691208 6.53250008
 9902896, -58.576117886915185 6.562218089930582, -58.57319988691248 6.602636089968215, -58.54972688689061 6.6782640900386525, -58.47944588682516 6.794445090146851, -58.45695488680421 6.827782090177905, -58.41972688676954 6.870282090217486, -58.39833588674962 6.879309090225888, -58.3165998866735 6.894236090239801, -58.25569988661678 6.876109090222911, -58.208617886572924 6.843054090192126, -58.1726178865394 6.812218090163412)))	
-PCN	Pitcairn Is.	MULTIPOLYGON (((-128.33221795188064 -24.32726393883749, -128.3269359518757 -24.326117938836433, -128.31042695186034 -24.325835938836164, -128.30168195185217 -24.334445938844183, -128.29388195184492 -24.352499938861, -128.2866819518382 -24.38639093889256, -128.2861179518377 -24.40166393890678, -128.29111795184235 -24.411390938915844, -128.30156395185207 -24.411672938916112, -128.3130819518628 -24.404717938909627, -128.3278179518765 -24.390554938896443, -128.34308195189075 -24.367217938874703, -128.34695495189436 -24.353617938862044, -128.34600895189345 -24.33819993884768, -128.336945951885 -24.329163938839258, -128.33221795188064 -24.32726393883749)), ((-130.08139095350967 -25.082226939540604, -130.09068195351833 -25.080699939539187, -130.10262695352944 -25.074445939533362, -130.1050549535317 -25.061463939521275, -130.0905639535182 -25.055699939515904, -130.06384595349334 -25.06826393952761, -130.0769359535055 -25.079726939538276, -130.08139095350967 -25.082226939540
 604)))	
-SGS	South Georgia & the South Sandwich Is.	MULTIPOLYGON (((-36.99139086681285 -54.35056396679887, -36.99972686682062 -54.348617966797065, -37.05944586687622 -54.329999966779724, -37.08375486689886 -54.31881796676931, -37.08222686689746 -54.29389096674609, -37.146117866956956 -54.26139096671582, -37.241808867046075 -54.247363966702764, -37.266254867068824 -54.25875496671337, -37.365835867161564 -54.271944966725655, -37.408335867201146 -54.26493596671913, -37.403472867196626 -54.18500896664469, -37.367226867162884 -54.17556396663589, -37.33555486713337 -54.17361796663408, -37.25208186705564 -54.15229096661422, -37.48986386727708 -54.12944496659294, -37.56118186734349 -54.14607296660843, -37.52944586731394 -54.16250896662373, -37.56222686734449 -54.170563966631235, -37.58944586736982 -54.17528196663563, -37.650417867426626 -54.18167296664158, -37.68528186745908 -54.17528196663563, -37.71917286749064 -54.140563966603295, -37.71757286748917 -54.09416396656008, -37.676390867450806 -54.074
 717966541975, -37.653826867429785 -54.072154966539586, -37.61979086739808 -54.04611796651534, -37.69221786746553 -54.034999966504984, -37.89778186765699 -54.04722696651637, -38.02257286777322 -54.054726966523354, -38.0237548677743 -54.00743596647931, -37.93361786769037 -53.99222696646515, -37.91028186766863 -53.98972696646282, -37.74721786751675 -53.99499996646773, -37.49499986728188 -54.01056396648222, -37.46139986725058 -54.036117966506026, -37.37389086716908 -54.04805496651714, -37.27028186707258 -54.050281966519215, -37.162781866972466 -54.03139096650162, -37.02778186684674 -54.05611796652465, -36.80944586664339 -54.08833596655465, -36.65639086650086 -54.107781966572766, -36.62375486647045 -54.120699966584795, -36.584163866433585 -54.20889096666693, -36.66757286651128 -54.24409996669972, -36.662645866506665 -54.27514496672863, -36.62667286647317 -54.28361796673653, -36.604026866452074 -54.26611796672023, -36.55680886640812 -54.245563966701084, -36.517081866371115 -54.23445496669
 074, -36.47889086633555 -54.23889096669487, -36.47263586632971 -54.26513596671931, -36.456117866314344 -54.3275089667774, -36.36999986623414 -54.35499996680301, -36.33667286620309 -54.35229096680048, -36.362090866226765 -54.293054966745316, -36.38368186624686 -54.27826396673154, -36.394799866257216 -54.24917296670444, -36.290208866159816 -54.26583596671996, -36.257226866129116 -54.28666396673936, -36.22917286610297 -54.33778196678697, -36.25610886612807 -54.36847296681555, -36.15999986603856 -54.44472696688657, -36.09680886597971 -54.54959096698423, -36.06389086594905 -54.57153596700467, -35.979726865870674 -54.57889096701152, -35.93471786582873 -54.62306396705266, -35.933890865827976 -54.700563967124836, -35.917363865812575 -54.715144967138414, -35.85667286575605 -54.74305496716441, -35.8280548657294 -54.75083596717165, -35.79396386569766 -54.76020896718038, -35.82778186572915 -54.79278196721072, -35.914172865809604 -54.81347296722999, -35.95944586585176 -54.81110896722779, -35.979
 726865870674 -54.80917296722598, -36.0006998658902 -54.80083596721822, -36.02528186591309 -54.787781967206065, -36.04583586593222 -54.77889096719778, -36.074717865959116 -54.768054967187695, -36.095308865978296 -54.76993596718945, -36.02111786590922 -54.81721796723348, -35.98972686587999 -54.8305549672459, -35.96430886585631 -54.83167296724694, -35.923617865818414 -54.8504179672644, -35.96139986585359 -54.86944496728212, -36.07639086596069 -54.890281967301526, -36.10472686598709 -54.88923596730055, -36.131463866011984 -54.8688909672816, -36.19917286607503 -54.80917296722598, -36.29749986616662 -54.733335967155355, -36.30250886617128 -54.71305496713647, -36.31721786618496 -54.686954967112165, -36.46860886632598 -54.52889096696495, -36.525908866379325 -54.497081966935326, -36.582226866431796 -54.49986396693792, -36.65555486650007 -54.491108966929765, -36.736945866575866 -54.47028196691037, -36.809799866643715 -54.44541796688721, -36.801108866635644 -54.41118196685533, -36.864935866695
 08 -54.34652696679511, -36.92528186675128 -54.337917966787096, -36.99139086681285 -54.35056396679887)), ((-26.248890856808117 -58.49860897066204, -26.264163856822336 -58.48806397065222, -26.290972856847304 -58.47861797064343, -26.37167285692246 -58.46305497062893, -26.389726856939262 -58.45972697062583, -26.406526856954912 -58.45944497062557, -26.41999985696748 -58.45667297062299, -26.458199857003052 -58.430699970598795, -26.433608856980157 -58.38916397056011, -26.416663856964362 -58.38360897055494, -26.403890856952472 -58.382508970553914, -26.39305485694237 -58.38278197055417, -26.317781856872273 -58.38639097055753, -26.29152685684781 -58.38806397055909, -26.265699856823773 -58.39417297056478, -26.246672856806043 -58.404444970574346, -26.241390856801132 -58.47167297063696, -26.243617856803212 -58.49472697065843, -26.248890856808117 -58.49860897066204)))	
-SHN	St. Helena	MULTIPOLYGON (((-5.712972837682543 -15.992863931075476, -5.729163837697627 -16.005490931087238, -5.768472837734237 -16.021945931102564, -5.787217837751683 -16.009163931090654, -5.792781837756877 -15.991108931073839, -5.768890837734631 -15.94736393103311, -5.748608837715722 -15.929163931016149, -5.728890837697378 -15.91389093100193, -5.716390837685736 -15.905281930993908, -5.699517837670015 -15.903754930992491, -5.671390837643827 -15.90944593099779, -5.645281837619507 -15.93999993102625, -5.646390837620544 -15.958335931043322, -5.660417837633588 -15.985690931068802, -5.700417837670841 -16.003754931085624, -5.7105548376802915 -15.996390931078764, -5.712972837682543 -15.992863931075476)))	
-SUR	Suriname	MULTIPOLYGON (((-55.12796388370384 5.82217308924136, -55.10444588368195 5.839445089257438, -55.01610888359967 5.850418089267663, -54.946672883535 5.846109089263649, -54.86444588345843 5.855136089272051, -54.88729088347971 5.879545089294794, -54.9688908835557 5.873336089289012, -54.99534588358034 5.865764089281953, -55.10625488368363 5.904582089318112, -55.14472688371946 5.934164089345657, -55.15944588373317 5.9634000893728825, -55.047363883628776 6.001809089408653, -54.97028188355699 5.988054089395845, -54.87694588347007 5.985282089393266, -54.77944588337927 5.982500089390669, -54.70994588331453 5.962436089371991, -54.639163883248614 5.954718089364803, -54.34445488297415 5.906945089320303, -54.29861788293145 5.898054089312026, -54.204726882844014 5.879718089294954, -54.17860888281969 5.871391089287201, -54.02556388267716 5.818609089238038, -53.990208882644225 5.746945089171291, -54.00652688265943 5.721245089147359, -54.04646388269663 5.653536089084298, -54.0515358827013
 44 5.590209089025322, -54.05180888270159 5.527082088966537, -54.067781882716474 5.491527088933424, -54.095835882742605 5.458054088902244, -54.120490882765566 5.431600088877616, -54.142226882785806 5.39527308884378, -54.16668188280859 5.347400088799191, -54.17069988281233 5.342218088794368, -54.19333588283341 5.315273088769274, -54.244999882881515 5.2850000887410715, -54.28348188291736 5.254864088713006, -54.317326882948876 5.208627088669942, -54.347781882977245 5.148336088613803, -54.37889088300622 5.112218088580164, -54.4086178830339 5.08055408855067, -54.448063883070645 5.0241640884981535, -54.45528188307736 5.004027088479404, -54.47610888309676 4.867773088352507, -54.47778188309832 4.7541640882466965, -54.47333588309418 4.734582088228464, -54.439726883062875 4.669164088167534, -54.42209088304645 4.601527088104547, -54.42326388304754 4.5643090880698765, -54.442917883065846 4.530691088038566, -54.45180888307412 4.512364088021499, -54.44023588306335 4.410645087926767, -54.4313998830
 5512 4.369164087888137, -54.39389088302019 4.237218087765257, -54.365008882993294 4.163609087696699, -54.36076388298933 4.042427087583846, -54.29028188292369 3.9338910874827633, -54.18868188282907 3.808745087366205, -54.14639088278969 3.7977820873559978, -54.12764588277223 3.788609087347453, -53.99778188265128 3.626945087196887, -53.986117882640414 3.601527087173224, -54.00110888265438 3.4483360870305546, -54.07110888271957 3.3127820869043063, -54.09445488274132 3.2950000868877396, -54.11875488276395 3.27778208687171, -54.187226882827716 3.1948640867944818, -54.206117882845305 3.14528208674831, -54.2084728828475 3.124309086728772, -54.19574588283565 3.096200086702595, -54.176117882817366 3.043891086653886, -54.16083588280314 2.9536090865697986, -54.19528188283522 2.796245086423241, -54.20459088284389 2.775000086403452, -54.222917882860955 2.755554086385345, -54.25695488289266 2.7188910863512064, -54.31513588294685 2.629164086267636, -54.32180888295305 2.5984730862390535, -54.3519548
 8298113 2.5238910861695985, -54.365908882994134 2.49660008614417, -54.420563883045034 2.434718086086548, -54.499172883118234 2.3650000860216096, -54.60378188321566 2.3291910859882705, -54.63472688324448 2.3200730859797716, -54.687499883293626 2.3255540859848765, -54.709099883313755 2.3879180860429585, -54.69020888329615 2.3995090860537545, -54.68986388329583 2.4516000861022604, -54.75312688335475 2.4706270861199897, -54.77538188337547 2.456845086107151, -54.80375488340191 2.4380540860896502, -54.84749988344264 2.436109086087839, -54.86916388346282 2.44194508609327, -54.96944588355622 2.550554086194424, -55.091945883670306 2.53471808617968, -55.11194588368893 2.527218086172695, -55.50333588405344 2.438891086090436, -55.71368188424934 2.4001360860543315, -55.86409988438943 2.471454086120758, -55.88639088441019 2.49708208614463, -55.91750888443917 2.5206910861666074, -55.94180888446179 2.5305540861757976, -55.96278188448133 2.533054086178126, -55.98249988449969 2.522082086167913, -56.0
 0041788451638 2.4508360861015603, -56.08444588459464 2.3575000860146247, -56.11583588462388 2.2491640859137334, -56.03639088454989 2.208891085876232, -55.90396388442656 2.0477820857261833, -55.90173588442448 1.90104508558953, -55.94264588446258 1.856109085547672, -55.96583588448418 1.8452820855375904, -55.99597288451224 1.8376360855304625, -56.0274998845416 1.8362450855291712, -56.06806388457939 1.8455540855378416, -56.11333588462155 1.863609085554657, -56.201663884703805 1.8916640855807856, -56.326954884820495 1.9252820856120962, -56.426390884913104 1.9341640856203668, -56.470635884954305 1.944500085629997, -56.47736388496057 1.9620820856463723, -56.55597288503378 2.020554085700823, -56.579726885055905 2.0273640857071626, -56.64611788511773 2.028054085707808, -56.68209088515124 2.0267640857066027, -56.77499988523776 2.1408360858128503, -56.810563885270895 2.1933360858617448, -56.853890885311245 2.283336085945564, -56.917781885370744 2.428054086080337, -56.94472688539584 2.483054086
 1315598, -57.11688188555617 2.757191086386868, -57.20083588563436 2.8228450864480124, -57.213335885646 2.878891086500218, -57.207217885640304 3.004236086616956, -57.210281885643155 3.035836086646384, -57.22028188565247 3.0650000866735354, -57.255008885684816 3.103609086709497, -57.28361788571145 3.140973086744296, -57.28999988571739 3.181391086781943, -57.29249988571972 3.2673640868620026, -57.28354588571139 3.318682086909803, -57.304172885730594 3.380418086967296, -57.42945488584728 3.3472180869363797, -57.53055488594143 3.3463910869356113, -57.61041788601581 3.3600000869482756, -57.642226886045435 3.3563910869449245, -57.65778188605992 3.4138910869984755, -57.63840888604189 3.457009087038628, -57.65444588605682 3.518609087095996, -57.66861788607001 3.5383360871143736, -57.740835886137276 3.613745087184597, -57.76056388615565 3.624164087194302, -57.8166728862079 3.6502820872186277, -57.83848188622821 3.6693090872363427, -57.84597288623519 3.692636087258066, -57.84930888623829 3.738
 8910873011554, -57.85945488624775 3.771664087331672, -57.86749988625523 3.7908360873495326, -57.876672886263776 3.8091640873665966, -57.93194588631526 3.8906910874425193, -57.95041788633246 3.913191087463474, -57.96889088634967 3.9291640874783553, -58.01639988639391 3.9636090875104344, -58.04375488641939 4.001527087545753, -58.071399886445136 4.15569108768932, -58.0618088864362 4.180136087712086, -58.039172886415116 4.211391087741205, -58.00278188638123 4.239718087767585, -57.954517886336276 4.288336087812866, -57.9491728863313 4.317218087839763, -57.94861788633078 4.349164087869511, -57.902781886288096 4.503609088013349, -57.8469458862361 4.6288910881300325, -57.84035488622996 4.669027088167411, -57.88778188627413 4.7683360882599, -57.909026886293915 4.777782088268694, -57.92486388630866 4.796391088286029, -57.92333588630724 4.821945088309818, -57.901390886286805 4.855554088341123, -57.84111788623066 4.927782088408392, -57.67625488607713 5.011527088486389, -57.63417288603793 5.0002
 82088475913, -57.61098188601633 4.992218088468405, -57.4736178858884 4.989164088465557, -57.41709088583576 4.989445088465814, -57.32722688575207 5.026109088499965, -57.321945885747155 5.075973088546405, -57.292363885719595 5.166245088630475, -57.27209088570072 5.177082088640574, -57.25055488568066 5.172636088636423, -57.231526885662944 5.146454088612046, -57.19104588562524 5.172009088635846, -57.20750888564058 5.223609088683901, -57.23520888566637 5.259945088717743, -57.26222688569153 5.22166408868209, -57.282781885710676 5.226391088686498, -57.32444588574948 5.303609088758407, -57.2994458857262 5.359718088810666, -57.27159988570027 5.384864088834078, -57.24850888567876 5.486109088928373, -57.18430888561896 5.51889108895891, -57.16742688560325 5.541391088979864, -57.13889088557667 5.671664089101185, -57.13597288557395 5.6925000891205855, -57.13249988557071 5.767500089190435, -57.06791788551057 5.941736089352716, -56.992499885440324 5.989445089397137, -56.96444588541421 5.99708208940
 4259, -56.70056388516845 5.965554089374891, -56.60361788507815 5.940500089351559, -56.55445488503237 5.948336089358861, -56.48000888496304 5.945418089356139, -56.26056388475867 5.889164089303748, -56.01778188453255 5.818336089237789, -55.910554884432685 5.778364089200565, -55.89444588441769 5.730273089155773, -55.89860888442156 5.67444508910377, -55.89955488442244 5.671909089101419, -55.885972884409796 5.683054089111792, -55.87778188440217 5.717636089143994, -55.89110888441458 5.775836089198208, -55.922717884444026 5.876073089291552, -55.85583588438173 5.948891089359378, -55.8277818843556 5.958336089368174, -55.76806388429999 5.967218089376445, -55.62028188416235 5.974445089383167, -55.548617884095606 5.977782089386281, -55.4127818839691 5.964164089373597, -55.37722688393599 5.960000089369714, -55.33902688390042 5.950136089360527, -55.266672883833024 5.923609089335827, -55.25389088382113 5.915836089328593, -55.230563883799405 5.898054089312026, -55.174999883747645 5.9072180893205655
 , -55.11555488369228 5.876982089292397, -55.11402688369087 5.8400000892579556, -55.12796388370384 5.82217308924136)))	
-TTO	Trinidad & Tobago	MULTIPOLYGON (((-61.0794458892466 10.824164093899824, -61.075563889242986 10.826109093901636, -61.02541788919628 10.840273093914831, -60.92833588910587 10.838609093913277, -60.90923588908808 10.827009093902475, -60.92305488910094 10.797218093874733, -60.94445488912088 10.762218093842137, -60.96305488913819 10.739164093820662, -60.98722688916071 10.714718093797899, -61.01791788918929 10.698473093782766, -61.03417288920443 10.678191093763871, -61.0454178892149 10.489164093587831, -61.02097288919214 10.392218093497547, -60.99860888917131 10.351600093459723, -61.00444588917675 10.149582093271576, -61.083617889250476 10.102773093227981, -61.10722688927247 10.091945093217888, -61.15222688931438 10.075554093202626, -61.202917889361586 10.069164093196676, -61.405281889550054 10.066945093194605, -61.526672889663104 10.06833609319591, -61.67708188980319 10.076109093203144, -61.7055548898297 10.07889109320574, -61.80611788992336 10.0811090932078, -61.83361788994897 10.071
 391093198756, -61.858335889972 10.06221809319021, -61.88028188999243 10.042500093171839, -61.90951789001966 10.040345093169833, -61.92159989003092 10.064864093192668, -61.817781889934224 10.127773093251264, -61.6477818897759 10.19721809331594, -61.50409988964209 10.237636093353572, -61.46139088960231 10.274309093387728, -61.4537548895952 10.294164093406224, -61.46305488960385 10.571245093664274, -61.47361788961369 10.597773093688986, -61.49583588963439 10.63527309372391, -61.54625488968135 10.669445093755726, -61.60125488973257 10.684582093769833, -61.62291788975274 10.678891093764534, -61.65778188978521 10.680064093765623, -61.662017889789155 10.708400093792008, -61.60278188973399 10.74221809382351, -61.47999988961965 10.75055409383127, -61.42854588957172 10.753954093834437, -61.384590889530784 10.779718093858435, -61.24249988939846 10.790273093868265, -61.19639988935552 10.789445093867485, -61.17180888933261 10.79910009387649, -61.1433358893061 10.815273093891548, -61.079445889246
 6 10.824164093899824)), ((-60.79749988898402 11.14166409419552, -60.84493588902819 11.157218094210009, -60.847226889030324 11.176945094228373, -60.756672888945985 11.242218094289171, -60.70083588889399 11.275836094320482, -60.65778188885389 11.301391094344282, -60.5295908887345 11.345554094385406, -60.52083588872635 11.330554094371436, -60.52472688872997 11.273891094318671, -60.53180888873656 11.259027094304827, -60.64180888883901 11.202218094251919, -60.66889088886424 11.198891094248822, -60.68778188888183 11.201945094251656, -60.73875488892931 11.182636094233672, -60.758199888947416 11.171245094223067, -60.79749988898402 11.14166409419552)))	
-VEN	Venezuela	MULTIPOLYGON (((-66.3102908941182 10.626018093715288, -66.28309089409287 10.64465409373264, -66.22987289404331 10.640554093728824, -66.0816818939053 10.576664093669322, -66.11972689394072 10.500000093597919, -65.95861789379067 10.356664093464431, -65.93573589376938 10.298300093410077, -65.81445489365642 10.228336093344922, -65.0813908929737 10.060554093188657, -64.76445489267853 10.097218093222807, -64.73279089264904 10.113473093237943, -64.71473589263222 10.179718093299641, -64.62597289254956 10.246664093361986, -64.57972689250649 10.25860909337311, -64.48250889241595 10.238054093353966, -64.37854589231912 10.301109093412691, -64.39584589233523 10.337218093446324, -64.36805489230936 10.384164093490043, -64.18205489213612 10.456545093557452, -63.80944589178911 10.442218093544113, -63.697499891684856 10.485554093584469, -63.83889089181653 10.551664093646039, -63.966390891935276 10.578473093671008, -64.14868189210505 10.570000093663111, -64.20098189215375 10.550273093644
 748, -64.23569089218608 10.514373093611312, -64.29959089224559 10.626527093715765, -64.264590892213 10.657773093744865, -64.1468088921033 10.617918093707743, -63.84278189182015 10.645827093733743, -63.534445891533 10.627082093716282, -63.25306389127094 10.678336093764017, -63.17222689119565 10.719718093802555, -62.99375489102944 10.716391093799459, -62.90667289094833 10.695836093780315, -62.697499890753534 10.747773093828684, -62.19250889028322 10.694164093778753, -61.87959088999179 10.728327093810577, -61.88333588999528 10.694718093779272, -61.9530548900602 10.648891093736594, -62.0855548901836 10.627218093716408, -62.249172890335984 10.627009093716211, -62.331108890412295 10.531664093627413, -62.527226890594946 10.540418093635566, -62.64972689070903 10.568191093661426, -62.91229989095358 10.528745093624693, -63.0042358910392 10.45298209355414, -62.87250889091652 10.524445093620685, -62.83860889088494 10.511664093608786, -62.8377088908841 10.397291093502275, -62.87180889091586 10.3
 89864093495348, -62.934308890974066 10.418473093521996, -63.00368189103868 10.394164093499356, -62.998408891033776 10.271600093385217, -62.93417289097394 10.279309093392385, -62.946663890985576 10.400900093505626, -62.8847358909279 10.374391093480938, -62.790090890839764 10.401336093506032, -62.73639089078975 10.37381809348041, -62.66639089072456 10.280554093393548, -62.630626890691246 10.107154093232054, -62.669308890727265 10.075000093202107, -62.82917289087615 10.053609093182189, -62.95694589099516 10.104309093229404, -63.015972891050126 10.095691093221376, -62.983854891020215 10.068918093196444, -62.91056389095196 10.076945093203918, -62.805281890853905 10.00860909314028, -62.66278189072119 10.059164093187363, -62.6157638906774 10.093191093219048, -62.605417890667766 10.127218093250747, -62.62333589068446 10.188609093307917, -62.60944589067152 10.223954093340836, -62.577499890641775 10.22513609334193, -62.48889089055925 10.153054093274804, -62.42694589050156 9.979164093112857, -
 62.31518189039747 9.752845092902078, -62.32264589040442 9.712082092864122, -62.277226890362115 9.747500092897099, -62.23680889032447 9.855000092997216, -62.25049089033722 9.967009093101538, -62.205699890295506 9.914027093052198, -62.165345890257925 9.715282092867099, -62.19610889028657 9.641664092798536, -62.17076389026296 9.657427092813222, -62.130008890225014 9.752109092901392, -62.133499890228265 9.82644509297063, -62.02743589012948 9.866418093007852, -62.11222689020845 9.929445093066548, -62.20153589029162 9.938336093074838, -62.231735890319754 9.964718093099407, -62.2092358902988 10.011036093142536, -62.17889089027054 10.014718093145973, -62.05389089015412 9.977500093111303, -61.96222689006875 9.91194509305025, -61.81167288992853 9.757891092906789, -61.73583588985791 9.600936092760605, -61.73333588985558 9.698745092851695, -61.80091788991852 9.812273092957426, -61.79278188991094 9.83110909297497, -61.77194588989154 9.830273092974195, -61.59770888972926 9.782773092929958, -61.57
 458188970773 9.800691092946636, -61.64805488977615 9.897364093036671, -61.619863889749894 9.90528209304405, -61.48056388962017 9.823609092967985, -61.407226889551865 9.704718092857263, -61.255981889411004 9.588891092749392, -61.04333588921297 9.575554092736965, -60.98757288916103 9.551809092714848, -60.85361788903627 9.444445092614856, -60.79819988898467 9.379309092554195, -60.78361788897108 9.305000092484988, -60.81889088900394 9.26889109245137, -60.987781889161226 9.188609092376595, -61.08459088925139 9.097500092291739, -61.098126889263995 9.043954092241876, -60.972708889147185 9.175209092364113, -60.9504908891265 9.175136092364042, -61.031535889201976 9.032082092230823, -61.09778188926367 8.963336092166799, -61.183335889343354 8.727782091947418, -61.210208889368374 8.595136091823875, -61.25090888940629 8.581454091811139, -61.436672889579285 8.60166409182996, -61.51972688965664 8.590418091819487, -61.59541788972713 8.616945091844187, -61.59889088973037 8.555000091786496, -61.39389
 088953945 8.474445091711473, -61.32917288947917 8.430827091670864, -61.16847288932951 8.495764091731331, -61.0775088892448 8.493054091728808, -61.0861088892528 8.421391091662073, -61.0735458892411 8.402918091644864, -61.017781889189166 8.46916409170656, -60.98125488915515 8.564445091795292, -60.71583588890796 8.604582091832683, -60.62716388882538 8.551182091782948, -60.46583588867513 8.5282640917616, -60.40875488862197 8.621600091848535, -60.23611788846118 8.627500091854017, -59.99028188823223 8.535273091768133, -59.80305488805786 8.2833360915335, -59.83285488808562 8.231527091485248, -59.92222688816885 8.211109091466227, -59.9797268882224 8.174864091432468, -60.0111818882517 8.059236091324792, -60.03778188827647 8.037009091304085, -60.12486388835757 8.028327091296006, -60.31972688853905 7.877500091155525, -60.533335888737994 7.803891091086982, -60.58875488878961 7.639309090933693, -60.662090888857904 7.566527090865918, -60.691108888884926 7.567082090866435, -60.71666388890873 7.540
 000090841204, -60.688263888882275 7.453473090760625, -60.66083588885674 7.447218090754802, -60.59139088879206 7.336391090651588, -60.63423588883197 7.254309090575134, -60.61749988881638 7.19444509051938, -60.5380638887424 7.124445090454188, -60.50576388871231 7.17270909049914, -60.45611788866607 7.195836090520686, -60.36049088857702 7.176245090502434, -60.278054888500236 7.118745090448883, -60.29125488851254 7.056600090391015, -60.463617888673056 6.906664090251368, -60.63778188883526 6.834927090184564, -60.69778188889114 6.766664090120983, -60.81611788900135 6.788336090141172, -60.89368188907359 6.765000090119429, -60.93965488911641 6.724582090081796, -61.12510888928912 6.714773090072654, -61.174445889335075 6.658745090020474, -61.20472688936327 6.5779180899452, -61.140008889303004 6.408609089787518, -61.160145889321754 6.1825000895769335, -61.26278188941734 6.107782089507353, -61.3378908894873 5.972782089381624, -61.38972688953557 5.940000089351088, -60.748890888938746 5.2225000886
 82864, -60.65520888885149 5.181318088644517, -60.5785458887801 4.952636088431532, -60.649308888845994 4.842918088329355, -60.7202818889121 4.776109088267134, -60.88652688906693 4.709718088205307, -60.92986388910728 4.591873088095554, -60.987090889160584 4.519309088027967, -61.163890889325245 4.494309088004684, -61.313608889464675 4.506664088016194, -61.50736388964512 4.390554087908058, -61.51069988964824 4.3034730878269585, -61.55438188968891 4.248818087776058, -61.69917288982376 4.259027087785569, -61.76291788988313 4.2430540877706875, -61.8488908899632 4.160554087693853, -61.914863890024634 4.146945087681175, -61.987499890092295 4.169582087702267, -62.05319989015348 4.150136087684146, -62.14264589023678 4.093191087631112, -62.440135890513844 4.1826730877144485, -62.539935890606785 4.112291087648913, -62.6041638906666 4.041945087583386, -62.72833589078225 4.038609087580284, -62.75778189080967 4.020273087563211, -62.78041789083075 3.9087450874593372, -62.72749989078147 3.73110908729
 3902, -62.73402689078755 3.6765270872430733, -62.78125489083153 3.604309087175807, -62.878054890921675 3.5601360871346657, -62.99056389102647 3.604309087175807, -63.24229089126091 3.8981270874494527, -63.335554891347755 3.9580540875052606, -63.419099891425574 3.967082087513674, -63.45819989146199 3.866454087419953, -63.491526891493024 3.857782087411877, -63.530135891528985 3.8672180874206674, -63.61417289160724 3.9448640874929737, -63.64445489163545 3.9486090874964646, -63.84806389182508 3.9588910875060463, -63.95625489192584 3.891245087443039, -64.01779089198314 3.886109087438257, -64.05270889201566 3.9084360874590516, -64.12639089208429 4.1095820876463875, -64.24889989219838 4.148054087682212, -64.33555489227909 4.154164087687903, -64.59201789251793 4.1277730876633285, -64.67472689259496 4.257500087784138, -64.74626389266159 4.287218087811823, -64.78167289269456 4.2863910878110545, -64.80000889271165 4.265073087791194, -64.80195489271345 4.210836087740688, -64.71313589263073 4.144
 027087678467, -64.62668189255022 3.9655540875122455, -64.44632689238225 3.7870090873459645, -64.30806389225349 3.7183360872820117, -64.19021789214374 3.5896540871621596, -64.18471789213861 3.5277820871045407, -64.23569989218609 3.432782087016065, -64.20529089215776 3.1933360867930674, -64.15889089211456 3.060836086669667, -63.987854891955266 2.718609086350938, -63.995417891962305 2.623054086261945, -64.04646389200985 2.509445086156134, -64.03403589199827 2.4713180861206325, -63.821808891800615 2.4258360860782773, -63.58167289157697 2.434718086086548, -63.36541789137557 2.4200000860728323, -63.346390891357856 2.4061090860598995, -63.360763891371235 2.259100085922981, -63.39944589140727 2.149509085820924, -63.60709089160065 2.105973085780377, -63.739172891723655 2.003054085684525, -63.825008891803606 1.9777820856609907, -63.93652689190746 1.9768090856600793, -64.00236389196877 1.9498640856349851, -64.0518908920149 1.8904820855796913, -64.07799089203921 1.6354180853421383, -64.11320889
 207201 1.5829180852932438, -64.26445489221287 1.4761090851937695, -64.3943088923338 1.5118090852270143, -64.52972689245992 1.4336090851541883, -64.59529089252098 1.3300000850576907, -64.69750889261618 1.262782084995095, -64.7572358926718 1.2443090849778855, -64.8190728927294 1.2794820850106419, -65.00695489290437 1.1658360849048108, -65.1362638930248 1.118473084860696, -65.16584589305235 0.9694450847218974, -65.19250889307719 0.9266640846820593, -65.32167289319747 0.9119450846683463, -65.38584589325724 0.8370820845986344, -65.40028189327069 0.7539540845212116, -65.43610889330405 0.6952820844665695, -65.52166389338373 0.6491640844236173, -65.55861789341814 0.6661090844393982, -65.58257289344046 0.7297910844987143, -65.5111178933739 0.8388910846003199, -65.510135893373 0.9019450846590331, -65.55944589341892 0.9711090847234516, -65.59542689345243 0.9904180847414352, -65.73529089358269 0.9827820847343247, -65.87083589370893 0.9083360846649953, -65.97959089381021 0.798745084562924, -66.1
 2709089394758 0.7341640845027797, -66.31472689412233 0.7513910845188292, -66.87045489463989 1.2209270849561165, -66.89168189465967 1.2513910849844905, -66.92639089469199 1.4597180851785083, -66.99167289475278 1.6958360853984118, -67.21153589495755 2.2436090859085596, -67.21694589496259 2.275282085938059, -67.17418189492277 2.336527085995101, -67.19250889493983 2.392500086047221, -67.32520889506341 2.474027086123158, -67.48556389521276 2.653336086290153, -67.53528189525906 2.680000086314976, -67.60583589532477 2.7933360864205383, -67.76583589547378 2.832500086457003, -67.82361789552759 2.8270820864519663, -67.8330728955364 2.8766640864981383, -67.4355638951662 3.253891086849464, -67.34639989508315 3.313682086905146, -67.29285489503329 3.3960450869818573, -67.30659989504609 3.4527820870346915, -67.38111789511548 3.4859730870656023, -67.43709089516761 3.648336087216819, -67.49104589521787 3.7243090872875655, -67.59987289531922 3.740691087302821, -67.63514589535207 3.797636087355855, -6
 7.7085088954204 4.0469540875880625, -67.78667289549318 4.166527087699421, -67.80625489551143 4.231809087760212, -67.78479989549145 4.334754087856098, -67.85875489556032 4.561245088067025, -67.80158189550707 4.973236088450719, -67.8486358955509 5.306518088761123, -67.80389089550923 5.38326408883259, -67.64944589536539 5.478336088921139, -67.61590889533416 5.5481910889861865, -67.65167289536745 5.683191089111915, -67.61999989533797 5.792218089213463, -67.4139818951461 5.995536089402819, -67.49252689521924 6.121409089520043, -67.48924589521619 6.153745089550156, -67.45445489518379 6.1930540895867665, -67.49626389522273 6.2054180895982824, -67.56361789528545 6.262500089651439, -67.6352818953522 6.28513608967252, -67.83118189553464 6.30757308969342, -67.91812689561561 6.238191089628799, -67.99792689568993 6.207218089599962, -68.15515489583636 6.222773089614449, -68.31945489598938 6.1680540895634834, -68.45389989611459 6.190554089584438, -68.63840889628644 6.135482089533156, -68.827790896
 4628 6.186391089580567, -69.05639989667571 6.2161090896082385, -69.19520889680498 6.100418089500494, -69.24174589684833 6.084100089485304, -69.2707088968753 6.090973089491698, -69.31611789691759 6.148609089545374, -69.42945489702315 6.1186090895174345, -70.11917289766549 6.975836090315795, -70.2218178977611 6.9740270903141095, -70.294726897829 6.9384730902809935, -70.55250889806908 7.058336090392629, -70.7197268982248 7.098054090429613, -70.88653589838016 7.07507309040821, -71.02500889850913 6.984445090323803, -71.18126389865465 6.9634730903042765, -71.33250889879551 7.022364090359119, -71.46389989891787 7.023336090360033, -71.60139089904592 7.057918090392235, -71.70195489913958 7.046391090381505, -71.83278189926142 6.987218090326394, -71.99236389941004 7.016245090353422, -72.06609989947871 7.06241809039642, -72.13292689954095 7.173336090499731, -72.16459989957045 7.262500090582762, -72.15472689956125 7.325282090641238, -72.26250889966164 7.389445090700988, -72.40167289979124 7.4072
 18090717549, -72.47244589985715 7.497982090802083, -72.45972689984531 7.920554091195626, -72.38938189977979 8.047564091313916, -72.3286178997232 8.061809091327177, -72.3366728997307 8.151945091411122, -72.3881998997787 8.369445091613684, -72.66446390003598 8.641109091866696, -72.77972690014333 9.080273092275704, -72.8855639002419 9.11916409231192, -72.96250890031357 9.178054092366764, -72.9811269003309 9.260827092443861, -73.0099999003578 9.302009092482209, -73.22195490055519 9.171109092360297, -73.37806390070058 9.171391092360565, -73.36389090068738 9.225827092411265, -73.24514590057679 9.40847309258136, -73.08168190042456 9.609445092768524, -73.00472690035288 9.768327092916508, -72.97750890032754 10.001945093134069, -72.93889990029157 10.11645409324072, -72.90354590025865 10.444445093546179, -72.49125489987468 11.12277309417793, -72.31764589971299 11.164509094216797, -72.20935489961214 11.25000009429641, -71.9684818993878 11.666245094684072, -71.7697268992027 11.700836094716294, -
 71.40333589886147 11.812773094820542, -71.32471789878825 11.853054094858052, -71.37861789883844 11.753336094765189, -71.44584589890106 11.723891094737766, -71.76583589919908 11.662364094680456, -71.95417289937447 11.594718094617463, -71.96639989938586 11.506391094535203, -71.93278189935455 11.363054094401704, -71.7408458991758 11.034164094095402, -71.763617899197 11.013745094076384, -71.69111789912948 10.834164093909138, -71.6618088991022 10.77750009385636, -71.57792689902406 10.71610909379919, -71.58168189902757 10.674718093760646, -71.64889989909017 10.442500093544368, -71.75569989918964 10.369718093476592, -71.79444589922572 10.321809093431966, -71.8411268992692 10.218891093336126, -72.1253548995339 9.818191092962934, -72.07792689948973 9.735554092885977, -71.97917289939775 9.623336092781472, -71.91084589933412 9.493609092660648, -71.73319989916868 9.375691092550824, -71.72361789915975 9.345000092522241, -71.75945489919313 9.118327092311148, -71.7148638991516 9.077918092273507, -
 71.62389089906688 9.043054092241036, -71.55278189900065 9.040836092238976, -71.3136088987779 9.1105540923039, -71.24139089871065 9.155418092345684, -71.16541789863989 9.273745092455883, -71.07486389855555 9.312500092491973, -71.05597289853796 9.338745092516419, -71.08917289856888 9.536600092700695, -71.05334589853551 9.703609092856226, -71.07339989855419 9.851109092993596, -71.26945489873678 10.150136093272081, -71.38556389884492 10.282773093395619, -71.43667289889251 10.36944509347633, -71.45861789891295 10.460000093560666, -71.54570889899406 10.568327093661566, -71.52639989897608 10.726945093809277, -71.44667289890182 10.795554093873179, -71.45167289890648 10.916391093985723, -71.49285489894484 10.961036094027293, -71.4119548988695 10.984164094048836, -71.28110889874763 10.989164094053493, -70.82556389832338 11.211391094260463, -70.50847289802806 11.248191094294725, -70.4466728979705 11.290000094333664, -70.23918189777727 11.353054094392391, -70.14249989768723 11.418336094453196, 
 -70.03486389758697 11.441318094474596, -70.02389989757677 11.491391094521234, -70.04779089759901 11.517773094545802, -69.987645897543 11.514718094542957, -69.87402689743719 11.426527094460823, -69.80139089736954 11.427218094461466, -69.7423998973146 11.499200094528504, -69.81653589738364 11.690973094707104, -70.18000889772216 11.603609094625739, -70.23598189777428 11.62889109464929, -70.24389989778166 11.775273094785618, -70.29403589782835 11.861664094866072, -70.28666389782148 11.92027309492066, -70.18749989772914 12.107773095095283, -70.01430889756783 12.197500095178839, -69.93471789749371 12.169718095152973, -69.85945489742362 12.071945095061906, -69.82375489739037 11.98805409498378, -69.81688189738396 11.850973094856116, -69.75778189732893 11.661391094679558, -69.7061178972808 11.548891094574785, -69.6318088972116 11.467636094499099, -69.5795178971629 11.46410009449582, -69.50695489709533 11.506945094535709, -69.36021789695867 11.493327094523039, -69.27487289687919 11.5339540945
 60869, -68.95389989658025 11.45166409448423, -68.8436818964776 11.447082094479967, -68.66042689630693 11.349864094389417, -68.60196389625249 11.290554094334183, -68.41833589608147 11.180000094231218, -68.24250889591772 10.874373093946588, -68.25195489592652 10.856664093930092, -68.32529089599481 10.843609093917934, -68.3280638959974 10.767500093847048, -68.25361789592806 10.588891093680715, -68.16514589584567 10.498891093596896, -67.86798189556892 10.464873093565217, -67.79610889550197 10.491945093590417, -67.54333589526657 10.53277309362845, -67.28029089502158 10.546664093641382, -67.00222689476261 10.610282093700633, -66.47056389426747 10.629164093718217, -66.34299089414866 10.604718093695453, -66.3102908941182 10.626018093715288)), ((-64.05555489201832 10.857218093930612, -64.1363998920936 10.945000094012357, -64.17403589212866 10.960418094026721, -64.22792689217884 10.93124509399955, -64.40569989234442 10.970136094035766, -64.37834589231893 11.056945094116614, -64.20180889215452
  11.08778209414534, -64.17584589213034 11.031664094093074, -64.10583589206514 10.995282094059192, -64.04278189200642 10.987636094052064, -63.98749989195494 11.076109094134466, -63.88493589185941 11.175618094227147, -63.84486389182209 11.127082094181944, -63.80472689178471 11.021391094083512, -63.81499989179429 10.978054094043145, -63.89000889186414 10.904445093974587, -64.05555489201832 10.857218093930612)), ((-61.163608889324976 8.68832709191068, -61.16499988932628 8.71527309193577, -61.042499889212195 8.821109092034334, -60.86055488904273 8.853336092064353, -60.97610888915035 8.725827091945604, -61.163608889324976 8.68832709191068)), ((-61.246945889402596 8.474718091711736, -61.2943088894467 8.493327091729071, -61.405281889550054 8.485836091722092, -61.543545889678825 8.54868209178062, -61.42639088956972 8.58332709181289, -61.279445889432864 8.569718091800212, -61.26149988941614 8.552964091784602, -61.27829988943179 8.516736091750872, -61.2635998894181 8.499927091735216, -61.18507
 2889344966 8.496736091732245, -61.246945889402596 8.474718091711736)), ((-61.1291728892929 8.501664091736828, -61.26368188941818 8.510209091744784, -61.253063889408295 8.545273091777446, -61.21750888937518 8.572500091802794, -61.14912688931149 8.54089109177336, -61.083617889250476 8.609718091837465, -60.99806388917081 8.59694509182556, -60.99860888917131 8.557782091789093, -61.04055488921037 8.51416409174847, -61.1291728892929 8.501664091736828)), ((-60.91028188908905 8.894164092102372, -61.01972688919098 8.846945092058391, -61.046390889215814 8.843891092055557, -60.94167288911828 9.011664092211802, -60.880345889061175 9.026527092225649, -60.840563889024125 8.99832709219939, -60.85625488903874 8.947364092151915, -60.91028188908905 8.894164092102372)), ((-65.2811088931597 10.88028209395209, -65.39334589326423 10.906945093976915, -65.41611789328543 10.927218093995805, -65.36445489323732 10.969164094034866, -65.30445489318144 10.976109094041334, -65.21215489309549 10.954164094020896, -
 65.19959089308378 10.898336093968908, -65.2811088931597 10.88028209395209)), ((-61.048054889217354 8.639718091865404, -61.146945889309464 8.654445091879111, -61.17722688933766 8.67666409189981, -60.93778188911466 8.721245091941327, -60.99680888916963 8.652636091877426, -61.048054889217354 8.639718091865404)), ((-60.85831788904065 9.06495409226143, -60.94333588911984 9.022218092221635, -61.061390889229784 8.896945092104957, -61.096672889262635 8.89090009209933, -61.07062688923838 8.97131809217423, -60.947226889123456 9.054718092251903, -60.850417889033295 9.092982092287542, -60.85831788904065 9.06495409226143)), ((-60.92333588910121 8.618327091845487, -60.988617889162 8.635554091861522, -60.84159988902509 8.726945091946632, -60.80944588899514 8.716945091937319, -60.82333588900808 8.652364091877175, -60.92333588910121 8.618327091845487)))	
-ASM	American Samoa	MULTIPOLYGON (((-170.74389999137958 -14.375554929569248, -170.74941799138472 -14.373890929567693, -170.7664449914006 -14.363608929558112, -170.82322699145345 -14.323754929521002, -170.80917299144036 -14.308054929506383, -170.79765499142965 -14.299308929498238, -170.68167299132162 -14.258054929459817, -170.6640269913052 -14.255417929457352, -170.5679179912157 -14.254308929456329, -170.56187299121007 -14.269999929470941, -170.57861799122566 -14.279163929479466, -170.63726399128026 -14.289445929489048, -170.74389999137958 -14.375554929569248)))	
-COK	Cook Is.	MULTIPOLYGON (((-159.7469819811379 -21.25667293597779, -159.79363598118135 -21.252781935974156, -159.83251798121756 -21.248472935970142, -159.84000898122454 -21.23916393596147, -159.83471798121963 -21.199308935924364, -159.82723598121265 -21.189863935915568, -159.7883269811764 -21.187499935913365, -159.75613598114643 -21.192363935917896, -159.73292698112482 -21.22624593594945, -159.73916398113062 -21.2524999359739, -159.7469819811379 -21.25667293597779)), ((-157.92889097944467 -21.94083593661496, -157.94696397946151 -21.93958193661379, -157.96376397947716 -21.92041793659594, -157.96363597947703 -21.90819093658456, -157.95751797947133 -21.89528193657253, -157.94778197946226 -21.88805493656581, -157.921735979438 -21.88146393655967, -157.88384497940274 -21.925208936600413, -157.88766397940628 -21.936808936611214, -157.92889097944467 -21.94083593661496)), ((-158.11667297961955 -20.019172934825278, -158.12668197962887 -20.009445934816213, -158.13041797963237 -19.995281934803
 018, -158.1253999796277 -19.978472934787362, -158.11152697961478 -19.9713179347807, -158.09475497959914 -19.97417293478337, -158.0836359795888 -19.98444593479293, -158.0813909795867 -19.996390934804054, -158.08876397959358 -20.01069993481738, -158.0983549796025 -20.016108934822412, -158.11667297961955 -20.019172934825278)), ((-157.71304497924365 -19.857226934674443, -157.71887297924908 -19.85166393466926, -157.7408179792695 -19.817645934637582, -157.73919997926802 -19.807508934628146, -157.71229997924297 -19.77312693459612, -157.70376397923502 -19.836808934655437, -157.70864497923955 -19.853054934670567, -157.71304497924365 -19.857226934674443)), ((-163.16946398432535 -18.091945933030402, -163.17128198432704 -18.08417293302317, -163.15472698431162 -18.06145493300201, -163.15725498431397 -18.080554933019798, -163.1633269843196 -18.089445933028074, -163.16946398432535 -18.091945933030402)), ((-165.84167298681402 -10.890835926323845, -165.84834498682025 -10.8842359263177, -165.82765498
 680098 -10.881317926314978, -165.84167298681402 -10.890835926323845)))	
-PYF	French Polynesia	MULTIPOLYGON (((-149.1791999712959 -17.870835932824477, -149.25809097136937 -17.85278193280766, -149.27570897138577 -17.84631793280164, -149.28893597139808 -17.833054932789295, -149.29795497140648 -17.82083593277791, -149.3694729714731 -17.738890932701594, -149.3785999714816 -17.743608932705982, -149.42086397152096 -17.756108932717623, -149.47168197156827 -17.766390932727205, -149.48763597158313 -17.76597293272681, -149.59057297167902 -17.711390932675982, -149.63891797172403 -17.625972932596426, -149.64169097172663 -17.611945932583367, -149.64141797172636 -17.592781932565515, -149.63559097172094 -17.561672932536553, -149.63250897171807 -17.54999993252568, -149.62388197171003 -17.540699932517015, -149.58739097167606 -17.516181932494177, -149.4921089715873 -17.493754932473294, -149.44998197154808 -17.499445932478594, -149.41473597151526 -17.509172932487658, -149.37362697147697 -17.526945932504205, -149.3591639714635 -17.534454932511196, -149.34861797145368 -17.542
 090932518306, -149.3327639714389 -17.57028193254456, -149.32666397143322 -17.592226932564998, -149.32333597143014 -17.65249993262114, -149.3230909714299 -17.67110893263846, -149.3240359714308 -17.68778193265399, -149.32014497142717 -17.702154932667383, -149.3075089714154 -17.712635932677145, -149.29306397140192 -17.717499932681676, -149.2305639713437 -17.730281932693572, -149.2077909713225 -17.734172932697206, -149.18473597130105 -17.73139093269461, -149.1747089712917 -17.736117932699017, -149.1622269712801 -17.751390932713235, -149.1547269712731 -17.764445932725394, -149.14837297126718 -17.781954932741698, -149.1466819712656 -17.805699932763815, -149.15221797127077 -17.83361793278982, -149.15780897127598 -17.849726932804813, -149.16559097128322 -17.86360893281774, -149.1741639712912 -17.869163932822914, -149.1791999712959 -17.870835932824477)), ((-139.05474496186676 -9.859999925363809, -139.1089179619172 -9.846945925351648, -139.11913596192673 -9.843608925348533, -139.1289089619358
 2 -9.838890925344145, -139.1411089619472 -9.830835925336643, -139.15142696195682 -9.820554925327073, -139.16879096197297 -9.79375492530211, -139.1722549619762 -9.772917925282698, -139.16726396197154 -9.759999925270677, -139.04444496185715 -9.69541792521052, -139.00472696182018 -9.69694592521195, -138.97568196179313 -9.708608925222805, -138.9687639617867 -9.722363925235626, -138.9570729617758 -9.741390925253341, -138.8903179617136 -9.757226925268085, -138.85058196167662 -9.756108925267043, -138.83611796166315 -9.749863925261238, -138.82531796165307 -9.740272925252299, -138.81251796164116 -9.737917925250102, -138.8097549616386 -9.748054925259552, -138.81558196164403 -9.759445925270157, -138.8319729616593 -9.770835925280764, -138.84915496167528 -9.781117925290346, -138.89585496171878 -9.806254925313752, -138.91085496173275 -9.808335925315689, -138.9794269617966 -9.8149999253219, -138.99999996181577 -9.8149999253219, -139.01319996182806 -9.811390925318534, -139.02973596184347 -9.8072269
 25314652, -139.04862696186106 -9.808199925315563, -139.06133596187289 -9.818890925325519, -139.05474496186676 -9.859999925363809)), ((-140.17782696291272 -8.956390924522253, -140.18945496292355 -8.954163924520174, -140.2058359629388 -8.944726924511386, -140.22584496295744 -8.930417924498059, -140.2305639629618 -8.921390924489657, -140.25613596298564 -8.827363924402093, -140.25339096298308 -8.813054924388766, -140.2497549629797 -8.80278192437919, -140.2450269629753 -8.793890924370913, -140.2366639629675 -8.7838909243616, -140.2251449629568 -8.778190924356295, -140.06890896281126 -8.81167292438748, -140.04281796278696 -8.830281924404801, -140.01599096276198 -8.852845924425822, -140.01196396275824 -8.870972924442697, -140.01515496276122 -8.888472924458995, -140.0226639627682 -8.898054924467928, -140.07781796281955 -8.918054924486555, -140.0908359628317 -8.9220819244903, -140.10487296284475 -8.918754924487203, -140.1197179628586 -8.918890924487329, -140.1669639629026 -8.933054924500524,
  -140.17683596291178 -8.940135924507118, -140.17782696291272 -8.956390924522253)), ((-151.4444909734056 -16.904445931924457, -151.46543597342512 -16.902917931923028, -151.47512697343413 -16.89749993191799, -151.49169997344958 -16.849172931872985, -151.49777297345523 -16.784026931812306, -151.49136397344927 -16.759999931789935, -151.48751797344568 -16.7494459317801, -151.4725179734317 -16.73971793177104, -151.43098197339302 -16.745554931776482, -151.35111797331865 -16.84583593186987, -151.3509819733185 -16.860345931883387, -151.40032697336449 -16.888335931909452, -151.4444909734056 -16.904445931924457)), ((-149.85442697192474 -17.574445932548443, -149.86834497193772 -17.56833593254275, -149.87805497194674 -17.563617932538364, -149.9250449719905 -17.52528193250265, -149.93808197200266 -17.509726932488164, -149.941681972006 -17.497217932476516, -149.93725497200188 -17.484163932464355, -149.9227909719884 -17.477781932458413, -149.91113597197756 -17.476108932456853, -149.79462697186906 -
 17.466799932448183, -149.78529097186035 -17.47125493245234, -149.78321797185842 -17.487781932467726, -149.79849097187264 -17.52778193250498, -149.84596397191686 -17.572499932546634, -149.85442697192474 -17.574445932548443)))	
-UMI	Jarvis I.	MULTIPOLYGON (((-160.02114498139323 -0.3980549165516862, -160.02810898139973 -0.3980549165516862, -160.04349098141404 -0.3922179165462438, -160.0451639814156 -0.3801359165349964, -160.03391798140512 -0.3743089165295714, -160.0177909813901 -0.3747179165299457, -160.00946398138237 -0.3847179165392589, -160.0129269813856 -0.3958359165496148, -160.02114498139323 -0.3980549165516862)))	
-NIU	Niue	MULTIPOLYGON (((-169.89389099058795 -19.145554934011656, -169.9308819906224 -19.124445933991993, -169.9522359906423 -19.073335933944392, -169.93028199062184 -19.01360893388876, -169.89474499058875 -18.970281933848412, -169.88476399057944 -18.963335933841947, -169.86889999056467 -18.963617933842215, -169.8151359905146 -18.970272933848406, -169.78155499048333 -19.065281933936888, -169.79809999049874 -19.087226933957325, -169.82443599052326 -19.110835933979317, -169.85028199054733 -19.125835933993287, -169.8591639905556 -19.130554933997686, -169.88806399058254 -19.14444593401062, -169.89389099058795 -19.145554934011656)))	
-WSM	Samoa	MULTIPOLYGON (((-172.59649999310494 -13.509108928762302, -172.55193599306344 -13.497217928751226, -172.47528199299205 -13.479717928734928, -172.39111799291368 -13.464172928720458, -172.36083599288548 -13.460554928717087, -172.34835499287385 -13.461390928717861, -172.303417992832 -13.472154928727889, -172.28779999281744 -13.484163928739065, -172.22249999275664 -13.563054928812548, -172.20306399273855 -13.59194592883945, -172.1933639927295 -13.613335928859371, -172.1683549927062 -13.680972928922358, -172.16781799270572 -13.691390928932066, -172.21235499274718 -13.806526929039293, -172.225035992759 -13.808890929041496, -172.25849999279018 -13.804308929037234, -172.39333599291575 -13.791672929025466, -172.48599099300202 -13.806808929039562, -172.50890899302337 -13.806663929039416, -172.5279269930411 -13.802708929035745, -172.5744359930844 -13.765835929001398, -172.59002699309892 -13.739717928977072, -172.69109999319306 -13.626108928871261, -172.7516909932495 -13.57402692882276
 , -172.77282699326918 -13.54999992880039, -172.78002699327587 -13.532572928784148, -172.7725359932689 -13.517499928770121, -172.75558199325312 -13.51028192876339, -172.73890899323757 -13.508472928761705, -172.728635993228 -13.513335928766239, -172.65527299315968 -13.519172928771681, -172.59649999310494 -13.509108928762302)), ((-171.44198199202972 -14.057499929273035, -171.4652729920514 -14.052781929268633, -171.47998199206512 -14.050554929266568, -171.52055499210292 -14.047781929263977, -171.5461089921267 -14.050281929266305, -171.5889269921666 -14.052499929268379, -171.64837299222194 -14.050281929266305, -171.76809999233345 -14.035835929252855, -171.91113599246665 -14.012499929231126, -172.05059999259655 -13.912499929137994, -172.0584999926039 -13.903190929129323, -172.06475499260972 -13.87819092910604, -172.05975499260506 -13.866945929095564, -172.02932699257673 -13.840272929070721, -171.90670899246254 -13.806663929039416, -171.8839089924413 -13.805554929038394, -171.8222639923838
 8 -13.807499929040205, -171.7480819923148 -13.83167292906272, -171.6191359921947 -13.87860892910642, -171.44418199203176 -13.984445929204995, -171.43070899201922 -14.002363929221687, -171.42919999201783 -14.01625492923462, -171.44198199202972 -14.057499929273035)))	
-TKL	Tokelau	MULTIPOLYGON (((-171.84805499240792 -9.218890924766725, -171.85885499241797 -9.209654924758127, -171.86271799242155 -9.18089992473135, -171.85243599241198 -9.170626924721773, -171.84419099240432 -9.191108924740846, -171.84376399240392 -9.210835924759223, -171.84805499240792 -9.218890924766725)))	
-TON	Tonga	MULTIPOLYGON (((-175.1452909954787 -21.268063935988394, -175.18639999551698 -21.252781935974156, -175.31445499563625 -21.17999993590638, -175.3236359956448 -21.174445935901204, -175.33642699565672 -21.161672935889314, -175.35140899567065 -21.14333593587223, -175.35748199567632 -21.131663935861354, -175.35999999567866 -21.10083593583265, -175.35319999567233 -21.0887549358214, -175.34112699566109 -21.074863935808466, -175.3142999956361 -21.06417293579851, -175.3035549956261 -21.069726935803672, -175.27667299560105 -21.124999935855158, -175.2452359955718 -21.12978193585961, -175.1490359954822 -21.17680893590341, -175.13836399547225 -21.175835935902498, -175.1319549954663 -21.159163935886966, -175.12945499546396 -21.14472693587352, -175.12139999545644 -21.13375493586331, -175.10723599544326 -21.12806393585801, -175.09362699543058 -21.124999935855158, -175.06542699540432 -21.125835935855932, -175.0487639953888 -21.13694593586628, -175.0459909953862 -21.149163935877652, -175.051
 69999539154 -21.161672935889314, -175.12083599545593 -21.262090935982826, -175.13503599546914 -21.267781935988125, -175.1452909954787 -21.268063935988394)), ((-173.93920899435545 -18.56889093347459, -173.93362699435025 -18.573054933478474, -173.9166909943345 -18.599726933503305, -173.9068269943253 -18.62375493352569, -173.90890899432722 -18.635563933536687, -173.98697299439993 -18.684172933581962, -174.05444499446276 -18.669726933568498, -174.06308199447082 -18.659299933558785, -174.07030899447756 -18.63597293353706, -174.06527299447285 -18.62499993352685, -174.05334499446175 -18.621117933523237, -174.03737299444688 -18.621117933523237, -174.0252999944356 -18.616672933519098, -174.01724499442813 -18.603054933506414, -174.01306399442424 -18.589726933493992, -174.00321799441505 -18.578199933483262, -173.99249099440507 -18.572226933477694, -173.9675269943818 -18.568054933473817, -173.93920899435545 -18.56889093347459)))	
-WLF	Wallis & Futuna	MULTIPOLYGON (((-178.06081799819398 -14.323890929521127, -178.13739099826532 -14.317081929514785, -178.15389999828068 -14.308054929506383, -178.17110899829672 -14.287781929487494, -178.1793549983044 -14.275417929475978, -178.18832699831276 -14.256108929457994, -178.19027299831455 -14.239726929442739, -178.18169999830658 -14.232363929435891, -178.12733599825594 -14.24860892945101, -178.04301799817742 -14.31749992951518, -178.06081799819398 -14.323890929521127)), ((-176.1650359964284 -13.35305492861697, -176.16906399643216 -13.351945928615933, -176.17724499643978 -13.341390928606103, -176.18808199644988 -13.313608928580223, -176.1910999964527 -13.286945928555397, -176.18581799644775 -13.257781928528232, -176.18307299644522 -13.24360892851503, -176.1783449964408 -13.232226928504431, -176.1583549964222 -13.21486392848827, -176.14809099641263 -13.216108928489419, -176.12193599638826 -13.258608928529, -176.14202699640697 -13.34381792860836, -176.16143599642507 -13.3527
 72928616702, -176.1650359964284 -13.35305492861697)))	
-ARG	Argentina	MULTIPOLYGON (((-71.85916389928599 -41.0112819543757, -71.85028189927772 -40.91250895428371, -71.95014589937072 -40.72694595411089, -71.85930889928613 -40.64347295403315, -71.77987289921215 -40.40896395381475, -71.71569989915238 -40.42361795382839, -71.6639638991042 -40.33451795374541, -71.66861789910853 -40.29694595371042, -71.7027178991403 -40.27895495369366, -71.719590899156 -40.302363953715464, -71.81806389924772 -40.20459095362441, -71.79139989922288 -40.11500895354098, -71.66694589910698 -40.04749995347811, -71.63334589907568 -39.95056395338783, -71.70500889914243 -39

<TRUNCATED>

[03/50] [abbrv] lucene-solr git commit: also test LatLonPoint.newDistanceQuery from TestLatLonPointQueries, and remove some test leniency

Posted by ho...@apache.org.
also test LatLonPoint.newDistanceQuery from TestLatLonPointQueries, and remove some test leniency


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/3cc8b6f8
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/3cc8b6f8
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/3cc8b6f8

Branch: refs/heads/jira/SOLR-445
Commit: 3cc8b6f8fd3c36cbd662540c890ec815bd312b6d
Parents: 9a3458f
Author: Mike McCandless <mi...@apache.org>
Authored: Mon Feb 29 15:45:09 2016 -0500
Committer: Mike McCandless <mi...@apache.org>
Committed: Mon Feb 29 15:45:09 2016 -0500

----------------------------------------------------------------------
 .../lucene/search/TestLatLonPointQueries.java   | 63 +++++++++++++++-----
 .../spatial/util/BaseGeoPointTestCase.java      | 20 +++++--
 2 files changed, 64 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3cc8b6f8/lucene/sandbox/src/test/org/apache/lucene/search/TestLatLonPointQueries.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/test/org/apache/lucene/search/TestLatLonPointQueries.java b/lucene/sandbox/src/test/org/apache/lucene/search/TestLatLonPointQueries.java
index 0916b15..7798b97 100644
--- a/lucene/sandbox/src/test/org/apache/lucene/search/TestLatLonPointQueries.java
+++ b/lucene/sandbox/src/test/org/apache/lucene/search/TestLatLonPointQueries.java
@@ -39,9 +39,7 @@ public class TestLatLonPointQueries extends BaseGeoPointTestCase {
 
   @Override
   protected Query newDistanceQuery(String field, double centerLat, double centerLon, double radiusMeters) {
-    // TODO: fix this to be debuggable before enabling!
-    // return LatLonPoint.newDistanceQuery(field, centerLat, centerLon, radiusMeters);
-    return null;
+    return LatLonPoint.newDistanceQuery(field, centerLat, centerLon, radiusMeters);
   }
 
   @Override
@@ -59,6 +57,53 @@ public class TestLatLonPointQueries extends BaseGeoPointTestCase {
 
     assert Double.isNaN(pointLat) == false;
 
+    int rectLatMinEnc = LatLonPoint.encodeLat(rect.minLat);
+    int rectLatMaxEnc = LatLonPoint.encodeLat(rect.maxLat);
+    int rectLonMinEnc = LatLonPoint.encodeLon(rect.minLon);
+    int rectLonMaxEnc = LatLonPoint.encodeLon(rect.maxLon);
+
+    int pointLatEnc = LatLonPoint.encodeLat(pointLat);
+    int pointLonEnc = LatLonPoint.encodeLon(pointLon);
+
+    if (rect.minLon < rect.maxLon) {
+      return pointLatEnc >= rectLatMinEnc &&
+        pointLatEnc < rectLatMaxEnc &&
+        pointLonEnc >= rectLonMinEnc &&
+        pointLonEnc < rectLonMaxEnc;
+    } else {
+      // Rect crosses dateline:
+      return pointLatEnc >= rectLatMinEnc &&
+        pointLatEnc < rectLatMaxEnc &&
+        (pointLonEnc >= rectLonMinEnc ||
+         pointLonEnc < rectLonMaxEnc);
+    }
+  }
+
+  @Override
+  protected double quantizeLat(double latRaw) {
+    return LatLonPoint.decodeLat(LatLonPoint.encodeLat(latRaw));
+  }
+
+  @Override
+  protected double quantizeLon(double lonRaw) {
+    return LatLonPoint.decodeLon(LatLonPoint.encodeLon(lonRaw));
+  }
+
+  // todo reconcile with GeoUtils (see LUCENE-6996)
+  public static double compare(final double v1, final double v2) {
+    final double delta = v1-v2;
+    return Math.abs(delta) <= BKD_TOLERANCE ? 0 : delta;
+  }
+
+  @Override
+  protected Boolean polyRectContainsPoint(GeoRect rect, double pointLat, double pointLon) {
+    // TODO write better random polygon tests
+
+    assert Double.isNaN(pointLat) == false;
+
+    // TODO: this comment is wrong!  we have fixed the quantization error (we now pre-quantize all randomly generated test points) yet the test
+    // still fails if we remove this evil "return null":
+    
     // false positive/negatives due to quantization error exist for both rectangles and polygons
     if (compare(pointLat, rect.minLat) == 0
         || compare(pointLat, rect.maxLat) == 0
@@ -89,18 +134,6 @@ public class TestLatLonPointQueries extends BaseGeoPointTestCase {
     }
   }
 
-  // todo reconcile with GeoUtils (see LUCENE-6996)
-  public static double compare(final double v1, final double v2) {
-    final double delta = v1-v2;
-    return Math.abs(delta) <= BKD_TOLERANCE ? 0 : delta;
-  }
-
-  @Override
-  protected Boolean polyRectContainsPoint(GeoRect rect, double pointLat, double pointLon) {
-    // TODO write better random polygon tests
-    return rectContainsPoint(rect, pointLat, pointLon);
-  }
-
   @Override
   protected Boolean circleContainsPoint(double centerLat, double centerLon, double radiusMeters, double pointLat, double pointLon) {
     double distanceMeters = GeoDistanceUtils.haversin(centerLat, centerLon, pointLat, pointLon);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3cc8b6f8/lucene/spatial/src/test/org/apache/lucene/spatial/util/BaseGeoPointTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/util/BaseGeoPointTestCase.java b/lucene/spatial/src/test/org/apache/lucene/spatial/util/BaseGeoPointTestCase.java
index 1980e9a..8313616 100644
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/util/BaseGeoPointTestCase.java
+++ b/lucene/spatial/src/test/org/apache/lucene/spatial/util/BaseGeoPointTestCase.java
@@ -422,7 +422,7 @@ public abstract class BaseGeoPointTestCase extends LuceneTestCase {
     } else {
       result = -90 + 180.0 * random().nextDouble();
     }
-    return result;
+    return quantizeLat(result);
   }
 
   public double randomLon(boolean small) {
@@ -432,7 +432,19 @@ public abstract class BaseGeoPointTestCase extends LuceneTestCase {
     } else {
       result = -180 + 360.0 * random().nextDouble();
     }
-    return result;
+    return quantizeLon(result);
+  }
+
+  /** Override this to quantize randomly generated lat, so the test won't fail due to quantization errors, which are 1) annoying to debug,
+   *  and 2) should never affect "real" usage terribly. */
+  protected double quantizeLat(double lat) {
+    return lat;
+  }
+
+  /** Override this to quantize randomly generated lon, so the test won't fail due to quantization errors, which are 1) annoying to debug,
+   *  and 2) should never affect "real" usage terribly. */
+  protected double quantizeLon(double lon) {
+    return lon;
   }
 
   protected GeoRect randomRect(boolean small, boolean canCrossDateLine) {
@@ -694,9 +706,9 @@ public abstract class BaseGeoPointTestCase extends LuceneTestCase {
 
                     @Override
                     protected void describe(int docID, double pointLat, double pointLon) {
-                      double distanceKM = SloppyMath.haversin(centerLat, centerLon, pointLat, pointLon);
+                      double distanceMeters = GeoDistanceUtils.haversin(centerLat, centerLon, pointLat, pointLon);
                       System.out.println("  docID=" + docID + " centerLon=" + centerLon + " centerLat=" + centerLat
-                          + " pointLon=" + pointLon + " pointLat=" + pointLat + " distanceMeters=" + (distanceKM * 1000)
+                          + " pointLon=" + pointLon + " pointLat=" + pointLat + " distanceMeters=" + distanceMeters
                           + " vs" + ((rangeQuery == true) ? " minRadiusMeters=" + minRadiusMeters : "") + " radiusMeters=" + radiusMeters);
                     }
                    };


[18/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxStrategy.java b/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxStrategy.java
deleted file mode 100644
index 869aa31..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxStrategy.java
+++ /dev/null
@@ -1,591 +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.bbox;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.document.LegacyDoubleField;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.FieldType;
-import org.apache.lucene.document.StringField;
-import org.apache.lucene.index.DocValuesType;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.ConstantScoreQuery;
-import org.apache.lucene.search.LegacyNumericRangeQuery;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.spatial.SpatialStrategy;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.query.SpatialOperation;
-import org.apache.lucene.spatial.query.UnsupportedSpatialOperation;
-import org.apache.lucene.spatial.util.DistanceToShapeValueSource;
-import org.apache.lucene.util.BytesRefBuilder;
-import org.apache.lucene.util.LegacyNumericUtils;
-
-
-/**
- * A SpatialStrategy for indexing and searching Rectangles by storing its
- * coordinates in numeric fields. It supports all {@link SpatialOperation}s and
- * has a custom overlap relevancy. It is based on GeoPortal's <a
- * href="http://geoportal.svn.sourceforge.net/svnroot/geoportal/Geoportal/trunk/src/com/esri/gpt/catalog/lucene/SpatialClauseAdapter.java">SpatialClauseAdapter</a>.
- * <p>
- * <b>Characteristics:</b>
- * <br>
- * <ul>
- * <li>Only indexes Rectangles; just one per field value. Other shapes can be provided
- * and the bounding box will be used.</li>
- * <li>Can query only by a Rectangle. Providing other shapes is an error.</li>
- * <li>Supports most {@link SpatialOperation}s but not Overlaps.</li>
- * <li>Uses the DocValues API for any sorting / relevancy.</li>
- * </ul>
- * <p>
- * <b>Implementation:</b>
- * <p>
- * This uses 4 double fields for minX, maxX, minY, maxY
- * and a boolean to mark a dateline cross. Depending on the particular {@link
- * SpatialOperation}s, there are a variety of {@link org.apache.lucene.search.LegacyNumericRangeQuery}s to be
- * done.
- * The {@link #makeOverlapRatioValueSource(com.spatial4j.core.shape.Rectangle, double)}
- * works by calculating the query bbox overlap percentage against the indexed
- * shape overlap percentage. The indexed shape's coordinates are retrieved from
- * {@link org.apache.lucene.index.LeafReader#getNumericDocValues}.
- *
- * @lucene.experimental
- */
-public class BBoxStrategy extends SpatialStrategy {
-
-  public static final String SUFFIX_MINX = "__minX";
-  public static final String SUFFIX_MAXX = "__maxX";
-  public static final String SUFFIX_MINY = "__minY";
-  public static final String SUFFIX_MAXY = "__maxY";
-  public static final String SUFFIX_XDL  = "__xdl";
-
-  /*
-   * The Bounding Box gets stored as four fields for x/y min/max and a flag
-   * that says if the box crosses the dateline (xdl).
-   */
-  protected final String field_bbox;
-  protected final String field_minX;
-  protected final String field_minY;
-  protected final String field_maxX;
-  protected final String field_maxY;
-  protected final String field_xdl; // crosses dateline
-
-  protected FieldType fieldType;//for the 4 numbers
-  protected FieldType xdlFieldType;
-
-  public BBoxStrategy(SpatialContext ctx, String fieldNamePrefix) {
-    super(ctx, fieldNamePrefix);
-    field_bbox = fieldNamePrefix;
-    field_minX = fieldNamePrefix + SUFFIX_MINX;
-    field_maxX = fieldNamePrefix + SUFFIX_MAXX;
-    field_minY = fieldNamePrefix + SUFFIX_MINY;
-    field_maxY = fieldNamePrefix + SUFFIX_MAXY;
-    field_xdl = fieldNamePrefix + SUFFIX_XDL;
-
-    FieldType fieldType = new FieldType(LegacyDoubleField.TYPE_NOT_STORED);
-    fieldType.setNumericPrecisionStep(8);//Solr's default
-    fieldType.setDocValuesType(DocValuesType.NUMERIC);
-    setFieldType(fieldType);
-  }
-
-  private int getPrecisionStep() {
-    return fieldType.numericPrecisionStep();
-  }
-
-  public FieldType getFieldType() {
-    return fieldType;
-  }
-
-  /** Used to customize the indexing options of the 4 number fields, and to a lesser degree the XDL field too. Search
-   * requires indexed=true, and relevancy requires docValues. If these features aren't needed then disable them.
-   * {@link FieldType#freeze()} is called on the argument. */
-  public void setFieldType(FieldType fieldType) {
-    fieldType.freeze();
-    this.fieldType = fieldType;
-    //only double's supported right now
-    if (fieldType.numericType() != FieldType.LegacyNumericType.DOUBLE)
-      throw new IllegalArgumentException("BBoxStrategy only supports doubles at this time.");
-    //for xdlFieldType, copy some similar options. Don't do docValues since it isn't needed here.
-    xdlFieldType = new FieldType(StringField.TYPE_NOT_STORED);
-    xdlFieldType.setStored(fieldType.stored());
-    xdlFieldType.setIndexOptions(fieldType.indexOptions());
-    xdlFieldType.freeze();
-  }
-
-  //---------------------------------
-  // Indexing
-  //---------------------------------
-
-  @Override
-  public Field[] createIndexableFields(Shape shape) {
-    return createIndexableFields(shape.getBoundingBox());
-  }
-
-  public Field[] createIndexableFields(Rectangle bbox) {
-    Field[] fields = new Field[5];
-    fields[0] = new ComboField(field_minX, bbox.getMinX(), fieldType);
-    fields[1] = new ComboField(field_maxX, bbox.getMaxX(), fieldType);
-    fields[2] = new ComboField(field_minY, bbox.getMinY(), fieldType);
-    fields[3] = new ComboField(field_maxY, bbox.getMaxY(), fieldType);
-    fields[4] = new ComboField(field_xdl, bbox.getCrossesDateLine()?"T":"F", xdlFieldType);
-    return fields;
-  }
-
-  /** Field subclass circumventing Field limitations. This one instance can have any combination of indexed, stored,
-   * and docValues.
-   */
-  private static class ComboField extends Field {
-    private ComboField(String name, Object value, FieldType type) {
-      super(name, type);//this expert constructor allows us to have a field that has docValues & indexed/stored
-      super.fieldsData = value;
-    }
-
-    //Is this a hack?  We assume that numericValue() is only called for DocValues purposes.
-    @Override
-    public Number numericValue() {
-      //Numeric DocValues only supports Long,
-      final Number number = super.numericValue();
-      if (number == null)
-        return null;
-      if (fieldType().numericType() == FieldType.LegacyNumericType.DOUBLE)
-        return Double.doubleToLongBits(number.doubleValue());
-      if (fieldType().numericType() == FieldType.LegacyNumericType.FLOAT)
-        return Float.floatToIntBits(number.floatValue());
-      return number.longValue();
-    }
-  }
-
-  //---------------------------------
-  // Value Source / Relevancy
-  //---------------------------------
-
-  /**
-   * Provides access to each rectangle per document as a ValueSource in which
-   * {@link org.apache.lucene.queries.function.FunctionValues#objectVal(int)} returns a {@link
-   * Shape}.
-   */ //TODO raise to SpatialStrategy
-  public ValueSource makeShapeValueSource() {
-    return new BBoxValueSource(this);
-  }
-
-  @Override
-  public ValueSource makeDistanceValueSource(Point queryPoint, double multiplier) {
-    //TODO if makeShapeValueSource gets lifted to the top; this could become a generic impl.
-    return new DistanceToShapeValueSource(makeShapeValueSource(), queryPoint, multiplier, ctx);
-  }
-
-  /** Returns a similarity based on {@link BBoxOverlapRatioValueSource}. This is just a
-   * convenience method. */
-  public ValueSource makeOverlapRatioValueSource(Rectangle queryBox, double queryTargetProportion) {
-    return new BBoxOverlapRatioValueSource(
-        makeShapeValueSource(), ctx.isGeo(), queryBox, queryTargetProportion, 0.0);
-  }
-
-  //---------------------------------
-  // Query Building
-  //---------------------------------
-
-  //  Utility on SpatialStrategy?
-//  public Query makeQueryWithValueSource(SpatialArgs args, ValueSource valueSource) {
-//    return new CustomScoreQuery(makeQuery(args), new FunctionQuery(valueSource));
-  //or...
-//  return new BooleanQuery.Builder()
-//      .add(new FunctionQuery(valueSource), BooleanClause.Occur.MUST)//matches everything and provides score
-//      .add(filterQuery, BooleanClause.Occur.FILTER)//filters (score isn't used)
-//  .build();
-//  }
-
-  @Override
-  public Query makeQuery(SpatialArgs args) {
-    Shape shape = args.getShape();
-    if (!(shape instanceof Rectangle))
-      throw new UnsupportedOperationException("Can only query by Rectangle, not " + shape);
-
-    Rectangle bbox = (Rectangle) shape;
-    Query spatial;
-
-    // Useful for understanding Relations:
-    // http://edndoc.esri.com/arcsde/9.1/general_topics/understand_spatial_relations.htm
-    SpatialOperation op = args.getOperation();
-         if( op == SpatialOperation.BBoxIntersects ) spatial = makeIntersects(bbox);
-    else if( op == SpatialOperation.BBoxWithin     ) spatial = makeWithin(bbox);
-    else if( op == SpatialOperation.Contains       ) spatial = makeContains(bbox);
-    else if( op == SpatialOperation.Intersects     ) spatial = makeIntersects(bbox);
-    else if( op == SpatialOperation.IsEqualTo      ) spatial = makeEquals(bbox);
-    else if( op == SpatialOperation.IsDisjointTo   ) spatial = makeDisjoint(bbox);
-    else if( op == SpatialOperation.IsWithin       ) spatial = makeWithin(bbox);
-    else { //no Overlaps support yet
-        throw new UnsupportedSpatialOperation(op);
-    }
-    return new ConstantScoreQuery(spatial);
-  }
-
-  /**
-   * Constructs a query to retrieve documents that fully contain the input envelope.
-   *
-   * @return the spatial query
-   */
-  Query makeContains(Rectangle bbox) {
-
-    // general case
-    // docMinX <= queryExtent.getMinX() AND docMinY <= queryExtent.getMinY() AND docMaxX >= queryExtent.getMaxX() AND docMaxY >= queryExtent.getMaxY()
-
-    // Y conditions
-    // docMinY <= queryExtent.getMinY() AND docMaxY >= queryExtent.getMaxY()
-    Query qMinY = LegacyNumericRangeQuery.newDoubleRange(field_minY, getPrecisionStep(), null, bbox.getMinY(), false, true);
-    Query qMaxY = LegacyNumericRangeQuery.newDoubleRange(field_maxY, getPrecisionStep(), bbox.getMaxY(), null, true, false);
-    Query yConditions = this.makeQuery(BooleanClause.Occur.MUST, qMinY, qMaxY);
-
-    // X conditions
-    Query xConditions;
-
-    // queries that do not cross the date line
-    if (!bbox.getCrossesDateLine()) {
-
-      // X Conditions for documents that do not cross the date line,
-      // documents that contain the min X and max X of the query envelope,
-      // docMinX <= queryExtent.getMinX() AND docMaxX >= queryExtent.getMaxX()
-      Query qMinX = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), null, bbox.getMinX(), false, true);
-      Query qMaxX = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), bbox.getMaxX(), null, true, false);
-      Query qMinMax = this.makeQuery(BooleanClause.Occur.MUST, qMinX, qMaxX);
-      Query qNonXDL = this.makeXDL(false, qMinMax);
-
-      if (!ctx.isGeo()) {
-        xConditions = qNonXDL;
-      } else {
-        // X Conditions for documents that cross the date line,
-        // the left portion of the document contains the min X of the query
-        // OR the right portion of the document contains the max X of the query,
-        // docMinXLeft <= queryExtent.getMinX() OR docMaxXRight >= queryExtent.getMaxX()
-        Query qXDLLeft = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), null, bbox.getMinX(), false, true);
-        Query qXDLRight = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), bbox.getMaxX(), null, true, false);
-        Query qXDLLeftRight = this.makeQuery(BooleanClause.Occur.SHOULD, qXDLLeft, qXDLRight);
-        Query qXDL = this.makeXDL(true, qXDLLeftRight);
-
-        Query qEdgeDL = null;
-        if (bbox.getMinX() == bbox.getMaxX() && Math.abs(bbox.getMinX()) == 180) {
-          double edge = bbox.getMinX() * -1;//opposite dateline edge
-          qEdgeDL = makeQuery(BooleanClause.Occur.SHOULD,
-              makeNumberTermQuery(field_minX, edge), makeNumberTermQuery(field_maxX, edge));
-        }
-
-        // apply the non-XDL and XDL conditions
-        xConditions = this.makeQuery(BooleanClause.Occur.SHOULD, qNonXDL, qXDL, qEdgeDL);
-      }
-    } else {
-      // queries that cross the date line
-
-      // No need to search for documents that do not cross the date line
-
-      // X Conditions for documents that cross the date line,
-      // the left portion of the document contains the min X of the query
-      // AND the right portion of the document contains the max X of the query,
-      // docMinXLeft <= queryExtent.getMinX() AND docMaxXRight >= queryExtent.getMaxX()
-      Query qXDLLeft = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), null, bbox.getMinX(), false, true);
-      Query qXDLRight = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), bbox.getMaxX(), null, true, false);
-      Query qXDLLeftRight = this.makeXDL(true, this.makeQuery(BooleanClause.Occur.MUST, qXDLLeft, qXDLRight));
-
-      Query qWorld = makeQuery(BooleanClause.Occur.MUST,
-          makeNumberTermQuery(field_minX, -180), makeNumberTermQuery(field_maxX, 180));
-
-      xConditions = makeQuery(BooleanClause.Occur.SHOULD, qXDLLeftRight, qWorld);
-    }
-
-    // both X and Y conditions must occur
-    return this.makeQuery(BooleanClause.Occur.MUST, xConditions, yConditions);
-  }
-
-  /**
-   * Constructs a query to retrieve documents that are disjoint to the input envelope.
-   *
-   * @return the spatial query
-   */
-  Query makeDisjoint(Rectangle bbox) {
-
-    // general case
-    // docMinX > queryExtent.getMaxX() OR docMaxX < queryExtent.getMinX() OR docMinY > queryExtent.getMaxY() OR docMaxY < queryExtent.getMinY()
-
-    // Y conditions
-    // docMinY > queryExtent.getMaxY() OR docMaxY < queryExtent.getMinY()
-    Query qMinY = LegacyNumericRangeQuery.newDoubleRange(field_minY, getPrecisionStep(), bbox.getMaxY(), null, false, false);
-    Query qMaxY = LegacyNumericRangeQuery.newDoubleRange(field_maxY, getPrecisionStep(), null, bbox.getMinY(), false, false);
-    Query yConditions = this.makeQuery(BooleanClause.Occur.SHOULD, qMinY, qMaxY);
-
-    // X conditions
-    Query xConditions;
-
-    // queries that do not cross the date line
-    if (!bbox.getCrossesDateLine()) {
-
-      // X Conditions for documents that do not cross the date line,
-      // docMinX > queryExtent.getMaxX() OR docMaxX < queryExtent.getMinX()
-      Query qMinX = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), bbox.getMaxX(), null, false, false);
-      if (bbox.getMinX() == -180.0 && ctx.isGeo()) {//touches dateline; -180 == 180
-        BooleanQuery.Builder bq = new BooleanQuery.Builder();
-        bq.add(qMinX, BooleanClause.Occur.MUST);
-        bq.add(makeNumberTermQuery(field_maxX, 180.0), BooleanClause.Occur.MUST_NOT);
-        qMinX = bq.build();
-      }
-      Query qMaxX = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, bbox.getMinX(), false, false);
-      if (bbox.getMaxX() == 180.0 && ctx.isGeo()) {//touches dateline; -180 == 180
-        BooleanQuery.Builder bq = new BooleanQuery.Builder();
-        bq.add(qMaxX, BooleanClause.Occur.MUST);
-        bq.add(makeNumberTermQuery(field_minX, -180.0), BooleanClause.Occur.MUST_NOT);
-        qMaxX = bq.build();
-      }
-      Query qMinMax = this.makeQuery(BooleanClause.Occur.SHOULD, qMinX, qMaxX);
-      Query qNonXDL = this.makeXDL(false, qMinMax);
-
-      if (!ctx.isGeo()) {
-        xConditions = qNonXDL;
-      } else {
-        // X Conditions for documents that cross the date line,
-
-        // both the left and right portions of the document must be disjoint to the query
-        // (docMinXLeft > queryExtent.getMaxX() OR docMaxXLeft < queryExtent.getMinX()) AND
-        // (docMinXRight > queryExtent.getMaxX() OR docMaxXRight < queryExtent.getMinX())
-        // where: docMaxXLeft = 180.0, docMinXRight = -180.0
-        // (docMaxXLeft  < queryExtent.getMinX()) equates to (180.0  < queryExtent.getMinX()) and is ignored
-        // (docMinXRight > queryExtent.getMaxX()) equates to (-180.0 > queryExtent.getMaxX()) and is ignored
-        Query qMinXLeft = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), bbox.getMaxX(), null, false, false);
-        Query qMaxXRight = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, bbox.getMinX(), false, false);
-        Query qLeftRight = this.makeQuery(BooleanClause.Occur.MUST, qMinXLeft, qMaxXRight);
-        Query qXDL = this.makeXDL(true, qLeftRight);
-
-        // apply the non-XDL and XDL conditions
-        xConditions = this.makeQuery(BooleanClause.Occur.SHOULD, qNonXDL, qXDL);
-      }
-      // queries that cross the date line
-    } else {
-
-      // X Conditions for documents that do not cross the date line,
-      // the document must be disjoint to both the left and right query portions
-      // (docMinX > queryExtent.getMaxX()Left OR docMaxX < queryExtent.getMinX()) AND (docMinX > queryExtent.getMaxX() OR docMaxX < queryExtent.getMinX()Left)
-      // where: queryExtent.getMaxX()Left = 180.0, queryExtent.getMinX()Left = -180.0
-      Query qMinXLeft = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), 180.0, null, false, false);
-      Query qMaxXLeft = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, bbox.getMinX(), false, false);
-      Query qMinXRight = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), bbox.getMaxX(), null, false, false);
-      Query qMaxXRight = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, -180.0, false, false);
-      Query qLeft = this.makeQuery(BooleanClause.Occur.SHOULD, qMinXLeft, qMaxXLeft);
-      Query qRight = this.makeQuery(BooleanClause.Occur.SHOULD, qMinXRight, qMaxXRight);
-      Query qLeftRight = this.makeQuery(BooleanClause.Occur.MUST, qLeft, qRight);
-
-      // No need to search for documents that do not cross the date line
-
-      xConditions = this.makeXDL(false, qLeftRight);
-    }
-
-    // either X or Y conditions should occur
-    return this.makeQuery(BooleanClause.Occur.SHOULD, xConditions, yConditions);
-  }
-
-  /**
-   * Constructs a query to retrieve documents that equal the input envelope.
-   *
-   * @return the spatial query
-   */
-  Query makeEquals(Rectangle bbox) {
-
-    // docMinX = queryExtent.getMinX() AND docMinY = queryExtent.getMinY() AND docMaxX = queryExtent.getMaxX() AND docMaxY = queryExtent.getMaxY()
-    Query qMinX = makeNumberTermQuery(field_minX, bbox.getMinX());
-    Query qMinY = makeNumberTermQuery(field_minY, bbox.getMinY());
-    Query qMaxX = makeNumberTermQuery(field_maxX, bbox.getMaxX());
-    Query qMaxY = makeNumberTermQuery(field_maxY, bbox.getMaxY());
-    return makeQuery(BooleanClause.Occur.MUST, qMinX, qMinY, qMaxX, qMaxY);
-  }
-
-  /**
-   * Constructs a query to retrieve documents that intersect the input envelope.
-   *
-   * @return the spatial query
-   */
-  Query makeIntersects(Rectangle bbox) {
-
-    // the original intersects query does not work for envelopes that cross the date line,
-    // switch to a NOT Disjoint query
-
-    // MUST_NOT causes a problem when it's the only clause type within a BooleanQuery,
-    // to get around it we add all documents as a SHOULD
-
-    // there must be an envelope, it must not be disjoint
-    Query qHasEnv;
-    if (ctx.isGeo()) {
-      Query qIsNonXDL = this.makeXDL(false);
-      Query qIsXDL = ctx.isGeo() ? this.makeXDL(true) : null;
-      qHasEnv = this.makeQuery(BooleanClause.Occur.SHOULD, qIsNonXDL, qIsXDL);
-    } else {
-      qHasEnv = this.makeXDL(false);
-    }
-
-    BooleanQuery.Builder qNotDisjoint = new BooleanQuery.Builder();
-    qNotDisjoint.add(qHasEnv, BooleanClause.Occur.MUST);
-    Query qDisjoint = makeDisjoint(bbox);
-    qNotDisjoint.add(qDisjoint, BooleanClause.Occur.MUST_NOT);
-
-    //Query qDisjoint = makeDisjoint();
-    //BooleanQuery qNotDisjoint = new BooleanQuery();
-    //qNotDisjoint.add(new MatchAllDocsQuery(),BooleanClause.Occur.SHOULD);
-    //qNotDisjoint.add(qDisjoint,BooleanClause.Occur.MUST_NOT);
-    return qNotDisjoint.build();
-  }
-
-  /**
-   * Makes a boolean query based upon a collection of queries and a logical operator.
-   *
-   * @param occur the logical operator
-   * @param queries the query collection
-   * @return the query
-   */
-  BooleanQuery makeQuery(BooleanClause.Occur occur, Query... queries) {
-    BooleanQuery.Builder bq = new BooleanQuery.Builder();
-    for (Query query : queries) {
-      if (query != null)
-        bq.add(query, occur);
-    }
-    return bq.build();
-  }
-
-  /**
-   * Constructs a query to retrieve documents are fully within the input envelope.
-   *
-   * @return the spatial query
-   */
-  Query makeWithin(Rectangle bbox) {
-
-    // general case
-    // docMinX >= queryExtent.getMinX() AND docMinY >= queryExtent.getMinY() AND docMaxX <= queryExtent.getMaxX() AND docMaxY <= queryExtent.getMaxY()
-
-    // Y conditions
-    // docMinY >= queryExtent.getMinY() AND docMaxY <= queryExtent.getMaxY()
-    Query qMinY = LegacyNumericRangeQuery.newDoubleRange(field_minY, getPrecisionStep(), bbox.getMinY(), null, true, false);
-    Query qMaxY = LegacyNumericRangeQuery.newDoubleRange(field_maxY, getPrecisionStep(), null, bbox.getMaxY(), false, true);
-    Query yConditions = this.makeQuery(BooleanClause.Occur.MUST, qMinY, qMaxY);
-
-    // X conditions
-    Query xConditions;
-
-    if (ctx.isGeo() && bbox.getMinX() == -180.0 && bbox.getMaxX() == 180.0) {
-      //if query world-wraps, only the y condition matters
-      return yConditions;
-
-    } else if (!bbox.getCrossesDateLine()) {
-      // queries that do not cross the date line
-
-      // docMinX >= queryExtent.getMinX() AND docMaxX <= queryExtent.getMaxX()
-      Query qMinX = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), bbox.getMinX(), null, true, false);
-      Query qMaxX = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, bbox.getMaxX(), false, true);
-      Query qMinMax = this.makeQuery(BooleanClause.Occur.MUST, qMinX, qMaxX);
-
-      double edge = 0;//none, otherwise opposite dateline of query
-      if (bbox.getMinX() == -180.0)
-        edge = 180;
-      else if (bbox.getMaxX() == 180.0)
-        edge = -180;
-      if (edge != 0 && ctx.isGeo()) {
-        Query edgeQ = makeQuery(BooleanClause.Occur.MUST,
-            makeNumberTermQuery(field_minX, edge), makeNumberTermQuery(field_maxX, edge));
-        qMinMax = makeQuery(BooleanClause.Occur.SHOULD, qMinMax, edgeQ);
-      }
-
-      xConditions = this.makeXDL(false, qMinMax);
-
-      // queries that cross the date line
-    } else {
-
-      // X Conditions for documents that do not cross the date line
-
-      // the document should be within the left portion of the query
-      // docMinX >= queryExtent.getMinX() AND docMaxX <= 180.0
-      Query qMinXLeft = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), bbox.getMinX(), null, true, false);
-      Query qMaxXLeft = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, 180.0, false, true);
-      Query qLeft = this.makeQuery(BooleanClause.Occur.MUST, qMinXLeft, qMaxXLeft);
-
-      // the document should be within the right portion of the query
-      // docMinX >= -180.0 AND docMaxX <= queryExtent.getMaxX()
-      Query qMinXRight = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), -180.0, null, true, false);
-      Query qMaxXRight = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, bbox.getMaxX(), false, true);
-      Query qRight = this.makeQuery(BooleanClause.Occur.MUST, qMinXRight, qMaxXRight);
-
-      // either left or right conditions should occur,
-      // apply the left and right conditions to documents that do not cross the date line
-      Query qLeftRight = this.makeQuery(BooleanClause.Occur.SHOULD, qLeft, qRight);
-      Query qNonXDL = this.makeXDL(false, qLeftRight);
-
-      // X Conditions for documents that cross the date line,
-      // the left portion of the document must be within the left portion of the query,
-      // AND the right portion of the document must be within the right portion of the query
-      // docMinXLeft >= queryExtent.getMinX() AND docMaxXLeft <= 180.0
-      // AND docMinXRight >= -180.0 AND docMaxXRight <= queryExtent.getMaxX()
-      Query qXDLLeft = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), bbox.getMinX(), null, true, false);
-      Query qXDLRight = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, bbox.getMaxX(), false, true);
-      Query qXDLLeftRight = this.makeQuery(BooleanClause.Occur.MUST, qXDLLeft, qXDLRight);
-      Query qXDL = this.makeXDL(true, qXDLLeftRight);
-
-      // apply the non-XDL and XDL conditions
-      xConditions = this.makeQuery(BooleanClause.Occur.SHOULD, qNonXDL, qXDL);
-    }
-
-    // both X and Y conditions must occur
-    return this.makeQuery(BooleanClause.Occur.MUST, xConditions, yConditions);
-  }
-
-  /**
-   * Constructs a query to retrieve documents that do or do not cross the date line.
-   *
-   * @param crossedDateLine <code>true</true> for documents that cross the date line
-   * @return the query
-   */
-  private Query makeXDL(boolean crossedDateLine) {
-    // The 'T' and 'F' values match solr fields
-    return new TermQuery(new Term(field_xdl, crossedDateLine ? "T" : "F"));
-  }
-
-  /**
-   * Constructs a query to retrieve documents that do or do not cross the date line
-   * and match the supplied spatial query.
-   *
-   * @param crossedDateLine <code>true</true> for documents that cross the date line
-   * @param query the spatial query
-   * @return the query
-   */
-  private Query makeXDL(boolean crossedDateLine, Query query) {
-    if (!ctx.isGeo()) {
-      assert !crossedDateLine;
-      return query;
-    }
-    BooleanQuery.Builder bq = new BooleanQuery.Builder();
-    bq.add(this.makeXDL(crossedDateLine), BooleanClause.Occur.MUST);
-    bq.add(query, BooleanClause.Occur.MUST);
-    return bq.build();
-  }
-
-  private Query makeNumberTermQuery(String field, double number) {
-    BytesRefBuilder bytes = new BytesRefBuilder();
-    LegacyNumericUtils.longToPrefixCoded(LegacyNumericUtils.doubleToSortableLong(number), 0, bytes);
-    return new TermQuery(new Term(field, bytes.get()));
-  }
-
-}
-
-
-

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxValueSource.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxValueSource.java b/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxValueSource.java
deleted file mode 100644
index 5d95407..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxValueSource.java
+++ /dev/null
@@ -1,115 +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.bbox;
-
-import com.spatial4j.core.shape.Rectangle;
-import org.apache.lucene.index.LeafReader;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.DocValues;
-import org.apache.lucene.index.NumericDocValues;
-import org.apache.lucene.queries.function.FunctionValues;
-import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.search.Explanation;
-import org.apache.lucene.util.Bits;
-
-import java.io.IOException;
-import java.util.Map;
-
-/**
- * A ValueSource in which the indexed Rectangle is returned from
- * {@link org.apache.lucene.queries.function.FunctionValues#objectVal(int)}.
- *
- * @lucene.internal
- */
-class BBoxValueSource extends ValueSource {
-
-  private final BBoxStrategy strategy;
-
-  public BBoxValueSource(BBoxStrategy strategy) {
-    this.strategy = strategy;
-  }
-
-  @Override
-  public String description() {
-    return "bboxShape(" + strategy.getFieldName() + ")";
-  }
-
-  @Override
-  public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
-    LeafReader reader = readerContext.reader();
-    final NumericDocValues minX = DocValues.getNumeric(reader, strategy.field_minX);
-    final NumericDocValues minY = DocValues.getNumeric(reader, strategy.field_minY);
-    final NumericDocValues maxX = DocValues.getNumeric(reader, strategy.field_maxX);
-    final NumericDocValues maxY = DocValues.getNumeric(reader, strategy.field_maxY);
-
-    final Bits validBits = DocValues.getDocsWithField(reader, strategy.field_minX);//could have chosen any field
-    //reused
-    final Rectangle rect = strategy.getSpatialContext().makeRectangle(0,0,0,0);
-
-    return new FunctionValues() {
-      @Override
-      public Object objectVal(int doc) {
-        if (!validBits.get(doc)) {
-          return null;
-        } else {
-          rect.reset(
-              Double.longBitsToDouble(minX.get(doc)), Double.longBitsToDouble(maxX.get(doc)),
-              Double.longBitsToDouble(minY.get(doc)), Double.longBitsToDouble(maxY.get(doc)));
-          return rect;
-        }
-      }
-
-      @Override
-      public String strVal(int doc) {//TODO support WKT output once Spatial4j does
-        Object v = objectVal(doc);
-        return v == null ? null : v.toString();
-      }
-
-      @Override
-      public boolean exists(int doc) {
-        return validBits.get(doc);
-      }
-
-      @Override
-      public Explanation explain(int doc) {
-        return Explanation.match(Float.NaN, toString(doc));
-      }
-
-      @Override
-      public String toString(int doc) {
-        return description() + '=' + strVal(doc);
-      }
-    };
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-
-    BBoxValueSource that = (BBoxValueSource) o;
-
-    if (!strategy.equals(that.strategy)) return false;
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    return strategy.hashCode();
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/package-info.java b/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/package-info.java
deleted file mode 100644
index c19529f..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
- 
-/** 
- * Bounding Box Spatial Strategy
- * <p>
- * Index a shape extent using 4 numeric fields and a flag to say if it crosses the dateline
- */
-package org.apache.lucene.spatial.bbox;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/composite/CompositeSpatialStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/composite/CompositeSpatialStrategy.java b/lucene/spatial/src/java/org/apache/lucene/spatial/composite/CompositeSpatialStrategy.java
deleted file mode 100644
index 7dc2dfa..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/composite/CompositeSpatialStrategy.java
+++ /dev/null
@@ -1,144 +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.composite;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.spatial.SpatialStrategy;
-import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.query.SpatialOperation;
-import org.apache.lucene.spatial.query.UnsupportedSpatialOperation;
-import org.apache.lucene.spatial.serialized.SerializedDVStrategy;
-import org.apache.lucene.spatial.util.ShapePredicateValueSource;
-
-/**
- * A composite {@link SpatialStrategy} based on {@link RecursivePrefixTreeStrategy} (RPT) and
- * {@link SerializedDVStrategy} (SDV).
- * RPT acts as an index to the precision available in SDV, and in some circumstances can avoid geometry lookups based
- * on where a cell is in relation to the query shape.  Currently the only predicate optimized like this is Intersects.
- * All predicates are supported except for the BBox* ones, and Disjoint.
- *
- * @lucene.experimental
- */
-public class CompositeSpatialStrategy extends SpatialStrategy {
-
-  //TODO support others? (BBox)
-  private final RecursivePrefixTreeStrategy indexStrategy;
-
-  /** Has the geometry. */ // TODO support others?
-  private final SerializedDVStrategy geometryStrategy;
-  private boolean optimizePredicates = true;
-
-  public CompositeSpatialStrategy(String fieldName,
-                                  RecursivePrefixTreeStrategy indexStrategy, SerializedDVStrategy geometryStrategy) {
-    super(indexStrategy.getSpatialContext(), fieldName);//field name; unused
-    this.indexStrategy = indexStrategy;
-    this.geometryStrategy = geometryStrategy;
-  }
-
-  public RecursivePrefixTreeStrategy getIndexStrategy() {
-    return indexStrategy;
-  }
-
-  public SerializedDVStrategy getGeometryStrategy() {
-    return geometryStrategy;
-  }
-
-  public boolean isOptimizePredicates() {
-    return optimizePredicates;
-  }
-
-  /** Set to false to NOT use optimized search predicates that avoid checking the geometry sometimes. Only useful for
-   * benchmarking. */
-  public void setOptimizePredicates(boolean optimizePredicates) {
-    this.optimizePredicates = optimizePredicates;
-  }
-
-  @Override
-  public Field[] createIndexableFields(Shape shape) {
-    List<Field> fields = new ArrayList<>();
-    Collections.addAll(fields, indexStrategy.createIndexableFields(shape));
-    Collections.addAll(fields, geometryStrategy.createIndexableFields(shape));
-    return fields.toArray(new Field[fields.size()]);
-  }
-
-  @Override
-  public ValueSource makeDistanceValueSource(Point queryPoint, double multiplier) {
-    //TODO consider indexing center-point in DV?  Guarantee contained by the shape, which could then be used for
-    // other purposes like faster WITHIN predicate?
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public Query makeQuery(SpatialArgs args) {
-    final SpatialOperation pred = args.getOperation();
-
-    if (pred == SpatialOperation.BBoxIntersects || pred == SpatialOperation.BBoxWithin) {
-      throw new UnsupportedSpatialOperation(pred);
-    }
-
-    if (pred == SpatialOperation.IsDisjointTo) {
-//      final Query intersectQuery = makeQuery(new SpatialArgs(SpatialOperation.Intersects, args.getShape()));
-//      DocValues.getDocsWithField(reader, geometryStrategy.getFieldName());
-      //TODO resurrect Disjoint spatial query utility accepting a field name known to have DocValues.
-      // update class docs when it's added.
-      throw new UnsupportedSpatialOperation(pred);
-    }
-
-    final ShapePredicateValueSource predicateValueSource =
-        new ShapePredicateValueSource(geometryStrategy.makeShapeValueSource(), pred, args.getShape());
-    //System.out.println("PredOpt: " + optimizePredicates);
-    if (pred == SpatialOperation.Intersects && optimizePredicates) {
-      // We have a smart Intersects impl
-
-      final SpatialPrefixTree grid = indexStrategy.getGrid();
-      final int detailLevel = grid.getLevelForDistance(args.resolveDistErr(ctx, 0.0));//default to max precision
-      return new IntersectsRPTVerifyQuery(args.getShape(), indexStrategy.getFieldName(), grid,
-          detailLevel, indexStrategy.getPrefixGridScanLevel(), predicateValueSource);
-    } else {
-      //The general path; all index matches get verified
-
-      SpatialArgs indexArgs;
-      if (pred == SpatialOperation.Contains) {
-        // note: we could map IsWithin as well but it's pretty darned slow since it touches all world grids
-        indexArgs = args;
-      } else {
-        //TODO add args.clone method with new predicate? Or simply make non-final?
-        indexArgs = new SpatialArgs(SpatialOperation.Intersects, args.getShape());
-        indexArgs.setDistErr(args.getDistErr());
-        indexArgs.setDistErrPct(args.getDistErrPct());
-      }
-
-      if (indexArgs.getDistErr() == null && indexArgs.getDistErrPct() == null) {
-        indexArgs.setDistErrPct(0.10);
-      }
-
-      final Query indexQuery = indexStrategy.makeQuery(indexArgs);
-      return new CompositeVerifyQuery(indexQuery, predicateValueSource);
-    }
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/composite/CompositeVerifyQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/composite/CompositeVerifyQuery.java b/lucene/spatial/src/java/org/apache/lucene/spatial/composite/CompositeVerifyQuery.java
deleted file mode 100644
index e03d959..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/composite/CompositeVerifyQuery.java
+++ /dev/null
@@ -1,121 +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.composite;
-
-import java.io.IOException;
-import java.util.Map;
-
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.queries.function.FunctionValues;
-import org.apache.lucene.queries.function.ValueSource;
-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;
-import org.apache.lucene.util.Bits;
-
-/**
- * A Query that considers an "indexQuery" to have approximate results, and a follow-on
- * {@link ValueSource}/{@link FunctionValues#boolVal(int)} is called to verify each hit
- * from {@link TwoPhaseIterator#matches()}.
- *
- * @lucene.experimental
- */
-public class CompositeVerifyQuery extends Query {
-  final Query indexQuery;//approximation (matches more than needed)
-  final ValueSource predicateValueSource;//we call boolVal(doc)
-
-  public CompositeVerifyQuery(Query indexQuery, ValueSource predicateValueSource) {
-    this.indexQuery = indexQuery;
-    this.predicateValueSource = predicateValueSource;
-  }
-
-  @Override
-  public Query rewrite(IndexReader reader) throws IOException {
-    final Query rewritten = indexQuery.rewrite(reader);
-    if (rewritten != indexQuery) {
-      return new CompositeVerifyQuery(rewritten, predicateValueSource);
-    }
-    return super.rewrite(reader);
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-    if (!super.equals(o)) return false;
-
-    CompositeVerifyQuery that = (CompositeVerifyQuery) o;
-
-    if (!indexQuery.equals(that.indexQuery)) return false;
-    if (!predicateValueSource.equals(that.predicateValueSource)) return false;
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = super.hashCode();
-    result = 31 * result + indexQuery.hashCode();
-    result = 31 * result + predicateValueSource.hashCode();
-    return result;
-  }
-
-  @Override
-  public String toString(String field) {
-    //TODO verify this looks good
-    return getClass().getSimpleName() + "(" + indexQuery.toString(field) + ", " + predicateValueSource + ")";
-  }
-
-  @Override
-  public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
-    final Weight indexQueryWeight = indexQuery.createWeight(searcher, false);//scores aren't unsupported
-    final Map valueSourceContext = ValueSource.newContext(searcher);
-
-    return new ConstantScoreWeight(this) {
-
-      @Override
-      public Scorer scorer(LeafReaderContext context) throws IOException {
-
-        final Scorer indexQueryScorer = indexQueryWeight.scorer(context);
-        if (indexQueryScorer == null) {
-          return null;
-        }
-
-        final FunctionValues predFuncValues = predicateValueSource.getValues(valueSourceContext, context);
-
-        final TwoPhaseIterator twoPhaseIterator = new TwoPhaseIterator(indexQueryScorer.iterator()) {
-          @Override
-          public boolean matches() throws IOException {
-            return predFuncValues.boolVal(indexQueryScorer.docID());
-          }
-
-          @Override
-          public float matchCost() {
-            return 100; // TODO: use cost of predFuncValues.boolVal()
-          }
-        };
-
-        return new ConstantScoreScorer(this, score(), twoPhaseIterator);
-      }
-    };
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java b/lucene/spatial/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java
deleted file mode 100644
index a963b6e..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java
+++ /dev/null
@@ -1,235 +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.composite;
-
-import java.io.IOException;
-import java.util.Map;
-
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.SpatialRelation;
-
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.queries.function.FunctionValues;
-import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.search.ConstantScoreScorer;
-import org.apache.lucene.search.ConstantScoreWeight;
-import org.apache.lucene.search.DocIdSet;
-import org.apache.lucene.search.DocIdSetIterator;
-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;
-import org.apache.lucene.spatial.prefix.AbstractVisitingPrefixTreeQuery;
-import org.apache.lucene.spatial.prefix.tree.Cell;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.util.DocIdSetBuilder;
-
-/**
- * A spatial Intersects predicate that distinguishes an approximated match from an exact match based on which cells
- * are within the query shape. It exposes a {@link TwoPhaseIterator} that will verify a match with a provided
- * predicate in the form of a {@link ValueSource} by calling {@link FunctionValues#boolVal(int)}.
- *
- * @lucene.internal
- */
-public class IntersectsRPTVerifyQuery extends Query {
-
-  private final IntersectsDifferentiatingQuery intersectsDiffQuery;
-  private final ValueSource predicateValueSource; // we call FunctionValues.boolVal(doc)
-
-  public IntersectsRPTVerifyQuery(Shape queryShape, String fieldName, SpatialPrefixTree grid, int detailLevel,
-                                  int prefixGridScanLevel, ValueSource predicateValueSource) {
-    this.predicateValueSource = predicateValueSource;
-    this.intersectsDiffQuery = new IntersectsDifferentiatingQuery(queryShape, fieldName, grid, detailLevel,
-        prefixGridScanLevel);
-  }
-
-  @Override
-  public String toString(String field) {
-    return "IntersectsVerified(fieldName=" + field + ")";
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (!super.equals(o)) return false;
-
-    IntersectsRPTVerifyQuery that = (IntersectsRPTVerifyQuery) o;
-
-    if (!intersectsDiffQuery.equals(that.intersectsDiffQuery)) return false;
-    return predicateValueSource.equals(that.predicateValueSource);
-
-  }
-
-  @Override
-  public int hashCode() {
-    int result = super.hashCode();
-    result = 31 * result + intersectsDiffQuery.hashCode();
-    result = 31 * result + predicateValueSource.hashCode();
-    return result;
-  }
-
-  @Override
-  public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
-    final Map valueSourceContext = ValueSource.newContext(searcher);
-
-    return new ConstantScoreWeight(this) {
-      @Override
-      public Scorer scorer(LeafReaderContext context) throws IOException {
-        // Compute approx & exact
-        final IntersectsDifferentiatingQuery.IntersectsDifferentiatingVisitor result =
-            intersectsDiffQuery.compute(context);
-        if (result.approxDocIdSet == null) {
-          return null;
-        }
-        final DocIdSetIterator approxDISI = result.approxDocIdSet.iterator();
-        if (approxDISI == null) {
-          return null;
-        }
-        final DocIdSetIterator exactIterator;
-        if (result.exactDocIdSet != null) {
-          // If both sets are the same, there's nothing to verify; we needn't return a TwoPhaseIterator
-          if (result.approxDocIdSet == result.exactDocIdSet) {
-            return new ConstantScoreScorer(this, score(), approxDISI);
-          }
-          exactIterator = result.exactDocIdSet.iterator();
-          assert exactIterator != null;
-        } else {
-          exactIterator = null;
-        }
-
-        final FunctionValues predFuncValues = predicateValueSource.getValues(valueSourceContext, context);
-
-        final TwoPhaseIterator twoPhaseIterator = new TwoPhaseIterator(approxDISI) {
-          @Override
-          public boolean matches() throws IOException {
-            final int doc = approxDISI.docID();
-            if (exactIterator != null) {
-              if (exactIterator.docID() < doc) {
-                exactIterator.advance(doc);
-              }
-              if (exactIterator.docID() == doc) {
-                return true;
-              }
-            }
-
-            return predFuncValues.boolVal(doc);
-          }
-
-          @Override
-          public float matchCost() {
-            return 100; // TODO: use cost of exactIterator.advance() and predFuncValues.boolVal()
-          }
-        };
-
-        return new ConstantScoreScorer(this, score(), twoPhaseIterator);
-      }
-    };
-  }
-
-  //This may be a "Query" but we don't use it as-such; the caller calls the constructor and then compute() and examines
-  // the results which consists of two parts -- the approximated results, and a subset of exact matches. The
-  // difference needs to be verified.
-  // TODO refactor AVPTQ to not be a Query?
-  private static class IntersectsDifferentiatingQuery extends AbstractVisitingPrefixTreeQuery {
-
-    public IntersectsDifferentiatingQuery(Shape queryShape, String fieldName, SpatialPrefixTree grid,
-                                          int detailLevel, int prefixGridScanLevel) {
-      super(queryShape, fieldName, grid, detailLevel, prefixGridScanLevel);
-    }
-
-    IntersectsDifferentiatingQuery.IntersectsDifferentiatingVisitor compute(LeafReaderContext context)
-        throws IOException {
-      final IntersectsDifferentiatingQuery.IntersectsDifferentiatingVisitor result =
-          new IntersectsDifferentiatingQuery.IntersectsDifferentiatingVisitor(context);
-      result.getDocIdSet();//computes
-      return result;
-    }
-
-    // TODO consider if IntersectsPrefixTreeQuery should simply do this and provide both sets
-
-    class IntersectsDifferentiatingVisitor extends VisitorTemplate {
-      DocIdSetBuilder approxBuilder = new DocIdSetBuilder(maxDoc);
-      DocIdSetBuilder exactBuilder = new DocIdSetBuilder(maxDoc);
-      boolean approxIsEmpty = true;
-      boolean exactIsEmpty = true;
-      DocIdSet exactDocIdSet;
-      DocIdSet approxDocIdSet;
-
-      public IntersectsDifferentiatingVisitor(LeafReaderContext context) throws IOException {
-        super(context);
-      }
-
-      @Override
-      protected void start() throws IOException {
-      }
-
-      @Override
-      protected DocIdSet finish() throws IOException {
-        if (exactIsEmpty) {
-          exactDocIdSet = null;
-        } else {
-          exactDocIdSet = exactBuilder.build();
-        }
-        if (approxIsEmpty) {
-          approxDocIdSet = exactDocIdSet;//optimization
-        } else {
-          if (exactDocIdSet != null) {
-            approxBuilder.add(exactDocIdSet.iterator());
-          }
-          approxDocIdSet = approxBuilder.build();
-        }
-        return null;//unused in this weird re-use of AVPTQ
-      }
-
-      @Override
-      protected boolean visitPrefix(Cell cell) throws IOException {
-        if (cell.getShapeRel() == SpatialRelation.WITHIN) {
-          exactIsEmpty = false;
-          collectDocs(exactBuilder);//note: we'll add exact to approx on finish()
-          return false;
-        } else if (cell.getLevel() == detailLevel) {
-          approxIsEmpty = false;
-          collectDocs(approxBuilder);
-          return false;
-        }
-        return true;
-      }
-
-      @Override
-      protected void visitLeaf(Cell cell) throws IOException {
-        if (cell.getShapeRel() == SpatialRelation.WITHIN) {
-          exactIsEmpty = false;
-          collectDocs(exactBuilder);//note: we'll add exact to approx on finish()
-        } else {
-          approxIsEmpty = false;
-          collectDocs(approxBuilder);
-        }
-      }
-    }
-
-    @Override
-    public DocIdSet getDocIdSet(LeafReaderContext context) throws IOException {
-      throw new IllegalStateException();
-    }
-
-    @Override
-    public String toString(String field) {
-      throw new IllegalStateException();
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/composite/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/composite/package-info.java b/lucene/spatial/src/java/org/apache/lucene/spatial/composite/package-info.java
deleted file mode 100644
index c207ea6..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/composite/package-info.java
+++ /dev/null
@@ -1,19 +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.
- */
-
-/** Composite strategies. */
-package org.apache.lucene.spatial.composite;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/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
index bd3dbdd..396d88e 100644
--- 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
@@ -57,6 +57,11 @@ public class GeoPointDistanceQuery extends GeoPointInBBoxQuery {
     this(field, TermEncoding.PREFIX, centerLon, centerLat, 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 centerLon, final double centerLat, final double radiusMeters) {
     this(field, termEncoding, GeoUtils.circleToBBox(centerLon, centerLat, radiusMeters), centerLon, centerLat, radiusMeters);
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceRangeQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceRangeQuery.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceRangeQuery.java
index e7faccb..f24aa6a 100644
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceRangeQuery.java
+++ b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceRangeQuery.java
@@ -30,6 +30,7 @@ import org.apache.lucene.spatial.geopoint.document.GeoPointField.TermEncoding;
  *    @lucene.experimental
  */
 public final class GeoPointDistanceRangeQuery extends GeoPointDistanceQuery {
+  /** minimum distance range (in meters) from lon, lat center location, maximum is inherited */
   protected final double minRadiusMeters;
 
   /**
@@ -41,6 +42,11 @@ public final class GeoPointDistanceRangeQuery extends GeoPointDistanceQuery {
     this(field, TermEncoding.PREFIX, centerLon, centerLat, minRadiusMeters, maxRadiusMeters);
   }
 
+  /**
+   * Constructs a query for all {@link org.apache.lucene.spatial.geopoint.document.GeoPointField} types within a minimum / maximum
+   * distance (in meters) range from a given point. Accepts an optional
+   * {@link org.apache.lucene.spatial.geopoint.document.GeoPointField.TermEncoding}
+   */
   public GeoPointDistanceRangeQuery(final String field, final TermEncoding termEncoding, final double centerLon, final double centerLat,
                                     final double minRadiusMeters, final double maxRadius) {
     super(field, termEncoding, centerLon, centerLat, maxRadius);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/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
index 64e8f76..32c0aec 100644
--- 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
@@ -45,11 +45,17 @@ import org.apache.lucene.spatial.util.GeoUtils;
  * @lucene.experimental
  */
 public class GeoPointInBBoxQuery extends Query {
+  /** field name */
   protected final String field;
+  /** minimum longitude value (in degrees) */
   protected final double minLon;
+  /** minimum latitude value (in degrees) */
   protected final double minLat;
+  /** maximum longitude value (in degrees) */
   protected final double maxLon;
+  /** maximum latitude value (in degrees) */
   protected final double maxLat;
+  /** term encoding enum to define how the points are encoded (PREFIX or NUMERIC) */
   protected final TermEncoding termEncoding;
 
   /**
@@ -60,6 +66,10 @@ public class GeoPointInBBoxQuery extends Query {
     this(field, TermEncoding.PREFIX, minLon, minLat, maxLon, maxLat);
   }
 
+  /**
+   * 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 minLon, final double minLat, final double maxLon, final double maxLat) {
     this.field = field;
     this.minLon = minLon;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/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
index 6b0d4dd..ef8c2ff 100644
--- 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
@@ -47,9 +47,15 @@ import org.apache.lucene.spatial.util.GeoUtils;
 public final class GeoPointInPolygonQuery extends GeoPointInBBoxQuery {
   // polygon position arrays - this avoids the use of any objects or
   // or geo library dependencies
+  /** array of x (longitude) values (in degrees) */
   protected final double[] x;
+  /** array of y (latitude) values (in degrees) */
   protected final double[] y;
 
+  /**
+   * 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.
+   */
   public GeoPointInPolygonQuery(final String field, final double[] polyLons, final double[] polyLats) {
     this(field, TermEncoding.PREFIX, GeoUtils.polyToBBox(polyLons, polyLats), polyLons, polyLats);
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeQuery.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeQuery.java
deleted file mode 100644
index 127e689..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeQuery.java
+++ /dev/null
@@ -1,133 +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.prefix;
-
-import java.io.IOException;
-
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.index.LeafReader;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.PostingsEnum;
-import org.apache.lucene.index.Terms;
-import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.ConstantScoreScorer;
-import org.apache.lucene.search.ConstantScoreWeight;
-import org.apache.lucene.search.DocIdSet;
-import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.Scorer;
-import org.apache.lucene.search.Weight;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.util.BitSet;
-import org.apache.lucene.util.DocIdSetBuilder;
-
-/**
- * Base class for Lucene Queries on SpatialPrefixTree fields.
- * @lucene.internal
- */
-public abstract class AbstractPrefixTreeQuery extends Query {
-
-  protected final Shape queryShape;
-  protected final String fieldName;
-  protected final SpatialPrefixTree grid;//not in equals/hashCode since it's implied for a specific field
-  protected final int detailLevel;
-
-  public AbstractPrefixTreeQuery(Shape queryShape, String fieldName, SpatialPrefixTree grid, int detailLevel) {
-    this.queryShape = queryShape;
-    this.fieldName = fieldName;
-    this.grid = grid;
-    this.detailLevel = detailLevel;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (super.equals(o) == false) return false;
-
-    AbstractPrefixTreeQuery that = (AbstractPrefixTreeQuery) o;
-
-    if (detailLevel != that.detailLevel) return false;
-    if (!fieldName.equals(that.fieldName)) return false;
-    if (!queryShape.equals(that.queryShape)) return false;
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = super.hashCode();
-    result = 31 * result + queryShape.hashCode();
-    result = 31 * result + fieldName.hashCode();
-    result = 31 * result + detailLevel;
-    return result;
-  }
-
-  @Override
-  public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
-    return new ConstantScoreWeight(this) {
-      @Override
-      public Scorer scorer(LeafReaderContext context) throws IOException {
-        DocIdSet docSet = getDocIdSet(context);
-        if (docSet == null) {
-          return null;
-        }
-        DocIdSetIterator disi = docSet.iterator();
-        if (disi == null) {
-          return null;
-        }
-        return new ConstantScoreScorer(this, score(), disi);
-      }
-    };
-  }
-
-  protected abstract DocIdSet getDocIdSet(LeafReaderContext context) throws IOException;
-
-  /** Holds transient state and docid collecting utility methods as part of
-   * traversing a {@link TermsEnum} for a {@link org.apache.lucene.index.LeafReaderContext}. */
-  public abstract class BaseTermsEnumTraverser {//TODO rename to LeafTermsEnumTraverser ?
-    //note: only 'fieldName' (accessed in constructor) keeps this from being a static inner class
-
-    protected final LeafReaderContext context;
-    protected final int maxDoc;
-
-    protected TermsEnum termsEnum;//remember to check for null!
-    protected PostingsEnum postingsEnum;
-
-    public BaseTermsEnumTraverser(LeafReaderContext context) throws IOException {
-      this.context = context;
-      LeafReader reader = context.reader();
-      this.maxDoc = reader.maxDoc();
-      Terms terms = reader.terms(fieldName);
-      if (terms != null)
-        this.termsEnum = terms.iterator();
-    }
-
-    protected void collectDocs(BitSet bitSet) throws IOException {
-      assert termsEnum != null;
-      postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.NONE);
-      bitSet.or(postingsEnum);
-    }
-
-    protected void collectDocs(DocIdSetBuilder docSetBuilder) throws IOException {
-      assert termsEnum != null;
-      postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.NONE);
-      docSetBuilder.add(postingsEnum);
-    }
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractVisitingPrefixTreeQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractVisitingPrefixTreeQuery.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractVisitingPrefixTreeQuery.java
deleted file mode 100644
index 2237ca9..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/AbstractVisitingPrefixTreeQuery.java
+++ /dev/null
@@ -1,380 +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.prefix;
-
-import java.io.IOException;
-import java.util.Iterator;
-
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.SpatialRelation;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.DocIdSet;
-import org.apache.lucene.spatial.prefix.tree.Cell;
-import org.apache.lucene.spatial.prefix.tree.CellIterator;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.util.BytesRef;
-
-/**
- * Traverses a {@link SpatialPrefixTree} indexed field, using the template and
- * visitor design patterns for subclasses to guide the traversal and collect
- * matching documents.
- * <p>
- * Subclasses implement {@link #getDocIdSet(org.apache.lucene.index.LeafReaderContext)}
- * by instantiating a custom {@link VisitorTemplate} subclass (i.e. an anonymous inner class)
- * and implement the required methods.
- *
- * @lucene.internal
- */
-public abstract class AbstractVisitingPrefixTreeQuery extends AbstractPrefixTreeQuery {
-
-  //Historical note: this code resulted from a refactoring of RecursivePrefixTreeQuery,
-  // which in turn came out of SOLR-2155
-
-  //This class perhaps could have been implemented in terms of FilteredTermsEnum & MultiTermQuery.
-  //  Maybe so for simple Intersects predicate but not for when we want to collect terms
-  //  differently depending on cell state like IsWithin and for fuzzy/accurate collection planned improvements.  At
-  //  least it would just make things more complicated.
-
-  protected final int prefixGridScanLevel;//at least one less than grid.getMaxLevels()
-
-  public AbstractVisitingPrefixTreeQuery(Shape queryShape, String fieldName, SpatialPrefixTree grid,
-                                         int detailLevel, int prefixGridScanLevel) {
-    super(queryShape, fieldName, grid, detailLevel);
-    this.prefixGridScanLevel = Math.max(0, Math.min(prefixGridScanLevel, grid.getMaxLevels() - 1));
-    assert detailLevel <= grid.getMaxLevels();
-  }
-
-  /**
-   * An abstract class designed to make it easy to implement predicates or
-   * other operations on a {@link SpatialPrefixTree} indexed field. An instance
-   * of this class is not designed to be re-used across LeafReaderContext
-   * instances so simply create a new one per-leaf.
-   * The {@link #getDocIdSet()} method here starts the work. It first checks
-   * that there are indexed terms; if not it quickly returns null. Then it calls
-   * {@link #start()} so a subclass can set up a return value, like an
-   * {@link org.apache.lucene.util.FixedBitSet}. Then it starts the traversal
-   * process, calling {@link #findSubCellsToVisit(org.apache.lucene.spatial.prefix.tree.Cell)}
-   * which by default finds the top cells that intersect {@code queryShape}. If
-   * there isn't an indexed cell for a corresponding cell returned for this
-   * method then it's short-circuited until it finds one, at which point
-   * {@link #visitPrefix(org.apache.lucene.spatial.prefix.tree.Cell)} is called. At
-   * some depths, of the tree, the algorithm switches to a scanning mode that
-   * calls {@link #visitScanned(org.apache.lucene.spatial.prefix.tree.Cell)}
-   * for each leaf cell found.
-   *
-   * @lucene.internal
-   */
-  public abstract class VisitorTemplate extends BaseTermsEnumTraverser {
-
-  /* Future potential optimizations:
-
-  * Can a polygon query shape be optimized / made-simpler at recursive depths
-    (e.g. intersection of shape + cell box)
-
-  * RE "scan" vs divide & conquer performance decision:
-    We should use termsEnum.docFreq() as an estimate on the number of places at
-    this depth.  It would be nice if termsEnum knew how many terms
-    start with the current term without having to repeatedly next() & test to find out.
-
-  * Perhaps don't do intermediate seek()'s to cells above detailLevel that have Intersects
-    relation because we won't be collecting those docs any way.  However seeking
-    does act as a short-circuit.  So maybe do some percent of the time or when the level
-    is above some threshold.
-
-  */
-
-    //
-    //  TODO MAJOR REFACTOR SIMPLIFICATION BASED ON TreeCellIterator  TODO
-    //
-
-    private VNode curVNode;//current pointer, derived from query shape
-    private BytesRef curVNodeTerm = new BytesRef();//curVNode.cell's term, without leaf. in main loop only
-
-    private BytesRef thisTerm;//the result of termsEnum.term()
-    private Cell indexedCell;//Cell wrapper of thisTerm. Always updated when thisTerm is.
-
-    public VisitorTemplate(LeafReaderContext context) throws IOException {
-      super(context);
-    }
-
-    public DocIdSet getDocIdSet() throws IOException {
-      assert curVNode == null : "Called more than once?";
-      if (termsEnum == null)
-        return null;
-      if (!nextTerm()) {//advances
-        return null;
-      }
-
-      curVNode = new VNode(null);
-      curVNode.reset(grid.getWorldCell());
-
-      start();
-
-      addIntersectingChildren();
-
-      main: while (thisTerm != null) {//terminates for other reasons too!
-
-        //Advance curVNode pointer
-        if (curVNode.children != null) {
-          //-- HAVE CHILDREN: DESCEND
-          assert curVNode.children.hasNext();//if we put it there then it has something
-          preSiblings(curVNode);
-          curVNode = curVNode.children.next();
-        } else {
-          //-- NO CHILDREN: ADVANCE TO NEXT SIBLING
-          VNode parentVNode = curVNode.parent;
-          while (true) {
-            if (parentVNode == null)
-              break main; // all done
-            if (parentVNode.children.hasNext()) {
-              //advance next sibling
-              curVNode = parentVNode.children.next();
-              break;
-            } else {
-              //reached end of siblings; pop up
-              postSiblings(parentVNode);
-              parentVNode.children = null;//GC
-              parentVNode = parentVNode.parent;
-            }
-          }
-        }
-
-        //Seek to curVNode's cell (or skip if termsEnum has moved beyond)
-        final int compare = indexedCell.compareToNoLeaf(curVNode.cell);
-        if (compare > 0) {
-          // The indexed cell is after; continue loop to next query cell
-          continue;
-        }
-        if (compare < 0) {
-          // The indexed cell is before; seek ahead to query cell:
-          //      Seek !
-          curVNode.cell.getTokenBytesNoLeaf(curVNodeTerm);
-          TermsEnum.SeekStatus seekStatus = termsEnum.seekCeil(curVNodeTerm);
-          if (seekStatus == TermsEnum.SeekStatus.END)
-            break; // all done
-          thisTerm = termsEnum.term();
-          indexedCell = grid.readCell(thisTerm, indexedCell);
-          if (seekStatus == TermsEnum.SeekStatus.NOT_FOUND) {
-            // Did we find a leaf of the cell we were looking for or something after?
-            if (!indexedCell.isLeaf() || indexedCell.compareToNoLeaf(curVNode.cell) != 0)
-              continue; // The indexed cell is after; continue loop to next query cell
-          }
-        }
-        // indexedCell == queryCell (disregarding leaf).
-
-        // If indexedCell is a leaf then there's no prefix (prefix sorts before) -- just visit and continue
-        if (indexedCell.isLeaf()) {
-          visitLeaf(indexedCell);//TODO or query cell? Though shouldn't matter.
-          if (!nextTerm()) break;
-          continue;
-        }
-        // If a prefix (non-leaf) then visit; see if we descend.
-        final boolean descend = visitPrefix(curVNode.cell);//need to use curVNode.cell not indexedCell
-        if (!nextTerm()) break;
-        // Check for adjacent leaf with the same prefix
-        if (indexedCell.isLeaf() && indexedCell.getLevel() == curVNode.cell.getLevel()) {
-          visitLeaf(indexedCell);//TODO or query cell? Though shouldn't matter.
-          if (!nextTerm()) break;
-        }
-
-
-        if (descend) {
-          addIntersectingChildren();
-        }
-
-      }//main loop
-
-      return finish();
-    }
-
-    /** Called initially, and whenever {@link #visitPrefix(org.apache.lucene.spatial.prefix.tree.Cell)}
-     * returns true. */
-    private void addIntersectingChildren() throws IOException {
-      assert thisTerm != null;
-      Cell cell = curVNode.cell;
-      if (cell.getLevel() >= detailLevel)
-        throw new IllegalStateException("Spatial logic error");
-
-      //Decide whether to continue to divide & conquer, or whether it's time to
-      // scan through terms beneath this cell.
-      // Scanning is a performance optimization trade-off.
-
-      //TODO use termsEnum.docFreq() as heuristic
-      boolean scan = cell.getLevel() >= prefixGridScanLevel;//simple heuristic
-
-      if (!scan) {
-        //Divide & conquer (ultimately termsEnum.seek())
-
-        Iterator<Cell> subCellsIter = findSubCellsToVisit(cell);
-        if (!subCellsIter.hasNext())//not expected
-          return;
-        curVNode.children = new VNodeCellIterator(subCellsIter, new VNode(curVNode));
-
-      } else {
-        //Scan (loop of termsEnum.next())
-
-        scan(detailLevel);
-      }
-    }
-
-    /**
-     * Called when doing a divide and conquer to find the next intersecting cells
-     * of the query shape that are beneath {@code cell}. {@code cell} is
-     * guaranteed to have an intersection and thus this must return some number
-     * of nodes.
-     */
-    protected CellIterator findSubCellsToVisit(Cell cell) {
-      return cell.getNextLevelCells(queryShape);
-    }
-
-    /**
-     * Scans ({@code termsEnum.next()}) terms until a term is found that does
-     * not start with curVNode's cell. If it finds a leaf cell or a cell at
-     * level {@code scanDetailLevel} then it calls {@link
-     * #visitScanned(org.apache.lucene.spatial.prefix.tree.Cell)}.
-     */
-    protected void scan(int scanDetailLevel) throws IOException {
-      //note: this can be a do-while instead in 6x; 5x has a back-compat with redundant leaves -- LUCENE-4942
-      while (curVNode.cell.isPrefixOf(indexedCell)) {
-        if (indexedCell.getLevel() == scanDetailLevel
-            || (indexedCell.getLevel() < scanDetailLevel && indexedCell.isLeaf())) {
-          visitScanned(indexedCell);
-        }
-        //advance
-        if (!nextTerm()) break;
-      }
-    }
-
-    private boolean nextTerm() throws IOException {
-      if ((thisTerm = termsEnum.next()) == null)
-        return false;
-      indexedCell = grid.readCell(thisTerm, indexedCell);
-      return true;
-    }
-
-    /** Used for {@link VNode#children}. */
-    private class VNodeCellIterator implements Iterator<VNode> {
-
-      final Iterator<Cell> cellIter;
-      private final VNode vNode;
-
-      VNodeCellIterator(Iterator<Cell> cellIter, VNode vNode) {
-        this.cellIter = cellIter;
-        this.vNode = vNode;
-      }
-
-      @Override
-      public boolean hasNext() {
-        return cellIter.hasNext();
-      }
-
-      @Override
-      public VNode next() {
-        assert hasNext();
-        vNode.reset(cellIter.next());
-        return vNode;
-      }
-
-      @Override
-      public void remove() {//it always removes
-      }
-    }
-
-    /** Called first to setup things. */
-    protected abstract void start() throws IOException;
-
-    /** Called last to return the result. */
-    protected abstract DocIdSet finish() throws IOException;
-
-    /**
-     * Visit an indexed non-leaf cell. The presence of a prefix cell implies
-     * there are leaf cells at further levels. The cell passed should have it's
-     * {@link org.apache.lucene.spatial.prefix.tree.Cell#getShapeRel()} set
-     * relative to the filtered shape.
-     *
-     * @param cell An intersecting cell; not a leaf.
-     * @return true to descend to more levels.
-     */
-    protected abstract boolean visitPrefix(Cell cell) throws IOException;
-
-    /**
-     * Called when an indexed leaf cell is found. An
-     * indexed leaf cell usually means associated documents won't be found at
-     * further detail levels.  However, if a document has
-     * multiple overlapping shapes at different resolutions, then this isn't true.
-     */
-    protected abstract void visitLeaf(Cell cell) throws IOException;
-
-    /**
-     * The cell is either indexed as a leaf or is the last level of detail. It
-     * might not even intersect the query shape, so be sure to check for that.
-     * The default implementation will check that and if passes then call
-     * {@link #visitLeaf(org.apache.lucene.spatial.prefix.tree.Cell)} or
-     * {@link #visitPrefix(org.apache.lucene.spatial.prefix.tree.Cell)}.
-     */
-    protected void visitScanned(Cell cell) throws IOException {
-      final SpatialRelation relate = cell.getShape().relate(queryShape);
-      if (relate.intersects()) {
-        cell.setShapeRel(relate);//just being pedantic
-        if (cell.isLeaf()) {
-          visitLeaf(cell);
-        } else {
-          visitPrefix(cell);
-        }
-      }
-    }
-
-    protected void preSiblings(VNode vNode) throws IOException {
-    }
-
-    protected void postSiblings(VNode vNode) throws IOException {
-    }
-  }//class VisitorTemplate
-
-  /**
-   * A visitor node/cell found via the query shape for {@link VisitorTemplate}.
-   * Sometimes these are reset(cell). It's like a LinkedList node but forms a
-   * tree.
-   *
-   * @lucene.internal
-   */
-  protected static class VNode {
-    //Note: The VNode tree adds more code to debug/maintain v.s. a flattened
-    // LinkedList that we used to have. There is more opportunity here for
-    // custom behavior (see preSiblings & postSiblings) but that's not
-    // leveraged yet. Maybe this is slightly more GC friendly.
-
-    final VNode parent;//only null at the root
-    Iterator<VNode> children;//null, then sometimes set, then null
-    Cell cell;//not null (except initially before reset())
-
-    /**
-     * call reset(cell) after to set the cell.
-     */
-    VNode(VNode parent) { // remember to call reset(cell) after
-      this.parent = parent;
-    }
-
-    void reset(Cell cell) {
-      assert cell != null;
-      this.cell = cell;
-      assert children == null;
-    }
-
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/BytesRefIteratorTokenStream.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/BytesRefIteratorTokenStream.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/BytesRefIteratorTokenStream.java
deleted file mode 100644
index e724ab0..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/BytesRefIteratorTokenStream.java
+++ /dev/null
@@ -1,72 +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.prefix;
-
-import java.io.IOException;
-
-import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.tokenattributes.BytesTermAttribute;
-import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.BytesRefIterator;
-
-/**
- * A TokenStream used internally by {@link org.apache.lucene.spatial.prefix.PrefixTreeStrategy}.
- *
- * This is modelled after {@link org.apache.lucene.analysis.LegacyNumericTokenStream}.
- *
- * @lucene.internal
- */
-class BytesRefIteratorTokenStream extends TokenStream {
-
-  public BytesRefIterator getBytesRefIterator() {
-    return bytesIter;
-  }
-
-  public BytesRefIteratorTokenStream setBytesRefIterator(BytesRefIterator iter) {
-    this.bytesIter = iter;
-    return this;
-  }
-
-  @Override
-  public void reset() throws IOException {
-    if (bytesIter == null)
-      throw new IllegalStateException("call setBytesRefIterator() before usage");
-  }
-
-  @Override
-  public final boolean incrementToken() throws IOException {
-    if (bytesIter == null)
-      throw new IllegalStateException("call setBytesRefIterator() before usage");
-
-    // get next
-    BytesRef bytes = bytesIter.next();
-    if (bytes == null) {
-      return false;
-    } else {
-      clearAttributes();
-      bytesAtt.setBytesRef(bytes);
-      //note: we don't bother setting posInc or type attributes.  There's no point to it.
-      return true;
-    }
-  }
-
-  //members
-  private final BytesTermAttribute bytesAtt = addAttribute(BytesTermAttribute.class);
-
-  private BytesRefIterator bytesIter = null; // null means not initialized
-
-}


[05/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/serialized/SerializedStrategyTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/serialized/SerializedStrategyTest.java b/lucene/spatial/src/test/org/apache/lucene/spatial/serialized/SerializedStrategyTest.java
deleted file mode 100644
index bed8339..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/serialized/SerializedStrategyTest.java
+++ /dev/null
@@ -1,66 +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.serialized;
-
-import java.io.IOException;
-
-import com.spatial4j.core.context.SpatialContext;
-import org.apache.lucene.spatial.SpatialMatchConcern;
-import org.apache.lucene.spatial.StrategyTestCase;
-import org.junit.Before;
-import org.junit.Test;
-
-public class SerializedStrategyTest extends StrategyTestCase {
-
-  @Before
-  @Override
-  public void setUp() throws Exception {
-    super.setUp();
-    this.ctx = SpatialContext.GEO;
-    this.strategy = new SerializedDVStrategy(ctx, "serialized");
-  }
-
-  @Override
-  protected boolean needsDocValues() {
-    return (strategy instanceof SerializedDVStrategy);
-  }
-
-  @Test
-  public void testBasicOperaions() throws IOException {
-    getAddAndVerifyIndexedDocuments(DATA_SIMPLE_BBOX);
-
-    executeQueries(SpatialMatchConcern.EXACT, QTEST_Simple_Queries_BBox);
-  }
-
-  @Test
-  public void testStatesBBox() throws IOException {
-    getAddAndVerifyIndexedDocuments(DATA_STATES_BBOX);
-
-    executeQueries(SpatialMatchConcern.FILTER, QTEST_States_IsWithin_BBox);
-    executeQueries(SpatialMatchConcern.FILTER, QTEST_States_Intersects_BBox);
-  }
-
-  @Test
-  public void testCitiesIntersectsBBox() throws IOException {
-    getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS);
-
-    executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_Intersects_BBox);
-  }
-
-  //sorting is tested in DistanceStrategyTest
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java b/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java
deleted file mode 100644
index 7c98d0244..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java
+++ /dev/null
@@ -1,227 +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.spatial4j;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.carrotsearch.randomizedtesting.annotations.Repeat;
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.spatial.composite.CompositeSpatialStrategy;
-import org.apache.lucene.spatial.prefix.RandomSpatialOpStrategyTestCase;
-import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
-import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
-import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
-import org.apache.lucene.spatial.query.SpatialOperation;
-import org.apache.lucene.spatial.serialized.SerializedDVStrategy;
-import org.apache.lucene.geo3d.GeoBBoxFactory;
-import org.apache.lucene.geo3d.GeoStandardCircle;
-import org.apache.lucene.geo3d.GeoPath;
-import org.apache.lucene.geo3d.GeoPoint;
-import org.apache.lucene.geo3d.GeoPolygonFactory;
-import org.apache.lucene.geo3d.GeoShape;
-import org.apache.lucene.geo3d.PlanetModel;
-import org.junit.Test;
-
-import static com.spatial4j.core.distance.DistanceUtils.DEGREES_TO_RADIANS;
-
-public class Geo3dRptTest extends RandomSpatialOpStrategyTestCase {
-
-  private SpatialPrefixTree grid;
-  private RecursivePrefixTreeStrategy rptStrategy;
-  {
-    this.ctx = SpatialContext.GEO;
-  }
-
-  private void setupGeohashGrid() {
-    this.grid = new GeohashPrefixTree(ctx, 2);//A fairly shallow grid
-    this.rptStrategy = newRPT();
-  }
-
-  protected RecursivePrefixTreeStrategy newRPT() {
-    final RecursivePrefixTreeStrategy rpt = new RecursivePrefixTreeStrategy(this.grid,
-        getClass().getSimpleName() + "_rpt");
-    rpt.setDistErrPct(0.10);//not too many cells
-    return rpt;
-  }
-
-  @Override
-  protected boolean needsDocValues() {
-    return true;//due to SerializedDVStrategy
-  }
-
-  private void setupStrategy() {
-    //setup
-    setupGeohashGrid();
-
-    SerializedDVStrategy serializedDVStrategy = new SerializedDVStrategy(ctx, getClass().getSimpleName() + "_sdv");
-    this.strategy = new CompositeSpatialStrategy("composite_" + getClass().getSimpleName(),
-        rptStrategy, serializedDVStrategy);
-  }
-
-  @Test
-  public void testFailure1() throws IOException {
-    setupStrategy();
-    final List<GeoPoint> points = new ArrayList<GeoPoint>();
-    points.add(new GeoPoint(PlanetModel.SPHERE, 18 * DEGREES_TO_RADIANS, -27 * DEGREES_TO_RADIANS));
-    points.add(new GeoPoint(PlanetModel.SPHERE, -57 * DEGREES_TO_RADIANS, 146 * DEGREES_TO_RADIANS));
-    points.add(new GeoPoint(PlanetModel.SPHERE, 14 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS));
-    points.add(new GeoPoint(PlanetModel.SPHERE, -15 * DEGREES_TO_RADIANS, 153 * DEGREES_TO_RADIANS));
-    
-    final Shape triangle = new Geo3dShape(GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points,0),ctx);
-    final Rectangle rect = ctx.makeRectangle(-49, -45, 73, 86);
-    testOperation(rect,SpatialOperation.Intersects,triangle, false);
-  }
-
-  @Test
-  public void testFailureLucene6535() throws IOException {
-    setupStrategy();
-
-    final List<GeoPoint> points = new ArrayList<>();
-    points.add(new GeoPoint(PlanetModel.SPHERE, 18 * DEGREES_TO_RADIANS, -27 * DEGREES_TO_RADIANS));
-    points.add(new GeoPoint(PlanetModel.SPHERE, -57 * DEGREES_TO_RADIANS, 146 * DEGREES_TO_RADIANS));
-    points.add(new GeoPoint(PlanetModel.SPHERE, 14 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS));
-    points.add(new GeoPoint(PlanetModel.SPHERE, -15 * DEGREES_TO_RADIANS, 153 * DEGREES_TO_RADIANS));
-    final GeoPath path = new GeoPath(PlanetModel.SPHERE, 29 * DEGREES_TO_RADIANS);
-    path.addPoint(55.0 * DEGREES_TO_RADIANS, -26.0 * DEGREES_TO_RADIANS);
-    path.addPoint(-90.0 * DEGREES_TO_RADIANS, 0.0);
-    path.addPoint(54.0 * DEGREES_TO_RADIANS, 165.0 * DEGREES_TO_RADIANS);
-    path.addPoint(-90.0 * DEGREES_TO_RADIANS, 0.0);
-    path.done();
-    final Shape shape = new Geo3dShape(path,ctx);
-    final Rectangle rect = ctx.makeRectangle(131, 143, 39, 54);
-    testOperation(rect,SpatialOperation.Intersects,shape,true);
-  }
-
-  @Test
-  @Repeat(iterations = 10)
-  public void testOperations() throws IOException {
-    setupStrategy();
-
-    testOperationRandomShapes(SpatialOperation.Intersects);
-  }
-
-  private Shape makeTriangle(double x1, double y1, double x2, double y2, double x3, double y3) {
-    final List<GeoPoint> geoPoints = new ArrayList<>();
-    geoPoints.add(new GeoPoint(PlanetModel.SPHERE, y1 * DEGREES_TO_RADIANS, x1 * DEGREES_TO_RADIANS));
-    geoPoints.add(new GeoPoint(PlanetModel.SPHERE, y2 * DEGREES_TO_RADIANS, x2 * DEGREES_TO_RADIANS));
-    geoPoints.add(new GeoPoint(PlanetModel.SPHERE, y3 * DEGREES_TO_RADIANS, x3 * DEGREES_TO_RADIANS));
-    final int convexPointIndex = 0;
-    final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, geoPoints, convexPointIndex);
-    return new Geo3dShape(shape, ctx);
-  }
-
-  @Override
-  protected Shape randomIndexedShape() {
-    return randomRectangle();
-  }
-
-  @Override
-  protected Shape randomQueryShape() {
-    final int shapeType = random().nextInt(4);
-    switch (shapeType) {
-    case 0: {
-        // Polygons
-        final int vertexCount = random().nextInt(3) + 3;
-        while (true) {
-          final List<GeoPoint> geoPoints = new ArrayList<>();
-          while (geoPoints.size() < vertexCount) {
-            final Point point = randomPoint();
-            final GeoPoint gPt = new GeoPoint(PlanetModel.SPHERE, point.getY() * DEGREES_TO_RADIANS, point.getX() * DEGREES_TO_RADIANS);
-            geoPoints.add(gPt);
-          }
-          final int convexPointIndex = random().nextInt(vertexCount);       //If we get this wrong, hopefully we get IllegalArgumentException
-          try {
-            final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, geoPoints, convexPointIndex);
-            return new Geo3dShape(shape, ctx);
-          } catch (IllegalArgumentException e) {
-            // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
-            // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
-            continue;
-          }
-        }
-      }
-    case 1: {
-        // Circles
-        while (true) {
-          final int circleRadius = random().nextInt(179) + 1;
-          final Point point = randomPoint();
-          try {
-            final GeoShape shape = new GeoStandardCircle(PlanetModel.SPHERE, point.getY() * DEGREES_TO_RADIANS, point.getX() * DEGREES_TO_RADIANS,
-              circleRadius * DEGREES_TO_RADIANS);
-            return new Geo3dShape(shape, ctx);
-          } catch (IllegalArgumentException e) {
-            // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
-            // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
-            continue;
-          }
-        }
-      }
-    case 2: {
-        // Rectangles
-        while (true) {
-          Point ulhcPoint = randomPoint();
-          Point lrhcPoint = randomPoint();
-          if (ulhcPoint.getY() < lrhcPoint.getY()) {
-            //swap
-            Point temp = ulhcPoint;
-            ulhcPoint = lrhcPoint;
-            lrhcPoint = temp;
-          }
-          try {
-            final GeoShape shape = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, ulhcPoint.getY() * DEGREES_TO_RADIANS,
-              lrhcPoint.getY() * DEGREES_TO_RADIANS,
-              ulhcPoint.getX() * DEGREES_TO_RADIANS,
-              lrhcPoint.getX() * DEGREES_TO_RADIANS);
-            //System.err.println("Trial rectangle shape: "+shape);
-            return new Geo3dShape(shape, ctx);
-          } catch (IllegalArgumentException e) {
-            // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
-            // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
-            continue;
-          }
-        }
-      }
-    case 3: {
-        // Paths
-        final int pointCount = random().nextInt(5) + 1;
-        final double width = (random().nextInt(89)+1) * DEGREES_TO_RADIANS;
-        while (true) {
-          try {
-            final GeoPath path = new GeoPath(PlanetModel.SPHERE, width);
-            for (int i = 0; i < pointCount; i++) {
-              final Point nextPoint = randomPoint();
-              path.addPoint(nextPoint.getY() * DEGREES_TO_RADIANS, nextPoint.getX() * DEGREES_TO_RADIANS);
-            }
-            path.done();
-            return new Geo3dShape(path, ctx);
-          } catch (IllegalArgumentException e) {
-            // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
-            // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
-            continue;
-          }
-        }
-      }
-    default:
-      throw new IllegalStateException("Unexpected shape type");
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTestCase.java b/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTestCase.java
deleted file mode 100644
index 3113aed..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTestCase.java
+++ /dev/null
@@ -1,264 +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.spatial4j;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-import com.carrotsearch.randomizedtesting.RandomizedContext;
-import com.spatial4j.core.TestLog;
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.distance.DistanceUtils;
-import com.spatial4j.core.shape.Circle;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.RectIntersectionTestHelper;
-import org.apache.lucene.geo3d.LatLonBounds;
-import org.apache.lucene.geo3d.GeoBBox;
-import org.apache.lucene.geo3d.GeoBBoxFactory;
-import org.apache.lucene.geo3d.GeoStandardCircle;
-import org.apache.lucene.geo3d.GeoPath;
-import org.apache.lucene.geo3d.GeoPoint;
-import org.apache.lucene.geo3d.GeoPolygonFactory;
-import org.apache.lucene.geo3d.GeoShape;
-import org.apache.lucene.geo3d.PlanetModel;
-import org.junit.Rule;
-import org.junit.Test;
-
-import static com.spatial4j.core.distance.DistanceUtils.DEGREES_TO_RADIANS;
-
-public abstract class Geo3dShapeRectRelationTestCase extends RandomizedShapeTestCase {
-  protected final static double RADIANS_PER_DEGREE = Math.PI/180.0;
-
-  @Rule
-  public final TestLog testLog = TestLog.instance;
-
-  protected final PlanetModel planetModel;
-
-  public Geo3dShapeRectRelationTestCase(PlanetModel planetModel) {
-    super(SpatialContext.GEO);
-    this.planetModel = planetModel;
-  }
-
-  protected GeoBBox getBoundingBox(final GeoShape path) {
-    LatLonBounds bounds = new LatLonBounds();
-    path.getBounds(bounds);
-
-    double leftLon;
-    double rightLon;
-    if (bounds.checkNoLongitudeBound()) {
-      leftLon = -Math.PI;
-      rightLon = Math.PI;
-    } else {
-      leftLon = bounds.getLeftLongitude().doubleValue();
-      rightLon = bounds.getRightLongitude().doubleValue();
-    }
-    double minLat;
-    if (bounds.checkNoBottomLatitudeBound()) {
-      minLat = -Math.PI * 0.5;
-    } else {
-      minLat = bounds.getMinLatitude().doubleValue();
-    }
-    double maxLat;
-    if (bounds.checkNoTopLatitudeBound()) {
-      maxLat = Math.PI * 0.5;
-    } else {
-      maxLat = bounds.getMaxLatitude().doubleValue();
-    }
-    return GeoBBoxFactory.makeGeoBBox(planetModel, maxLat, minLat, leftLon, rightLon);
-  }
-
-  abstract class Geo3dRectIntersectionTestHelper extends RectIntersectionTestHelper<Geo3dShape> {
-
-    public Geo3dRectIntersectionTestHelper(SpatialContext ctx) {
-      super(ctx);
-    }
-
-    //20 times each -- should be plenty
-
-    protected int getContainsMinimum(int laps) {
-      return 20;
-    }
-
-    protected int getIntersectsMinimum(int laps) {
-      return 20;
-    }
-
-    // producing "within" cases in Geo3D based on our random shapes doesn't happen often. It'd be nice to increase this.
-    protected int getWithinMinimum(int laps) {
-      return 2;
-    }
-
-    protected int getDisjointMinimum(int laps) {
-      return 20;
-    }
-
-    protected int getBoundingMinimum(int laps) {
-      return 20;
-    }
-  }
-
-  @AwaitsFix(bugUrl = "https://issues.apache.org/jira/browse/LUCENE-6867")
-  @Test
-  public void testGeoCircleRect() {
-    new Geo3dRectIntersectionTestHelper(ctx) {
-
-      @Override
-      protected Geo3dShape generateRandomShape(Point nearP) {
-        final int circleRadius = 180 - random().nextInt(180);//no 0-radius
-        final Point point = nearP;
-        final GeoShape shape = new GeoStandardCircle(planetModel, point.getY() * DEGREES_TO_RADIANS, point.getX() * DEGREES_TO_RADIANS,
-            circleRadius * DEGREES_TO_RADIANS);
-        return new Geo3dShape(planetModel, shape, ctx);
-      }
-
-      @Override
-      protected Point randomPointInEmptyShape(Geo3dShape shape) {
-        GeoPoint geoPoint = ((GeoStandardCircle)shape.shape).getCenter();
-        return geoPointToSpatial4jPoint(geoPoint);
-      }
-
-    }.testRelateWithRectangle();
-  }
-
-  @AwaitsFix(bugUrl = "https://issues.apache.org/jira/browse/LUCENE-6867")
-  @Test
-  public void testGeoBBoxRect() {
-    new Geo3dRectIntersectionTestHelper(ctx) {
-
-      @Override
-      protected boolean isRandomShapeRectangular() {
-        return true;
-      }
-
-      @Override
-      protected Geo3dShape generateRandomShape(Point nearP) {
-        // (ignoring nearP)
-        Point ulhcPoint = randomPoint();
-        Point lrhcPoint = randomPoint();
-        if (ulhcPoint.getY() < lrhcPoint.getY()) {
-          //swap
-          Point temp = ulhcPoint;
-          ulhcPoint = lrhcPoint;
-          lrhcPoint = temp;
-        }
-        final GeoShape shape = GeoBBoxFactory.makeGeoBBox(planetModel, ulhcPoint.getY() * DEGREES_TO_RADIANS,
-            lrhcPoint.getY() * DEGREES_TO_RADIANS,
-            ulhcPoint.getX() * DEGREES_TO_RADIANS,
-            lrhcPoint.getX() * DEGREES_TO_RADIANS);
-        return new Geo3dShape(planetModel, shape, ctx);
-      }
-
-      @Override
-      protected Point randomPointInEmptyShape(Geo3dShape shape) {
-        return shape.getBoundingBox().getCenter();
-      }
-    }.testRelateWithRectangle();
-  }
-
-  @AwaitsFix(bugUrl = "https://issues.apache.org/jira/browse/LUCENE-6867")
-  @Test
-  public void testGeoPolygonRect() {
-    new Geo3dRectIntersectionTestHelper(ctx) {
-
-      @Override
-      protected Geo3dShape generateRandomShape(Point nearP) {
-        final Point centerPoint = randomPoint();
-        final int maxDistance = random().nextInt(160) + 20;
-        final Circle pointZone = ctx.makeCircle(centerPoint, maxDistance);
-        final int vertexCount = random().nextInt(3) + 3;
-        while (true) {
-          final List<GeoPoint> geoPoints = new ArrayList<>();
-          while (geoPoints.size() < vertexCount) {
-            final Point point = randomPointIn(pointZone);
-            final GeoPoint gPt = new GeoPoint(planetModel, point.getY() * DEGREES_TO_RADIANS, point.getX() * DEGREES_TO_RADIANS);
-            geoPoints.add(gPt);
-          }
-          final int convexPointIndex = random().nextInt(vertexCount); //If we get this wrong, hopefully we get IllegalArgumentException
-          try {
-            final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(planetModel, geoPoints, convexPointIndex);
-            return new Geo3dShape(planetModel, shape, ctx);
-          } catch (IllegalArgumentException e) {
-            // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
-            // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
-            continue;
-          }
-        }
-      }
-
-      @Override
-      protected Point randomPointInEmptyShape(Geo3dShape shape) {
-        throw new IllegalStateException("unexpected; need to finish test code");
-      }
-
-      @Override
-      protected int getWithinMinimum(int laps) {
-        // Long/thin so lets just find 1.
-        return 1;
-      }
-
-    }.testRelateWithRectangle();
-  }
-
-  @AwaitsFix(bugUrl = "https://issues.apache.org/jira/browse/LUCENE-6867")
-  @Test
-  public void testGeoPathRect() {
-    new Geo3dRectIntersectionTestHelper(ctx) {
-
-      @Override
-      protected Geo3dShape generateRandomShape(Point nearP) {
-        final Point centerPoint = randomPoint();
-        final int maxDistance = random().nextInt(160) + 20;
-        final Circle pointZone = ctx.makeCircle(centerPoint, maxDistance);
-        final int pointCount = random().nextInt(5) + 1;
-        final double width = (random().nextInt(89)+1) * DEGREES_TO_RADIANS;
-        while (true) {
-          try {
-            final GeoPath path = new GeoPath(planetModel, width);
-            for (int i = 0; i < pointCount; i++) {
-              final Point nextPoint = randomPointIn(pointZone);
-              path.addPoint(nextPoint.getY() * DEGREES_TO_RADIANS, nextPoint.getX() * DEGREES_TO_RADIANS);
-            }
-            path.done();
-            return new Geo3dShape(planetModel, path, ctx);
-          } catch (IllegalArgumentException e) {
-            // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
-            // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
-            continue;
-          }
-        }
-      }
-
-      @Override
-      protected Point randomPointInEmptyShape(Geo3dShape shape) {
-        throw new IllegalStateException("unexpected; need to finish test code");
-      }
-
-      @Override
-      protected int getWithinMinimum(int laps) {
-        // Long/thin so lets just find 1.
-        return 1;
-      }
-
-    }.testRelateWithRectangle();
-  }
-
-  private Point geoPointToSpatial4jPoint(GeoPoint geoPoint) {
-    return ctx.makePoint(geoPoint.getLongitude() * DistanceUtils.RADIANS_TO_DEGREES,
-        geoPoint.getLongitude() * DistanceUtils.RADIANS_TO_DEGREES);
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeSphereModelRectRelationTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeSphereModelRectRelationTest.java b/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeSphereModelRectRelationTest.java
deleted file mode 100644
index aac0a0a..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeSphereModelRectRelationTest.java
+++ /dev/null
@@ -1,72 +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.spatial4j;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import com.spatial4j.core.shape.Rectangle;
-import org.apache.lucene.geo3d.GeoArea;
-import org.apache.lucene.geo3d.GeoBBox;
-import org.apache.lucene.geo3d.GeoBBoxFactory;
-import org.apache.lucene.geo3d.GeoStandardCircle;
-import org.apache.lucene.geo3d.GeoPoint;
-import org.apache.lucene.geo3d.GeoPolygonFactory;
-import org.apache.lucene.geo3d.GeoShape;
-import org.apache.lucene.geo3d.PlanetModel;
-import org.junit.Test;
-
-public class Geo3dShapeSphereModelRectRelationTest extends Geo3dShapeRectRelationTestCase {
-
-  public Geo3dShapeSphereModelRectRelationTest() {
-    super(PlanetModel.SPHERE);
-  }
-
-  @Test
-  public void testFailure1() {
-    final GeoBBox rect = GeoBBoxFactory.makeGeoBBox(planetModel, 88 * RADIANS_PER_DEGREE, 30 * RADIANS_PER_DEGREE, -30 * RADIANS_PER_DEGREE, 62 * RADIANS_PER_DEGREE);
-    final List<GeoPoint> points = new ArrayList<>();
-    points.add(new GeoPoint(planetModel, 66.2465299717 * RADIANS_PER_DEGREE, -29.1786158537 * RADIANS_PER_DEGREE));
-    points.add(new GeoPoint(planetModel, 43.684447915 * RADIANS_PER_DEGREE, 46.2210986329 * RADIANS_PER_DEGREE));
-    points.add(new GeoPoint(planetModel, 30.4579218227 * RADIANS_PER_DEGREE, 14.5238410082 * RADIANS_PER_DEGREE));
-    final GeoShape path = GeoPolygonFactory.makeGeoPolygon(planetModel, points,0);
-
-    final GeoPoint point = new GeoPoint(planetModel, 34.2730264413182 * RADIANS_PER_DEGREE, 82.75500168892472 * RADIANS_PER_DEGREE);
-
-    // Apparently the rectangle thinks the polygon is completely within it... "shape inside rectangle"
-    assertTrue(GeoArea.WITHIN == rect.getRelationship(path));
-
-    // Point is within path? Apparently not...
-    assertFalse(path.isWithin(point));
-
-    // If it is within the path, it must be within the rectangle, and similarly visa versa
-    assertFalse(rect.isWithin(point));
-
-  }
-
-  @Test
-  public void testFailure2_LUCENE6475() {
-    GeoShape geo3dCircle = new GeoStandardCircle(planetModel, 1.6282053147165243E-4 * RADIANS_PER_DEGREE,
-        -70.1600629789353 * RADIANS_PER_DEGREE, 86 * RADIANS_PER_DEGREE);
-    Geo3dShape geo3dShape = new Geo3dShape(planetModel, geo3dCircle, ctx);
-    Rectangle rect = ctx.makeRectangle(-118, -114, -2.0, 32.0);
-    assertTrue(geo3dShape.relate(rect).intersects());
-    // thus the bounding box must intersect too
-    assertTrue(geo3dShape.getBoundingBox().relate(rect).intersects());
-
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeWGS84ModelRectRelationTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeWGS84ModelRectRelationTest.java b/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeWGS84ModelRectRelationTest.java
deleted file mode 100644
index a9ff58d..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeWGS84ModelRectRelationTest.java
+++ /dev/null
@@ -1,95 +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.spatial4j;
-
-import org.apache.lucene.geo3d.GeoArea;
-import org.apache.lucene.geo3d.GeoBBox;
-import org.apache.lucene.geo3d.GeoBBoxFactory;
-import org.apache.lucene.geo3d.GeoCircle;
-import org.apache.lucene.geo3d.GeoStandardCircle;
-import org.apache.lucene.geo3d.GeoPath;
-import org.apache.lucene.geo3d.GeoPoint;
-import org.apache.lucene.geo3d.PlanetModel;
-import org.junit.Test;
-
-public class Geo3dShapeWGS84ModelRectRelationTest extends Geo3dShapeRectRelationTestCase {
-
-  public Geo3dShapeWGS84ModelRectRelationTest() {
-    super(PlanetModel.WGS84);
-  }
-
-  @Test
-  public void testFailure1() {
-    final GeoBBox rect = GeoBBoxFactory.makeGeoBBox(planetModel, 90 * RADIANS_PER_DEGREE, 74 * RADIANS_PER_DEGREE,
-        40 * RADIANS_PER_DEGREE, 60 * RADIANS_PER_DEGREE);
-    final GeoPath path = new GeoPath(planetModel, 4 * RADIANS_PER_DEGREE);
-    path.addPoint(84.4987594274 * RADIANS_PER_DEGREE, -22.8345484402 * RADIANS_PER_DEGREE);
-    path.done();
-    assertTrue(GeoArea.DISJOINT == rect.getRelationship(path));
-    // This is what the test failure claimed...
-    //assertTrue(GeoArea.CONTAINS == rect.getRelationship(path));
-    //final GeoBBox bbox = getBoundingBox(path);
-    //assertFalse(GeoArea.DISJOINT == rect.getRelationship(bbox));
-  }
-
-  @Test
-  public void testFailure2() {
-    final GeoBBox rect = GeoBBoxFactory.makeGeoBBox(planetModel, -74 * RADIANS_PER_DEGREE, -90 * RADIANS_PER_DEGREE,
-        0 * RADIANS_PER_DEGREE, 26 * RADIANS_PER_DEGREE);
-    final GeoCircle circle = new GeoStandardCircle(planetModel, -87.3647352103 * RADIANS_PER_DEGREE, 52.3769709972 * RADIANS_PER_DEGREE, 1 * RADIANS_PER_DEGREE);
-    assertTrue(GeoArea.DISJOINT == rect.getRelationship(circle));
-    // This is what the test failure claimed...
-    //assertTrue(GeoArea.CONTAINS == rect.getRelationship(circle));
-    //final GeoBBox bbox = getBoundingBox(circle);
-    //assertFalse(GeoArea.DISJOINT == rect.getRelationship(bbox));
-  }
-
-  @Test
-  public void testFailure3() {
-    /*
-   [junit4]   1> S-R Rel: {}, Shape {}, Rectangle {}    lap# {} [CONTAINS, Geo3dShape{planetmodel=PlanetModel: {ab=1.0011188180710464, c=0.9977622539852008}, shape=GeoPath: {planetmodel=PlanetModel: {ab=1.0011188180710464, c=0.9977622539852008}, width=1.53588974175501(87.99999999999999), 
-    points={[[X=0.12097657665150223, Y=-0.6754177666095532, Z=0.7265376136709238], [X=-0.3837892785614207, Y=0.4258049113530899, Z=0.8180007850434892]]}}}, 
-    Rect(minX=4.0,maxX=36.0,minY=16.0,maxY=16.0), 6981](no slf4j subst; sorry)
-   [junit4] FAILURE 0.59s | Geo3dWGS84ShapeRectRelationTest.testGeoPathRect <<<
-   [junit4]    > Throwable #1: java.lang.AssertionError: Geo3dShape{planetmodel=PlanetModel: {ab=1.0011188180710464, c=0.9977622539852008}, shape=GeoPath: {planetmodel=PlanetModel: {ab=1.0011188180710464, c=0.9977622539852008}, width=1.53588974175501(87.99999999999999), 
-    points={[[X=0.12097657665150223, Y=-0.6754177666095532, Z=0.7265376136709238], [X=-0.3837892785614207, Y=0.4258049113530899, Z=0.8180007850434892]]}}} intersect Pt(x=23.81626064835212,y=16.0)
-   [junit4]    >  at __randomizedtesting.SeedInfo.seed([2595268DA3F13FEA:6CC30D8C83453E5D]:0)
-   [junit4]    >  at org.apache.lucene.spatial.spatial4j.RandomizedShapeTestCase._assertIntersect(RandomizedShapeTestCase.java:168)
-   [junit4]    >  at org.apache.lucene.spatial.spatial4j.RandomizedShapeTestCase.assertRelation(RandomizedShapeTestCase.java:153)
-   [junit4]    >  at org.apache.lucene.spatial.spatial4j.RectIntersectionTestHelper.testRelateWithRectangle(RectIntersectionTestHelper.java:128)
-   [junit4]    >  at org.apache.lucene.spatial.spatial4j.Geo3dWGS84ShapeRectRelationTest.testGeoPathRect(Geo3dWGS84ShapeRectRelationTest.java:265)
-  */
-    final GeoBBox rect = GeoBBoxFactory.makeGeoBBox(planetModel, 16 * RADIANS_PER_DEGREE, 16 * RADIANS_PER_DEGREE, 4 * RADIANS_PER_DEGREE, 36 * RADIANS_PER_DEGREE);
-    final GeoPoint pt = new GeoPoint(planetModel, 16 * RADIANS_PER_DEGREE, 23.81626064835212 * RADIANS_PER_DEGREE);
-    final GeoPath path = new GeoPath(planetModel, 88 * RADIANS_PER_DEGREE);
-    path.addPoint(46.6369060853 * RADIANS_PER_DEGREE, -79.8452213228 * RADIANS_PER_DEGREE);
-    path.addPoint(54.9779334519 * RADIANS_PER_DEGREE, 132.029177424 * RADIANS_PER_DEGREE);
-    path.done();
-    System.out.println("rect=" + rect);
-    // Rectangle is within path (this is wrong; it's on the other side.  Should be OVERLAPS)
-    assertTrue(GeoArea.OVERLAPS == rect.getRelationship(path));
-    // Rectangle contains point
-    //assertTrue(rect.isWithin(pt));
-    // Path contains point (THIS FAILS)
-    //assertTrue(path.isWithin(pt));
-    // What happens: (1) The center point of the horizontal line is within the path, in fact within a radius of one of the endpoints.
-    // (2) The point mentioned is NOT inside either SegmentEndpoint.
-    // (3) The point mentioned is NOT inside the path segment, either.  (I think it should be...)
-  }
-
-}
-

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/RandomizedShapeTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/RandomizedShapeTestCase.java b/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/RandomizedShapeTestCase.java
deleted file mode 100644
index db72520..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/RandomizedShapeTestCase.java
+++ /dev/null
@@ -1,289 +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.spatial4j;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.distance.DistanceUtils;
-import com.spatial4j.core.shape.Circle;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.SpatialRelation;
-import com.spatial4j.core.shape.impl.Range;
-
-import static com.spatial4j.core.shape.SpatialRelation.CONTAINS;
-import static com.spatial4j.core.shape.SpatialRelation.WITHIN;
-
-import org.apache.lucene.util.LuceneTestCase;
-
-import static com.carrotsearch.randomizedtesting.RandomizedTest.*;
-
-/**
- * A base test class with utility methods to help test shapes.
- * Extends from RandomizedTest.
- */
-public abstract class RandomizedShapeTestCase extends LuceneTestCase {
-
-  protected static final double EPS = 10e-9;
-
-  protected SpatialContext ctx;//needs to be set ASAP
-
-  /** Used to reduce the space of numbers to increase the likelihood that
-   * random numbers become equivalent, and thus trigger different code paths.
-   * Also makes some random shapes easier to manually examine.
-   */
-  protected final double DIVISIBLE = 2;// even coordinates; (not always used)
-
-  protected RandomizedShapeTestCase() {
-  }
-
-  public RandomizedShapeTestCase(SpatialContext ctx) {
-    this.ctx = ctx;
-  }
-
-  @SuppressWarnings("unchecked")
-  public static void checkShapesImplementEquals( Class<?>[] classes ) {
-    for( Class<?> clazz : classes ) {
-      try {
-        clazz.getDeclaredMethod( "equals", Object.class );
-      } catch (Exception e) {
-        fail("Shape needs to define 'equals' : " + clazz.getName());
-      }
-      try {
-        clazz.getDeclaredMethod( "hashCode" );
-      } catch (Exception e) {
-        fail("Shape needs to define 'hashCode' : " + clazz.getName());
-      }
-    }
-  }
-
-  //These few norm methods normalize the arguments for creating a shape to
-  // account for the dateline. Some tests loop past the dateline or have offsets
-  // that go past it and it's easier to have them coded that way and correct for
-  // it here.  These norm methods should be used when needed, not frivolously.
-
-  protected double normX(double x) {
-    return ctx.isGeo() ? DistanceUtils.normLonDEG(x) : x;
-  }
-
-  protected double normY(double y) {
-    return ctx.isGeo() ? DistanceUtils.normLatDEG(y) : y;
-  }
-
-  protected Rectangle makeNormRect(double minX, double maxX, double minY, double maxY) {
-    if (ctx.isGeo()) {
-      if (Math.abs(maxX - minX) >= 360) {
-        minX = -180;
-        maxX = 180;
-      } else {
-        minX = DistanceUtils.normLonDEG(minX);
-        maxX = DistanceUtils.normLonDEG(maxX);
-      }
-
-    } else {
-      if (maxX < minX) {
-        double t = minX;
-        minX = maxX;
-        maxX = t;
-      }
-      minX = boundX(minX, ctx.getWorldBounds());
-      maxX = boundX(maxX, ctx.getWorldBounds());
-    }
-    if (maxY < minY) {
-      double t = minY;
-      minY = maxY;
-      maxY = t;
-    }
-    minY = boundY(minY, ctx.getWorldBounds());
-    maxY = boundY(maxY, ctx.getWorldBounds());
-    return ctx.makeRectangle(minX, maxX, minY, maxY);
-  }
-
-  public static double divisible(double v, double divisible) {
-    return (int) (Math.round(v / divisible) * divisible);
-  }
-
-  protected double divisible(double v) {
-    return divisible(v, DIVISIBLE);
-  }
-
-  /** reset()'s p, and confines to world bounds. Might not be divisible if
-   * the world bound isn't divisible too.
-   */
-  protected Point divisible(Point p) {
-    Rectangle bounds = ctx.getWorldBounds();
-    double newX = boundX( divisible(p.getX()), bounds );
-    double newY = boundY( divisible(p.getY()), bounds );
-    p.reset(newX, newY);
-    return p;
-  }
-
-  static double boundX(double i, Rectangle bounds) {
-    return bound(i, bounds.getMinX(), bounds.getMaxX());
-  }
-
-  static double boundY(double i, Rectangle bounds) {
-    return bound(i, bounds.getMinY(), bounds.getMaxY());
-  }
-
-  static double bound(double i, double min, double max) {
-    if (i < min) return min;
-    if (i > max) return max;
-    return i;
-  }
-
-  protected void assertRelation(SpatialRelation expected, Shape a, Shape b) {
-    assertRelation(null, expected, a, b);
-  }
-
-  protected void assertRelation(String msg, SpatialRelation expected, Shape a, Shape b) {
-    _assertIntersect(msg, expected, a, b);
-    //check flipped a & b w/ transpose(), while we're at it
-    _assertIntersect(msg, expected.transpose(), b, a);
-  }
-
-  private void _assertIntersect(String msg, SpatialRelation expected, Shape a, Shape b) {
-    SpatialRelation sect = a.relate(b);
-    if (sect == expected)
-      return;
-    msg = ((msg == null) ? "" : msg+"\r") + a +" intersect "+b;
-    if (expected == WITHIN || expected == CONTAINS) {
-      if (a.getClass().equals(b.getClass())) // they are the same shape type
-        assertEquals(msg,a,b);
-      else {
-        //they are effectively points or lines that are the same location
-        assertTrue(msg,!a.hasArea());
-        assertTrue(msg,!b.hasArea());
-
-        Rectangle aBBox = a.getBoundingBox();
-        Rectangle bBBox = b.getBoundingBox();
-        if (aBBox.getHeight() == 0 && bBBox.getHeight() == 0
-            && (aBBox.getMaxY() == 90 && bBBox.getMaxY() == 90
-            || aBBox.getMinY() == -90 && bBBox.getMinY() == -90))
-          ;//== a point at the pole
-        else
-          assertEquals(msg, aBBox, bBBox);
-      }
-    } else {
-      assertEquals(msg,expected,sect);//always fails
-    }
-  }
-
-  protected void assertEqualsRatio(String msg, double expected, double actual) {
-    double delta = Math.abs(actual - expected);
-    double base = Math.min(actual, expected);
-    double deltaRatio = base==0 ? delta : Math.min(delta,delta / base);
-    assertEquals(msg,0,deltaRatio, EPS);
-  }
-
-  protected int randomIntBetweenDivisible(int start, int end) {
-    return randomIntBetweenDivisible(start, end, (int)DIVISIBLE);
-  }
-  /** Returns a random integer between [start, end]. Integers between must be divisible by the 3rd argument. */
-  protected int randomIntBetweenDivisible(int start, int end, int divisible) {
-    // DWS: I tested this
-    int divisStart = (int) Math.ceil( (start+1) / (double)divisible );
-    int divisEnd = (int) Math.floor( (end-1) / (double)divisible );
-    int divisRange = Math.max(0,divisEnd - divisStart + 1);
-    int r = randomInt(1 + divisRange);//remember that '0' is counted
-    if (r == 0)
-      return start;
-    if (r == 1)
-      return end;
-    return (r-2 + divisStart)*divisible;
-  }
-
-  protected Rectangle randomRectangle(Point nearP) {
-    Rectangle bounds = ctx.getWorldBounds();
-    if (nearP == null)
-      nearP = randomPointIn(bounds);
-
-    Range xRange = randomRange(rarely() ? 0 : nearP.getX(), Range.xRange(bounds, ctx));
-    Range yRange = randomRange(rarely() ? 0 : nearP.getY(), Range.yRange(bounds, ctx));
-
-    return makeNormRect(
-        divisible(xRange.getMin()),
-        divisible(xRange.getMax()),
-        divisible(yRange.getMin()),
-        divisible(yRange.getMax()) );
-  }
-
-  private Range randomRange(double near, Range bounds) {
-    double mid = near + randomGaussian() * bounds.getWidth() / 6;
-    double width = Math.abs(randomGaussian()) * bounds.getWidth() / 6;//1/3rd
-    return new Range(mid - width / 2, mid + width / 2);
-  }
-
-  private double randomGaussianZeroTo(double max) {
-    if (max == 0)
-      return max;
-    assert max > 0;
-    double r;
-    do {
-      r = Math.abs(randomGaussian()) * (max * 0.50);
-    } while (r > max);
-    return r;
-  }
-
-  protected Rectangle randomRectangle(int divisible) {
-    double rX = randomIntBetweenDivisible(-180, 180, divisible);
-    double rW = randomIntBetweenDivisible(0, 360, divisible);
-    double rY1 = randomIntBetweenDivisible(-90, 90, divisible);
-    double rY2 = randomIntBetweenDivisible(-90, 90, divisible);
-    double rYmin = Math.min(rY1,rY2);
-    double rYmax = Math.max(rY1,rY2);
-    if (rW > 0 && rX == 180)
-      rX = -180;
-    return makeNormRect(rX, rX + rW, rYmin, rYmax);
-  }
-
-  protected Point randomPoint() {
-    return randomPointIn(ctx.getWorldBounds());
-  }
-
-  protected Point randomPointIn(Circle c) {
-    double d = c.getRadius() * randomDouble();
-    double angleDEG = 360 * randomDouble();
-    Point p = ctx.getDistCalc().pointOnBearing(c.getCenter(), d, angleDEG, ctx, null);
-    assertEquals(CONTAINS,c.relate(p));
-    return p;
-  }
-
-  protected Point randomPointIn(Rectangle r) {
-    double x = r.getMinX() + randomDouble()*r.getWidth();
-    double y = r.getMinY() + randomDouble()*r.getHeight();
-    x = normX(x);
-    y = normY(y);
-    Point p = ctx.makePoint(x,y);
-    assertEquals(CONTAINS,r.relate(p));
-    return p;
-  }
-
-  protected Point randomPointInOrNull(Shape shape) {
-    if (!shape.hasArea())// or try the center?
-      throw new UnsupportedOperationException("Need area to define shape!");
-    Rectangle bbox = shape.getBoundingBox();
-    for (int i = 0; i < 1000; i++) {
-      Point p = randomPointIn(bbox);
-      if (shape.relate(p).intersects()) {
-        return p;
-      }
-    }
-    return null;//tried too many times and failed
-  }
-}
-

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoPointTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoPointTest.java b/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoPointTest.java
deleted file mode 100644
index e652581..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoPointTest.java
+++ /dev/null
@@ -1,82 +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.spatial4j.geo3d;
-
-import org.apache.lucene.geo3d.GeoPoint;
-import org.apache.lucene.geo3d.PlanetModel;
-import org.apache.lucene.util.LuceneTestCase;
-import org.junit.Test;
-
-import com.spatial4j.core.distance.DistanceUtils;
-
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomFloat;
-
-/**
- * Test basic GeoPoint functionality.
- */
-public class GeoPointTest extends LuceneTestCase {
-
-  @Test
-  public void testConversion() {
-    testPointRoundTrip(PlanetModel.SPHERE, 90 * DistanceUtils.DEGREES_TO_RADIANS, 0, 1e-6);
-    testPointRoundTrip(PlanetModel.SPHERE, -90 * DistanceUtils.DEGREES_TO_RADIANS, 0, 1e-6);
-    testPointRoundTrip(PlanetModel.WGS84, 90 * DistanceUtils.DEGREES_TO_RADIANS, 0, 1e-6);
-    testPointRoundTrip(PlanetModel.WGS84, -90 * DistanceUtils.DEGREES_TO_RADIANS, 0, 1e-6);
-
-    final int times = atLeast(100);
-    for (int i = 0; i < times; i++) {
-      final double pLat = (randomFloat() * 180.0 - 90.0) * DistanceUtils.DEGREES_TO_RADIANS;
-      final double pLon = (randomFloat() * 360.0 - 180.0) * DistanceUtils.DEGREES_TO_RADIANS;
-      testPointRoundTrip(PlanetModel.SPHERE, pLat, pLon, 1e-6);//1e-6 since there's a square root in there (Karl says)
-      testPointRoundTrip(PlanetModel.WGS84, pLat, pLon, 1e-6);
-    }
-  }
-
-  protected void testPointRoundTrip(PlanetModel planetModel, double pLat, double pLon, double epsilon) {
-    final GeoPoint p1 = new GeoPoint(planetModel, pLat, pLon);
-    // In order to force the reverse conversion, we have to construct a geopoint from just x,y,z
-    final GeoPoint p2 = new GeoPoint(p1.x, p1.y, p1.z);
-    // Now, construct the final point based on getLatitude() and getLongitude()
-    final GeoPoint p3 = new GeoPoint(planetModel, p2.getLatitude(), p2.getLongitude());
-    double dist = p1.arcDistance(p3);
-    assertEquals(0, dist, epsilon);
-  }
-
-  @Test
-  public void testSurfaceDistance() {
-    final int times = atLeast(100);
-    for (int i = 0; i < times; i++) {
-      final double p1Lat = (randomFloat() * 180.0 - 90.0) * DistanceUtils.DEGREES_TO_RADIANS;
-      final double p1Lon = (randomFloat() * 360.0 - 180.0) * DistanceUtils.DEGREES_TO_RADIANS;
-      final double p2Lat = (randomFloat() * 180.0 - 90.0) * DistanceUtils.DEGREES_TO_RADIANS;
-      final double p2Lon = (randomFloat() * 360.0 - 180.0) * DistanceUtils.DEGREES_TO_RADIANS;
-      final GeoPoint p1 = new GeoPoint(PlanetModel.SPHERE, p1Lat, p1Lon);
-      final GeoPoint p2 = new GeoPoint(PlanetModel.SPHERE, p2Lat, p2Lon);
-      final double arcDistance = p1.arcDistance(p2);
-      // Compute ellipsoid distance; it should agree for a sphere
-      final double surfaceDistance = PlanetModel.SPHERE.surfaceDistance(p1,p2);
-      assertEquals(arcDistance, surfaceDistance, 1e-6);
-    }
-  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void testBadLatLon() {
-    new GeoPoint(PlanetModel.SPHERE, 50.0, 32.2);
-  }
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test/org/apache/lucene/spatial/vector/TestPointVectorStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/vector/TestPointVectorStrategy.java b/lucene/spatial/src/test/org/apache/lucene/spatial/vector/TestPointVectorStrategy.java
deleted file mode 100644
index d62a0a8..0000000
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/vector/TestPointVectorStrategy.java
+++ /dev/null
@@ -1,63 +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.vector;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Circle;
-import com.spatial4j.core.shape.Point;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.spatial.SpatialMatchConcern;
-import org.apache.lucene.spatial.StrategyTestCase;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.query.SpatialOperation;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.io.IOException;
-
-public class TestPointVectorStrategy extends StrategyTestCase {
-
-  @Before
-  @Override
-  public void setUp() throws Exception {
-    super.setUp();
-    this.ctx = SpatialContext.GEO;
-    this.strategy = new PointVectorStrategy(ctx, getClass().getSimpleName());
-  }
-
-  @Test
-  public void testCircleShapeSupport() {
-    Circle circle = ctx.makeCircle(ctx.makePoint(0, 0), 10);
-    SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, circle);
-    Query query = this.strategy.makeQuery(args);
-
-    assertNotNull(query);
-  }
-
-  @Test(expected = UnsupportedOperationException.class)
-  public void testInvalidQueryShape() {
-    Point point = ctx.makePoint(0, 0);
-    SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, point);
-    this.strategy.makeQuery(args);
-  }
-
-  @Test
-  public void testCitiesIntersectsBBox() throws IOException {
-    getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS);
-    executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_Intersects_BBox);
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/solr/common-build.xml
----------------------------------------------------------------------
diff --git a/solr/common-build.xml b/solr/common-build.xml
index eab251b..6a06928 100644
--- a/solr/common-build.xml
+++ b/solr/common-build.xml
@@ -100,7 +100,7 @@
     <pathelement location="${highlighter.jar}"/>
     <pathelement location="${memory.jar}"/>
     <pathelement location="${misc.jar}"/>
-    <pathelement location="${spatial.jar}"/>
+    <pathelement location="${spatial-extras.jar}"/>
     <pathelement location="${expressions.jar}"/>
     <pathelement location="${suggest.jar}"/>
     <pathelement location="${grouping.jar}"/>
@@ -169,7 +169,7 @@
 
   <target name="prep-lucene-jars" 
           depends="jar-lucene-core, jar-backward-codecs, jar-analyzers-phonetic, jar-analyzers-kuromoji, jar-codecs,jar-expressions, jar-suggest, jar-highlighter, jar-memory,
-                   jar-misc, jar-spatial, jar-grouping, jar-queries, jar-queryparser, jar-join, jar-sandbox">
+                   jar-misc, jar-spatial-extras, jar-grouping, jar-queries, jar-queryparser, jar-join, jar-sandbox">
       <property name="solr.deps.compiled" value="true"/>
   </target>
   
@@ -245,7 +245,7 @@
   <property name="lucenedocs" location="${common.dir}/build/docs"/>
 
   <!-- dependency to ensure all lucene javadocs are present -->
-  <target name="lucene-javadocs" depends="javadocs-lucene-core,javadocs-analyzers-common,javadocs-analyzers-icu,javadocs-analyzers-kuromoji,javadocs-analyzers-phonetic,javadocs-analyzers-smartcn,javadocs-analyzers-morfologik,javadocs-analyzers-stempel,javadocs-analyzers-uima,javadocs-backward-codecs,javadocs-codecs,javadocs-expressions,javadocs-suggest,javadocs-grouping,javadocs-queries,javadocs-queryparser,javadocs-highlighter,javadocs-memory,javadocs-misc,javadocs-spatial,javadocs-join,javadocs-test-framework"/>
+  <target name="lucene-javadocs" depends="javadocs-lucene-core,javadocs-analyzers-common,javadocs-analyzers-icu,javadocs-analyzers-kuromoji,javadocs-analyzers-phonetic,javadocs-analyzers-smartcn,javadocs-analyzers-morfologik,javadocs-analyzers-stempel,javadocs-analyzers-uima,javadocs-backward-codecs,javadocs-codecs,javadocs-expressions,javadocs-suggest,javadocs-grouping,javadocs-queries,javadocs-queryparser,javadocs-highlighter,javadocs-memory,javadocs-misc,javadocs-spatial-extras,javadocs-join,javadocs-test-framework"/>
 
   <!-- create javadocs for the current module -->
   <target name="javadocs" depends="compile-core,define-lucene-javadoc-url,lucene-javadocs,javadocs-solr-core,check-javadocs-uptodate" unless="javadocs-uptodate-${name}">
@@ -322,7 +322,7 @@
           <link offline="true" href="${lucene.javadoc.url}highlighter" packagelistloc="${lucenedocs}/highlighter"/>
           <link offline="true" href="${lucene.javadoc.url}memory" packagelistloc="${lucenedocs}/memory"/>
           <link offline="true" href="${lucene.javadoc.url}misc" packagelistloc="${lucenedocs}/misc"/>
-          <link offline="true" href="${lucene.javadoc.url}spatial" packagelistloc="${lucenedocs}/spatial"/>
+          <link offline="true" href="${lucene.javadoc.url}spatial-extras" packagelistloc="${lucenedocs}/spatial-extras"/>
           <links/>
           <link href=""/>
         </sources>


[36/50] [abbrv] lucene-solr git commit: SOLR-445: Merge branch 'master' into jira/SOLR-445

Posted by ho...@apache.org.
SOLR-445: Merge branch 'master' into jira/SOLR-445


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/18804d6f
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/18804d6f
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/18804d6f

Branch: refs/heads/jira/SOLR-445
Commit: 18804d6fcaf16904ff94b83f3c18c8efcaa48860
Parents: 546f142 89db495
Author: Chris Hostetter <ho...@apache.org>
Authored: Mon Feb 29 17:18:28 2016 -0700
Committer: Chris Hostetter <ho...@apache.org>
Committed: Mon Feb 29 17:18:28 2016 -0700

----------------------------------------------------------------------
 dev-tools/idea/.idea/ant.xml                    |     1 +
 dev-tools/idea/.idea/modules.xml                |     1 +
 dev-tools/idea/.idea/workspace.xml              |    41 +-
 .../idea/lucene/benchmark/src/benchmark.iml     |     2 +-
 .../lucene/spatial-extras/spatial-extras.iml    |    32 +
 dev-tools/idea/lucene/spatial/spatial.iml       |    15 -
 dev-tools/idea/solr/core/src/java/solr-core.iml |     2 +-
 .../idea/solr/core/src/solr-core-tests.iml      |     2 +-
 dev-tools/maven/lucene/pom.xml.template         |     1 +
 .../lucene/spatial-extras/pom.xml.template      |    62 +
 dev-tools/maven/lucene/spatial/pom.xml.template |     2 +-
 dev-tools/scripts/smokeTestRelease.py           |     2 +-
 lucene/CHANGES.txt                              |    21 +-
 .../miscellaneous/StemmerOverrideFilter.java    |     2 +-
 lucene/benchmark/build.xml                      |     8 +-
 lucene/build.xml                                |     3 +-
 .../codecs/blockterms/BlockTermsReader.java     |     4 +-
 .../org/apache/lucene/document/BinaryPoint.java |   169 +-
 .../document/DocumentStoredFieldVisitor.java    |     7 +-
 .../org/apache/lucene/document/DoublePoint.java |   158 +-
 .../org/apache/lucene/document/FieldType.java   |    14 +-
 .../org/apache/lucene/document/FloatPoint.java  |   158 +-
 .../org/apache/lucene/document/IntPoint.java    |   152 +-
 .../org/apache/lucene/document/LongPoint.java   |   156 +-
 .../org/apache/lucene/document/StoredField.java |     4 +-
 .../org/apache/lucene/index/CheckIndex.java     |    10 +-
 .../apache/lucene/index/PrefixCodedTerms.java   |     2 +-
 .../lucene/index/SortedDocValuesWriter.java     |     2 +-
 .../lucene/index/SortedSetDocValuesWriter.java  |     2 +-
 .../apache/lucene/index/TermsHashPerField.java  |     2 +-
 .../apache/lucene/search/FuzzyTermsEnum.java    |     5 +-
 .../lucene/search/LegacyNumericRangeQuery.java  |    12 +-
 .../apache/lucene/search/PointInSetQuery.java   |   378 +
 .../apache/lucene/search/PointRangeQuery.java   |   433 +-
 .../apache/lucene/search/ScoringRewrite.java    |     2 +-
 .../org/apache/lucene/search/SortField.java     |     2 +-
 .../search/UsageTrackingQueryCachingPolicy.java |    16 +-
 .../org/apache/lucene/store/MMapDirectory.java  |    10 +-
 .../java/org/apache/lucene/util/ArrayUtil.java  |    20 +-
 .../java/org/apache/lucene/util/BytesRef.java   |   122 +-
 .../org/apache/lucene/util/BytesRefHash.java    |    10 +-
 .../org/apache/lucene/util/CollectionUtil.java  |     4 +-
 .../org/apache/lucene/util/DocIdSetBuilder.java |    14 +-
 .../apache/lucene/util/LegacyNumericUtils.java  |     4 -
 .../org/apache/lucene/util/NumericUtils.java    |    15 +-
 .../org/apache/lucene/util/OfflineSorter.java   |     2 +-
 .../org/apache/lucene/document/TestField.java   |    16 +-
 .../apache/lucene/document/TestFieldType.java   |     6 +
 .../index/TestDemoParallelLeafReader.java       |     3 +-
 .../apache/lucene/index/TestMultiFields.java    |     4 +-
 .../apache/lucene/search/TestPointQueries.java  |   852 +-
 .../TestUsageTrackingFilterCachingPolicy.java   |     4 +-
 .../apache/lucene/util/TestBytesRefArray.java   |     5 +-
 .../apache/lucene/util/TestBytesRefHash.java    |    12 +-
 .../lucene/util/TestInPlaceMergeSorter.java     |     4 +-
 .../org/apache/lucene/util/TestIntroSorter.java |     4 +-
 .../org/apache/lucene/util/TestTimSorter.java   |     3 +-
 .../org/apache/lucene/util/TestUnicodeUtil.java |    15 +-
 .../demo/facet/DistanceFacetsExample.java       |    10 +-
 .../lucene/demo/facet/RangeFacetsExample.java   |     4 +-
 .../facet/range/TestRangeFacetCounts.java       |    21 +-
 .../search/highlight/HighlighterTest.java       |     3 +-
 .../search/join/TermsIncludingScoreQuery.java   |     2 +-
 .../apache/lucene/search/join/TermsQuery.java   |    11 +-
 .../apache/lucene/search/join/TestJoinUtil.java |     2 +-
 .../apache/lucene/index/memory/MemoryIndex.java |    13 +-
 lucene/module-build.xml                         |    22 +
 .../apache/lucene/queries/TermsQueryTest.java   |    25 +
 .../apache/lucene/document/BigIntegerPoint.java |   108 +-
 .../lucene/document/InetAddressPoint.java       |   121 +-
 .../org/apache/lucene/document/LatLonPoint.java |   148 +-
 .../lucene/search/DocValuesTermsQuery.java      |     2 +-
 .../lucene/search/PointDistanceQuery.java       |   179 +
 .../lucene/search/PointInPolygonQuery.java      |     8 +-
 .../apache/lucene/search/PointInRectQuery.java  |   200 -
 .../lucene/document/TestBigIntegerPoint.java    |    23 +-
 .../lucene/document/TestInetAddressPoint.java   |    30 +-
 .../apache/lucene/document/TestLatLonPoint.java |   162 +
 .../lucene/search/TestDocValuesRangeQuery.java  |     9 +-
 .../lucene/search/TestLatLonPointQueries.java   |    71 +-
 lucene/spatial-extras/build.xml                 |    57 +
 lucene/spatial-extras/ivy.xml                   |    36 +
 .../apache/lucene/spatial/SpatialStrategy.java  |   149 +
 .../bbox/BBoxOverlapRatioValueSource.java       |   251 +
 .../spatial/bbox/BBoxSimilarityValueSource.java |   117 +
 .../lucene/spatial/bbox/BBoxStrategy.java       |   588 +
 .../lucene/spatial/bbox/BBoxValueSource.java    |   115 +
 .../lucene/spatial/bbox/package-info.java       |    23 +
 .../composite/CompositeSpatialStrategy.java     |   144 +
 .../spatial/composite/CompositeVerifyQuery.java |   120 +
 .../composite/IntersectsRPTVerifyQuery.java     |   235 +
 .../lucene/spatial/composite/package-info.java  |    19 +
 .../org/apache/lucene/spatial/package-info.java |    21 +
 .../spatial/prefix/AbstractPrefixTreeQuery.java |   133 +
 .../prefix/AbstractVisitingPrefixTreeQuery.java |   380 +
 .../prefix/BytesRefIteratorTokenStream.java     |    72 +
 .../spatial/prefix/CellToBytesRefIterator.java  |    49 +
 .../spatial/prefix/ContainsPrefixTreeQuery.java |   362 +
 .../spatial/prefix/HeatmapFacetCounter.java     |   310 +
 .../prefix/IntersectsPrefixTreeQuery.java       |    95 +
 .../prefix/NumberRangePrefixTreeStrategy.java   |   199 +
 .../PointPrefixTreeFieldCacheProvider.java      |    48 +
 .../spatial/prefix/PrefixTreeFacetCounter.java  |   201 +
 .../spatial/prefix/PrefixTreeStrategy.java      |   208 +
 .../prefix/RecursivePrefixTreeStrategy.java     |   192 +
 .../prefix/TermQueryPrefixTreeStrategy.java     |   111 +
 .../spatial/prefix/WithinPrefixTreeQuery.java   |   232 +
 .../lucene/spatial/prefix/package-info.java     |    21 +
 .../apache/lucene/spatial/prefix/tree/Cell.java |   109 +
 .../spatial/prefix/tree/CellIterator.java       |    76 +
 .../prefix/tree/DateRangePrefixTree.java        |   444 +
 .../spatial/prefix/tree/FilterCellIterator.java |    61 +
 .../spatial/prefix/tree/GeohashPrefixTree.java  |   162 +
 .../lucene/spatial/prefix/tree/LegacyCell.java  |   242 +
 .../spatial/prefix/tree/LegacyPrefixTree.java   |    84 +
 .../prefix/tree/NumberRangePrefixTree.java      |   989 +
 .../prefix/tree/PackedQuadPrefixTree.java       |   459 +
 .../spatial/prefix/tree/QuadPrefixTree.java     |   308 +
 .../prefix/tree/SingletonCellIterator.java      |    36 +
 .../spatial/prefix/tree/SpatialPrefixTree.java  |   117 +
 .../prefix/tree/SpatialPrefixTreeFactory.java   |    99 +
 .../spatial/prefix/tree/TreeCellIterator.java   |    87 +
 .../spatial/prefix/tree/package-info.java       |    30 +
 .../lucene/spatial/query/SpatialArgs.java       |   148 +
 .../lucene/spatial/query/SpatialArgsParser.java |   146 +
 .../lucene/spatial/query/SpatialOperation.java  |   179 +
 .../query/UnsupportedSpatialOperation.java      |    28 +
 .../lucene/spatial/query/package-info.java      |    21 +
 .../serialized/SerializedDVStrategy.java        |   278 +
 .../lucene/spatial/serialized/package-info.java |    21 +
 .../lucene/spatial/spatial4j/Geo3dShape.java    |   185 +
 .../lucene/spatial/spatial4j/package-info.java  |    19 +
 .../spatial/util/CachingDoubleValueSource.java  |    93 +
 .../util/DistanceToShapeValueSource.java        |   122 +
 .../spatial/util/ShapeAreaValueSource.java      |   116 +
 .../lucene/spatial/util/ShapeFieldCache.java    |    54 +
 .../ShapeFieldCacheDistanceValueSource.java     |   112 +
 .../spatial/util/ShapeFieldCacheProvider.java   |    87 +
 .../spatial/util/ShapePredicateValueSource.java |   113 +
 .../lucene/spatial/util/package-info.java       |    21 +
 .../spatial/vector/DistanceValueSource.java     |   120 +
 .../spatial/vector/PointVectorStrategy.java     |   178 +
 .../lucene/spatial/vector/package-info.java     |    21 +
 lucene/spatial-extras/src/java/overview.html    |    67 +
 .../src/test-files/cities-Intersects-BBox.txt   |     3 +
 .../src/test-files/data/LUCENE-4464.txt         |     3 +
 .../src/test-files/data/countries-bbox.txt      |   249 +
 .../src/test-files/data/countries-poly.txt      |   249 +
 .../src/test-files/data/geonames-IE.txt         | 22929 +++++++++++++++++
 .../src/test-files/data/simple-bbox.txt         |     4 +
 .../src/test-files/data/states-bbox.txt         |    52 +
 .../src/test-files/data/states-poly.txt         |    52 +
 .../src/test-files/data/world-cities-points.txt |  2680 ++
 .../src/test-files/simple-Queries-BBox.txt      |     9 +
 .../src/test-files/states-Intersects-BBox.txt   |     3 +
 .../src/test-files/states-IsWithin-BBox.txt     |     4 +
 .../lucene/spatial/DistanceStrategyTest.java    |   135 +
 .../apache/lucene/spatial/PortedSolr3Test.java  |   167 +
 .../lucene/spatial/QueryEqualsHashCodeTest.java |   119 +
 .../apache/lucene/spatial/SpatialArgsTest.java  |    50 +
 .../apache/lucene/spatial/SpatialExample.java   |   200 +
 .../lucene/spatial/SpatialMatchConcern.java     |    31 +
 .../apache/lucene/spatial/SpatialTestCase.java  |   280 +
 .../apache/lucene/spatial/SpatialTestData.java  |    71 +
 .../apache/lucene/spatial/SpatialTestQuery.java |    96 +
 .../apache/lucene/spatial/StrategyTestCase.java |   252 +
 .../lucene/spatial/TestTestFramework.java       |    68 +
 .../lucene/spatial/bbox/TestBBoxStrategy.java   |   301 +
 .../composite/CompositeStrategyTest.java        |   142 +
 .../prefix/CellToBytesRefIterator50.java        |    44 +
 .../spatial/prefix/DateNRStrategyTest.java      |   143 +
 .../spatial/prefix/HeatmapFacetCounterTest.java |   252 +
 .../lucene/spatial/prefix/JtsPolygonTest.java   |   117 +
 .../spatial/prefix/NumberRangeFacetsTest.java   |   275 +
 .../RandomSpatialOpFuzzyPrefixTree50Test.java   |    31 +
 .../RandomSpatialOpFuzzyPrefixTreeTest.java     |   533 +
 .../prefix/RandomSpatialOpStrategyTestCase.java |   141 +
 .../prefix/TestRecursivePrefixTreeStrategy.java |   122 +
 .../prefix/TestTermQueryPrefixGridStrategy.java |    63 +
 .../prefix/tree/DateRangePrefixTreeTest.java    |   175 +
 .../prefix/tree/SpatialPrefixTreeTest.java      |   114 +
 .../spatial/query/SpatialArgsParserTest.java    |    77 +
 .../serialized/SerializedStrategyTest.java      |    66 +
 .../lucene/spatial/spatial4j/Geo3dRptTest.java  |   227 +
 .../Geo3dShapeRectRelationTestCase.java         |   262 +
 .../Geo3dShapeSphereModelRectRelationTest.java  |    72 +
 .../Geo3dShapeWGS84ModelRectRelationTest.java   |    94 +
 .../spatial4j/RandomizedShapeTestCase.java      |   288 +
 .../spatial/spatial4j/geo3d/GeoPointTest.java   |    80 +
 .../spatial/vector/TestPointVectorStrategy.java |    63 +
 lucene/spatial/build.xml                        |    30 -
 lucene/spatial/ivy.xml                          |    15 -
 .../apache/lucene/spatial/SpatialStrategy.java  |   149 -
 .../bbox/BBoxOverlapRatioValueSource.java       |   251 -
 .../spatial/bbox/BBoxSimilarityValueSource.java |   117 -
 .../lucene/spatial/bbox/BBoxStrategy.java       |   591 -
 .../lucene/spatial/bbox/BBoxValueSource.java    |   115 -
 .../lucene/spatial/bbox/package-info.java       |    23 -
 .../composite/CompositeSpatialStrategy.java     |   144 -
 .../spatial/composite/CompositeVerifyQuery.java |   121 -
 .../composite/IntersectsRPTVerifyQuery.java     |   235 -
 .../lucene/spatial/composite/package-info.java  |    19 -
 .../geopoint/search/GeoPointDistanceQuery.java  |     5 +
 .../search/GeoPointDistanceRangeQuery.java      |     6 +
 .../geopoint/search/GeoPointInBBoxQuery.java    |    10 +
 .../geopoint/search/GeoPointInPolygonQuery.java |     6 +
 .../spatial/prefix/AbstractPrefixTreeQuery.java |   133 -
 .../prefix/AbstractVisitingPrefixTreeQuery.java |   380 -
 .../prefix/BytesRefIteratorTokenStream.java     |    72 -
 .../spatial/prefix/CellToBytesRefIterator.java  |    49 -
 .../spatial/prefix/ContainsPrefixTreeQuery.java |   362 -
 .../spatial/prefix/HeatmapFacetCounter.java     |   310 -
 .../prefix/IntersectsPrefixTreeQuery.java       |    95 -
 .../prefix/NumberRangePrefixTreeStrategy.java   |   199 -
 .../PointPrefixTreeFieldCacheProvider.java      |    48 -
 .../spatial/prefix/PrefixTreeFacetCounter.java  |   201 -
 .../spatial/prefix/PrefixTreeStrategy.java      |   208 -
 .../prefix/RecursivePrefixTreeStrategy.java     |   196 -
 .../prefix/TermQueryPrefixTreeStrategy.java     |   111 -
 .../spatial/prefix/WithinPrefixTreeQuery.java   |   233 -
 .../lucene/spatial/prefix/package-info.java     |    21 -
 .../apache/lucene/spatial/prefix/tree/Cell.java |   109 -
 .../spatial/prefix/tree/CellIterator.java       |    76 -
 .../prefix/tree/DateRangePrefixTree.java        |   444 -
 .../spatial/prefix/tree/FilterCellIterator.java |    61 -
 .../spatial/prefix/tree/GeohashPrefixTree.java  |   162 -
 .../lucene/spatial/prefix/tree/LegacyCell.java  |   242 -
 .../spatial/prefix/tree/LegacyPrefixTree.java   |    84 -
 .../prefix/tree/NumberRangePrefixTree.java      |   989 -
 .../prefix/tree/PackedQuadPrefixTree.java       |   459 -
 .../spatial/prefix/tree/QuadPrefixTree.java     |   308 -
 .../prefix/tree/SingletonCellIterator.java      |    36 -
 .../spatial/prefix/tree/SpatialPrefixTree.java  |   117 -
 .../prefix/tree/SpatialPrefixTreeFactory.java   |    99 -
 .../spatial/prefix/tree/TreeCellIterator.java   |    87 -
 .../spatial/prefix/tree/package-info.java       |    30 -
 .../lucene/spatial/query/SpatialArgs.java       |   148 -
 .../lucene/spatial/query/SpatialArgsParser.java |   146 -
 .../lucene/spatial/query/SpatialOperation.java  |   179 -
 .../query/UnsupportedSpatialOperation.java      |    28 -
 .../lucene/spatial/query/package-info.java      |    21 -
 .../serialized/SerializedDVStrategy.java        |   278 -
 .../lucene/spatial/serialized/package-info.java |    21 -
 .../lucene/spatial/spatial4j/Geo3dShape.java    |   185 -
 .../lucene/spatial/spatial4j/package-info.java  |    19 -
 .../spatial/util/CachingDoubleValueSource.java  |    93 -
 .../util/DistanceToShapeValueSource.java        |   122 -
 .../lucene/spatial/util/GeoEncodingUtils.java   |    26 +-
 .../org/apache/lucene/spatial/util/GeoRect.java |     7 +
 .../lucene/spatial/util/GeoRelationUtils.java   |     4 +
 .../spatial/util/ShapeAreaValueSource.java      |   116 -
 .../lucene/spatial/util/ShapeFieldCache.java    |    54 -
 .../ShapeFieldCacheDistanceValueSource.java     |   112 -
 .../spatial/util/ShapeFieldCacheProvider.java   |    87 -
 .../spatial/util/ShapePredicateValueSource.java |   113 -
 .../spatial/vector/DistanceValueSource.java     |   120 -
 .../spatial/vector/PointVectorStrategy.java     |   182 -
 .../lucene/spatial/vector/package-info.java     |    21 -
 lucene/spatial/src/java/overview.html           |    50 +-
 .../src/test-files/cities-Intersects-BBox.txt   |     3 -
 .../spatial/src/test-files/data/LUCENE-4464.txt |     3 -
 .../src/test-files/data/countries-bbox.txt      |   249 -
 .../src/test-files/data/countries-poly.txt      |   249 -
 .../spatial/src/test-files/data/geonames-IE.txt | 22929 -----------------
 .../spatial/src/test-files/data/simple-bbox.txt |     5 -
 .../spatial/src/test-files/data/states-bbox.txt |    52 -
 .../spatial/src/test-files/data/states-poly.txt |    52 -
 .../src/test-files/data/world-cities-points.txt |  2680 --
 .../src/test-files/simple-Queries-BBox.txt      |     9 -
 .../src/test-files/states-Intersects-BBox.txt   |     3 -
 .../src/test-files/states-IsWithin-BBox.txt     |     4 -
 .../lucene/spatial/DistanceStrategyTest.java    |   135 -
 .../apache/lucene/spatial/PortedSolr3Test.java  |   167 -
 .../lucene/spatial/QueryEqualsHashCodeTest.java |   119 -
 .../apache/lucene/spatial/SpatialArgsTest.java  |    50 -
 .../apache/lucene/spatial/SpatialExample.java   |   200 -
 .../lucene/spatial/SpatialMatchConcern.java     |    31 -
 .../apache/lucene/spatial/SpatialTestCase.java  |   281 -
 .../apache/lucene/spatial/SpatialTestData.java  |    71 -
 .../apache/lucene/spatial/SpatialTestQuery.java |    96 -
 .../apache/lucene/spatial/StrategyTestCase.java |   252 -
 .../lucene/spatial/TestTestFramework.java       |    68 -
 .../lucene/spatial/bbox/TestBBoxStrategy.java   |   301 -
 .../composite/CompositeStrategyTest.java        |   142 -
 .../prefix/CellToBytesRefIterator50.java        |    44 -
 .../spatial/prefix/DateNRStrategyTest.java      |   143 -
 .../spatial/prefix/HeatmapFacetCounterTest.java |   252 -
 .../lucene/spatial/prefix/JtsPolygonTest.java   |   117 -
 .../spatial/prefix/NumberRangeFacetsTest.java   |   275 -
 .../RandomSpatialOpFuzzyPrefixTree50Test.java   |    31 -
 .../RandomSpatialOpFuzzyPrefixTreeTest.java     |   533 -
 .../prefix/RandomSpatialOpStrategyTestCase.java |   141 -
 .../prefix/TestRecursivePrefixTreeStrategy.java |   122 -
 .../prefix/TestTermQueryPrefixGridStrategy.java |    63 -
 .../prefix/tree/DateRangePrefixTreeTest.java    |   175 -
 .../prefix/tree/SpatialPrefixTreeTest.java      |   114 -
 .../spatial/query/SpatialArgsParserTest.java    |    77 -
 .../serialized/SerializedStrategyTest.java      |    66 -
 .../lucene/spatial/spatial4j/Geo3dRptTest.java  |   227 -
 .../Geo3dShapeRectRelationTestCase.java         |   264 -
 .../Geo3dShapeSphereModelRectRelationTest.java  |    72 -
 .../Geo3dShapeWGS84ModelRectRelationTest.java   |    95 -
 .../spatial4j/RandomizedShapeTestCase.java      |   289 -
 .../spatial/spatial4j/geo3d/GeoPointTest.java   |    82 -
 .../spatial/util/BaseGeoPointTestCase.java      |    20 +-
 .../spatial/vector/TestPointVectorStrategy.java |    63 -
 .../org/apache/lucene/geo3d/Geo3DPoint.java     |    67 +-
 .../lucene/geo3d/PointInGeo3DShapeQuery.java    |    16 +-
 .../org/apache/lucene/geo3d/TestGeo3DPoint.java |    18 +-
 .../search/suggest/SortedInputIterator.java     |     7 +-
 .../suggest/fst/FSTCompletionBuilder.java       |     5 +-
 .../lucene/search/suggest/tst/TSTLookup.java    |    51 +-
 .../search/suggest/TestInputIterator.java       |    21 +-
 .../suggest/document/TestSuggestField.java      |     3 +-
 .../search/suggest/fst/BytesRefSortersTest.java |     5 +-
 .../index/BaseDocValuesFormatTestCase.java      |     2 +-
 .../lucene/index/BasePointFormatTestCase.java   |     5 +-
 .../org/apache/lucene/util/LuceneTestCase.java  |    18 +
 .../java/org/apache/lucene/util/TestUtil.java   |    23 +-
 solr/CHANGES.txt                                |    37 +
 solr/common-build.xml                           |     8 +-
 .../SolrStopwordsCarrot2LexicalDataFactory.java |     6 +-
 .../carrot2/EchoClusteringAlgorithm.java        |     6 +-
 .../carrot2/EchoStemsClusteringAlgorithm.java   |     8 +-
 .../carrot2/EchoTokensClusteringAlgorithm.java  |     6 +-
 ...exicalResourcesCheckClusteringAlgorithm.java |     6 +-
 .../carrot2/MockClusteringAlgorithm.java        |    12 +-
 .../solr/collection1/conf/solrconfig.xml        |     2 +-
 .../test-files/solr/minimr/conf/solrconfig.xml  |     2 +-
 .../test-files/solr/mrunit/conf/solrconfig.xml  |     2 +-
 .../collection1/conf/solrconfig.xml             |     2 +-
 .../solr/solrcloud/conf/solrconfig.xml          |     2 +-
 .../org/apache/solr/cloud/ElectionContext.java  |   114 +-
 .../java/org/apache/solr/cloud/Overseer.java    |   122 +-
 .../cloud/OverseerCollectionMessageHandler.java |    36 +-
 .../solr/cloud/OverseerNodePrioritizer.java     |     2 +-
 .../solr/cloud/OverseerTaskProcessor.java       |    14 +-
 .../solr/cloud/SizeLimitedDistributedMap.java   |     5 +-
 .../org/apache/solr/cloud/ZkController.java     |    15 +-
 .../solr/core/CachingDirectoryFactory.java      |     3 +-
 .../org/apache/solr/core/CoreDescriptor.java    |     1 +
 .../org/apache/solr/handler/BlobHandler.java    |    38 -
 .../apache/solr/handler/SolrConfigHandler.java  |     3 +-
 .../solr/handler/admin/CollectionsHandler.java  |    25 +-
 .../solr/handler/admin/CoreAdminOperation.java  |    22 +-
 .../handler/component/StatsValuesFactory.java   |    10 +-
 .../analysis/ManagedSynonymFilterFactory.java   |     1 -
 .../org/apache/solr/update/SolrIndexConfig.java |    12 +-
 .../processor/DistributedUpdateProcessor.java   |     2 +-
 .../src/resources/SystemCollectionSchema.xml    |    17 +
 .../resources/SystemCollectionSolrConfig.xml    |    20 +
 .../org/apache/solr/TestDistributedSearch.java  |    11 +-
 .../org/apache/solr/cloud/DeleteShardTest.java  |     2 +-
 .../org/apache/solr/cloud/ForceLeaderTest.java  |     4 +-
 .../apache/solr/cloud/OverseerRolesTest.java    |     2 +-
 .../org/apache/solr/cloud/OverseerTest.java     |    28 +-
 .../cloud/TestRandomRequestDistribution.java    |     2 +-
 .../cloud/TestSizeLimitedDistributedMap.java    |    58 +
 .../solr/core/TestImplicitCoreProperties.java   |    61 +-
 .../apache/solr/core/TestSolrConfigHandler.java |     4 +-
 .../handler/component/StatsComponentTest.java   |    44 +-
 .../solr/index/hdfs/CheckHdfsIndexTest.java     |     2 +
 .../TestManagedSynonymFilterFactory.java        |     8 +-
 .../example-DIH/solr/db/conf/solrconfig.xml     |     2 +-
 .../example-DIH/solr/mail/conf/solrconfig.xml   |     2 +-
 .../example-DIH/solr/rss/conf/solrconfig.xml    |     2 +-
 .../example-DIH/solr/solr/conf/solrconfig.xml   |     2 +-
 .../example-DIH/solr/tika/conf/solrconfig.xml   |     2 +-
 solr/example/files/conf/solrconfig.xml          |     2 +-
 .../conf/solrconfig.xml                         |     2 +-
 .../conf/solrconfig.xml                         |     4 +-
 .../solr/BaseDistributedSearchTestCase.java     |    32 +
 .../cloud/AbstractFullDistribZkTestBase.java    |     2 +-
 .../apache/solr/cloud/SolrCloudTestCase.java    |   163 +
 solr/webapp/web/index.html                      |     2 +-
 375 files changed, 45384 insertions(+), 42663 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/18804d6f/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java
----------------------------------------------------------------------


[22/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test-files/data/world-cities-points.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test-files/data/world-cities-points.txt b/lucene/spatial-extras/src/test-files/data/world-cities-points.txt
new file mode 100644
index 0000000..01a6bcc
--- /dev/null
+++ b/lucene/spatial-extras/src/test-files/data/world-cities-points.txt
@@ -0,0 +1,2680 @@
+#id	name	shape
+G292223	Dubai	POINT(55.280000 25.252220)
+G292672	Sharjah	POINT(55.391110 25.362220)
+G292913	Al ‘Ayn	POINT(55.760560 24.191670)
+G292932	`Ajmān	POINT(55.435040 25.411110)
+G292968	Abu Dhabi	POINT(54.366670 24.466670)
+G1133616	Mazār-e Sharīf	POINT(67.110870 36.709040)
+G1135689	Kunduz	POINT(68.857000 36.728960)
+G1138336	Kandahār	POINT(65.710130 31.613320)
+G1138958	Kabul	POINT(69.172330 34.528130)
+G1139715	Jalālābād	POINT(70.451530 34.426470)
+G1140026	Herāt	POINT(62.199670 34.348170)
+G3183875	Tirana	POINT(19.818890 41.327500)
+G616052	Yerevan	POINT(44.513610 40.181110)
+G2240449	Luanda	POINT(13.234440 -8.838330)
+G3347939	Lobito	POINT(13.545560 -12.348060)
+G3348313	Huambo	POINT(15.739170 -12.776110)
+G3351663	Benguela	POINT(13.407220 -12.578330)
+G3429577	Resistencia	POINT(-58.983330 -27.450000)
+G3429652	Quilmes	POINT(-58.269440 -34.720280)
+G3429886	Posadas	POINT(-55.883330 -27.383330)
+G3430863	Mar del Plata	POINT(-57.550000 -38.000000)
+G3432043	La Plata	POINT(-57.948890 -34.931390)
+G3433899	Formosa	POINT(-58.183330 -26.183330)
+G3435217	Corrientes	POINT(-58.833330 -27.466670)
+G3435910	Buenos Aires	POINT(-58.377230 -34.613150)
+G3835869	Santiago del Estero	POINT(-64.266670 -27.783330)
+G3836277	Santa Fe de la Vera Cruz	POINT(-60.700000 -31.633330)
+G3836564	San Salvador de Jujuy	POINT(-65.300000 -24.183330)
+G3836873	San Miguel de Tucumán	POINT(-65.216670 -26.816670)
+G3837056	San Luis	POINT(-66.350000 -33.300000)
+G3837213	San Juan	POINT(-68.536390 -31.537500)
+G3837702	San Fernando del Valle de Catamarca	POINT(-65.783330 -28.466670)
+G3838233	Salta	POINT(-65.416670 -24.783330)
+G3838583	Rosario	POINT(-60.666390 -32.951110)
+G3838874	Río Cuarto	POINT(-64.350000 -33.133330)
+G3841956	Paraná	POINT(-60.533330 -31.733330)
+G3843123	Neuquén	POINT(-68.066670 -38.950000)
+G3844421	Mendoza	POINT(-68.816670 -32.883330)
+G3848950	La Rioja	POINT(-66.850000 -29.433330)
+G3860259	Córdoba	POINT(-64.183330 -31.400000)
+G3865086	Bahía Blanca	POINT(-62.283330 -38.716670)
+G2761369	Vienna	POINT(16.372080 48.208490)
+G2766824	Salzburg	POINT(13.043990 47.799410)
+G2772400	Linz	POINT(14.286110 48.306390)
+G2778067	Graz	POINT(15.450000 47.066670)
+G7279909	Linz-Wels-Steyr	POINT(14.183690 48.154580)
+G2063523	Perth	POINT(115.833330 -31.933330)
+G2078025	Adelaide	POINT(138.600000 -34.933330)
+G2147714	Sydney	POINT(151.207320 -33.867850)
+G2155472	Newcastle	POINT(151.776470 -32.927150)
+G2158177	Melbourne	POINT(144.963320 -37.814000)
+G2165087	Gold Coast	POINT(153.433330 -28.000000)
+G2165796	Geelong West	POINT(144.350000 -38.133330)
+G2165798	Geelong	POINT(144.360690 -38.147110)
+G2171507	Wollongong	POINT(150.883330 -34.433330)
+G2172517	Canberra	POINT(149.128070 -35.283460)
+G2172797	Cairns	POINT(145.766670 -16.916670)
+G2174003	Brisbane	POINT(153.028090 -27.467940)
+G7280463	North Shore	POINT(152.901850 -31.402370)
+G7281838	Logan City	POINT(153.109440 -27.639170)
+G584923	Sumqayıt	POINT(49.668610 40.589720)
+G586523	Kirowabad	POINT(46.360560 40.682780)
+G587084	Baku	POINT(49.892010 40.377670)
+G3186573	Zenica	POINT(17.906390 44.201390)
+G3191281	Sarajevo	POINT(18.356440 43.848640)
+G3204541	Banja Luka	POINT(17.185560 44.775830)
+G1185098	Tungi	POINT(90.405830 23.890000)
+G1185099	Sylhet	POINT(91.871670 24.896670)
+G1185106	Jamālpur	POINT(89.933330 24.916670)
+G1185117	Narsingdi	POINT(90.718060 23.920830)
+G1185128	Rājshāhi	POINT(88.600000 24.366670)
+G1185155	Nārāyanganj	POINT(90.501110 23.623330)
+G1185162	Mymensingh	POINT(90.400000 24.750000)
+G1185186	Comilla	POINT(91.204440 23.457780)
+G1185188	Rangpur	POINT(89.250000 25.750000)
+G1185241	Dhaka	POINT(90.407440 23.710400)
+G1192366	Pār Naogaon	POINT(88.950840 24.802870)
+G1203891	Dinājpur	POINT(88.638640 25.627150)
+G1205733	Chittagong	POINT(91.836390 22.333060)
+G1336134	Cox’s Bāzār	POINT(91.979770 21.453240)
+G1336135	Khulna	POINT(89.567230 22.813480)
+G1336137	Barisāl	POINT(90.371110 22.701940)
+G1336140	Jessore	POINT(89.213150 23.168690)
+G1336144	Tāngāil	POINT(89.916670 24.250000)
+G1337233	Bogra	POINT(89.366670 24.850000)
+G6545349	Saidpur	POINT(88.891690 25.777690)
+G2792413	Liège	POINT(5.567490 50.633730)
+G2797656	Gent	POINT(3.716670 51.050000)
+G2800481	Charleroi	POINT(4.452480 50.409470)
+G2800866	Brussels	POINT(4.348780 50.850450)
+G2803138	Antwerpen	POINT(4.403460 51.219890)
+G2357048	Ouagadougou	POINT(-1.538340 12.364230)
+G2362344	Bobo-Dioulasso	POINT(-4.297900 11.177150)
+G726050	Varna	POINT(27.916670 43.216670)
+G727011	Sofia	POINT(23.324150 42.697510)
+G727523	Ruse	POINT(25.970830 43.856390)
+G728193	Plovdiv	POINT(24.750000 42.150000)
+G732770	Burgas	POINT(27.467810 42.506060)
+G425378	Bujumbura	POINT(29.364400 -3.382200)
+G2392087	Porto-Novo	POINT(2.603590 6.496460)
+G2392204	Parakou	POINT(2.616670 9.350000)
+G2394560	Djougou	POINT(1.666940 9.705000)
+G2394819	Cotonou	POINT(2.433330 6.350000)
+G2395914	Abomey-Calavi	POINT(2.350000 6.450000)
+G3903320	Tarija	POINT(-64.729560 -21.535490)
+G3903987	Sucre	POINT(-65.262740 -19.033320)
+G3904906	Santa Cruz de la Sierra	POINT(-63.166670 -17.800000)
+G3909234	Oruro	POINT(-67.150000 -17.983330)
+G3911925	La Paz	POINT(-68.150000 -16.500000)
+G3919968	Cochabamba	POINT(-66.156800 -17.389500)
+G3386496	Teresina	POINT(-42.801940 -5.089170)
+G3387296	Sobral	POINT(-40.349720 -3.686110)
+G3388368	São Luís	POINT(-44.302780 -2.529720)
+G3389353	Santarém	POINT(-54.708330 -2.443060)
+G3390760	Recife	POINT(-34.881110 -8.053890)
+G3392242	Petrolina	POINT(-40.500830 -9.398610)
+G3392740	Paulista	POINT(-34.873060 -7.940830)
+G3392998	Parnamirim	POINT(-35.262780 -5.915560)
+G3393536	Olinda	POINT(-34.855280 -8.008890)
+G3394023	Natal	POINT(-35.209440 -5.795000)
+G3394682	Mossoró	POINT(-37.344170 -5.187500)
+G3395473	Maracanaú	POINT(-38.625560 -3.876670)
+G3395981	Maceió	POINT(-35.735280 -9.665830)
+G3396016	Macapá	POINT(-51.066390 0.038890)
+G3397147	Juazeiro do Norte	POINT(-39.315280 -7.213060)
+G3397277	João Pessoa	POINT(-34.863060 -7.115000)
+G3397838	Jaboatão	POINT(-35.001390 -8.180280)
+G3398269	Imperatriz	POINT(-47.491670 -5.526390)
+G3399415	Fortaleza	POINT(-38.543060 -3.717220)
+G3402429	Caucaia	POINT(-38.653060 -3.736110)
+G3402655	Caruaru	POINT(-35.976110 -8.283330)
+G3403642	Campina Grande	POINT(-35.881110 -7.230560)
+G3405870	Belém	POINT(-48.504440 -1.455830)
+G3407327	Arapiraca	POINT(-36.661110 -9.752500)
+G3407669	Ananindeua	POINT(-48.372220 -1.365560)
+G3444876	Volta Redonda	POINT(-44.104170 -22.523060)
+G3444914	Vitória da Conquista	POINT(-40.839440 -14.866110)
+G3444924	Vitória	POINT(-40.337780 -20.319440)
+G3445026	Vila Velha	POINT(-40.292500 -20.329720)
+G3445156	Viamão	POINT(-51.023330 -30.081110)
+G3445451	Várzea Grande	POINT(-56.132500 -15.646670)
+G3445831	Uberlândia	POINT(-48.277220 -18.918610)
+G3445839	Uberaba	POINT(-47.931940 -19.748330)
+G3446682	Taubaté	POINT(-45.555280 -23.026390)
+G3447186	Taboão da Serra	POINT(-46.791670 -23.626110)
+G3447212	Suzano	POINT(-46.310830 -23.542500)
+G3447259	Sumaré	POINT(-47.266940 -22.821940)
+G3447399	Sorocaba	POINT(-47.458060 -23.501670)
+G3447624	Sete Lagoas	POINT(-44.246670 -19.465830)
+G3447779	Serra	POINT(-40.307780 -20.128610)
+G3448136	São Vicente	POINT(-46.391940 -23.963060)
+G3448439	São Paulo	POINT(-46.636110 -23.547500)
+G3448622	São Leopoldo	POINT(-51.147220 -29.760280)
+G3448636	São José dos Campos	POINT(-45.886940 -23.179440)
+G3448639	São José do Rio Preto	POINT(-49.379440 -20.819720)
+G3448742	São José	POINT(-49.166670 -28.233330)
+G3448877	São João de Meriti	POINT(-43.372220 -22.803890)
+G3449319	São Carlos	POINT(-47.890830 -22.017500)
+G3449344	São Bernardo do Campo	POINT(-46.565000 -23.693890)
+G3449433	Santos	POINT(-46.333610 -23.960830)
+G3449701	Santo André	POINT(-46.538330 -23.663890)
+G3450083	Santa Maria	POINT(-53.806940 -29.684170)
+G3450144	Santa Luzia	POINT(-43.851390 -19.769720)
+G3450404	Santa Bárbara d'Oeste	POINT(-47.413610 -22.753610)
+G3450554	Salvador	POINT(-38.510830 -12.971110)
+G3450909	Rondonópolis	POINT(-54.635560 -16.470830)
+G3451138	Rio Grande	POINT(-52.098610 -32.035000)
+G3451190	Rio de Janeiro	POINT(-43.207500 -22.902780)
+G3451234	Rio Claro	POINT(-47.561390 -22.411390)
+G3451328	Ribeirão Preto	POINT(-47.810280 -21.177500)
+G3451353	Ribeirão das Neves	POINT(-44.086670 -19.766940)
+G3452324	Presidente Prudente	POINT(-51.388890 -22.125560)
+G3452465	Praia Grande	POINT(-46.402780 -24.005830)
+G3452925	Porto Alegre	POINT(-51.230000 -30.033060)
+G3453186	Ponta Grossa	POINT(-50.161940 -25.095000)
+G3453643	Piracicaba	POINT(-47.649170 -22.725280)
+G3454031	Petrópolis	POINT(-43.178610 -22.505000)
+G3454244	Pelotas	POINT(-52.342500 -31.771940)
+G3454857	Passo Fundo	POINT(-52.406670 -28.262780)
+G3455775	Osasco	POINT(-46.791670 -23.532500)
+G3456068	Novo Hamburgo	POINT(-51.130560 -29.678330)
+G3456160	Nova Iguaçu	POINT(-43.451110 -22.759170)
+G3456166	Nova Friburgo	POINT(-42.531110 -22.281940)
+G3456223	Nossa Senhora do Socorro	POINT(-37.126110 -10.855000)
+G3456283	Niterói	POINT(-43.103610 -22.883330)
+G3456814	Montes Claros	POINT(-43.861670 -16.735000)
+G3457001	Mogi das Cruzes	POINT(-46.188330 -23.522780)
+G3457381	Mauá	POINT(-46.461390 -23.667780)
+G3457671	Maringá	POINT(-51.938610 -23.425280)
+G3457692	Marília	POINT(-49.945830 -22.213890)
+G3458449	Londrina	POINT(-51.162780 -23.310280)
+G3458575	Limeira	POINT(-47.401670 -22.564720)
+G3458930	Lages	POINT(-50.326110 -27.816110)
+G3459462	Jundiaí	POINT(-46.884170 -23.186390)
+G3459505	Juiz de Fora	POINT(-43.350280 -21.764170)
+G3459712	Joinville	POINT(-48.845560 -26.304440)
+G3460370	Jacareí	POINT(-45.965830 -23.305280)
+G3460644	Itaquaquecetuba	POINT(-46.348330 -23.486110)
+G3460718	Itapevi	POINT(-46.934170 -23.548890)
+G3460748	Itapecerica da Serra	POINT(-46.849170 -23.716940)
+G3460845	Itajaí	POINT(-48.661940 -26.907780)
+G3460949	Itabuna	POINT(-39.280280 -14.785560)
+G3460950	Itaboraí	POINT(-42.859440 -22.744440)
+G3461144	Ipatinga	POINT(-42.536670 -19.468330)
+G3461311	Indaiatuba	POINT(-47.218060 -23.090280)
+G3461408	Ilhéus	POINT(-39.049440 -14.788890)
+G3461655	Hortolândia	POINT(-47.220000 -22.858330)
+G3461786	Guarulhos	POINT(-46.533330 -23.462780)
+G3461789	Guarujá	POINT(-46.256390 -23.993060)
+G3461879	Guarapuava	POINT(-51.458060 -25.395280)
+G3462089	Gravataí	POINT(-50.991940 -29.944440)
+G3462315	Governador Valadares	POINT(-41.949440 -18.851110)
+G3462377	Goiânia	POINT(-49.253890 -16.678610)
+G3462980	Francisco Morato	POINT(-46.745280 -23.281670)
+G3463011	Franca	POINT(-47.400830 -20.538610)
+G3463030	Foz do Iguaçu	POINT(-54.588060 -25.547780)
+G3463237	Florianópolis	POINT(-48.549170 -27.596670)
+G3463422	Ferraz de Vasconcelos	POINT(-46.368610 -23.540830)
+G3463478	Feira de Santana	POINT(-38.966670 -12.266670)
+G3464305	Embu	POINT(-46.852220 -23.648890)
+G3464374	Duque de Caxias	POINT(-43.311670 -22.785560)
+G3464460	Dourados	POINT(-54.805560 -22.221110)
+G3464688	Divinópolis	POINT(-44.883890 -20.138890)
+G3464739	Diadema	POINT(-46.622780 -23.686110)
+G3464975	Curitiba	POINT(-49.273060 -25.427780)
+G3465038	Cuiabá	POINT(-56.096670 -15.596110)
+G3465196	Criciúma	POINT(-49.369720 -28.677500)
+G3465284	Cotia	POINT(-46.919170 -23.603890)
+G3465624	Contagem	POINT(-44.053610 -19.931670)
+G3465927	Colombo	POINT(-49.224170 -25.291670)
+G3466296	Chapecó	POINT(-52.618330 -27.096390)
+G3466537	Caxias do Sul	POINT(-51.179440 -29.168060)
+G3466779	Cascavel	POINT(-53.455280 -24.955830)
+G3466998	Carapicuíba	POINT(-46.835560 -23.522500)
+G3467467	Canoas	POINT(-51.183610 -29.917780)
+G3467693	Campos	POINT(-41.300000 -21.750000)
+G3467747	Campo Grande	POINT(-54.646390 -20.442780)
+G3467865	Campinas	POINT(-47.060830 -22.905560)
+G3468031	Camaçari	POINT(-38.324170 -12.697500)
+G3468376	Cachoeiro de Itapemirim	POINT(-41.112780 -20.848890)
+G3469058	Brasília	POINT(-47.929720 -15.779720)
+G3469968	Blumenau	POINT(-49.066110 -26.919440)
+G3470044	Betim	POINT(-44.198330 -19.967780)
+G3470127	Belo Horizonte	POINT(-43.937780 -19.920830)
+G3470142	Belford Roxo	POINT(-43.399440 -22.764170)
+G3470279	Bauru	POINT(-49.060560 -22.314720)
+G3470353	Barueri	POINT(-46.876110 -23.510560)
+G3470583	Barreiras	POINT(-44.990000 -12.152780)
+G3470636	Barra Mansa	POINT(-44.171390 -22.544170)
+G3471766	Araraquara	POINT(-48.175560 -21.794440)
+G3471859	Araçatuba	POINT(-50.432780 -21.208890)
+G3471872	Aracaju	POINT(-37.071670 -10.911110)
+G3472177	Angra dos Reis	POINT(-44.318060 -23.006670)
+G3472287	Anápolis	POINT(-48.952780 -16.326670)
+G3472343	Americana	POINT(-47.331390 -22.739170)
+G3474574	Palmas	POINT(-48.360280 -10.212780)
+G3662574	Rio Branco	POINT(-67.810000 -9.974720)
+G3662762	Porto Velho	POINT(-63.903890 -8.761940)
+G3663517	Manaus	POINT(-60.025000 -3.101940)
+G3664980	Boa Vista	POINT(-60.673330 2.819720)
+G6316406	Aparecida de Goiânia	POINT(-49.243890 -16.823330)
+G6317344	Jaboatão dos Guararapes	POINT(-35.014720 -8.112780)
+G3571824	Nassau	POINT(-77.343060 25.058230)
+G933773	Gaborone	POINT(25.908590 -24.654510)
+G620127	Vitsyebsk	POINT(30.194440 55.192500)
+G625144	Minsk	POINT(27.566670 53.900000)
+G625665	Mahilyow	POINT(30.336390 53.913890)
+G627904	Hrodna	POINT(23.814720 53.681390)
+G627907	Homyel’	POINT(30.983330 52.441670)
+G629634	Brest	POINT(23.700000 52.100000)
+G630429	Baranavichy	POINT(26.033330 53.133330)
+G630468	Babruysk	POINT(29.233330 53.150000)
+G5881791	Abbotsford	POINT(-122.252570 49.057980)
+G5894171	Barrie	POINT(-79.666340 44.400110)
+G5907364	Brampton	POINT(-79.766330 43.683410)
+G5911592	Burlington	POINT(-79.837130 43.386210)
+G5911606	Burnaby	POINT(-122.952630 49.266360)
+G5913490	Calgary	POINT(-114.085290 51.050110)
+G5946768	Edmonton	POINT(-113.468710 53.550140)
+G5959974	Gatineau	POINT(-75.701640 45.477230)
+G5964700	Greater Sudbury	POINT(-80.990010 46.490000)
+G5969785	Hamilton	POINT(-79.949640 43.233410)
+G5992996	Kitchener	POINT(-80.482990 43.450100)
+G6050610	Laval	POINT(-73.692000 45.569950)
+G6058560	London	POINT(-81.233040 42.983390)
+G6059891	Longueuil	POINT(-73.518060 45.531210)
+G6075357	Mississauga	POINT(-79.658300 43.578900)
+G6077243	Montréal	POINT(-73.587810 45.508840)
+G6091104	North York	POINT(-79.416300 43.766810)
+G6094578	Oshawa	POINT(-78.849570 43.900120)
+G6094817	Ottawa	POINT(-75.698120 45.411170)
+G6119109	Regina	POINT(-104.617800 50.450080)
+G6122085	Richmond	POINT(-123.136830 49.170030)
+G6141256	Saskatoon	POINT(-106.634520 52.116790)
+G6159905	Surrey	POINT(-122.825090 49.106350)
+G6167865	Toronto	POINT(-79.416300 43.700110)
+G6173331	Vancouver	POINT(-123.119340 49.249660)
+G6173577	Vaughan	POINT(-79.532910 43.833410)
+G6174041	Victoria	POINT(-123.369300 48.432940)
+G6182962	Windsor	POINT(-83.016540 42.300080)
+G6183235	Winnipeg	POINT(-97.147040 49.884400)
+G6324729	Halifax	POINT(-63.572390 44.645330)
+G6325494	Québec	POINT(-71.214540 46.812280)
+G7602078	Ladner	POINT(-123.082410 49.089380)
+G204405	Uvira	POINT(29.145830 -3.406670)
+G204953	Tshikapa	POINT(20.800000 -6.416670)
+G207570	Mwene-Ditu	POINT(23.450000 -7.000000)
+G209228	Mbuji-Mayi	POINT(23.600000 -6.150000)
+G212730	Kisangani	POINT(25.200000 0.516670)
+G214481	Kananga	POINT(22.417780 -5.895830)
+G216449	Gandajika	POINT(23.950000 -6.750000)
+G217562	Butembo	POINT(29.283330 0.150000)
+G217831	Bukavu	POINT(28.860830 -2.508330)
+G922704	Lubumbashi	POINT(27.466670 -11.666670)
+G922741	Likasi	POINT(26.733330 -10.981390)
+G922773	Kolwezi	POINT(25.472500 -10.716670)
+G2312895	Mbandaka	POINT(18.266670 0.066670)
+G2313002	Matadi	POINT(13.450000 -5.816670)
+G2314302	Kinshasa	POINT(15.321460 -4.324590)
+G2314705	Kikwit	POINT(18.818060 -5.038610)
+G2593460	Masina	POINT(15.391390 -4.383610)
+G2389853	Bangui	POINT(18.554960 4.361220)
+G2255414	Pointe-Noire	POINT(11.846110 -4.794720)
+G2260535	Brazzaville	POINT(15.283270 -4.266900)
+G2657896	Zürich	POINT(8.550000 47.366670)
+G2660646	Genève	POINT(6.145690 46.202220)
+G2661604	Basel	POINT(7.600000 47.566670)
+G2279755	Yamoussoukro	POINT(-5.283330 6.816670)
+G2282006	San-Pédro	POINT(-6.616670 4.733330)
+G2286304	Korhogo	POINT(-5.633330 9.450000)
+G2290486	Daloa	POINT(-6.451940 6.874720)
+G2290956	Bouaké	POINT(-5.033060 7.683330)
+G2293521	Abobo	POINT(-4.020560 5.418890)
+G2293538	Abidjan	POINT(-4.028060 5.341110)
+G3868121	Viña del Mar	POINT(-71.551830 -33.024570)
+G3868626	Valparaíso	POINT(-71.627250 -33.039320)
+G3870011	Temuco	POINT(-72.600000 -38.733330)
+G3870282	Talcahuano	POINT(-73.116670 -36.716670)
+G3870294	Talca	POINT(-71.666670 -35.433330)
+G3871336	Santiago	POINT(-70.566560 -33.426280)
+G3872348	San Bernardo	POINT(-70.716670 -33.600000)
+G3873775	Rancagua	POINT(-70.744440 -34.170830)
+G3874960	Puerto Montt	POINT(-72.936940 -41.471670)
+G3875024	Puente Alto	POINT(-70.583330 -33.616670)
+G3884373	La Serena	POINT(-71.254170 -29.907780)
+G3887127	Iquique	POINT(-70.143060 -20.220830)
+G3893629	Coquimbo	POINT(-71.343610 -29.953330)
+G3893894	Concepción	POINT(-73.049770 -36.826990)
+G3895088	Chillán	POINT(-72.103440 -36.606640)
+G3899361	Arica	POINT(-70.304170 -18.475000)
+G3899539	Antofagasta	POINT(-70.400000 -23.650000)
+G7281017	La Pintana	POINT(-70.634190 -33.583310)
+G2220957	Yaoundé	POINT(11.516670 3.866670)
+G2224827	Ngaoundéré	POINT(13.583330 7.316670)
+G2226275	Mokolo	POINT(13.801880 10.739780)
+G2228373	Maroua	POINT(14.315920 10.590950)
+G2229152	Loum	POINT(9.735100 4.718200)
+G2229798	Kousséri	POINT(15.030630 12.076890)
+G2231320	Garoua	POINT(13.400000 9.300000)
+G2232239	Edéa	POINT(10.133330 3.800000)
+G2232593	Douala	POINT(9.708400 4.046900)
+G2234359	Bertoua	POINT(13.683330 4.583330)
+G2234974	Bamenda	POINT(10.158240 5.952660)
+G2235189	Bafoussam	POINT(10.417860 5.473660)
+G1280849	Kashi	POINT(75.979720 39.454720)
+G1529102	Urunchi	POINT(87.583330 43.800000)
+G1529114	Turpan	POINT(89.166670 42.933330)
+G1529195	Shihezi	POINT(86.033330 44.300000)
+G1529376	Korla	POINT(86.146940 41.759720)
+G1529569	Changji	POINT(87.316670 44.016670)
+G1529641	Aral	POINT(81.263610 40.515560)
+G1529660	Aksu	POINT(80.264440 41.123060)
+G1783621	Zunyi	POINT(106.907220 27.686670)
+G1783633	Zoucheng	POINT(116.965560 35.400560)
+G1783745	Zigong	POINT(104.776890 29.341620)
+G1783763	Zhuzhou	POINT(113.150000 27.833330)
+G1783873	Zhumadian	POINT(114.029440 32.979440)
+G1783934	Shangqiu	POINT(115.650000 34.450000)
+G1784130	Zhoukou	POINT(114.633330 33.633330)
+G1784554	Zhicheng	POINT(111.504720 30.295560)
+G1784580	Yizheng	POINT(119.178890 32.269170)
+G1784642	Zhenjiang	POINT(119.434170 32.209170)
+G1784658	Zhengzhou	POINT(113.648610 34.757780)
+G1784853	Zhaoqing	POINT(112.459720 23.051160)
+G1784990	Zhanjiang	POINT(110.342710 21.281450)
+G1785018	Zhangzhou	POINT(117.655560 24.513330)
+G1785286	Zibo	POINT(118.063330 36.790560)
+G1785294	Anyang	POINT(114.328890 36.099440)
+G1785453	Zaozhuang	POINT(117.554170 34.864720)
+G1785462	Zaoyang	POINT(112.754170 32.127220)
+G1785725	Yunfu	POINT(112.037300 22.930560)
+G1785738	Yuncheng	POINT(110.992780 35.023060)
+G1785974	Yuci	POINT(112.731940 37.680280)
+G1786067	Yuanlin	POINT(112.885950 30.415130)
+G1786640	Yingcheng	POINT(113.550000 30.950000)
+G1786657	Yinchuan	POINT(106.273060 38.468060)
+G1786746	Yichun	POINT(114.400000 27.833330)
+G1786764	Yichang	POINT(111.284720 30.714440)
+G1786770	Yibin	POINT(104.623830 28.766670)
+G1787093	Yantai	POINT(121.400000 37.533330)
+G1787227	Yangzhou	POINT(119.435830 32.397220)
+G1787323	Yangshuo	POINT(110.489670 24.780810)
+G1787351	Yangquan	POINT(113.563330 37.857500)
+G1787746	Yancheng	POINT(120.125280 33.385560)
+G1787824	Tongshan	POINT(117.157070 34.180450)
+G1787858	Xuri	POINT(117.966670 28.466670)
+G1788046	Xuchang	POINT(113.816670 34.016670)
+G1788450	Xinzhou	POINT(112.733330 38.409170)
+G1788534	Xinyang	POINT(114.065560 32.122780)
+G1788572	Xinxiang	POINT(113.867220 35.308890)
+G1788618	Xintai	POINT(117.751940 35.900560)
+G1788694	Xinpu	POINT(119.159440 34.599720)
+G1788852	Xining	POINT(101.766670 36.616670)
+G1788927	Xingtai	POINT(114.494170 37.063060)
+G1789137	Xindi	POINT(113.466670 29.816670)
+G1789273	Sanshui	POINT(112.891610 23.154860)
+G1790254	Xiaogan	POINT(113.900000 30.916670)
+G1790353	Xianyang	POINT(108.702610 34.337780)
+G1790371	Xiantao	POINT(113.400000 30.383330)
+G1790396	Xianning	POINT(114.216670 29.883330)
+G1790437	Zhuhai	POINT(113.567780 22.276940)
+G1790492	Xiangtan	POINT(112.900000 27.850000)
+G1790587	Xiangfan	POINT(112.145000 32.041670)
+G1790630	Xi’an	POINT(108.928610 34.258330)
+G1790645	Xiamen	POINT(118.081870 24.479790)
+G1790840	Wuzhou	POINT(111.316670 23.483330)
+G1790894	Wuxue	POINT(115.552500 29.850580)
+G1790923	Wuxi	POINT(120.288570 31.568870)
+G1791121	Changde	POINT(111.678060 29.032220)
+G1791236	Wuhu	POINT(118.375480 31.336570)
+G1791247	Wuhan	POINT(114.266670 30.583330)
+G1791249	Wuhai	POINT(106.812220 39.664720)
+G1791388	Wenzhou	POINT(120.666820 27.999420)
+G1791636	Weinan	POINT(109.508910 34.503550)
+G1791673	Weihai	POINT(122.113610 37.501670)
+G1791681	Weifang	POINT(119.101940 36.710000)
+G1791748	Wanxian	POINT(108.389720 30.803890)
+G1792260	Wafangdian	POINT(122.008060 39.618330)
+G1792520	Tongzhou	POINT(116.599440 39.905280)
+G1792621	Wusong	POINT(117.783330 30.950000)
+G1792947	Tianjin	POINT(117.176670 39.142220)
+G1793346	Tangshan	POINT(118.183330 39.633330)
+G1793424	Tanggu	POINT(117.646940 39.021110)
+G1793505	Taizhou	POINT(119.910630 32.493330)
+G1793511	Taiyuan	POINT(112.560280 37.869440)
+G1793724	Tai’an	POINT(117.120000 36.185280)
+G1793743	Suzhou	POINT(116.978890 33.636110)
+G1793879	Suizhou	POINT(113.363060 31.711110)
+G1794903	Shiyan	POINT(110.778060 32.647500)
+G1794904	Shiyan	POINT(110.783330 32.566670)
+G1795060	Shiqi	POINT(113.385210 22.516820)
+G1795196	Tongchuan	POINT(109.089720 35.080560)
+G1795270	Shijiazhuang	POINT(114.478610 38.041390)
+G1795565	Shenzhen	POINT(114.068300 22.545540)
+G1795816	Shashi	POINT(112.244720 30.307220)
+G1795855	Shaoxing	POINT(120.581110 30.001670)
+G1795874	Shaoguan	POINT(113.583330 24.800000)
+G1795928	Shanwei	POINT(115.347500 22.781990)
+G1795940	Shantou	POINT(116.714790 23.368140)
+G1796236	Shanghai	POINT(121.458060 31.222220)
+G1796663	Sanming	POINT(117.618610 26.248610)
+G1797121	Jieyang	POINT(116.364160 23.528860)
+G1797132	Rizhao	POINT(119.455280 35.427500)
+G1797353	Quanzhou	POINT(118.585830 24.913890)
+G1797595	Qinhuangdao	POINT(119.588330 39.931670)
+G1797873	Huaiyin	POINT(119.019170 33.588610)
+G1797929	Qingdao	POINT(120.371940 36.098610)
+G1797945	Qingyuan	POINT(113.033330 23.700000)
+G1798422	Puyang	POINT(115.005280 35.702780)
+G1798425	Puyang	POINT(119.886110 29.460280)
+G1798449	Putian	POINT(119.010280 25.439440)
+G1798654	Pingxiang	POINT(113.850000 27.616670)
+G1798827	Pingdingshan	POINT(113.301190 33.738470)
+G1798998	Dadukou	POINT(101.705390 26.547900)
+G1799397	Ningbo	POINT(121.549450 29.878190)
+G1799491	Neijiang	POINT(105.062160 29.583540)
+G1799629	Nanyang	POINT(112.532780 32.994720)
+G1799722	Nantong	POINT(120.874720 32.030280)
+G1799846	Nanping	POINT(118.173610 26.645000)
+G1799869	Nanning	POINT(108.316670 22.816670)
+G1799962	Nanjing	POINT(118.777780 32.061670)
+G1800146	Nanchong	POINT(106.084740 30.795080)
+G1800163	Nanchang	POINT(115.883330 28.683330)
+G1800627	Mianyang	POINT(104.754240 31.459340)
+G1800657	Mentougou	POINT(116.091670 39.939170)
+G1801757	Luqiao	POINT(121.377150 28.580840)
+G1801792	Luoyang	POINT(112.453610 34.683610)
+G1801934	Luohe	POINT(114.035280 33.571670)
+G1802204	Luancheng	POINT(114.651670 37.879170)
+G1802238	Loudi	POINT(111.994440 27.734440)
+G1802875	Liuyang	POINT(113.633330 28.150000)
+G1803318	Linyi	POINT(118.342780 35.063060)
+G1803331	Linxia	POINT(103.206390 35.600280)
+G1803422	Linhai	POINT(121.116670 28.850000)
+G1803567	Linfen	POINT(111.518890 36.088890)
+G1803791	Licheng	POINT(113.828360 23.295540)
+G1803834	Liaocheng	POINT(115.964720 36.443890)
+G1804153	Leshan	POINT(103.763860 29.562280)
+G1804386	Laohekou	POINT(111.667780 32.385830)
+G1804430	Lanzhou	POINT(103.792220 36.056390)
+G1804540	Langfang	POINT(116.694720 39.509720)
+G1804586	Laiyang	POINT(120.713610 36.975830)
+G1804651	Kunming	POINT(102.718330 25.038890)
+G1804850	Kaiyuan	POINT(103.303720 23.697670)
+G1804879	Kaifeng	POINT(114.348330 34.791110)
+G1805179	Jiujiang	POINT(115.983330 29.733330)
+G1805298	Jinzhou	POINT(121.716670 39.100000)
+G1805518	Jining	POINT(116.581390 35.405000)
+G1805540	Jingzhou	POINT(112.190280 30.350280)
+G1805611	Jingmen	POINT(112.204720 31.033610)
+G1805618	Jingling	POINT(113.100000 30.650000)
+G1805680	Jingdezhen	POINT(117.207890 29.294700)
+G1805741	Jincheng	POINT(112.832780 35.502220)
+G1805753	Jinan	POINT(116.997220 36.668330)
+G1805953	Jiaxing	POINT(120.748330 30.765560)
+G1805987	Jiaozuo	POINT(113.233060 35.239720)
+G1806096	Jiaozhou	POINT(120.003330 36.283890)
+G1806299	Jiangmen	POINT(113.083330 22.583330)
+G1806408	Yangjiang	POINT(111.966670 21.850000)
+G1806445	Ji’an	POINT(114.979270 27.117160)
+G1806466	Guangyuan	POINT(105.823000 32.442020)
+G1806535	Huzhou	POINT(120.096390 30.866110)
+G1806696	Humen	POINT(113.673060 22.818980)
+G1806776	Huizhou	POINT(114.400000 23.083330)
+G1806882	Xinhui	POINT(113.048200 22.456000)
+G1807143	Huangyan	POINT(121.259440 28.647780)
+G1807234	Huangshi	POINT(115.100000 30.216670)
+G1807508	Huanggang	POINT(116.999610 23.677040)
+G1807681	Huainan	POINT(116.996940 32.626390)
+G1807700	Huaibei	POINT(116.791670 33.974440)
+G1808198	Heze	POINT(115.441110 35.243060)
+G1808316	Yiyang	POINT(112.328330 28.589170)
+G1808370	Hengyang	POINT(112.615000 26.888060)
+G1808392	Hengshui	POINT(115.701110 37.732220)
+G1808722	Hefei	POINT(117.280830 31.863890)
+G1808770	Hebi	POINT(114.192500 35.899170)
+G1808926	Hangzhou	POINT(120.168890 30.255280)
+G1808931	Hangu	POINT(117.789170 39.248890)
+G1808963	Handan	POINT(114.467780 36.600560)
+G1809061	Jiaojiang	POINT(121.442780 28.680280)
+G1809078	Haikou	POINT(110.341670 20.045830)
+G1809412	Guli	POINT(120.033330 28.883330)
+G1809461	Guiyang	POINT(106.716670 26.583330)
+G1809498	Guilin	POINT(110.286390 25.281940)
+G1809858	Guangzhou	POINT(113.250000 23.116670)
+G1809879	Guangshui	POINT(113.997800 31.619900)
+G1810295	Gaozhou	POINT(110.846070 21.939240)
+G1810437	Gaoping	POINT(106.102940 30.775760)
+G1810458	Gaomi	POINT(119.752780 36.383330)
+G1810821	Fuzhou	POINT(119.306110 26.061390)
+G1810845	Fuyang	POINT(115.816670 32.900000)
+G1810979	Fuling	POINT(107.391940 29.702220)
+G1811103	Foshan	POINT(113.131480 23.026770)
+G1811619	Ezhou	POINT(114.833330 30.400000)
+G1812101	Dongying	POINT(118.485560 37.456390)
+G1812521	Donghai	POINT(115.642040 22.945940)
+G1812545	Dongguan	POINT(113.744720 23.048890)
+G1812728	Dingzhou	POINT(114.995560 38.513060)
+G1812955	Dezhou	POINT(116.292500 37.448610)
+G1812961	Deyang	POINT(104.381980 31.130190)
+G1813253	Dayan	POINT(100.220720 26.868790)
+G1814082	Daliang	POINT(113.247010 22.850420)
+G1814087	Dalian	POINT(121.602220 38.912220)
+G1814757	Chuzhou	POINT(118.297780 32.321940)
+G1814786	Yangchun	POINT(111.783330 22.166670)
+G1814906	Chongqing	POINT(106.552780 29.562780)
+G1815059	Chenzhou	POINT(113.033330 25.800000)
+G1815286	Chengdu	POINT(104.066670 30.666670)
+G1815302	Chenghua	POINT(116.770070 23.461320)
+G1815395	Chaozhou	POINT(116.637860 23.665130)
+G1815456	Changzhou	POINT(119.966670 31.783330)
+G1815463	Changzhi	POINT(111.738610 35.208890)
+G1815577	Changsha	POINT(112.966670 28.200000)
+G1816080	Cangzhou	POINT(116.866670 38.316670)
+G1816234	Bozhou	POINT(115.770280 33.877220)
+G1816265	Boshan	POINT(117.833330 36.483330)
+G1816440	Bengbu	POINT(117.360830 32.940830)
+G1816670	Beijing	POINT(116.397230 39.907500)
+G1816705	Beihai	POINT(109.100000 21.483330)
+G1816971	Baoding	POINT(115.490280 38.851110)
+G1817240	Baiyin	POINT(104.208060 36.558330)
+G1817720	Shangyu	POINT(120.871110 30.015560)
+G1817968	Anshun	POINT(105.933330 26.250000)
+G1817993	Anqing	POINT(117.050560 30.509170)
+G1818116	Anbu	POINT(116.680920 23.448950)
+G1886760	Suzhou	POINT(120.618060 31.311390)
+G1915223	Zhongshan	POINT(110.582910 21.322560)
+G1919014	Lianghu	POINT(120.898450 29.991520)
+G1927639	Yueyang	POINT(113.091940 29.333330)
+G2033168	Zhaodong	POINT(125.983330 46.083330)
+G2033196	Zhangjiakou	POINT(114.879440 40.810000)
+G2033370	Yingkou	POINT(122.224720 40.668060)
+G2033413	Yichun	POINT(128.900000 47.700000)
+G2033467	Yanji	POINT(129.507780 42.907500)
+G2033574	Xuanhua	POINT(115.044720 40.610280)
+G2034312	Ulan Hot	POINT(122.083330 46.083330)
+G2034400	Tongliao	POINT(122.265280 43.612500)
+G2034439	Tieling	POINT(123.841390 42.293060)
+G2034655	Suihua	POINT(126.996940 46.640560)
+G2034714	Siping	POINT(124.368610 43.163330)
+G2034786	Shuangyashan	POINT(131.153890 46.636110)
+G2034937	Shenyang	POINT(123.432780 41.792220)
+G2035225	Ranghulu	POINT(124.866670 46.650000)
+G2035261	Qitaihe	POINT(130.850000 45.800000)
+G2035265	Qiqihar	POINT(123.967220 47.340830)
+G2035513	Panshan	POINT(122.049440 41.188060)
+G2035644	Nanpiao	POINT(120.747920 41.098220)
+G2035715	Mudanjiang	POINT(129.600000 44.583330)
+G2035980	Longfeng	POINT(125.116670 46.550000)
+G2036109	Liaoyuan	POINT(125.135830 42.903610)
+G2036113	Liaoyang	POINT(123.173060 41.271940)
+G2036389	Jixi	POINT(130.966670 45.300000)
+G2036401	Jiutai	POINT(125.832780 44.152500)
+G2036427	Jinzhou	POINT(121.141670 41.107780)
+G2036434	Lianshan	POINT(120.853270 40.764320)
+G2036458	Jining	POINT(113.105830 41.027500)
+G2036502	Jilin	POINT(126.560280 43.850830)
+G2036581	Jiamusi	POINT(130.350000 46.833330)
+G2036670	Hulan Ergi	POINT(123.633330 47.204170)
+G2036892	Hohhot	POINT(111.652220 40.810560)
+G2036920	Hengshan	POINT(130.916670 45.200000)
+G2036986	Hegang	POINT(130.366670 47.400000)
+G2037013	Harbin	POINT(126.650000 45.750000)
+G2037078	Hailar	POINT(119.700000 49.200000)
+G2037086	Haicheng	POINT(122.741670 40.851940)
+G2037346	Fuxin	POINT(121.658890 42.015560)
+G2037355	Fushun	POINT(123.923330 41.855830)
+G2037620	Dongling	POINT(123.575830 41.814440)
+G2037799	Datong	POINT(113.291390 40.093610)
+G2037860	Daqing	POINT(125.000000 46.583330)
+G2037886	Dandong	POINT(124.394720 40.129170)
+G2038067	Chifeng	POINT(118.963610 42.268330)
+G2038087	Chengde	POINT(117.936110 40.972500)
+G2038120	Chaoyang	POINT(120.458610 41.570280)
+G2038180	Changchun	POINT(125.322780 43.880000)
+G2038300	Benxi	POINT(123.765000 41.288610)
+G2038342	Beipiao	POINT(120.779170 41.791940)
+G2038432	Baotou	POINT(109.822220 40.652220)
+G2038569	Baicheng	POINT(122.816670 45.616670)
+G2038584	Baishan	POINT(126.428610 41.943060)
+G2038632	Anshan	POINT(122.990000 41.123610)
+G2038650	Anda	POINT(125.316670 46.400000)
+G7158935	东海岛	POINT(110.396130 21.024480)
+G7283386	Changshu City	POINT(120.742210 31.646150)
+G7304020	Fenghuang	POINT(109.599610 27.935570)
+G7602670	Zhu Cheng City	POINT(119.402590 35.995020)
+G3665900	Villavicencio	POINT(-73.626640 4.142000)
+G3666304	Valledupar	POINT(-73.250560 10.476940)
+G3666645	Tuluá	POINT(-76.200000 4.086670)
+G3667849	Soledad	POINT(-74.766670 10.917220)
+G3667905	Soacha	POINT(-74.221390 4.587220)
+G3667983	Sincelejo	POINT(-75.397780 9.304720)
+G3668605	Santa Marta	POINT(-74.201670 11.247220)
+G3671916	Popayán	POINT(-76.613160 2.438230)
+G3672486	Pereira	POINT(-75.696110 4.813330)
+G3672778	Pasto	POINT(-77.281110 1.213610)
+G3673164	Palmira	POINT(-76.303610 3.539440)
+G3673899	Neiva	POINT(-75.281880 2.927300)
+G3674453	Montería	POINT(-75.890000 8.757500)
+G3674962	Medellín	POINT(-75.536110 6.291390)
+G3675443	Manizales	POINT(-75.520560 5.070000)
+G3680450	Itagüí	POINT(-75.611390 6.171940)
+G3680656	Ibagué	POINT(-75.232220 4.438890)
+G3682385	Floridablanca	POINT(-73.089720 7.064720)
+G3682631	Envigado	POINT(-75.563890 6.173060)
+G3685095	Dos Quebradas	POINT(-75.672500 4.834720)
+G3685533	Cúcuta	POINT(-72.505280 7.883330)
+G3687238	Cartagena	POINT(-75.514440 10.399720)
+G3687925	Cali	POINT(-76.522500 3.437220)
+G3688451	Buenaventura	POINT(-77.069720 3.893330)
+G3688465	Bucaramanga	POINT(-73.125830 7.129720)
+G3688689	Bogotá	POINT(-74.081750 4.609710)
+G3688928	Bello	POINT(-75.562220 6.338890)
+G3689147	Barranquilla	POINT(-74.796390 10.963890)
+G3689169	Barrancabermeja	POINT(-73.854720 7.065280)
+G3689560	Armenia	POINT(-75.681110 4.533890)
+G3621849	San José	POINT(-84.083330 9.933330)
+G3536729	Santiago de Cuba	POINT(-75.821940 20.024720)
+G3537906	Santa Clara	POINT(-79.966670 22.400000)
+G3544091	Pinar del Río	POINT(-83.698060 22.417500)
+G3550598	Las Tunas	POINT(-76.951110 20.961670)
+G3553478	Havana	POINT(-82.383040 23.133020)
+G3556969	Holguín	POINT(-76.263060 20.887220)
+G3557689	Guantánamo	POINT(-75.209170 20.144440)
+G3564124	Cienfuegos	POINT(-80.435560 22.146110)
+G3566067	Camagüey	POINT(-77.916940 21.380830)
+G3567597	Bayamo	POINT(-76.643330 20.379170)
+G146268	Nicosia	POINT(33.366670 35.166670)
+G146384	Limassol	POINT(33.033330 34.675000)
+G3067696	Praha	POINT(14.420760 50.088040)
+G3068160	Plzeň	POINT(13.377590 49.747470)
+G3068799	Ostrava	POINT(18.282040 49.834650)
+G3078610	Brno	POINT(16.607960 49.195220)
+G2805753	Wuppertal	POINT(7.183330 51.266670)
+G2809346	Wiesbaden	POINT(8.250000 50.083330)
+G2825297	Stuttgart	POINT(9.177020 48.782320)
+G2831580	Solingen	POINT(7.083330 51.183330)
+G2842647	Saarbrücken	POINT(7.000000 49.233330)
+G2844588	Rostock	POINT(12.140490 54.088700)
+G2848756	Berlin Reinickendorf	POINT(13.333330 52.566670)
+G2855598	Berlin Pankow	POINT(13.401860 52.569260)
+G2856883	Osnabrück	POINT(8.050000 52.266670)
+G2857458	Oldenburg	POINT(8.200000 53.166670)
+G2860410	Oberhausen	POINT(6.850000 51.466670)
+G2861650	Nuremberg	POINT(11.068330 49.447780)
+G2864072	Neue Neustadt	POINT(11.633330 52.150000)
+G2864118	Neuß	POINT(6.683330 51.200000)
+G2867543	Münster	POINT(7.625710 51.962360)
+G2867714	München	POINT(11.575490 48.137430)
+G2867838	Mülheim an der Ruhr	POINT(6.883330 51.433330)
+G2869894	Mönchengladbach	POINT(6.433330 51.200000)
+G2873891	Mannheim	POINT(8.464720 49.488330)
+G2874225	Mainz	POINT(8.271110 50.000000)
+G2874545	Magdeburg	POINT(11.666670 52.166670)
+G2875376	Ludwigshafen am Rhein	POINT(8.435280 49.481110)
+G2875601	Lübeck	POINT(10.687290 53.868930)
+G2878234	Leverkusen	POINT(7.000000 51.033330)
+G2879139	Leipzig	POINT(12.371290 51.339620)
+G2884509	Krefeld	POINT(6.566670 51.333330)
+G2886242	Köln	POINT(6.950000 50.933330)
+G2891122	Kiel	POINT(10.134890 54.321330)
+G2892518	Kassel	POINT(9.500000 51.316670)
+G2892794	Karlsruhe	POINT(8.385830 49.004720)
+G2905891	Herne	POINT(7.216670 51.550000)
+G2910685	Harburg	POINT(9.983330 53.466670)
+G2910831	Hannover	POINT(9.733220 52.370520)
+G2911240	Hamm	POINT(7.820890 51.680330)
+G2911285	Wandsbek	POINT(10.100000 53.566670)
+G2911287	Marienthal	POINT(10.083330 53.566670)
+G2911293	Eimsbüttel	POINT(9.983330 53.566670)
+G2911296	Altona	POINT(9.933330 53.550000)
+G2911298	Hamburg	POINT(10.000000 53.550000)
+G2911522	Halle	POINT(12.000000 51.500000)
+G2912621	Hagen	POINT(7.466670 51.350000)
+G2921466	Gelsenkirchen	POINT(7.050000 51.516670)
+G2925177	Freiburg	POINT(7.852220 47.995900)
+G2925533	Frankfurt am Main	POINT(8.683330 50.116670)
+G2928810	Essen	POINT(7.016670 51.450000)
+G2929670	Erfurt	POINT(11.033330 50.983330)
+G2934246	Düsseldorf	POINT(6.776160 51.221720)
+G2934691	Duisburg	POINT(6.750000 51.433330)
+G2935022	Dresden	POINT(13.738320 51.050890)
+G2935517	Dortmund	POINT(7.450000 51.516670)
+G2940132	Chemnitz	POINT(12.916670 50.833330)
+G2944388	Bremen	POINT(8.807770 53.075160)
+G2945024	Braunschweig	POINT(10.533330 52.266670)
+G2946447	Bonn	POINT(7.100000 50.733330)
+G2947416	Bochum	POINT(7.216670 51.483330)
+G2949186	Bielefeld	POINT(8.533330 52.033330)
+G2950159	Berlin	POINT(13.410530 52.524370)
+G2954172	Augsburg	POINT(10.883330 48.366670)
+G3247449	Aachen	POINT(6.083420 50.776640)
+G6545310	Berlin Mitte	POINT(13.404890 52.520030)
+G6941055	Bochum-Hordel	POINT(7.175600 51.501680)
+G7289614	Halle Neustadt	POINT(11.916050 51.479240)
+G7290245	Berlin Steglitz Zehlendorf	POINT(13.241830 52.434850)
+G7290251	Berlin Wilmersdorf	POINT(13.290970 52.500970)
+G7290252	Berlin Spandau	POINT(13.199210 52.551100)
+G223817	Djibouti	POINT(43.144680 11.587670)
+G2618425	Copenhagen	POINT(12.565530 55.675940)
+G2624652	Århus	POINT(10.210760 56.156740)
+G3492908	Santo Domingo	POINT(-69.988570 18.500120)
+G3492914	Santiago de los Caballeros	POINT(-70.700000 19.450000)
+G3493032	San Pedro de Macorís	POINT(-69.297180 18.461560)
+G3500957	La Romana	POINT(-68.972850 18.427340)
+G3511540	San Cristóbal	POINT(-70.100000 18.416670)
+G2474141	Boumerdas	POINT(3.477170 36.766390)
+G2479536	Skikda	POINT(6.909210 36.876170)
+G2481007	Sidi Bel Abbès	POINT(-0.630850 35.189940)
+G2485926	Oran	POINT(-0.641670 35.691110)
+G2498766	El Achir	POINT(4.627440 36.063860)
+G2498954	Ech Chettia	POINT(1.255380 36.195910)
+G2501152	Constantine	POINT(6.614720 36.365000)
+G2505329	Bejaïa	POINT(5.084330 36.755870)
+G2505572	Batna	POINT(6.174140 35.555970)
+G2505854	Bab Ezzouar	POINT(3.182910 36.726150)
+G2506999	Annaba	POINT(7.766670 36.900000)
+G2507480	Algiers	POINT(3.041970 36.752500)
+G3651297	Santo Domingo de los Colorados	POINT(-79.150000 -0.250000)
+G3652462	Quito	POINT(-78.524950 -0.229850)
+G3652941	Portoviejo	POINT(-80.450000 -1.050000)
+G3654410	Manta	POINT(-80.733330 -0.950000)
+G3654533	Machala	POINT(-79.966670 -3.266670)
+G3657509	Guayaquil	POINT(-79.900000 -2.166670)
+G3658192	Durán	POINT(-79.833330 -2.200000)
+G3658666	Cuenca	POINT(-78.983330 -2.883330)
+G3660689	Ambato	POINT(-78.616750 -1.249080)
+G588409	Tallinn	POINT(24.753530 59.436960)
+G347497	Tanda	POINT(30.998060 30.791110)
+G347591	Ṭalkha	POINT(31.373890 31.053060)
+G347796	Sūhāj	POINT(31.700000 26.550000)
+G350550	Qinā	POINT(32.727220 26.170000)
+G354775	Kafr ad Dawwār	POINT(30.128430 31.133850)
+G355795	Hilwan	POINT(31.333330 29.850000)
+G358448	Damanhûr	POINT(30.466670 31.033330)
+G358619	Port Said	POINT(32.307500 31.280560)
+G359173	Banī Suwayf	POINT(31.088890 29.063890)
+G359280	Banhā	POINT(31.187500 30.460830)
+G359493	Az Zaqāzīq	POINT(31.510280 30.591390)
+G359783	Asyūţ	POINT(31.182780 27.182780)
+G359792	Aswān	POINT(32.898890 24.087500)
+G359796	Suez	POINT(32.550000 29.966670)
+G360502	Luxor	POINT(32.642100 25.698930)
+G360630	Cairo	POINT(31.249670 30.062630)
+G360686	Al Minyā	POINT(30.744440 28.119440)
+G360761	Al Manşūrah	POINT(31.376670 31.043060)
+G360829	Al Maḩallah al Kubrá	POINT(31.166940 30.976110)
+G360995	Al Jīzah	POINT(31.212220 30.008610)
+G361055	Ismailia	POINT(32.277220 30.605280)
+G361058	Alexandria	POINT(29.919170 31.198060)
+G361320	Al Fayyūm	POINT(30.840000 29.307780)
+G411165	Idfu	POINT(32.874720 24.980280)
+G2462881	Laâyoune / El Aaiún	POINT(-13.203150 27.162240)
+G343300	Asmara	POINT(38.933330 15.333330)
+G2509954	Valencia	POINT(-0.377390 39.469750)
+G2510911	Sevilla	POINT(-5.986940 37.377220)
+G2511174	Santa Cruz de Tenerife	POINT(-16.254620 28.468240)
+G2511401	La Laguna	POINT(-16.316670 28.483330)
+G2512989	Palma	POINT(2.650240 39.569390)
+G2513416	Murcia	POINT(-1.116670 37.983330)
+G2514256	Málaga	POINT(-4.420340 36.720160)
+G2515270	Las Palmas de Gran Canaria	POINT(-15.416670 28.100000)
+G2516326	Jerez de la Frontera	POINT(-6.133330 36.683330)
+G2517117	Granada	POINT(-3.606670 37.188170)
+G2518559	Elx	POINT(-0.701070 38.262180)
+G2519240	Córdoba	POINT(-4.766670 37.883330)
+G2519752	Castelló de la Plana	POINT(-0.033330 39.983330)
+G2520058	Cartagena	POINT(-0.983330 37.600000)
+G2521886	Almería	POINT(-2.459740 36.838140)
+G2521978	Alicante	POINT(-0.481490 38.345170)
+G2522258	Albacete	POINT(-1.850000 38.983330)
+G3104324	Zaragoza	POINT(-0.877340 41.656060)
+G3104499	Vitoria-Gasteiz	POINT(-2.666670 42.850000)
+G3105976	Vigo	POINT(-8.716670 42.233330)
+G3106672	Valladolid	POINT(-4.716670 41.650000)
+G3108286	Terrassa	POINT(2.016670 41.566670)
+G3109718	Santander	POINT(-3.804440 43.464720)
+G3110044	San Sebastián	POINT(-1.974990 43.312830)
+G3111108	Salamanca	POINT(-5.650000 40.966670)
+G3111199	Sabadell	POINT(2.109420 41.543290)
+G3114472	Pamplona	POINT(-1.643230 42.816870)
+G3114711	Oviedo	POINT(-5.844760 43.360290)
+G3116025	Móstoles	POINT(-3.864960 40.322340)
+G3117735	Madrid	POINT(-3.702560 40.416500)
+G3118150	Logroño	POINT(-2.450000 42.466670)
+G3118594	Leganés	POINT(-3.763500 40.327180)
+G3119841	A Coruña	POINT(-8.396000 43.371350)
+G3120619	L'Hospitalet de Llobregat	POINT(2.100280 41.359670)
+G3121424	Gijón	POINT(-5.664440 43.541110)
+G3121437	Getafe	POINT(-3.732950 40.305710)
+G3121960	Fuenlabrada	POINT(-3.800000 40.283330)
+G3127461	Burgos	POINT(-3.700000 42.350000)
+G3128026	Bilbao	POINT(-2.925280 43.262710)
+G3128760	Barcelona	POINT(2.158990 41.388790)
+G3129028	Badalona	POINT(2.247410 41.450040)
+G3130564	Alcorcón	POINT(-3.824870 40.345820)
+G3130616	Alcalá de Henares	POINT(-3.366670 40.483330)
+G6252065	Nou Barris	POINT(2.177270 41.441630)
+G6544100	Eixample	POINT(2.161790 41.388960)
+G6544105	Sant Martí	POINT(2.199330 41.418140)
+G330186	Nazrēt	POINT(39.266670 8.550000)
+G331180	Mek’elē	POINT(39.475280 13.496670)
+G336014	Gonder	POINT(37.466670 12.600000)
+G338832	Dirē Dawa	POINT(41.866110 9.593060)
+G342884	Bahir Dar	POINT(37.383330 11.600000)
+G344979	Addis Ababa	POINT(38.746890 9.024970)
+G632453	Vantaa	POINT(25.040990 60.294140)
+G633679	Turku	POINT(22.268690 60.451480)
+G634963	Tampere	POINT(23.787120 61.499110)
+G658225	Helsinki	POINT(24.935450 60.169520)
+G660158	Espoo	POINT(24.652200 60.205200)
+G2972315	Toulouse	POINT(1.443670 43.604260)
+G2972328	Toulon	POINT(5.933330 43.116670)
+G2973783	Strasbourg	POINT(7.742960 48.583420)
+G2980291	Saint-Étienne	POINT(4.400000 45.433330)
+G2983990	Rennes	POINT(-1.683330 48.083330)
+G2984114	Reims	POINT(4.033330 49.250000)
+G2988507	Paris	POINT(2.348800 48.853410)
+G2990440	Nice	POINT(7.266080 43.703130)
+G2990969	Nantes	POINT(-1.553360 47.217250)
+G2992166	Montpellier	POINT(3.883330 43.600000)
+G2995469	Marseille	POINT(5.381070 43.296950)
+G2996944	Lyon	POINT(4.850000 45.750000)
+G2998324	Lille	POINT(3.066670 50.633330)
+G3003796	Le Havre	POINT(0.107670 49.493800)
+G3014728	Grenoble	POINT(5.716670 45.166670)
+G3031582	Bordeaux	POINT(-0.566670 44.833330)
+G3037656	Angers	POINT(-0.550000 47.466670)
+G2399697	Libreville	POINT(9.450000 0.383330)
+G2633691	Wolverhampton	POINT(-2.122960 52.585470)
+G2634853	Walsall	POINT(-1.983960 52.585280)
+G2636389	Swindon	POINT(-1.781160 51.557970)
+G2636432	Swansea	POINT(-3.943230 51.620790)
+G2636503	Sutton	POINT(-0.200000 51.350000)
+G2636531	Sunderland	POINT(-1.382220 54.904650)
+G2636841	Stoke-on-Trent	POINT(-2.185380 53.004150)
+G2637433	Southend-on-Sea	POINT(0.714330 51.537820)
+G2637487	Southampton	POINT(-1.404280 50.903950)
+G2638077	Sheffield	POINT(-1.465900 53.382970)
+G2639577	Reading	POINT(-0.971130 51.456250)
+G2639912	Preston	POINT(-2.716670 53.766670)
+G2639996	Portsmouth	POINT(-1.091250 50.798990)
+G2640101	Poole	POINT(-2.000000 50.716670)
+G2640194	Plymouth	POINT(-4.143050 50.371530)
+G2640729	Oxford	POINT(-1.255960 51.752220)
+G2641170	Nottingham	POINT(-1.150470 52.953600)
+G2641181	Norwich	POINT(1.298340 52.627830)
+G2641430	Northampton	POINT(-0.883330 52.250000)
+G2641673	Newcastle upon Tyne	POINT(-1.613960 54.973280)
+G2642465	Milton Keynes	POINT(-0.755830 52.041720)
+G2643123	Manchester	POINT(-2.237430 53.480950)
+G2643339	Luton	POINT(-0.417480 51.879670)
+G2643741	City of London	POINT(-0.091840 51.512790)
+G2643743	London	POINT(-0.125740 51.508530)
+G2644210	Liverpool	POINT(-2.977940 53.410580)
+G2644668	Leicester	POINT(-1.131690 52.638600)
+G2644688	Leeds	POINT(-1.547850 53.796480)
+G2645425	Hull	POINT(-0.335250 53.744600)
+G2646003	Islington	POINT(-0.103040 51.536220)
+G2648579	Glasgow	POINT(-4.257630 55.865150)
+G2650225	Edinburgh	POINT(-3.196480 55.952060)
+G2650752	Dundee	POINT(-2.966670 56.500000)
+G2650839	Dudley	POINT(-2.083330 52.500000)
+G2651347	Derby	POINT(-1.476630 52.922770)
+G2652221	Coventry	POINT(-1.512170 52.406560)
+G2653822	Cardiff	POINT(-3.180000 51.480000)
+G2654675	Bristol	POINT(-2.596650 51.455230)
+G2654993	Bradford	POINT(-1.752060 53.793910)
+G2655095	Bournemouth	POINT(-1.879500 50.720480)
+G2655603	Birmingham	POINT(-1.899830 52.481420)
+G2655984	Belfast	POINT(-5.933330 54.583330)
+G2657832	Aberdeen	POINT(-2.098140 57.143690)
+G7535661	London Borough of Harrow	POINT(-0.333330 51.566670)
+G611717	Tbilisi	POINT(44.833680 41.694110)
+G613607	K'ut'aisi	POINT(42.699740 42.249610)
+G2294700	Tema	POINT(-0.016670 5.616670)
+G2294877	Tamale	POINT(-0.833330 9.400000)
+G2294915	Takoradi	POINT(-1.750000 4.883330)
+G2298890	Kumasi	POINT(-1.616670 6.683330)
+G2306079	Achiaman	POINT(-0.333330 5.700000)
+G2306104	Accra	POINT(-0.196900 5.556020)
+G2422465	Conakry	POINT(-13.677290 9.537950)
+G2422488	Camayenne	POINT(-13.687780 9.535000)
+G2309527	Malabo	POINT(8.783330 3.750000)
+G2310046	Bata	POINT(9.750000 1.850000)
+G255274	Piraeus	POINT(23.637080 37.947450)
+G255683	Pátrai	POINT(21.734440 38.244440)
+G264371	Athens	POINT(23.716220 37.979450)
+G734077	Thessaloníki	POINT(22.943890 40.640280)
+G3587902	Villa Nueva	POINT(-90.587500 14.526940)
+G3592519	Mixco	POINT(-90.606390 14.633330)
+G3598132	Guatemala City	POINT(-90.513270 14.640720)
+G2374775	Bissau	POINT(-15.583330 11.850000)
+G3378644	Georgetown	POINT(-58.155270 6.804480)
+G1819609	Kowloon	POINT(114.183330 22.316670)
+G1819729	Hong Kong	POINT(114.157690 22.285520)
+G3600949	Tegucigalpa	POINT(-87.206810 14.081800)
+G3601782	San Pedro Sula	POINT(-88.033330 15.500000)
+G3186886	Zagreb	POINT(15.977980 45.814440)
+G3190261	Split	POINT(16.439150 43.508910)
+G6618983	Zagreb - Centar	POINT(15.977530 45.813130)
+G3718426	Port-au-Prince	POINT(-72.335000 18.539170)
+G3719028	Pétionville	POINT(-72.285280 18.512500)
+G3726786	Delmas 73	POINT(-72.302780 18.544720)
+G3727135	Croix des Bouquets	POINT(-72.225000 18.575000)
+G3728338	Carrefour	POINT(-72.399220 18.541140)
+G715429	Szeged	POINT(20.148240 46.253000)
+G717582	Miskolc	POINT(20.783330 48.100000)
+G721472	Debrecen	POINT(21.633330 47.533330)
+G3046526	Pécs	POINT(18.233330 46.083330)
+G3054643	Budapest	POINT(19.039910 47.498010)
+G6942354	Nagyvárad	POINT(21.927340 47.060530)
+G1213614	Sunggal	POINT(98.615100 3.576500)
+G1214189	Percut	POINT(98.864000 3.625300)
+G1214191	Perbaungan	POINT(98.956000 3.567900)
+G1214204	Pematangsiantar	POINT(99.068700 2.959500)
+G1214520	Medan	POINT(98.666670 3.583330)
+G1215355	Binjai	POINT(98.485400 3.600100)
+G1215502	Banda Aceh	POINT(95.322200 5.557700)
+G1621177	Yogyakarta	POINT(110.360830 -7.782780)
+G1622786	Makassar	POINT(119.422100 -5.140000)
+G1624494	Tegal	POINT(109.140200 -6.869400)
+G1624647	Tasikmalaya	POINT(108.200000 -7.333330)
+G1624917	Bandarlampung	POINT(105.258030 -5.425440)
+G1625084	Tangerang	POINT(106.630000 -6.178060)
+G1625812	Surakarta	POINT(110.831670 -7.556110)
+G1625822	Surabaya	POINT(112.750830 -7.249170)
+G1626100	Sumedang Utara	POINT(107.916670 -6.850000)
+G1626381	Sukabumi	POINT(106.926670 -6.918060)
+G1626560	Soreang	POINT(107.518330 -7.033060)
+G1626801	Situbondo	POINT(114.009760 -7.706230)
+G1627549	Serang	POINT(106.150200 -6.114900)
+G1627896	Semarang	POINT(110.420300 -6.993200)
+G1629001	Samarinda	POINT(117.150000 -0.500000)
+G1629131	Salatiga	POINT(110.492780 -7.331940)
+G1629710	Rengasdengklok	POINT(107.298060 -6.159170)
+G1630328	Purwokerto	POINT(109.234440 -7.421390)
+G1630333	Purwodadi	POINT(110.915800 -7.086800)
+G1630341	Purwakarta	POINT(107.443330 -6.556940)
+G1630634	Probolinggo	POINT(113.215900 -7.754300)
+G1630789	Pontianak	POINT(109.333330 -0.033330)
+G1630997	Plumbon	POINT(108.472780 -6.705000)
+G1631648	Pemalang	POINT(109.366670 -6.900000)
+G1631761	Pekanbaru	POINT(101.450000 0.533330)
+G1631766	Pekalongan	POINT(109.675300 -6.888600)
+G1632033	Pasuruan	POINT(112.907500 -7.645300)
+G1632228	Pasarkemis	POINT(106.530280 -6.170280)
+G1632276	Parung	POINT(106.733060 -6.421390)
+G1632937	Pamulang	POINT(106.738330 -6.342780)
+G1633034	Palu	POINT(119.870700 -0.891700)
+G1633070	Palembang	POINT(104.745800 -2.916730)
+G1633419	Padang	POINT(100.354270 -0.949240)
+G1635882	Mataram	POINT(116.116670 -8.583330)
+G1636544	Manado	POINT(124.845500 1.487000)
+G1636556	Mamuju	POINT(118.888500 -2.674800)
+G1636722	Malang	POINT(112.630400 -7.979700)
+G1636930	Madiun	POINT(111.523900 -7.629800)
+G1637510	Loa Janan	POINT(117.095030 -0.582950)
+G1638063	Lembang	POINT(107.617500 -6.811670)
+G1638284	Lawang	POINT(112.694700 -7.835300)
+G1638868	Labuhanbajo	POINT(119.887700 -8.496400)
+G1640344	Kendari	POINT(122.498890 -3.945000)
+G1640660	Kediri	POINT(112.016670 -7.816670)
+G1642588	Jember	POINT(113.703170 -8.166040)
+G1642858	Jambi	POINT(103.616670 -1.600000)
+G1642911	Jakarta	POINT(106.845130 -6.214620)
+G1645524	Depok	POINT(106.818610 -6.400000)
+G1645528	Denpasar	POINT(115.216670 -8.650000)
+G1645895	Curug	POINT(106.556390 -6.265830)
+G1646170	Cirebon	POINT(108.557000 -6.706300)
+G1646194	Ciputat	POINT(106.695560 -6.237500)
+G1646448	Cimahi	POINT(107.542500 -6.872220)
+G1646494	Cileungsi	POINT(106.959170 -6.394720)
+G1647003	Cibinong	POINT(106.854170 -6.481670)
+G1647383	Ciampea	POINT(106.700830 -6.554720)
+G1648473	Bogor	POINT(106.789170 -6.594440)
+G1649150	Bengkulu	POINT(102.265540 -3.800440)
+G1649378	Bekasi	POINT(106.989600 -6.234900)
+G1650213	Banjarmasin	POINT(114.591000 -3.324420)
+G1650227	Banjaran	POINT(107.587780 -7.045280)
+G1650357	Bandung	POINT(107.618610 -6.903890)
+G1650527	Balikpapan	POINT(116.828870 -1.267530)
+G1651531	Ambon	POINT(128.200000 -3.716670)
+G1985663	Cikupa	POINT(106.508330 -6.236390)
+G2057087	Kupang	POINT(123.583330 -10.166670)
+G2964506	Dún Laoghaire	POINT(-6.135860 53.293950)
+G2964574	Dublin	POINT(-6.267190 53.343990)
+G2965140	Cork	POINT(-8.470610 51.897970)
+G281184	Jerusalem	POINT(35.225300 31.779020)
+G293397	Tel Aviv	POINT(34.766670 32.066670)
+G293703	Rishon LeẔiyyon	POINT(34.804440 31.964170)
+G294071	Netanya	POINT(34.857780 32.333610)
+G294751	H̱olon	POINT(34.772220 32.011390)
+G294801	Haifa	POINT(34.989170 32.815560)
+G295530	Beersheba	POINT(34.791300 31.251810)
+G295629	Ashdod	POINT(34.650000 31.816670)
+G6693674	Petah Tikva	POINT(34.885030 32.091740)
+G7498240	West Jerusalem	POINT(35.219610 31.781990)
+G1252797	Yamunānagar	POINT(77.283330 30.100000)
+G1252948	Warangal	POINT(79.583330 18.000000)
+G1253084	Vizianagaram	POINT(83.416670 18.116670)
+G1253102	Vishākhapatnam	POINT(83.300000 17.700000)
+G1253133	Virār	POINT(72.800000 19.466670)
+G1253184	Vijayawāda	POINT(80.616670 16.516670)
+G1253237	Verāval	POINT(70.366670 20.900000)
+G1253286	Vellore	POINT(79.133330 12.933330)
+G1253405	Benares	POINT(83.000000 25.333330)
+G1253573	Vadodara	POINT(73.200000 22.300000)
+G1253747	Unnāo	POINT(80.500000 26.533330)
+G1253894	Ulhāsnagar	POINT(73.150000 19.216670)
+G1253914	Ujjain	POINT(75.766670 23.183330)
+G1253986	Udaipur	POINT(73.691830 24.571170)
+G1254089	Tumkūr	POINT(77.101670 13.342220)
+G1254163	Thiruvananthapuram	POINT(76.916670 8.483330)
+G1254187	Trichūr	POINT(76.216670 10.516670)
+G1254241	Tonk	POINT(75.783330 26.166670)
+G1254348	Tiruppūr	POINT(77.350000 11.100000)
+G1254360	Tirupati	POINT(79.416670 13.650000)
+G1254361	Tirunelveli	POINT(77.700000 8.733330)
+G1254388	Tiruchchirāppalli	POINT(78.683330 10.816670)
+G1254649	Thanjāvūr	POINT(79.150000 10.800000)
+G1254661	Thāne	POINT(72.966670 19.200000)
+G1254745	Teni	POINT(77.483330 10.000000)
+G1255349	Surendranagar	POINT(71.683330 22.700000)
+G1255364	Sūrat	POINT(72.833330 21.166670)
+G1255634	Srīnagar	POINT(74.816670 34.083330)
+G1255744	Sonīpat	POINT(77.016670 28.983330)
+G1255969	Sītāpur	POINT(80.683330 27.566670)
+G1256052	Sirsa	POINT(75.016670 29.533330)
+G1256237	Shimla	POINT(77.166670 31.100000)
+G1256287	Silchar	POINT(92.800000 24.816670)
+G1256320	Sīkar	POINT(75.150000 27.616670)
+G1256422	Shrīrāmpur	POINT(88.342220 22.752780)
+G1256436	Solāpur	POINT(75.916670 17.683330)
+G1256451	Shivpurī	POINT(77.650000 25.433330)
+G1256515	Shimoga	POINT(75.566670 13.916670)
+G1256525	Shiliguri	POINT(88.433330 26.700000)
+G1256728	Shāhjahānpur	POINT(79.916670 27.883330)
+G1257022	Satna	POINT(80.833330 24.583330)
+G1257416	Sāngli	POINT(74.564170 16.854380)
+G1257540	Sambhal	POINT(78.550000 28.583330)
+G1257542	Sambalpur	POINT(83.966670 21.450000)
+G1257629	Salem	POINT(78.166670 11.650000)
+G1257806	Sahāranpur	POINT(77.550000 29.966670)
+G1257845	Sāgar	POINT(78.716670 23.833330)
+G1258076	Rohtak	POINT(76.566670 28.900000)
+G1258182	Rewa	POINT(81.300000 24.533330)
+G1258342	Ratlām	POINT(75.066670 23.316670)
+G1258526	Rānchī	POINT(85.333330 23.350000)
+G1258599	Rāmpur	POINT(79.033330 28.816670)
+G1258831	Rāj Nāndgaon	POINT(81.033330 21.100000)
+G1258847	Rājkot	POINT(70.783330 22.300000)
+G1258932	Rājahmundry	POINT(81.783330 16.983330)
+G1258980	Raipur	POINT(81.633330 21.233330)
+G1259004	Raigarh Fort	POINT(73.433330 18.250000)
+G1259009	Rāiganj	POINT(88.116670 25.616670)
+G1259012	Rāichūr	POINT(77.366670 16.200000)
+G1259064	Rāe Bareli	POINT(81.233330 26.216670)
+G1259091	Quilon	POINT(76.600000 8.883330)
+G1259166	Pūrnia	POINT(87.466670 25.783330)
+G1259184	Puri	POINT(85.850000 19.800000)
+G1259229	Pune	POINT(73.855350 18.519570)
+G1259239	Punāsa	POINT(76.400000 22.233330)
+G1259312	Proddatūr	POINT(78.550000 14.733330)
+G1259425	Pondicherry	POINT(79.830000 11.930000)
+G1259652	Pimpri	POINT(73.800000 18.616670)
+G1260086	Patna	POINT(85.116670 25.600000)
+G1260107	Patiāla	POINT(76.400280 30.326670)
+G1260137	Pathānkot	POINT(75.650000 32.283330)
+G1260341	Parbhani	POINT(76.783330 19.266670)
+G1260476	Pānīpat	POINT(76.968060 29.388890)
+G1260482	Pānihāti	POINT(88.374440 22.694170)
+G1260692	Pallāvaram	POINT(80.183610 12.976110)
+G1260716	Pāli	POINT(73.333330 25.766670)
+G1261039	Orai	POINT(79.466670 25.983330)
+G1261045	Ongole	POINT(80.050000 15.500000)
+G1261258	Nizāmābād	POINT(78.116670 18.666670)
+G1261481	New Delhi	POINT(77.224450 28.635760)
+G1261529	Nellore	POINT(79.966670 14.433330)
+G1261731	Nāsik	POINT(73.800000 19.983330)
+G1261913	Nāngloi Jāt	POINT(77.066670 28.683330)
+G1261927	Nandyāl	POINT(78.483330 15.483330)
+G1262131	Naihāti	POINT(88.416940 22.902780)
+G1262180	Nāgpur	POINT(79.100000 21.150000)
+G1262204	Nāgercoil	POINT(77.433330 8.166670)
+G1262292	Nadiād	POINT(72.866670 22.700000)
+G1262321	Mysore	POINT(76.649720 12.307220)
+G1262330	Muzaffarpur	POINT(85.400000 26.116670)
+G1262332	Muzaffarnagar	POINT(77.683330 29.466670)
+G1262395	Murwāra	POINT(80.400000 23.850000)
+G1262482	Munger	POINT(86.466670 25.383330)
+G1262771	Morena	POINT(78.000000 26.496940)
+G1262801	Morādābād	POINT(78.783330 28.833330)
+G1262995	Mirzāpur	POINT(82.583330 25.150000)
+G1263214	Meerut	POINT(77.700000 28.983330)
+G1263220	Medinīpur	POINT(87.333330 22.433330)
+G1263311	Mau	POINT(83.550000 25.950000)
+G1263364	Mathura	POINT(77.683330 27.500000)
+G1263780	Mangalore	POINT(74.883330 12.866670)
+G1264115	Mālegaon	POINT(74.533330 20.550000)
+G1264521	Madurai	POINT(78.116670 9.933330)
+G1264527	Chennai	POINT(80.278470 13.087840)
+G1264543	Madhyamgram	POINT(88.450000 22.700000)
+G1264637	Machilīpatnam	POINT(81.133330 16.166670)
+G1264728	Ludhiāna	POINT(75.850000 30.900000)
+G1264733	Lucknow	POINT(80.916670 26.850000)
+G1264773	Loni	POINT(77.283330 28.750000)
+G1265014	Lātūr	POINT(76.583330 18.400000)
+G1265711	Kulti	POINT(86.850000 23.733330)
+G1265767	Kūkatpalli	POINT(78.416670 17.483330)
+G1265873	Calicut	POINT(75.766670 11.250000)
+G1266049	Kota	POINT(75.833330 25.183330)
+G1266122	Korba	POINT(82.683330 22.350000)
+G1266285	Kolhāpur	POINT(74.216670 16.700000)
+G1266976	Kharagpur	POINT(87.333330 22.333330)
+G1267031	Khandwa	POINT(76.333330 21.833330)
+G1267076	Khammam	POINT(80.150000 17.250000)
+G1267480	Katihār	POINT(87.583330 25.533330)
+G1267708	Karnāl	POINT(76.983330 29.683330)
+G1267755	Karīmnagar	POINT(79.150000 18.433330)
+G1267995	Kānpur	POINT(80.350000 26.466670)
+G1268159	Kānchipuram	POINT(79.716670 12.833330)
+G1268257	Kāmārhāti	POINT(88.374720 22.671110)
+G1268295	Kalyān	POINT(73.150000 19.250000)
+G1268561	Kākināda	POINT(82.216670 16.933330)
+G1268773	Jūnāgadh	POINT(70.466670 21.516670)
+G1268782	Jalandhar	POINT(75.579170 31.325560)
+G1268865	Jodhpur	POINT(73.030000 26.286670)
+G1268907	Jīnd	POINT(76.316670 29.316670)
+G1269006	Jhānsi	POINT(78.583330 25.433330)
+G1269135	Jaunpur	POINT(82.683330 25.733330)
+G1269280	Jāmuria	POINT(87.083330 23.700000)
+G1269300	Jamshedpur	POINT(86.183330 22.800000)
+G1269317	Jāmnagar	POINT(70.066670 22.466670)
+G1269321	Jammu	POINT(74.866670 32.733330)
+G1269395	Jālna	POINT(75.883330 19.833330)
+G1269407	Jālgaon	POINT(75.566670 21.016670)
+G1269515	Jaipur	POINT(75.816670 26.916670)
+G1269633	Jabalpur	POINT(79.950060 23.166970)
+G1269723	Ingrāj Bāzār	POINT(88.150000 25.000000)
+G1269743	Indore	POINT(75.833300 22.717920)
+G1269771	Imphāl	POINT(93.950000 24.816670)
+G1269834	Ichalkaranji	POINT(74.466670 16.700000)
+G1269843	Hyderābād	POINT(78.474440 17.375280)
+G1269910	Hugli	POINT(88.402500 22.895560)
+G1269920	Hubli	POINT(75.166670 15.350000)
+G1269935	Hospet	POINT(76.400000 15.266670)
+G1269937	Hoshiārpur	POINT(75.917220 31.532220)
+G1270022	Hisār	POINT(75.716670 29.166670)
+G1270351	Haridwār	POINT(78.166670 29.966670)
+G1270393	Hāpur	POINT(77.783330 28.716670)
+G1270396	Hāora	POINT(88.310280 22.589170)
+G1270407	Hanumāngarh	POINT(74.316670 29.583330)
+G1270583	Gwalior	POINT(78.179170 26.223610)
+G1270642	Gurgaon	POINT(77.033330 28.466670)
+G1270668	Guntūr	POINT(80.450000 16.300000)
+G1270711	Guna	POINT(77.316670 24.650000)
+G1270752	Gulbarga	POINT(76.833330 17.333330)
+G1270926	Gorakhpur	POINT(75.683330 29.450000)
+G1270927	Gorakhpur	POINT(83.373890 26.755000)
+G1271308	Ghāziābād	POINT(77.433330 28.666670)
+G1271439	Gaya	POINT(85.000000 24.783330)
+G1271476	Guwāhāti	POINT(91.750950 26.186170)
+G1271685	Gangānagar	POINT(73.883330 29.916670)
+G1271715	Gāndhīnagar	POINT(72.683330 23.216670)
+G1271850	Gadag	POINT(75.616670 15.416670)
+G1271885	Fīrozābād	POINT(78.416670 27.150000)
+G1271912	Fatehpur	POINT(80.800000 25.933330)
+G1271942	Farrukhābād	POINT(79.566670 27.400000)
+G1271951	Farīdābād	POINT(77.316670 28.433330)
+G1271976	Faizābād	POINT(82.133330 26.783330)
+G1271987	Etāwah	POINT(79.023900 26.776900)
+G1272051	Elūru	POINT(81.100000 16.700000)
+G1272175	Durgāpur	POINT(87.316670 23.483330)
+G1272181	Durg	POINT(81.283330 21.183330)
+G1272423	Dombivli	POINT(73.083330 19.216670)
+G1272543	Dindigul	POINT(77.950000 10.350000)
+G1272691	Dhule	POINT(74.783330 20.900000)
+G1272979	Dhanbād	POINT(86.450000 23.800000)
+G1273066	Dewās	POINT(76.066670 22.966670)
+G1273294	Delhi	POINT(77.216670 28.666670)
+G1273313	Dehra Dūn	POINT(78.033330 30.316670)
+G1273491	Darbhanga	POINT(85.900000 26.166670)
+G1273581	Dānāpur	POINT(85.050000 25.633330)
+G1273780	Cuttack	POINT(85.879270 20.464970)
+G1273802	Cuddalore	POINT(79.750000 11.750000)
+G1273865	Coimbatore	POINT(76.966670 11.000000)
+G1273874	Cochin	POINT(76.233330 9.966670)
+G1274693	Chandrapur	POINT(79.300000 19.950000)
+G1274746	Chandīgarh	POINT(76.793300 30.734300)
+G1274784	Chandannagar	POINT(88.377220 22.869170)
+G1275004	Calcutta	POINT(88.369720 22.569720)
+G1275068	Burhānpur	POINT(76.233330 21.300000)
+G1275120	Bulandshahr	POINT(77.850000 28.400000)
+G1275163	Budaun	POINT(79.116670 28.050000)
+G1275198	Brahmapur	POINT(84.783330 19.316670)
+G1275248	Borivli	POINT(72.850000 19.233330)
+G1275339	Mumbai	POINT(72.847940 19.014410)
+G1275362	Bokāro	POINT(85.966670 23.783330)
+G1275637	Bilāspur	POINT(82.150000 22.083330)
+G1275665	Bīkāner	POINT(73.300000 28.016670)
+G1275701	Bijāpur	POINT(75.700000 16.833330)
+G1275716	Bihār Sharīf	POINT(85.516670 25.183330)
+G1275738	Bīdar	POINT(77.550000 17.900000)
+G1275778	Bhusāwal	POINT(75.766670 21.050000)
+G1275817	Bhubaneshwar	POINT(85.833330 20.233330)
+G1275841	Bhopāl	POINT(77.400000 23.266670)
+G1275899	Bhiwāni	POINT(76.133330 28.783330)
+G1275901	Bhiwandi	POINT(73.066670 19.300000)
+G1275926	Bhind	POINT(78.788330 26.564170)
+G1275960	Bhīlwāra	POINT(74.633330 25.350000)
+G1275971	Bhilai	POINT(81.433330 21.216670)
+G1276032	Bhāvnagar	POINT(72.150000 21.766670)
+G1276058	Bhātpāra	POINT(88.408890 22.871390)
+G1276070	Bhatinda	POINT(74.950000 30.200000)
+G1276100	Bharūch	POINT(72.966670 21.700000)
+G1276128	Bharatpur	POINT(77.483330 27.216670)
+G1276300	Bhāgalpur	POINT(87.000000 25.250000)
+G1276321	Bhadrāvati	POINT(75.716670 13.866670)
+G1276509	Bellary	POINT(76.933330 15.150000)
+G1276533	Belgaum	POINT(74.500000 15.866670)
+G1277013	Bareilly	POINT(79.416670 28.350000)
+G1277029	Barddhamān	POINT(87.850000 23.250000)
+G1277065	Bārāsat	POINT(88.516670 22.716670)
+G1277082	Baranagar	POINT(88.365280 22.643330)
+G1277333	Bengalore	POINT(77.603290 12.976230)
+G1277397	Bānda	POINT(80.333330 25.483330)
+G1277539	Bāli	POINT(88.340280 22.646110)
+G1277799	Bahraich	POINT(81.600000 27.583330)
+G1277820	Baharampur	POINT(88.250000 24.100000)
+G1277835	Bahādurgarh	POINT(76.916670 28.683330)
+G1278130	Āvadi	POINT(80.101670 13.115560)
+G1278149	Aurangābād	POINT(75.333330 19.883330)
+G1278314	Āsansol	POINT(86.983330 23.683330)
+G1278483	Ara	POINT(84.666670 25.566670)
+G1278672	Anantapur	POINT(77.600000 14.683330)
+G1278708	Amroha	POINT(78.466670 28.916670)
+G1278710	Amritsar	POINT(74.865560 31.633060)
+G1278718	Amrāvati	POINT(77.750000 20.933330)
+G1278840	Ambattūr	POINT(80.162220 13.098330)
+G1278903	Amarnāth	POINT(73.166670 19.200000)
+G1278946	Alwar	POINT(76.600000 27.566670)
+G1278985	Alleppey	POINT(76.326400 9.490040)
+G1278994	Allahābād	POINT(81.850000 25.450000)
+G1279017	Alīgarh	POINT(78.083330 27.883330)
+G1279064	Alandur	POINT(80.206110 13.002500)
+G1279105	Akola	POINT(77.000000 20.733330)
+G1279159	Ajmer	POINT(74.633330 26.450000)
+G1279186	Āīzawl	POINT(92.716670 23.733330)
+G1279228	Ahmadnagar	POINT(74.733330 19.083330)
+G1279233	Ahmadābād	POINT(72.616670 23.033330)
+G1279259	Āgra	POINT(78.016670 27.183330)
+G1279290	Agartala	POINT(91.275000 23.836390)
+G1279335	Ādoni	POINT(77.283330 15.633330)
+G1344377	Haldia	POINT(88.109750 22.060460)
+G1348818	Nangi	POINT(88.215280 22.508330)
+G6943660	Shivaji Nagar	POINT(73.852630 18.530170)
+G7279746	Noida	POINT(77.330000 28.580000)
+G7279754	Singrauli	POINT(82.675350 24.199730)
+G7284820	Jaigaon	POINT(89.375580 26.847660)
+G7302826	Lal Bahadur Nagar	POINT(78.557570 17.347690)
+G7302833	Gajuwaka	POINT(83.216670 17.700000)
+G7302845	Quthbullapur	POINT(78.458180 17.501070)
+G7302856	Serilingampalle	POINT(78.301960 17.493130)
+G91597	Sāmarrā’	POINT(43.875620 34.200960)
+G94787	Kirkuk	POINT(44.392220 35.468060)
+G94824	Karbalā’	POINT(44.008470 32.611440)
+G95446	Arbīl	POINT(44.010620 36.192570)
+G97990	Ba‘qūbah	POINT(44.655450 33.748460)
+G98182	Baghdad	POINT(44.400880 33.340580)
+G98463	As Sulaymānīyah	POINT(45.437490 35.561130)
+G98530	As Samāwah	POINT(45.294400 31.331980)
+G98717	Ar Ramādī	POINT(43.305840 33.422570)
+G98854	An Nāşirīyah	POINT(46.261020 31.052050)
+G98860	An Najaf al Ashraf	POINT(44.339760 31.998540)
+G99071	Al Mawşil al Jadīdah	POINT(43.097770 36.334640)
+G99072	Mosul	POINT(43.118890 36.335000)
+G99131	Al Kūt	POINT(45.819020 32.514700)
+G99347	Al Ḩillah	POINT(44.435260 32.480140)
+G99454	Al Fallūjah	POINT(43.779510 33.353800)
+G99532	Al Başrah	POINT(47.788850 30.534880)
+G99608	Al ‘Amārah	POINT(47.139600 31.840640)
+G99762	Ad Dīwānīyah	POINT(44.930630 31.990510)
+G100077	Abū Ghurayb	POINT(44.185000 33.308330)
+G388349	Al Başrat al Qadīmah	POINT(47.814910 30.497210)
+G14256	Āzādshahr	POINT(48.570730 34.790880)
+G23814	Kahrīz	POINT(47.055300 34.383800)
+G32767	Qarchak	POINT(51.568890 35.439440)
+G111453	Zanjān	POINT(48.478700 36.673600)
+G111822	Yazd	POINT(54.367500 31.897220)
+G112214	Varāmīn	POINT(51.645700 35.324200)
+G112931	Tehrān	POINT(51.421510 35.694390)
+G113646	Tabrīz	POINT(46.291900 38.080000)
+G114259	Sīrjān	POINT(55.681400 29.452000)
+G115019	Shīrāz	POINT(52.538800 29.603600)
+G116667	Sāveh	POINT(50.356600 35.021300)
+G116996	Shari-i-Tajan	POINT(53.056520 36.562970)
+G117392	Saqqez	POINT(46.273500 36.249920)
+G117574	Sanandaj	POINT(46.992300 35.314400)
+G118063	Sabzevār	POINT(57.681910 36.212600)
+G118743	Rasht	POINT(49.583190 37.280770)
+G119208	Qom	POINT(50.876400 34.640100)
+G119505	Qazvīn	POINT(50.004900 36.279700)
+G121801	Orūmīyeh	POINT(45.076050 37.552740)
+G122285	Neyshābūr	POINT(58.795760 36.213290)
+G122438	Naz̧arābād	POINT(50.607500 35.952100)
+G124665	Mashhad	POINT(59.606200 36.297000)
+G125185	Malāyer	POINT(48.823500 34.296900)
+G125446	Mahābād	POINT(45.722200 36.763100)
+G126972	Khvoy	POINT(44.952100 38.550300)
+G127319	Khorramshahr	POINT(48.166400 30.439700)
+G127349	Khorramābād	POINT(48.355830 33.487780)
+G128226	Kermānshāh	POINT(47.065000 34.314170)
+G128234	Kermān	POINT(57.081230 30.293680)
+G128477	Kāshān	POINT(51.436440 33.983080)
+G128747	Karaj	POINT(51.010300 35.835500)
+G132144	Hamadān	POINT(48.514560 34.799220)
+G132892	Gorgān	POINT(54.434750 36.838660)
+G139817	Bandar Būshehr	POINT(50.838500 28.968400)
+G139889	Būkān	POINT(46.208900 36.521000)
+G140044	Borūjerd	POINT(48.751600 33.897300)
+G140380	Bojnūrd	POINT(57.329030 37.474730)
+G140463	Bīrjand	POINT(59.221140 32.866280)
+G141681	Bandar ‘Abbās	POINT(56.280800 27.186500)
+G142363	Bābol	POINT(52.678950 36.551320)
+G143083	Ardabīl	POINT(48.293300 38.249800)
+G143127	Arāk	POINT(49.689160 34.091740)
+G143534	Āmol	POINT(52.350720 36.469610)
+G144448	Ahvāz	POINT(48.669300 31.320300)
+G145459	Ābādān	POINT(48.304300 30.339200)
+G418606	Najafābād	POINT(51.366800 32.634400)
+G418710	Khomeynī Shahr	POINT(51.521130 32.700180)
+G418863	Eşfahān	POINT(51.677610 32.657220)
+G1159301	Zāhedān	POINT(60.862900 29.496300)
+G2523630	Reggio di Calabria	POINT(15.661290 38.110470)
+G2523920	Palermo	POINT(13.359760 38.115820)
+G2524170	Messina	POINT(15.549690 38.193270)
+G2525068	Catania	POINT(15.087190 37.502130)
+G2525473	Cagliari	POINT(9.134620 39.207380)
+G3164527	Verona	POINT(10.997790 45.434190)
+G3164603	Venice	POINT(12.326670 45.438610)
+G3165185	Trieste	POINT(13.780000 45.648610)
+G3165524	Torino	POINT(7.686820 45.070490)
+G3165926	Taranto	POINT(17.229720 40.476110)
+G3169070	Roma	POINT(12.483900 41.894740)
+G3169921	Prato	POINT(11.090920 43.884250)
+G3171457	Parma	POINT(10.328980 44.802660)
+G3171728	Padova	POINT(11.881810 45.415190)
+G3172394	Napoli	POINT(14.250000 40.833330)
+G3173331	Modena	POINT(10.925390 44.647830)
+G3173435	Milano	POINT(9.189510 45.464270)
+G3173529	Mestre	POINT(12.242500 45.490280)
+G3174659	Livorno	POINT(10.316000 43.542640)
+G3176219	Genova	POINT(8.933860 44.406320)
+G3176885	Foggia	POINT(15.549250 41.460930)
+G3176959	Florence	POINT(11.250000 43.766670)
+G3181554	Brescia	POINT(10.227270 45.524780)
+G3181928	Bologna	POINT(11.338750 44.493810)
+G3182351	Bari	POINT(16.851180 41.117730)
+G3489297	New Kingston	POINT(-76.783190 18.007470)
+G3489854	Kingston	POINT(-76.793580 17.997020)
+G246013	Wādī as Sīr	POINT(35.816670 31.950000)
+G248946	Irbid	POINT(35.850000 32.555560)
+G250090	Az Zarqā’	POINT(36.087960 32.072750)
+G250441	Amman	POINT(35.945030 31.955220)
+G1847963	Atsugi	POINT(139.359720 35.438890)
+G1847966	Akashi	POINT(134.983330 34.633330)
+G1848254	Yono	POINT(139.633330 35.883330)
+G1848313	Yokosuka	POINT(139.667220 35.283610)
+G1848354	Yokohama-shi	POINT(139.642500 35.447780)
+G1848373	Yokkaichi	POINT(136.616670 34.966670)
+G1848522	Yao	POINT(135.600000 34.616670)
+G1849053	Utsunomiya-shi	POINT(139.883610 36.565830)
+G1849372	Uji	POINT(135.800000 34.883330)
+G1849498	Ube	POINT(131.251110 33.943060)
+G1849796	Tsu-shi	POINT(136.508610 34.730280)
+G1849814	Toyota	POINT(137.150000 35.083330)
+G1849837	Toyonaka	POINT(135.469320 34.782440)
+G1849846	Toyohashi	POINT(137.383330 34.766670)
+G1849876	Toyama-shi	POINT(137.211390 36.695280)
+G1849892	Tottori	POINT(134.233330 35.500000)
+G1850147	Tokyo	POINT(139.581300 35.614880)
+G1850158	Tokushima-shi	POINT(134.559440 34.065830)
+G1850181	Tokorozawa	POINT(139.469030 35.799160)
+G1850692	Nishi-Tokyo-shi	POINT(139.538300 35.725260)
+G1850910	Takatsuki	POINT(135.616780 34.848330)
+G1851002	Takasaki	POINT(139.016670 36.333330)
+G1851012	Takarazuka	POINT(135.356970 34.799360)
+G1851032	Takaoka	POINT(137.016670 36.750000)
+G1851100	Takamatsu-shi	POINT(134.043330 34.340280)
+G1851307	Tachikawa	POINT(139.418060 35.692780)
+G1851348	Suzuka	POINT(136.583330 34.883330)
+G1851483	Suita	POINT(135.515670 34.761430)
+G1851604	Sōka	POINT(139.804440 35.820280)
+G1851717	Shizuoka-shi	POINT(138.383060 34.976940)
+G1852140	Shinagawa-ku	POINT(139.730170 35.609020)
+G1852225	Shimonoseki	POINT(130.950000 33.950000)
+G1852383	Shimminatochō	POINT(135.200000 34.183330)
+G1852899	Sasebo	POINT(129.722780 33.159170)
+G1853195	Sakai	POINT(135.466670 34.583330)
+G1853295	Sagamihara	POINT(139.354440 35.553060)
+G1853303	Saga-shi	POINT(130.298800 33.249320)
+G1853483	Oyama	POINT(139.800000 36.300000)
+G1853574	Ōtsu-shi	POINT(135.868330 35.004440)
+G1853677	Ōta	POINT(139.366670 36.300000)
+G1853909	Ōsaka-shi	POINT(135.502180 34.693740)
+G1854376	Okazaki	POINT(137.166670 34.950000)
+G1854383	Okayama-shi	POINT(133.935000 34.661670)
+G1854487	Ōita-shi	POINT(131.612500 33.238060)
+G1854703	Ōgaki	POINT(136.616670 35.350000)
+G1854747	Odawara	POINT(139.159720 35.255560)
+G1854902	Numazu	POINT(138.866670 35.100000)
+G1855207	Nishinomiya	POINT(135.333330 34.716670)
+G1855431	Niigata-shi	POINT(139.023610 37.902220)
+G1855503	Nerima	POINT(139.650000 35.733330)
+G1855612	Nara-shi	POINT(135.804850 34.685050)
+G1856035	Naha-shi	POINT(127.681110 26.212500)
+G1856057	Nagoya-shi	POINT(136.906410 35.181470)
+G1856177	Nagasaki-shi	POINT(129.873610 32.744720)
+G1856184	Nagareyama	POINT(139.902660 35.856300)
+G1856199	Nagaoka	POINT(138.850000 37.450000)
+G1856215	Nagano-shi	POINT(138.181110 36.651390)
+G1856717	Miyazaki-shi	POINT(131.423890 31.911110)
+G1856942	Mitaka-shi	POINT(139.559630 35.683510)
+G1857144	Minami-rinkan	POINT(139.450000 35.483330)
+G1857519	Matsumoto	POINT(137.966670 36.233330)
+G1857550	Matsue-shi	POINT(133.050560 35.472220)
+G1857553	Matsudo	POINT(139.900000 35.783330)
+G1857843	Maebashi-shi	POINT(139.060830 36.391110)
+G1857871	Machida	POINT(139.450830 35.540280)
+G1857910	Kyoto	POINT(135.753850 35.021070)
+G1858088	Kurume	POINT(130.516670 33.316670)
+G1858296	Kure	POINT(132.566670 34.233330)
+G1858311	Kurashiki	POINT(133.766670 34.583330)
+G1858421	Kumamoto-shi	POINT(130.741670 32.789720)
+G1858428	Kumagaya	POINT(139.383330 36.133330)
+G1858729	Koshigaya	POINT(139.783330 35.883330)
+G1858926	Komaki	POINT(136.916670 35.283330)
+G1859100	Kōfu-shi	POINT(138.568330 35.663890)
+G1859116	Kodaira	POINT(139.483890 35.726390)
+G1859146	Kōchi-shi	POINT(133.531110 33.559720)
+G1859171	Kōbe-shi	POINT(135.183000 34.691300)
+G1859307	Kitakyūshū	POINT(130.833330 33.833330)
+G1859383	Kishiwada	POINT(135.366670 34.466670)
+G1859642	Kawasaki	POINT(139.717220 35.520560)
+G1859675	Kawanishi	POINT(135.416670 34.816670)
+G1859730	Kawaguchi	POINT(139.720560 35.805000)
+G1859740	Kawagoe	POINT(139.485280 35.908610)
+G1859884	Kasukabe	POINT(139.753610 35.976390)
+G1859891	Kasugai	POINT(136.972290 35.247620)
+G1859924	Kashiwa	POINT(139.968890 35.854440)
+G1860243	Kanazawa-shi	POINT(136.625560 36.594440)
+G1860437	Kami-renjaku	POINT(139.550000 35.683330)
+G1860672	Kamakura	POINT(139.550280 35.308890)
+G1860704	Kakogawa	POINT(134.850000 34.766670)
+G1860827	Kagoshima-shi	POINT(130.558140 31.560180)
+G1861107	Izumi	POINT(135.433330 34.483330)
+G1861310	Itami	POINT(135.401260 34.784270)
+G1861949	Ichinomiya	POINT(136.800000 35.300000)
+G1861968	Ichikawa	POINT(139.924720 35.719720)
+G1862033	Ibaraki	POINT(135.568280 34.816410)
+G1862415	Hiroshima-shi	POINT(132.459370 34.396270)
+G1862462	Hiratsuka	POINT(139.342220 35.323060)
+G1862540	Hirakata	POINT(135.649140 34.813520)
+G1862599	Hino	POINT(139.400280 35.673060)
+G1862627	Himeji	POINT(134.700000 34.816670)
+G1863289	Hamamatsu	POINT(137.733330 34.700000)
+G1863431	Hadano	POINT(139.223610 35.371110)
+G1863440	Hachiōji	POINT(139.323890 35.655830)
+G1863641	Gifu-shi	POINT(136.760390 35.422910)
+G1863905	Funabashi	POINT(139.983330 35.693060)
+G1863917	Fukuyama	POINT(133.366670 34.483330)
+G1863967	Fukuoka-shi	POINT(130.418060 33.606390)
+G1863985	Fukui-shi	POINT(136.222570 36.064430)
+G1864092	Fujisawa	POINT(139.470000 35.341940)
+G1864134	Fuji	POINT(138.683330 35.166670)
+G1864154	Fuchū	POINT(139.483330 35.666670)
+G1864518	Chōfu	POINT(139.552220 35.655560)
+G1864624	Chigasaki	POINT(139.403890 35.326110)
+G1865005	Ashikaga	POINT(139.450000 36.333330)
+G1865294	Anjō	POINT(137.080540 34.958280)
+G1865387	Amagasaki	POINT(135.416670 34.716670)
+G1865714	Ageo	POINT(139.588610 35.969720)
+G1907146	Sayama	POINT(139.412120 35.852950)
+G1926004	Wakayama-shi	POINT(135.167500 34.226110)
+G1926099	Matsuyama-shi	POINT(132.765740 33.839160)
+G2110556	Yamagata-shi	POINT(140.363330 38.240560)
+G2110683	Tsukuba	POINT(140.100000 36.200000)
+G2111149	Sendai-shi	POINT(140.871940 38.268890)
+G2111220	Sakura	POINT(140.233330 35.716670)
+G2111687	Narashino	POINT(140.033330 35.683330)
+G2111834	Morioka-shi	POINT(141.152500 39.703610)
+G2111901	Mito-shi	POINT(140.446670 36.341390)
+G2112141	Kōriyama	POINT(140.383330 37.400000)
+G2112312	Katsuta	POINT(140.533330 36.383330)
+G2112539	Iwaki	POINT(140.883330 37.050000)
+G2112664	Ichihara	POINT(140.083330 35.516670)
+G2112708	Hitachi	POINT(140.650000 36.600000)
+G2112923	Fukushima-shi	POINT(140.467780 37.750000)
+G2113015	Chiba-shi	POINT(140.123330 35.604720)
+G2113126	Akita	POINT(140.116670 39.716670)
+G2113719	Akita-shi	POINT(140.103330 39.718060)
+G2127733	Tomakomai	POINT(141.603330 42.636940)
+G2128295	Sapporo-shi	POINT(141.346940 43.064170)
+G2128815	Obihiro	POINT(143.204440 42.917220)
+G2129376	Kushiro	POINT(144.374720 42.975000)
+G2130057	Hirosaki	POINT(140.472500 40.593060)
+G2130188	Hakodate	POINT(140.736670 41.775830)
+G2130203	Hachinohe	POINT(141.500000 40.500000)
+G2130629	Asahikawa	POINT(142.370280 43.767780)
+G2130658	Aomori-shi	POINT(140.740000 40.824440)
+G6697563	Neyagawa	POINT(135.627590 34.766150)
+G6822096	Hitachi-Naka	POINT(140.534790 36.396590)
+G6825489	Jōetsu	POINT(138.236420 37.148280)
+G6940394	Saitama	POINT(139.656570 35.908070)
+G7279570	Higashimurayama-shi	POINT(139.468520 35.754590)
+G184622	Nakuru	POINT(36.066670 -0.283330)
+G184745	Nairobi	POINT(36.816670 -1.283330)
+G186301	Mombasa	POINT(39.660500 -4.055000)
+G191245	Kisumu	POINT(34.750000 -0.100000)
+G198629	Eldoret	POINT(35.269920 0.520360)
+G1527534	Osh	POINT(72.790000 40.529440)
+G1528675	Bishkek	POINT(74.590000 42.870000)
+G1821306	Phnom Penh	POINT(104.916010 11.562450)
+G1831142	Sihanoukville	POINT(103.529580 10.609320)
+G1831797	Bătdâmbâng	POINT(103.198220 13.102710)
+G1866923	Wŏnsan	POINT(127.443610 39.152780)
+G1869446	Songnim	POINT(125.645000 38.754170)
+G1870883	Sariwŏn	POINT(125.755830 38.507220)
+G1871859	Pyongyang	POINT(125.754320 39.033850)
+G1873757	Namp’o	POINT(125.407780 38.737500)
+G1876373	Kaesŏng	POINT(126.554440 37.970830)
+G1877030	Hŭngnam	POINT(127.618610 39.831670)
+G1877449	Hamhŭng	POINT(127.536390 39.918330)
+G1877615	Haeju	POINT(125.714720 38.040560)
+G2040893	Sinŭiju	POINT(124.398060 40.100560)
+G2043572	Kanggye-si	POINT(126.585230 40.969460)
+G2044757	Ch’ŏngjin	POINT(129.775830 41.795560)
+G1832157	Yŏsu	POINT(127.737780 34.744170)
+G1832847	Yangju	POINT(127.061690 37.833110)
+G1833105	Wŏnju	POINT(127.945280 37.351390)
+G1833747	Ulsan	POINT(129.316670 35.537220)
+G1833788	Ŭijŏngbu	POINT(127.047400 37.741500)
+G1835235	Taejŏn	POINT(127.419720 36.321390)
+G1835329	Taegu	POINT(128.591110 35.870280)
+G1835553	Suwŏn	POINT(127.008890 37.291110)
+G1835648	Sunch’ŏn	POINT(127.489470 34.948080)
+G1835848	Seoul	POINT(126.977830 37.568260)
+G1838524	Pusan	POINT(129.040280 35.102780)
+G1838716	Puch’ŏn	POINT(126.783060 37.498890)
+G1839071	P’ohang	POINT(129.365000 36.032220)
+G1839652	Osan	POINT(127.070560 37.152220)
+G1841066	Mokp’o	POINT(126.388610 34.793610)
+G1841245	Masan	POINT(128.572500 35.208060)
+G1841603	Kyŏngju	POINT(129.211670 35.842780)
+G1841811	Kwangju	POINT(126.915560 35.154720)
+G1841988	Kuri	POINT(127.139400 37.598600)
+G1842025	Kunsan	POINT(126.711390 35.978610)
+G1842225	Kumi	POINT(128.336000 36.113600)
+G1842485	Goyang	POINT(126.835000 37.656390)
+G1842943	Kimhae	POINT(128.881110 35.234170)
+G1843137	Kangnŭng	POINT(128.896110 37.755560)
+G1843491	Iksan	POINT(126.954440 35.943890)
+G1843564	Inch’ŏn	POINT(126.731670 37.453610)
+G1843702	Ich'ŏn	POINT(127.442500 37.279170)
+G1843847	Hwaseong	POINT(126.816900 37.206820)
+G1845136	Ch’unch’ŏn	POINT(127.734170 37.874720)
+G1845457	Chŏnju	POINT(127.148890 35.821940)
+G1845604	Ch’ŏngju	POINT(127.489720 36.637220)
+G1845759	Ch’ŏnan	POINT(127.152200 36.806500)
+G1846052	Chinju	POINT(128.084720 35.192780)
+G1846266	Cheju	POINT(126.521940 33.509720)
+G1846326	Ch’angwŏn	POINT(128.681110 35.228060)
+G1846898	Anyang	POINT(126.926940 37.392500)
+G1846918	Ansan	POINT(126.821940 37.323610)
+G1897000	Sŏngnam	POINT(127.137780 37.438610)
+G1948005	Kwangmyŏng	POINT(126.866390 37.477220)
+G608668	Oral	POINT(51.366670 51.233330)
+G609655	Karagandy	POINT(54.866670 50.066670)
+G610529	Atyrau	POINT(51.883330 47.116670)
+G610611	Aqtöbe	POINT(57.207180 50.279690)
+G1516905	Taraz	POINT(71.366670 42.900000)
+G1518262	Temirtau	POINT(72.948330 50.054440)
+G1518543	Taldyqorghan	POINT(77.916670 45.000000)
+G1518980	Shymkent	POINT(69.600000 42.300000)
+G1519422	Semey	POINT(80.227500 50.411110)
+G1519922	Qyzylorda	POINT(65.509170 44.852780)
+G1519928	Qostanay	POINT(63.583330 53.166670)
+G1519942	Qaraghandy	POINT(73.099440 49.798890)
+G1520172	Petropavlovsk	POINT(69.162780 54.875280)
+G1520240	Pavlodar	POINT(76.950000 52.300000)
+G1520316	Ust’-Kamenogorsk	POINT(82.610280 49.978890)
+G1526273	Astana	POINT(71.445980 51.180100)
+G1526384	Almaty	POINT(76.950000 43.250000)
+G1651944	Vientiane	POINT(102.600000 17.966670)
+G266826	Tripoli	POINT(35.849720 34.436670)
+G268064	Sidon	POINT(35.368890 33.563060)
+G268743	Ra’s Bayrūt	POINT(35.483330 33.900000)
+G276781	Beirut	POINT(35.494420 33.888940)
+G1234633	Moratuwa	POINT(79.881600 6.773000)
+G1242833	Jaffna	POINT(80.013700 9.656700)
+G1246321	Galkissa	POINT(79.863000 6.829300)
+G1248991	Colombo	POINT(79.847780 6.931940)
+G2274895	Monrovia	POINT(-10.796900 6.300540)
+G593116	Vilnius	POINT(25.279800 54.689160)
+G598098	Klaipėda	POINT(21.117500 55.717220)
+G598316	Kaunas	POINT(23.900000 54.900000)
+G456172	Riga	POINT(24.105890 56.946000)
+G88319	Banghāzī	POINT(20.066670 32.116670)
+G89055	Al Bayḑā’	POINT(21.755060 32.762720)
+G2210221	Tarhūnah	POINT(13.633200 32.435020)
+G2210247	Tripoli	POINT(13.187460 32.875190)
+G2214846	Mişrātah	POINT(15.092540 32.375350)
+G2216885	Ḩārat az Zāwiyah	POINT(12.715000 32.763060)
+G2219905	Al Khums	POINT(14.266670 32.650000)
+G2528910	Tétouan	POINT(-5.372420 35.571090)
+G2530335	Tangier	POINT(-5.813650 35.780580)
+G2537763	Salé	POINT(-6.816600 34.038920)
+G2537881	Safi	POINT(-9.237180 32.299390)
+G2538475	Rabat	POINT(-6.832550 34.013250)
+G2540483	Oujda	POINT(-1.907640 34.680520)
+G2542051	Mohammedia	POINT(-7.394420 33.706590)
+G2542715	Meknès	POINT(-5.547270 33.893520)
+G2542997	Marrakech	POINT(-8.008280 31.631480)
+G2544248	Khouribga	POINT(-6.906300 32.881080)
+G2544571	Kenitra	POINT(-6.580200 34.261010)
+G2548885	Fès	POINT(-4.999800 34.037150)
+G2553604	Casablanca	POINT(-7.619160 33.592780)
+G2555745	Beni Mellal	POINT(-6.349840 32.337250)
+G2561668	Agadir	POINT(-9.598150 30.420180)
+G617239	Tiraspol	POINT(29.643330 46.840280)
+G618426	Chişinău	POINT(28.857500 47.005560)
+G1053384	Toamasina	POINT(49.383330 -18.166670)
+G1062663	Mahajanga	POINT(46.316670 -15.716670)
+G1064890	Fianarantsoa	POINT(47.083330 -21.433330)
+G1070940	Antananarivo	POINT(47.530980 -18.914330)
+G785842	Skopje	POINT(21.433330 42.000000)
+G2460596	Bamako	POINT(-8.000000 12.650000)
+G1293960	Taunggyi	POINT(97.033330 20.783330)
+G1295765	Akyab	POINT(92.900000 20.150000)
+G1298824	Rangoon	POINT(96.156110 16.805280)
+G1300466	Bago	POINT(96.479720 17.336670)
+G1308465	Mawlamyine	POINT(97.625560 16.491390)
+G1308522	Monywa	POINT(95.133330 22.116670)
+G1309611	Myeik	POINT(98.600000 12.433330)
+G1309793	Meiktila	POINT(95.866670 20.866670)
+G1311874	Mandalay	POINT(96.083590 21.974730)
+G1328421	Pathein	POINT(94.733330 16.783330)
+G6611854	Nay Pyi Taw	POINT(96.129720 19.745000)
+G2028462	Ulaanbaatar	POINT(106.883240 47.907710)
+G1821274	Macau	POINT(113.546110 22.200560)
+G2377450	Nouakchott	POINT(-15.949750 18.100330)
+G934154	Port Louis	POINT(57.498890 -20.161940)
+G927967	Lilongwe	POINT(33.783330 -13.983330)
+G931755	Blantyre	POINT(35.013870 -15.786820)
+G3514450	Xochimilco	POINT(-99.107500 19.262220)
+G3514519	Xico	POINT(-98.933330 19.266670)
+G3514663	Alvaro Obregón	POINT(-99.225000 19.373330)
+G3514670	Villahermosa	POINT(-92.916670 17.983330)
+G3514674	Gustavo A. Madero	POINT(-99.095830 19.478610)
+G3514783	Veracruz	POINT(-96.133330 19.200000)
+G3515001	Tuxtla Gutiérrez	POINT(-93.116670 16.750000)
+G3515302	Toluca	POINT(-99.667220 19.288330)
+G3515428	Tlalpan	POINT(-99.166670 19.283330)
+G3515431	Tlalnepantla	POINT(-99.221670 19.526940)
+G3515463	Tlahuac	POINT(-99.003330 19.281670)
+G3515807	Cuautitlán Izcalli	POINT(-99.246670 19.646940)
+G3516109	Tehuacán	POINT(-97.383330 18.450000)
+G3516266	Tapachula	POINT(-92.283330 14.900000)
+G3516355	Tampico	POINT(-97.850000 22.216670)
+G3518135	San Pablo de las Salinas	POINT(-99.096390 19.665830)
+G3520339	Reynosa	POINT(-98.283330 26.083330)
+G3521081	Puebla de Zaragoza	POINT(-98.200000 19.050000)
+G3521168	Poza Rica de Hidalgo	POINT(-97.459460 20.533150)
+G3522210	Pachuca de Soto	POINT(-98.733290 20.116970)
+G3522507	Oaxaca de Juárez	POINT(-96.716670 17.050000)
+G3522551	Nuevo Laredo	POINT(-99.516670 27.500000)
+G3522732	Nicolás Romero	POINT(-99.313060 19.621940)
+G3522790	Naucalpan de Juárez	POINT(-99.239630 19.478510)
+G3523183	Minatitlán	POINT(-94.516670 17.983330)
+G3523303	Metepec	POINT(-99.607780 19.253610)
+G3523349	Mérida	POINT(-89.616670 20.966670)
+G3523466	Heroica Matamoros	POINT(-97.500000 25.883330)
+G3523760	Magdalena Contreras	POINT(-99.233330 19.283330)
+G3523908	Los Reyes	POINT(-98.966670 19.350000)
+G3526485	Jiutepec	POINT(-99.183330 18.866670)
+G3526617	Jalapa Enríquez	POINT(-96.916670 19.533330)
+G3526682	Ixtapaluca	POINT(-98.883330 19.316670)
+G3526683	Iztapalapa	POINT(-99.051940 19.351110)
+G3526700	Iztacalco	POINT(-99.084720 19.396670)
+G3529612	Ecatepec	POINT(-99.052500 19.601110)
+G3529947	Cuernavaca	POINT(-99.250000 18.916670)
+G3530049	Cuajimalpa	POINT(-99.301110 19.355830)
+G3530139	Coyoacán	POINT(-99.160280 19.328890)
+G3530517	Coatzacoalcos	POINT(-94.416670 18.150000)
+G3530569	Coacalco	POINT(-99.110280 19.631670)
+G3530580	Ciudad Victoria	POINT(-99.133330 23.733330)
+G3530589	Ciudad Nezahualcóyotl	POINT(-99.033060 19.413610)
+G3530594	Ciudad Madero	POINT(-97.833330 22.266670)
+G3530597	Mexico City	POINT(-99.127660 19.428470)
+G3530757	Cholula	POINT(-98.303520 19.064060)
+G3530870	Chilpancingo de los Bravos	POINT(-99.500000 17.550000)
+G3531200	Chalco de Díaz Covarrubias	POINT(-98.900000 19.266670)
+G3531673	Cancún	POINT(-86.846560 21.174290)
+G3531732	Campeche	POINT(-90.533330 19.850000)
+G3532497	Azcapotzalco	POINT(-99.183610 19.488890)
+G3532624	Ciudad López Mateos	POINT(-99.261390 19.558330)
+G3533462	Acapulco de Juárez	POINT(-99.890100 16.863360)
+G3827406	Benito Juarez	POINT(-99.165000 19.385000)
+G3827407	Venustiano Carranza	POINT(-99.099170 19.430000)
+G3827408	Miguel Hidalgo	POINT(-99.202780 19.422500)
+G3827409	Cuauhtémoc	POINT(-99.156940 19.417220)
+G3979770	Zapopan	POINT(-103.400000 20.716670)
+G3980760	Uruapan del Progreso	POINT(-102.066670 19.416670)
+G3981254	Torreón	POINT(-103.433330 25.550000)
+G3981369	Tonalá	POINT(-103.233330 20.616670)
+G3981461	Tlaquepaque	POINT(-103.316670 20.650000)
+G3981609	Tijuana	POINT(-117.016670 32.533330)
+G3981941	Tepic	POINT(-104.900000 21.500000)
+G3982912	Soledad Díez Gutiérrez	POINT(-100.950000 22.200000)
+G3984583	Santa Catarina	POINT(-100.458130 25.673250)
+G3985241	San Nicolás de los Garza	POINT(-100.300000 25.750000)
+G3985606	San Luis Potosí	POINT(-100.983330 22.150000)
+G3988086	Saltillo	POINT(-101.000000 25.416670)
+G3991164	Querétaro	POINT(-100.383330 20.600000)
+G3991328	Puerto Vallarta	POINT(-105.230660 20.620410)
+G3995402	Morelia	POINT(-101.184430 19.700780)
+G3995465	Monterrey	POINT(-100.316670 25.666670)
+G3995523	Monclova	POINT(-101.416670 26.900000)
+G3996069	Mexicali	POINT(-115.468330 32.651940)
+G3996322	Mazatlán	POINT(-106.416670 23.216670)
+G3997479	Los Mochis	POINT(-108.966670 25.766670)
+G3998655	León	POINT(-101.666670 21.116670)
+G4000900	La Paz	POINT(-110.300000 24.166670)
+G4004330	Irapuato	POINT(-101.350000 20.683330)
+G4004886	Heroica Nogales	POINT(-110.933330 31.333330)
+G4004898	Hermosillo	POINT(-110.966670 29.066670)
+G4005492	Guadalupe	POINT(-100.250000 25.683330)
+G4005539	Guadalajara	POINT(-103.333330 20.666670)
+G4005775	Gómez Palacio	POINT(-103.500000 25.566670)
+G4005867	General Escobedo	POINT(-100.333330 25.816670)
+G4006702	Ensenada	POINT(-116.616670 31.866670)
+G4011743	Durango	POINT(-104.666670 24.033330)
+G4012176	Culiacán	POINT(-107.389720 24.799440)
+G4013704	Ciudad Obregón	POINT(-109.933330 27.483330)
+G4013708	Ciudad Juárez	POINT(-106.483330 31.733330)
+G4014338	Chihuahua	POINT(-106.083330 28.633330)
+G4014875	Celaya	POINT(-100.816670 20.516670)
+G4018390	Apodaca	POINT(-100.200000 25.766670)
+G4019233	Aguascalientes	POINT(-102.300000 21.883330)
+G7280708	Colonia del Valle	POINT(-99.162040 19.386110)
+G1732687	Batu Pahat	POINT(102.933330 1.850000)
+G1732745	Sekudai	POINT(103.666670 1.533330)
+G1732752	Johor Bahru	POINT(103.757800 1.465500)
+G1732811	Kluang	POINT(103.332800 2.025100)
+G1732903	Shah Alam	POINT(101.532810 3.085070)
+G1732905	Klang	POINT(101.450000 3.033330)
+G1733432	Kota Kinabalu	POINT(116.066670 5.983330)
+G1734052	Sandakan	POINT(118.117900 5.840200)
+G1734199	Tawau	POINT(117.900000 4.250000)
+G1734393	Kulim	POINT(100.561770 5.364990)
+G1734586	Taiping	POINT(100.733330 4.850000)
+G1734634	Ipoh	POINT(101.082900 4.584100)
+G1734705	Kuala Terengganu	POINT(103.140800 5.330200)
+G1734759	Melaka	POINT(102.248060 2.196940)
+G1734810	Seremban	POINT(101.933330 2.716670)
+G1735079	Bukit Mertajam	POINT(100.466700 5.363010)
+G1735106	George Town	POINT(100.335430 5.411230)
+G1735158	Petaling Jaya	POINT(101.606710 3.107260)
+G1735161	Kuala Lumpur	POINT(101.686530 3.141200)
+G1735227	Kuantan	POINT(103.326000 3.807700)
+G1735498	Sungai Petani	POINT(100.487720 5.647000)
+G1735634	Kuching	POINT(110.333330 1.550000)
+G1735902	Sibu	POINT(111.816670 2.300000)
+G1736309	Alor Setar	POINT(100.360140 6.121040)
+G1736376	Kota Bharu	POINT(102.238600 6.133280)
+G1737486	Bintulu	POINT(113.033330 3.166670)
+G1738050	Miri	POINT(113.983330 4.383330)
+G1771023	Kampung Baru Subang	POINT(101.533330 3.150000)
+G1028434	Quelimane	POINT(36.888330 -17.878610)
+G1033356	Nampula	POINT(39.266600 -15.116460)
+G1035025	Cidade de Nacala	POINT(40.672780 -14.542780)
+G1039854	Matola	POINT(32.458890 -25.962220)
+G1040652	Maputo	POINT(32.589170 -25.965280)
+G1049261	Chimoio	POINT(33.483330 -19.116390)
+G1052373	Beira	POINT(34.838890 -19.843610)
+G3352136	Windhoek	POINT(17.083230 -22.559410)
+G2437798	Zinder	POINT(8.988370 13.804870)
+G2440485	Niamey	POINT(2.111780 13.512500)
+G2441291	Maradi	POINT(7.101740 13.500000)
+G2317765	Zaria	POINT(7.725180 11.113240)
+G2319133	Warri	POINT(5.750000 5.516670)
+G2320576	Umuahia	POINT(7.489590 5.526270)
+G2320831	Ugep	POINT(8.081200 5.808600)
+G2322794	Abuja	POINT(7.180830 9.175830)
+G2322911	Sokoto	POINT(5.239020 13.060920)
+G2323390	Saki	POINT(3.383330 8.666670)
+G2323411	Shagamu	POINT(3.647760 6.843230)
+G2323675	Sapele	POINT(5.676660 5.894050)
+G2324774	Port Harcourt	POINT(7.013400 4.777420)
+G2325200	Oyo	POINT(3.933330 7.850000)
+G2325314	Owo	POINT(5.586810 7.196200)
+G2325330	Owerri	POINT(7.030410 5.483330)
+G2326016	Onitsha	POINT(6.788450 6.145430)
+G2326171	Ondo	POINT(4.833330 7.100000)
+G2328765	Nnewi	POINT(6.914780 6.019860)
+G2329821	Mubi	POINT(13.264360 10.267610)
+G2330100	Minna	POINT(6.556940 9.613890)
+G2331140	Makurdi	POINT(8.512100 7.741100)
+G2331447	Maiduguri	POINT(13.160270 11.846440)
+G2332459	Lagos	POINT(3.395830 6.453060)
+G2334327	Kishi	POINT(3.850000 9.083330)
+G2334802	Katsina	POINT(7.600630 12.989430)
+G2335204	Kano	POINT(8.513810 11.994350)
+G2335727	Kaduna	POINT(7.438280 10.522240)
+G2335953	Jos	POINT(8.900000 9.916670)
+G2336056	Jimeta	POINT(12.466670 9.283330)
+G2336905	Iwo	POINT(4.183330 7.633330)
+G2337207	Ise-Ekiti	POINT(5.428100 7.463200)
+G2337490	Inisa	POINT(4.333330 7.850000)
+G2337639	Ilorin	POINT(4.550000 8.500000)
+G2337704	Ilesa	POINT(4.733330 7.616670)
+G2337765	Ila Orangun	POINT(4.900000 8.016670)
+G2338106	Ikot-Ekpene	POINT(7.710820 5.179380)
+G2338273	Ikire	POINT(4.183330 7.350000)
+G2338385	Ijero-Ekiti	POINT(5.074200 7.813900)
+G2338400	Ijebu-Ode	POINT(3.915880 6.816090)
+G2339354	Ibadan	POINT(3.896390 7.387780)
+G2339937	Gusau	POINT(6.661350 12.162780)
+G2340451	Gombe	POINT(11.167290 10.289690)
+G2343279	Enugu	POINT(7.494300 6.440200)
+G2343983	Effon Alaiye	POINT(4.916670 7.650000)
+G2344082	Ebute Ikorodu	POINT(3.488180 6.600860)
+G2345521	Damaturu	POINT(11.960800 11.747000)
+G2346229	Calabar	POINT(8.322000 4.951700)
+G2347209	Bida	POINT(6.016670 9.083330)
+G2347283	Benin City	POINT(5.627490 6.335040)
+G2347470	Bauchi	POINT(9.843270 10.313440)
+G2348773	Awka	POINT(7.074110 6.210090)
+G2350841	Akure	POINT(5.193120 7.252560)
+G2352778	Abuja	POINT(7.489760 9.057350)
+G2352947	Abeokuta	POINT(3.350000 7.150000)
+G2353151	Aba	POINT(7.366670 5.106580)
+G3617763	Managua	POINT(-86.250400 12.132820)
+G2745912	Utrecht	POINT(5.122220 52.090830)
+G2746301	Tilburg	POINT(5.091300 51.555510)
+G2747373	Den Haag	POINT(4.298610 52.076670)
+G2747891	Rotterdam	POINT(4.47917

<TRUNCATED>

[14/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/util/DistanceToShapeValueSource.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/util/DistanceToShapeValueSource.java b/lucene/spatial/src/java/org/apache/lucene/spatial/util/DistanceToShapeValueSource.java
deleted file mode 100644
index 57cad87..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/util/DistanceToShapeValueSource.java
+++ /dev/null
@@ -1,122 +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.util;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.queries.function.FunctionValues;
-import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
-import org.apache.lucene.search.Explanation;
-import org.apache.lucene.search.IndexSearcher;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.distance.DistanceCalculator;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Shape;
-
-/**
- * The distance from a provided Point to a Point retrieved from a ValueSource via
- * {@link org.apache.lucene.queries.function.FunctionValues#objectVal(int)}. The distance
- * is calculated via a {@link com.spatial4j.core.distance.DistanceCalculator}.
- *
- * @lucene.experimental
- */
-public class DistanceToShapeValueSource extends ValueSource {
-  private final ValueSource shapeValueSource;
-  private final Point queryPoint;
-  private final double multiplier;
-  private final DistanceCalculator distCalc;
-
-  //TODO if FunctionValues returns NaN; will things be ok?
-  private final double nullValue;//computed
-
-  public DistanceToShapeValueSource(ValueSource shapeValueSource, Point queryPoint,
-                                    double multiplier, SpatialContext ctx) {
-    this.shapeValueSource = shapeValueSource;
-    this.queryPoint = queryPoint;
-    this.multiplier = multiplier;
-    this.distCalc = ctx.getDistCalc();
-    this.nullValue =
-        (ctx.isGeo() ? 180 * multiplier : Double.MAX_VALUE);
-  }
-
-  @Override
-  public String description() {
-    return "distance(" + queryPoint + " to " + shapeValueSource.description() + ")*" + multiplier + ")";
-  }
-
-  @Override
-  public void createWeight(Map context, IndexSearcher searcher) throws IOException {
-    shapeValueSource.createWeight(context, searcher);
-  }
-
-  @Override
-  public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
-    final FunctionValues shapeValues = shapeValueSource.getValues(context, readerContext);
-
-    return new DoubleDocValues(this) {
-      @Override
-      public double doubleVal(int doc) {
-        Shape shape = (Shape) shapeValues.objectVal(doc);
-        if (shape == null || shape.isEmpty())
-          return nullValue;
-        Point pt = shape.getCenter();
-        return distCalc.distance(queryPoint, pt) * multiplier;
-      }
-
-      @Override
-      public Explanation explain(int doc) {
-        Explanation exp = super.explain(doc);
-        List<Explanation> details = new ArrayList<>(Arrays.asList(exp.getDetails()));
-        details.add(shapeValues.explain(doc));
-        return Explanation.match(exp.getValue(), exp.getDescription(), details);
-      }
-    };
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-
-    DistanceToShapeValueSource that = (DistanceToShapeValueSource) o;
-
-    if (!queryPoint.equals(that.queryPoint)) return false;
-    if (Double.compare(that.multiplier, multiplier) != 0) return false;
-    if (!shapeValueSource.equals(that.shapeValueSource)) return false;
-    if (!distCalc.equals(that.distCalc)) return false;
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result;
-    long temp;
-    result = shapeValueSource.hashCode();
-    result = 31 * result + queryPoint.hashCode();
-    temp = Double.doubleToLongBits(multiplier);
-    result = 31 * result + (int) (temp ^ (temp >>> 32));
-    return result;
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoEncodingUtils.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoEncodingUtils.java b/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoEncodingUtils.java
index de62318..451688d 100644
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoEncodingUtils.java
+++ b/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoEncodingUtils.java
@@ -49,52 +49,52 @@ public final class GeoEncodingUtils {
   private GeoEncodingUtils() {
   }
 
+  /**
+   * encode longitude, latitude geopoint values using morton encoding method
+   * https://en.wikipedia.org/wiki/Z-order_curve
+   */
   public static final Long mortonHash(final double lon, final double lat) {
     return BitUtil.interleave(scaleLon(lon), scaleLat(lat));
   }
 
+  /** decode longitude value from morton encoded geo point */
   public static final double mortonUnhashLon(final long hash) {
     return unscaleLon(BitUtil.deinterleave(hash));
   }
 
+  /** decode latitude value from morton encoded geo point */
   public static final double mortonUnhashLat(final long hash) {
     return unscaleLat(BitUtil.deinterleave(hash >>> 1));
   }
 
-  protected static final long scaleLon(final double val) {
+  private static final long scaleLon(final double val) {
     return (long) ((val-MIN_LON_INCL) * LON_SCALE);
   }
 
-  protected static final long scaleLat(final double val) {
+  private static final long scaleLat(final double val) {
     return (long) ((val-MIN_LAT_INCL) * LAT_SCALE);
   }
 
-  protected static final double unscaleLon(final long val) {
+  private static final double unscaleLon(final long val) {
     return (val / LON_SCALE) + MIN_LON_INCL;
   }
 
-  protected static final double unscaleLat(final long val) {
+  private static final double unscaleLat(final long val) {
     return (val / LAT_SCALE) + MIN_LAT_INCL;
   }
 
-  /**
-   * Compare two position values within a {@link GeoEncodingUtils#TOLERANCE} factor
-   */
+  /** Compare two position values within a {@link GeoEncodingUtils#TOLERANCE} factor */
   public static double compare(final double v1, final double v2) {
     final double delta = v1-v2;
     return Math.abs(delta) <= TOLERANCE ? 0 : delta;
   }
 
-  /**
-   * Convert a geocoded morton long into a prefix coded geo term
-   */
+  /** 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
-   */
+  /** Convert a prefix coded geo term back into the geocoded morton long */
   public static long prefixCodedToGeoCoded(final BytesRef val) {
     final long result = fromBytes((byte)0, (byte)0, (byte)0, (byte)0,
         val.bytes[val.offset+0], val.bytes[val.offset+1], val.bytes[val.offset+2], val.bytes[val.offset+3]);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoRect.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoRect.java b/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoRect.java
index fa93e61..68a450c 100644
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoRect.java
+++ b/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoRect.java
@@ -18,11 +18,18 @@ package org.apache.lucene.spatial.util;
 
 /** Represents a lat/lon rectangle. */
 public class GeoRect {
+  /** minimum longitude value (in degrees) */
   public final double minLon;
+  /** minimum latitude value (in degrees) */
   public final double maxLon;
+  /** maximum longitude value (in degrees) */
   public final double minLat;
+  /** maximum latitude value (in degrees) */
   public final double maxLat;
 
+  /**
+   * Constructs a bounding box by first validating the provided latitude and longitude coordinates
+   */
   public GeoRect(double minLon, double maxLon, double minLat, double maxLat) {
     if (GeoUtils.isValidLon(minLon) == false) {
       throw new IllegalArgumentException("invalid minLon " + minLon);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoRelationUtils.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoRelationUtils.java b/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoRelationUtils.java
index 32e30bd..d9d6991 100644
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoRelationUtils.java
+++ b/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoRelationUtils.java
@@ -245,6 +245,10 @@ public class GeoRelationUtils {
     return false;
   }
 
+  /**
+   * Computes whether a rectangle is within a polygon (shared boundaries not allowed) with more rigor than the
+   * {@link GeoRelationUtils#rectWithinPolyApprox} counterpart
+   */
   public static boolean rectWithinPolyPrecise(final double rMinX, final double rMinY, final double rMaxX, final double rMaxY,
                                        final double[] shapeX, final double[] shapeY, final double sMinX,
                                        final double sMinY, final double sMaxX, final double sMaxY) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeAreaValueSource.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeAreaValueSource.java b/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeAreaValueSource.java
deleted file mode 100644
index dd391d1..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeAreaValueSource.java
+++ /dev/null
@@ -1,116 +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.util;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Shape;
-
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.queries.function.FunctionValues;
-import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
-import org.apache.lucene.search.Explanation;
-import org.apache.lucene.search.IndexSearcher;
-
-/**
- * The area of a Shape retrieved from a ValueSource via
- * {@link org.apache.lucene.queries.function.FunctionValues#objectVal(int)}.
- *
- * @see Shape#getArea(com.spatial4j.core.context.SpatialContext)
- *
- * @lucene.experimental
- */
-public class ShapeAreaValueSource extends ValueSource {
-  private final ValueSource shapeValueSource;
-  private final SpatialContext ctx;//not part of identity; should be associated with shapeValueSource indirectly
-  private final boolean geoArea;
-  private double multiplier;
-
-  public ShapeAreaValueSource(ValueSource shapeValueSource, SpatialContext ctx, boolean geoArea, double multiplier) {
-    this.shapeValueSource = shapeValueSource;
-    this.ctx = ctx;
-    this.geoArea = geoArea;
-    this.multiplier = multiplier;
-  }
-
-  @Override
-  public String description() {
-    return "area(" + shapeValueSource.description() + ",geo=" + geoArea + ")";
-  }
-
-  @Override
-  public void createWeight(Map context, IndexSearcher searcher) throws IOException {
-    shapeValueSource.createWeight(context, searcher);
-  }
-
-  @Override
-  public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
-    final FunctionValues shapeValues = shapeValueSource.getValues(context, readerContext);
-
-    return new DoubleDocValues(this) {
-      @Override
-      public double doubleVal(int doc) {
-        Shape shape = (Shape) shapeValues.objectVal(doc);
-        if (shape == null || shape.isEmpty())
-          return 0;//or NaN?
-        //This part of Spatial4j API is kinda weird. Passing null means 2D area, otherwise geo
-        //   assuming ctx.isGeo()
-        return shape.getArea( geoArea ? ctx : null ) * multiplier;
-      }
-
-      @Override
-      public boolean exists(int doc) {
-        return shapeValues.exists(doc);
-      }
-
-      @Override
-      public Explanation explain(int doc) {
-        Explanation exp = super.explain(doc);
-        List<Explanation> details = new ArrayList<>(Arrays.asList(exp.getDetails()));
-        details.add(shapeValues.explain(doc));
-        return Explanation.match(exp.getValue(), exp.getDescription(), details);
-      }
-    };
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-
-    ShapeAreaValueSource that = (ShapeAreaValueSource) o;
-
-    if (geoArea != that.geoArea) return false;
-    if (!shapeValueSource.equals(that.shapeValueSource)) return false;
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = shapeValueSource.hashCode();
-    result = 31 * result + (geoArea ? 1 : 0);
-    return result;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeFieldCache.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeFieldCache.java b/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeFieldCache.java
deleted file mode 100644
index 480369b..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeFieldCache.java
+++ /dev/null
@@ -1,54 +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.util;
-
-import com.spatial4j.core.shape.Shape;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Bounded Cache of Shapes associated with docIds.  Note, multiple Shapes can be
- * associated with a given docId.
- * <p>
- * WARNING: This class holds the data in an extremely inefficient manner as all Points are in memory as objects and they
- * are stored in many ArrayLists (one per document).  So it works but doesn't scale.  It will be replaced in the future.
- *
- * @lucene.internal
- */
-public class ShapeFieldCache<T extends Shape> {
-  private final List<T>[] cache;
-  public final int defaultLength;
-
-  @SuppressWarnings({"unchecked", "rawtypes"})
-  public ShapeFieldCache( int length, int defaultLength ) {
-    cache = new List[length];
-    this.defaultLength= defaultLength;
-  }
-
-  public void add( int docid, T s ) {
-    List<T> list = cache[docid];
-    if( list == null ) {
-      list = cache[docid] = new ArrayList<>(defaultLength);
-    }
-    list.add( s );
-  }
-
-  public List<T> getShapes( int docid ) {
-    return cache[docid];
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheDistanceValueSource.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheDistanceValueSource.java b/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheDistanceValueSource.java
deleted file mode 100644
index e4cb146..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheDistanceValueSource.java
+++ /dev/null
@@ -1,112 +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.util;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.distance.DistanceCalculator;
-import com.spatial4j.core.shape.Point;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.queries.function.FunctionValues;
-import org.apache.lucene.queries.function.ValueSource;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-
-/**
- * An implementation of the Lucene ValueSource that returns the spatial distance
- * between an input point and a document's points in
- * {@link ShapeFieldCacheProvider}. The shortest distance is returned if a
- * document has more than one point.
- *
- * @lucene.internal
- */
-public class ShapeFieldCacheDistanceValueSource extends ValueSource {
-
-  private final SpatialContext ctx;
-  private final Point from;
-  private final ShapeFieldCacheProvider<Point> provider;
-  private final double multiplier;
-
-  public ShapeFieldCacheDistanceValueSource(SpatialContext ctx,
-      ShapeFieldCacheProvider<Point> provider, Point from, double multiplier) {
-    this.ctx = ctx;
-    this.from = from;
-    this.provider = provider;
-    this.multiplier = multiplier;
-  }
-
-  @Override
-  public String description() {
-    return getClass().getSimpleName()+"("+provider+", "+from+")";
-  }
-
-  @Override
-  public FunctionValues getValues(Map context, final LeafReaderContext readerContext) throws IOException {
-    return new FunctionValues() {
-      private final ShapeFieldCache<Point> cache =
-          provider.getCache(readerContext.reader());
-      private final Point from = ShapeFieldCacheDistanceValueSource.this.from;
-      private final DistanceCalculator calculator = ctx.getDistCalc();
-      private final double nullValue = (ctx.isGeo() ? 180 * multiplier : Double.MAX_VALUE);
-
-      @Override
-      public float floatVal(int doc) {
-        return (float) doubleVal(doc);
-      }
-
-      @Override
-      public double doubleVal(int doc) {
-
-        List<Point> vals = cache.getShapes( doc );
-        if( vals != null ) {
-          double v = calculator.distance(from, vals.get(0));
-          for( int i=1; i<vals.size(); i++ ) {
-            v = Math.min(v, calculator.distance(from, vals.get(i)));
-          }
-          return v * multiplier;
-        }
-        return nullValue;
-      }
-
-      @Override
-      public String toString(int doc) {
-        return description() + "=" + floatVal(doc);
-      }
-    };
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-
-    ShapeFieldCacheDistanceValueSource that = (ShapeFieldCacheDistanceValueSource) o;
-
-    if (!ctx.equals(that.ctx)) return false;
-    if (!from.equals(that.from)) return false;
-    if (!provider.equals(that.provider)) return false;
-    if (multiplier != that.multiplier) return false;
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    return from.hashCode();
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheProvider.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheProvider.java b/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheProvider.java
deleted file mode 100644
index 04c52f7..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheProvider.java
+++ /dev/null
@@ -1,87 +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.util;
-
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.index.*;
-import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.util.BytesRef;
-
-import java.io.IOException;
-import java.util.WeakHashMap;
-import java.util.logging.Logger;
-
-/**
- * Provides access to a {@link ShapeFieldCache} for a given {@link org.apache.lucene.index.LeafReader}.
- *
- * If a Cache does not exist for the Reader, then it is built by iterating over
- * the all terms for a given field, reconstructing the Shape from them, and adding
- * them to the Cache.
- *
- * @lucene.internal
- */
-public abstract class ShapeFieldCacheProvider<T extends Shape> {
-  private Logger log = Logger.getLogger(getClass().getName());
-
-  // it may be a List<T> or T
-  WeakHashMap<IndexReader, ShapeFieldCache<T>> sidx = new WeakHashMap<>();
-
-  protected final int defaultSize;
-  protected final String shapeField;
-
-  public ShapeFieldCacheProvider(String shapeField, int defaultSize) {
-    this.shapeField = shapeField;
-    this.defaultSize = defaultSize;
-  }
-
-  protected abstract T readShape( BytesRef term );
-
-  public synchronized ShapeFieldCache<T> getCache(LeafReader reader) throws IOException {
-    ShapeFieldCache<T> idx = sidx.get(reader);
-    if (idx != null) {
-      return idx;
-    }
-    long startTime = System.currentTimeMillis();
-
-    log.fine("Building Cache [" + reader.maxDoc() + "]");
-    idx = new ShapeFieldCache<>(reader.maxDoc(),defaultSize);
-    int count = 0;
-    PostingsEnum docs = null;
-    Terms terms = reader.terms(shapeField);
-    if (terms != null) {
-      TermsEnum te = terms.iterator();
-      BytesRef term = te.next();
-      while (term != null) {
-        T shape = readShape(term);
-        if( shape != null ) {
-          docs = te.postings(docs, PostingsEnum.NONE);
-          Integer docid = docs.nextDoc();
-          while (docid != DocIdSetIterator.NO_MORE_DOCS) {
-            idx.add( docid, shape );
-            docid = docs.nextDoc();
-            count++;
-          }
-        }
-        term = te.next();
-      }
-    }
-    sidx.put(reader, idx);
-    long elapsed = System.currentTimeMillis() - startTime;
-    log.fine("Cached: [" + count + " in " + elapsed + "ms] " + idx);
-    return idx;
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapePredicateValueSource.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapePredicateValueSource.java b/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapePredicateValueSource.java
deleted file mode 100644
index b1dfaaa..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapePredicateValueSource.java
+++ /dev/null
@@ -1,113 +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.util;
-
-import com.spatial4j.core.shape.Shape;
-
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.queries.function.FunctionValues;
-import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.queries.function.docvalues.BoolDocValues;
-import org.apache.lucene.search.Explanation;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.spatial.query.SpatialOperation;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A boolean ValueSource that compares a shape from a provided ValueSource with a given Shape and sees
- * if it matches a given {@link SpatialOperation} (the predicate).
- *
- * @lucene.experimental
- */
-public class ShapePredicateValueSource extends ValueSource {
-  private final ValueSource shapeValuesource;//the left hand side
-  private final SpatialOperation op;
-  private final Shape queryShape;//the right hand side (constant)
-
-  /**
-   *
-   * @param shapeValuesource Must yield {@link Shape} instances from its objectVal(doc). If null
-   *                         then the result is false. This is the left-hand (indexed) side.
-   * @param op the predicate
-   * @param queryShape The shape on the right-hand (query) side.
-   */
-  public ShapePredicateValueSource(ValueSource shapeValuesource, SpatialOperation op, Shape queryShape) {
-    this.shapeValuesource = shapeValuesource;
-    this.op = op;
-    this.queryShape = queryShape;
-  }
-
-  @Override
-  public String description() {
-    return shapeValuesource + " " + op + " " + queryShape;
-  }
-
-  @Override
-  public void createWeight(Map context, IndexSearcher searcher) throws IOException {
-    shapeValuesource.createWeight(context, searcher);
-  }
-
-  @Override
-  public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
-    final FunctionValues shapeValues = shapeValuesource.getValues(context, readerContext);
-
-    return new BoolDocValues(this) {
-      @Override
-      public boolean boolVal(int doc) {
-        Shape indexedShape = (Shape) shapeValues.objectVal(doc);
-        if (indexedShape == null)
-          return false;
-        return op.evaluate(indexedShape, queryShape);
-      }
-
-      @Override
-      public Explanation explain(int doc) {
-        Explanation exp = super.explain(doc);
-        List<Explanation> details = new ArrayList<>(Arrays.asList(exp.getDetails()));
-        details.add(shapeValues.explain(doc));
-        return Explanation.match(exp.getValue(), exp.getDescription(), details);
-      }
-    };
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-
-    ShapePredicateValueSource that = (ShapePredicateValueSource) o;
-
-    if (!shapeValuesource.equals(that.shapeValuesource)) return false;
-    if (!op.equals(that.op)) return false;
-    if (!queryShape.equals(that.queryShape)) return false;
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = shapeValuesource.hashCode();
-    result = 31 * result + op.hashCode();
-    result = 31 * result + queryShape.hashCode();
-    return result;
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/vector/DistanceValueSource.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/vector/DistanceValueSource.java b/lucene/spatial/src/java/org/apache/lucene/spatial/vector/DistanceValueSource.java
deleted file mode 100644
index d31fd59..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/vector/DistanceValueSource.java
+++ /dev/null
@@ -1,120 +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.vector;
-
-import com.spatial4j.core.distance.DistanceCalculator;
-import com.spatial4j.core.shape.Point;
-import org.apache.lucene.index.LeafReader;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.DocValues;
-import org.apache.lucene.index.NumericDocValues;
-import org.apache.lucene.queries.function.FunctionValues;
-import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.util.Bits;
-
-import java.io.IOException;
-import java.util.Map;
-
-/**
- * An implementation of the Lucene ValueSource model that returns the distance
- * for a {@link PointVectorStrategy}.
- *
- * @lucene.internal
- */
-public class DistanceValueSource extends ValueSource {
-
-  private PointVectorStrategy strategy;
-  private final Point from;
-  private final double multiplier;
-
-  /**
-   * Constructor.
-   */
-  public DistanceValueSource(PointVectorStrategy strategy, Point from, double multiplier) {
-    this.strategy = strategy;
-    this.from = from;
-    this.multiplier = multiplier;
-  }
-
-  /**
-   * Returns the ValueSource description.
-   */
-  @Override
-  public String description() {
-    return "DistanceValueSource("+strategy+", "+from+")";
-  }
-
-  /**
-   * Returns the FunctionValues used by the function query.
-   */
-  @Override
-  public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
-    LeafReader reader = readerContext.reader();
-
-    final NumericDocValues ptX = DocValues.getNumeric(reader, strategy.getFieldNameX());
-    final NumericDocValues ptY = DocValues.getNumeric(reader, strategy.getFieldNameY());
-    final Bits validX =  DocValues.getDocsWithField(reader, strategy.getFieldNameX());
-    final Bits validY =  DocValues.getDocsWithField(reader, strategy.getFieldNameY());
-
-    return new FunctionValues() {
-
-      private final Point from = DistanceValueSource.this.from;
-      private final DistanceCalculator calculator = strategy.getSpatialContext().getDistCalc();
-      private final double nullValue =
-          (strategy.getSpatialContext().isGeo() ? 180 * multiplier : Double.MAX_VALUE);
-
-      @Override
-      public float floatVal(int doc) {
-        return (float) doubleVal(doc);
-      }
-
-      @Override
-      public double doubleVal(int doc) {
-        // make sure it has minX and area
-        if (validX.get(doc)) {
-          assert validY.get(doc);
-          return calculator.distance(from, Double.longBitsToDouble(ptX.get(doc)), Double.longBitsToDouble(ptY.get(doc))) * multiplier;
-        }
-        return nullValue;
-      }
-
-      @Override
-      public String toString(int doc) {
-        return description() + "=" + floatVal(doc);
-      }
-    };
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-
-    DistanceValueSource that = (DistanceValueSource) o;
-
-    if (!from.equals(that.from)) return false;
-    if (!strategy.equals(that.strategy)) return false;
-    if (multiplier != that.multiplier) return false;
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    return from.hashCode();
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/vector/PointVectorStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/vector/PointVectorStrategy.java b/lucene/spatial/src/java/org/apache/lucene/spatial/vector/PointVectorStrategy.java
deleted file mode 100644
index d046e24..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/vector/PointVectorStrategy.java
+++ /dev/null
@@ -1,182 +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.vector;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Circle;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.document.LegacyDoubleField;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.FieldType;
-import org.apache.lucene.queries.function.FunctionRangeQuery;
-import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.ConstantScoreQuery;
-import org.apache.lucene.search.LegacyNumericRangeQuery;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.spatial.SpatialStrategy;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.query.SpatialOperation;
-import org.apache.lucene.spatial.query.UnsupportedSpatialOperation;
-
-/**
- * Simple {@link SpatialStrategy} which represents Points in two numeric {@link
- * org.apache.lucene.document.LegacyDoubleField}s.  The Strategy's best feature is decent distance sort.
- *
- * <p>
- * <b>Characteristics:</b>
- * <br>
- * <ul>
- * <li>Only indexes points; just one per field value.</li>
- * <li>Can query by a rectangle or circle.</li>
- * <li>{@link
- * org.apache.lucene.spatial.query.SpatialOperation#Intersects} and {@link
- * SpatialOperation#IsWithin} is supported.</li>
- * <li>Uses the FieldCache for
- * {@link #makeDistanceValueSource(com.spatial4j.core.shape.Point)} and for
- * searching with a Circle.</li>
- * </ul>
- *
- * <p>
- * <b>Implementation:</b>
- * <p>
- * This is a simple Strategy.  Search works with {@link org.apache.lucene.search.LegacyNumericRangeQuery}s on
- * an x and y pair of fields.  A Circle query does the same bbox query but adds a
- * ValueSource filter on
- * {@link #makeDistanceValueSource(com.spatial4j.core.shape.Point)}.
- * <p>
- * One performance shortcoming with this strategy is that a scenario involving
- * both a search using a Circle and sort will result in calculations for the
- * spatial distance being done twice -- once for the filter and second for the
- * sort.
- *
- * @lucene.experimental
- */
-public class PointVectorStrategy extends SpatialStrategy {
-
-  public static final String SUFFIX_X = "__x";
-  public static final String SUFFIX_Y = "__y";
-
-  private final String fieldNameX;
-  private final String fieldNameY;
-
-  public int precisionStep = 8; // same as solr default
-
-  public PointVectorStrategy(SpatialContext ctx, String fieldNamePrefix) {
-    super(ctx, fieldNamePrefix);
-    this.fieldNameX = fieldNamePrefix+SUFFIX_X;
-    this.fieldNameY = fieldNamePrefix+SUFFIX_Y;
-  }
-
-  public void setPrecisionStep( int p ) {
-    precisionStep = p;
-    if (precisionStep<=0 || precisionStep>=64)
-      precisionStep=Integer.MAX_VALUE;
-  }
-
-  String getFieldNameX() {
-    return fieldNameX;
-  }
-
-  String getFieldNameY() {
-    return fieldNameY;
-  }
-
-  @Override
-  public Field[] createIndexableFields(Shape shape) {
-    if (shape instanceof Point)
-      return createIndexableFields((Point) shape);
-    throw new UnsupportedOperationException("Can only index Point, not " + shape);
-  }
-
-  /** @see #createIndexableFields(com.spatial4j.core.shape.Shape) */
-  public Field[] createIndexableFields(Point point) {
-    FieldType doubleFieldType = new FieldType(LegacyDoubleField.TYPE_NOT_STORED);
-    doubleFieldType.setNumericPrecisionStep(precisionStep);
-    Field[] f = new Field[2];
-    f[0] = new LegacyDoubleField(fieldNameX, point.getX(), doubleFieldType);
-    f[1] = new LegacyDoubleField(fieldNameY, point.getY(), doubleFieldType);
-    return f;
-  }
-
-  @Override
-  public ValueSource makeDistanceValueSource(Point queryPoint, double multiplier) {
-    return new DistanceValueSource(this, queryPoint, multiplier);
-  }
-
-  @Override
-  public ConstantScoreQuery makeQuery(SpatialArgs args) {
-    if(! SpatialOperation.is( args.getOperation(),
-        SpatialOperation.Intersects,
-        SpatialOperation.IsWithin ))
-      throw new UnsupportedSpatialOperation(args.getOperation());
-    Shape shape = args.getShape();
-    if (shape instanceof Rectangle) {
-      Rectangle bbox = (Rectangle) shape;
-      return new ConstantScoreQuery(makeWithin(bbox));
-    } else if (shape instanceof Circle) {
-      Circle circle = (Circle)shape;
-      Rectangle bbox = circle.getBoundingBox();
-      Query approxQuery = makeWithin(bbox);
-      BooleanQuery.Builder bqBuilder = new BooleanQuery.Builder();
-      FunctionRangeQuery vsRangeQuery =
-          new FunctionRangeQuery(makeDistanceValueSource(circle.getCenter()), 0.0, circle.getRadius(), true, true);
-      bqBuilder.add(approxQuery, BooleanClause.Occur.FILTER);//should have lowest "cost" value; will drive iteration
-      bqBuilder.add(vsRangeQuery, BooleanClause.Occur.FILTER);
-      return new ConstantScoreQuery(bqBuilder.build());
-    } else {
-      throw new UnsupportedOperationException("Only Rectangles and Circles are currently supported, " +
-          "found [" + shape.getClass() + "]");//TODO
-    }
-  }
-
-  /**
-   * Constructs a query to retrieve documents that fully contain the input envelope.
-   */
-  private Query makeWithin(Rectangle bbox) {
-    BooleanQuery.Builder bq = new BooleanQuery.Builder();
-    BooleanClause.Occur MUST = BooleanClause.Occur.MUST;
-    if (bbox.getCrossesDateLine()) {
-      //use null as performance trick since no data will be beyond the world bounds
-      bq.add(rangeQuery(fieldNameX, null/*-180*/, bbox.getMaxX()), BooleanClause.Occur.SHOULD );
-      bq.add(rangeQuery(fieldNameX, bbox.getMinX(), null/*+180*/), BooleanClause.Occur.SHOULD );
-      bq.setMinimumNumberShouldMatch(1);//must match at least one of the SHOULD
-    } else {
-      bq.add(rangeQuery(fieldNameX, bbox.getMinX(), bbox.getMaxX()), MUST);
-    }
-    bq.add(rangeQuery(fieldNameY, bbox.getMinY(), bbox.getMaxY()), MUST);
-    return bq.build();
-  }
-
-  private LegacyNumericRangeQuery<Double> rangeQuery(String fieldName, Double min, Double max) {
-    return LegacyNumericRangeQuery.newDoubleRange(
-        fieldName,
-        precisionStep,
-        min,
-        max,
-        true,
-        true);//inclusive
-  }
-
-}
-
-
-
-

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/vector/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/vector/package-info.java b/lucene/spatial/src/java/org/apache/lucene/spatial/vector/package-info.java
deleted file mode 100644
index 990f8bd..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/vector/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.
- */
- 
-/** 
- * Spatial strategy that uses two fields.
- */
-package org.apache.lucene.spatial.vector;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/overview.html
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/overview.html b/lucene/spatial/src/java/overview.html
index fb6d4f6..032d22a 100644
--- a/lucene/spatial/src/java/overview.html
+++ b/lucene/spatial/src/java/overview.html
@@ -21,47 +21,13 @@
   <body>
 
   <h1>The Spatial Module for Apache Lucene</h1>
-
-  <p>
-    The spatial module is new to Lucene 4, replacing the old "contrib" module
-    that came before it. The principle interface to the module is
-    a {@link org.apache.lucene.spatial.SpatialStrategy}
-    which encapsulates an approach to indexing and searching
-    based on shapes.  Different Strategies have different features and
-    performance profiles, which are documented at each Strategy implementation
-    class level.
-  </p>
-  <p>
-    For some sample code showing how to use the API, see
-      SpatialExample.java in the tests.
-  </p>
-  <p>
-    The spatial module uses
-    <a href="https://github.com/spatial4j/spatial4j">Spatial4j</a>
-    heavily.  Spatial4j is an ASL licensed library with these capabilities:
-    <ul>
-    <li>Provides shape implementations, namely point, rectangle,
-      and circle.  Both geospatial contexts and plain 2D Euclidean/Cartesian contexts
-      are supported.
-      With an additional dependency, it adds polygon and other geometry shape
-      support via integration with
-      <a href="http://sourceforge.net/projects/jts-topo-suite/">JTS Topology Suite</a>.
-      This includes dateline wrap support.</li>
-    <li>Shape parsing and serialization, including
-      <a href="http://en.wikipedia.org/wiki/Well-known_text">Well-Known Text (WKT)</a>
-      (via JTS).</li>
-    <li>Distance and other spatial related math calculations.</li>
-    </ul>
-  </p>
-  <p>
-    Historical note: The new spatial module was once known as
-    Lucene Spatial Playground (LSP) as an external project.  In ~March 2012, LSP
-    split into this new module as part of Lucene and Spatial4j externally. A
-    large chunk of the LSP implementation originated as SOLR-2155 which uses
-    trie/prefix-tree algorithms with a geohash encoding.  That approach is
-    implemented in {@link org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy}
-    today.
-  </p>
-
+    <p>
+      APIs for geospatial indexing and querying. Dependencies for the spatial module are
+      restricted to inner lucene modules only. That is, no third-party dependencies
+      are allowed. The intent is to keep this module free of any integration or
+      licensing issues that might arise as a result of depending on an external library.
+      For adding or leveraging spatial features that require third-party libraries see
+      the <a href="../spatial-extras/overview-summary.html">spatial-extras</a> package.
+    </p>
   </body>
 </html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test-files/cities-Intersects-BBox.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test-files/cities-Intersects-BBox.txt b/lucene/spatial/src/test-files/cities-Intersects-BBox.txt
deleted file mode 100644
index e85748c..0000000
--- a/lucene/spatial/src/test-files/cities-Intersects-BBox.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-[San Francisco] G5391959 @ Intersects(ENVELOPE(-122.524918, -122.360123, 37.817108, 37.674973))
-[Wellington] G2179537 @ Intersects(ENVELOPE(174.711456, 174.854279, -41.213837, -41.360779))
-[Barcelona] G6544100 G3128760  @  Intersects(ENVELOPE(2.127228, 2.226105, 41.408844, 41.333313))
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test-files/data/LUCENE-4464.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test-files/data/LUCENE-4464.txt b/lucene/spatial/src/test-files/data/LUCENE-4464.txt
deleted file mode 100644
index dfb5a40..0000000
--- a/lucene/spatial/src/test-files/data/LUCENE-4464.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-#id	name	shape
-poly1	poly1	POLYGON ((-93.17288720912401 45.280265431486754, -93.17232270645628 45.2802724629027, -93.17229737711205 45.279497574052314, -93.1722224854913 45.277577770983854, -93.17218124644266 45.276747010395624, -93.16722650828461 45.276819421108826, -93.16581262076448 45.27684404529939, -93.16363038333625 45.276882054199596, -93.16249244695301 45.276929493877525, -93.16247370542268 45.27641118002343, -93.16246893668628 45.276279382682894, -93.1624671302382 45.274701063846244, -93.16246679905096 45.273381422360785, -93.16247689122851 45.273189685068424, -93.16249146710186 45.27291249464421, -93.16249868565903 45.272467966062614, -93.16247955957382 45.27177209534391, -93.1624787718002 45.27127651548793, -93.16247840794293 45.27104491547271, -93.16247917486976 45.27087000356473, -93.1624817727418 45.270279315147775, -93.16252487154968 45.26996729342093, -93.16254025661699 45.26976826077157, -93.16247902564132 45.269527941604, -93.16242684845764 45.2692774997531, -93.16242126018722 4
 5.26894470083864, -93.16241263011544 45.26769394309626, -93.16246809168283 45.26571736107859, -93.16247263940593 45.26195548919013, -93.16253090997651 45.258615729449964, -93.16256878834184 45.25650987969364, -93.1626048203569 45.2546538608912, -93.16265873943591 45.251876274357876, -93.16275002007988 45.2510418534315, -93.16282237443883 45.25042383853711, -93.16286421513767 45.249181538840595, -93.16288289220509 45.24862697953288, -93.1629601120395 45.248250613185206, -93.16301002807151 45.24802483983211, -93.16301621932013 45.247670020958665, -93.16301519349018 45.247478630666144, -93.16303001333274 45.24727504082362, -93.16303463142393 45.24713931946277, -93.16302280990728 45.2470107542477, -93.16298327344437 45.24685970499298, -93.16294217154733 45.246633449219054, -93.16294315088282 45.246419514713516, -93.16295754265565 45.24621538933992, -93.16296755618336 45.24580786412655, -93.16296268372803 45.245362220836384, -93.16296319568123 45.245046689033444, -93.16297766811293 45.24
 481357093532, -93.16296370759883 45.2445699039253, -93.16294931051515 45.24231310924752, -93.16294559876471 45.24173111255096, -93.16295568091667 45.240776604513705, -93.1629609359182 45.24053954238007, -93.1629658719288 45.24019639978025, -93.1625355179785 45.24018482062359, -93.15847246037083 45.24007549519542, -93.15641780558727 45.24006372373029, -93.15470331938288 45.24002991133718, -93.1515176880772 45.240038275846665, -93.14892151971884 45.24004508944476, -93.14597353408716 45.240012024375574, -93.14198169289922 45.239944427606616, -93.14246140322608 45.21441838866706, -93.14239730934507 45.20842345035032, -93.14240307538512 45.203669567890245, -93.13209436867183 45.20385828388066, -93.13238731320574 45.19696183064252, -93.13244550539693 45.19559178376392, -93.13255875219626 45.19292582294682, -93.12747185962866 45.19303831675316, -93.12741613255534 45.196689407842044, -93.12341724811418 45.196748516850086, -93.12336451543653 45.19630050937325, -93.12233270487748 45.196311891
 79194, -93.12244695905335 45.18943470505876, -93.12752867296823 45.18931969757398, -93.1275981937757 45.18579899512077, -93.12249095182051 45.18589579364393, -93.12250905286206 45.18230218633591, -93.11745336177542 45.182234528897865, -93.11742994994425 45.17494109686777, -93.11234677240823 45.174914625057596, -93.11232755368056 45.178541858988, -93.09142510557425 45.17830768889981, -93.0878908215621 45.18208021181682, -93.04087986544745 45.182020129318005, -93.02011304608662 45.18206919600553, -92.99725469269949 45.18154883703301, -92.9866455346556 45.18162938363265, -92.98002761377205 45.181741313792635, -92.97460481311676 45.1817232745721, -92.95815138711436 45.18159971137449, -92.95832448011389 45.16710586357575, -92.95821211351648 45.15266682925307, -92.94804883291458 45.152678829402525, -92.94820512323935 45.14582287000843, -92.94821449767262 45.14541149629351, -92.93808126859899 45.145435393255234, -92.938064080176 45.1464755574292, -92.93790172782569 45.15630033200825, -92.9
 3776855788026 45.156299483202375, -92.93416458772786 45.15627656196406, -92.92776593175911 45.156235863288074, -92.92779198321185 45.15260820059608, -92.9228643837518 45.15257871636257, -92.91761510291013 45.15254730117589, -92.91755895303478 45.15978011255037, -92.90742527225278 45.15975884768774, -92.90734951861361 45.16700513027527, -92.90243435593408 45.16697925148226, -92.90226994175299 45.16697838648701, -92.90228225598396 45.16960751885433, -92.90228682505473 45.170583562524534, -92.89838293958822 45.17058359192683, -92.89776337384279 45.17058359923907, -92.89720228241329 45.170636798053465, -92.89720546113311 45.171648743169875, -92.89721045187194 45.17323675651512, -92.89721215942521 45.17377958217219, -92.8972133713998 45.17416655315385, -92.89752994284902 45.17416793500262, -92.90230392627396 45.174188700362095, -92.90230695467396 45.17483317173849, -92.90230939234701 45.175352265892315, -92.90231342163983 45.17620891826606, -92.9023378718661 45.18141217320357, -92.898291
 95794003 45.18137903577816, -92.89197067471983 45.181327269964534, -92.86573042754982 45.18111238484799, -92.86537258386163 45.18110945889712, -92.86579788828743 45.16683341076013, -92.85850341291456 45.166840495697045, -92.85576616527777 45.1668651317465, -92.8455814929548 45.16695680639518, -92.8403672382906 45.167003741522834, -92.84037534438275 45.166359277271084, -92.83914257524022 45.166407761467035, -92.83786182101709 45.16655768366541, -92.83762301824869 45.16658563659705, -92.83700510809494 45.16665797101126, -92.83700330475195 45.1670405349812, -92.83520392476423 45.16704646605868, -92.83519998302931 45.1672093811339, -92.83518241658018 45.17114095264113, -92.8351705215998 45.17380185475555, -92.83516823773242 45.17431412368648, -92.82501384033566 45.174380025018145, -92.82373302900695 45.174963166130034, -92.82127603798283 45.17799740439804, -92.81495695139105 45.17798284134312, -92.81498212776123 45.18394380043827, -92.81496335262872 45.20297631525698, -92.81496300732859
  45.2033351264244, -92.8149190887153 45.20460132029917, -92.81473397710002 45.21, -92.8198460035041 45.21, -92.81985864578533 45.21352006541341, -92.81476009958381 45.21350519453624, -92.81473397710002 45.211, -92.79434616877515 45.20979982288059, -92.79434485197183 45.210003888814526, -92.7942994128934 45.217028016258524, -92.79414754531777 45.217027433538036, -92.75950558164095 45.216895251116746, -92.75791266717471 45.216889175072694, -92.75634408090858 45.21737192056616, -92.75539334998972 45.21781096867505, -92.75544275719047 45.219840930849315, -92.75232263931744 45.219847708152834, -92.75345360864661 45.22241622713623, -92.75393100188802 45.22290500013628, -92.75454911801587 45.22425238152991, -92.75465656863904 45.22441872007679, -92.75478824580995 45.22461252606749, -92.75573200183275 45.22594899943625, -92.7559326169467 45.2263989667922, -92.756173357985 45.22677479396459, -92.75628338889855 45.227185737281864, -92.75651400327136 45.22770300256764, -92.75667800355963 45.22
 8069998932774, -92.75745600158125 45.23052599674398, -92.75737071502948 45.23131853178694, -92.75760683805547 45.23212889115611, -92.7575248338702 45.23249816977935, -92.75760900807862 45.233043995948975, -92.75740715667484 45.23498808590038, -92.75739258433605 45.23515457917446, -92.75736004212973 45.235441823970014, -92.75728900664646 45.2361259970008, -92.75750924881613 45.23833187652166, -92.75783421241928 45.239151014730965, -92.75799784052033 45.2401986059374, -92.75814399470411 45.24075700093086, -92.75910499448543 45.24444199845027, -92.75927217262658 45.246363482652335, -92.759708376526 45.24795052230262, -92.76024900009054 45.24960000150479, -92.76026400206055 45.25171699829065, -92.75984499770836 45.25286799832034, -92.75883599655404 45.25442699925451, -92.75592228367496 45.256779108256175, -92.75559993467031 45.25707105760005, -92.75540261715516 45.25725539605134, -92.75458100472993 45.258140999051975, -92.75362100152239 45.25941899619891, -92.75258800661327 45.261786002
 1943, -92.7523530053651 45.26244399793552, -92.7521330910868 45.26318539548715, -92.75199986320791 45.26381589028983, -92.7519440909167 45.26415703570502, -92.75192391851121 45.26559725594415, -92.75247612752318 45.26746623235666, -92.75254008932185 45.26768063816608, -92.75267394173396 45.268130176728555, -92.75287910082022 45.2688320393691, -92.7530104867237 45.26921012533672, -92.75329204456183 45.26980089141646, -92.75414711285153 45.2712720735891, -92.7552129966957 45.27237299947564, -92.75574299378961 45.27288399662051, -92.75678399520334 45.273891998902435, -92.75750199664172 45.27442999825494, -92.75801999923948 45.274822998224586, -92.75866321741752 45.27578539520815, -92.7589271849383 45.27616491445647, -92.75924599787822 45.27671899844492, -92.75941999802778 45.27718649803985, -92.75960999785612 45.27731999914, -92.75978699565532 45.27743849638546, -92.76004300142414 45.277978995119405, -92.76061199738588 45.27882799808139, -92.76117799722955 45.280582999200305, -92.76136
 19999475 45.28220800042353, -92.76167096088638 45.2836803717185, -92.76198517744629 45.2850267976271, -92.76206945308458 45.2853507773657, -92.76202745146396 45.286658659028, -92.76204199858486 45.28698499388888, -92.76201199644161 45.28793199672008, -92.76200399722086 45.28821299803955, -92.76121399640145 45.28913599914764, -92.7603870028136 45.28991599406784, -92.75871000510011 45.29096499709372, -92.75799200634881 45.291140996050984, -92.75687800551285 45.29148399845183, -92.75507700319366 45.2919269952758, -92.75480030147037 45.291986779669465, -92.74569331443023 45.29606484000191, -92.74555580404507 45.29614422445335, -92.74523588498667 45.29631411941847, -92.76071968429389 45.29617634034589, -92.79448651640953 45.29587194744184, -92.82553071142016 45.29634288822895, -92.82523623967 45.28697641600944, -92.8246113114385 45.27459391718561, -92.82414631698042 45.26733414102221, -92.83443181636859 45.267466042102846, -92.83450366471794 45.265666722695805, -92.8395297613521 45.26570
 782145342, -92.83954651660255 45.2675117790906, -92.85488466565545 45.267633226883305, -92.85446380439222 45.260381978642265, -92.8530801070886 45.256940031152055, -92.8746167542768 45.2569553750289, -92.87517983690772 45.26774272327855, -92.88032459143679 45.26775272915376, -92.88028907325248 45.27498539130476, -92.885429695981 45.27499516876503, -92.88541044770409 45.27862274921294, -92.8854460740016 45.28269595676258, -92.8858306795285 45.28583335680999, -92.89095994168375 45.285838365551086, -92.89147668909354 45.290056047991875, -92.89183494474656 45.292995365557246, -92.89287941280966 45.29621886928581, -92.93574219102997 45.296382695230655, -92.9366855829562 45.29639453639271, -92.93730010601949 45.29640233268984, -92.93773633826109 45.296407862218295, -92.95031707870098 45.29656663627082, -92.95732733387652 45.29663267857854, -92.95723233585932 45.305785498930874, -92.95755812361517 45.31807293816823, -92.9575313307762 45.325662873647204, -92.96200814151011 45.32569410734573
 , -92.96201051236334 45.33056403262943, -92.95763365021791 45.330562956294486, -92.95750484414667 45.34006528297348, -92.95740249422305 45.3523406680097, -92.96272753035339 45.352295608902175, -92.96260253143201 45.363259386181184, -92.95732537061275 45.363286992831206, -92.95715614538045 45.36869421119079, -92.97302216756823 45.36904156334545, -92.9731090974606 45.37554810693529, -92.98760985309234 45.37555619312347, -92.98429494637762 45.38215591061988, -92.9924184629002 45.38233326055907, -93.01850137881846 45.38277378724873, -93.01956464133914 45.41174708503911, -93.03973263863047 45.412106304897264, -93.06569776540464 45.412656360563524, -93.08346874844985 45.41297273973574, -93.09263091377308 45.41335460313747, -93.1012213163472 45.413720365424695, -93.10759754754753 45.41373499082408, -93.14214551761233 45.41373101611429, -93.1421802894172 45.40666589187203, -93.14209155741717 45.38498980813781, -93.14398965535287 45.369981475770224, -93.13861914028635 45.36992203894643, -93.
 13946982733188 45.35540022959687, -93.14362673736643 45.35542059147377, -93.14338145836778 45.34816201728363, -93.14259222919002 45.34815677471413, -93.14123737100095 45.34271091215897, -93.14120170425102 45.34166175650565, -93.14159640367895 45.340845226624126, -93.16430988689314 45.34107128935172, -93.1641229508536 45.33731028186903, -93.163783504365 45.32713863170596, -93.16354815472778 45.31568179036097, -93.1634974864936 45.3115083559682, -93.16335415000293 45.30838048844207, -93.16326942872365 45.30653168298998, -93.16286993093225 45.29781375116957, -93.16292479029 45.297483756012355, -93.16251838572086 45.29748043583636, -93.16242411934059 45.29340169752503, -93.16237192435095 45.291513658346155, -93.16125915756838 45.29101148729498, -93.16224903398384 45.290456018307964, -93.16243543883762 45.29031474509565, -93.16248365754952 45.29016960982244, -93.1625270557542 45.28932067928762, -93.16350507037129 45.28940282906675, -93.16413761242012 45.28944739938537, -93.16430369461645
  45.289411531953206, -93.164472138656 45.28937514511818, -93.16431016328954 45.288334379584406, -93.16422830296436 45.28780835028316, -93.16373011428878 45.287807744950875, -93.16348868413621 45.28778563548775, -93.16304669211718 45.28779811404454, -93.16252493722239 45.28781182501286, -93.1625182014603 45.28601279964026, -93.1625127377889 45.28416325442296, -93.1717122152211 45.28391079701647, -93.17291828928865 45.28387769615237, -93.17292468588315 45.28327561174209, -93.1729215958459 45.28269914269899, -93.17290904354249 45.28216703245599, -93.17290447076888 45.281410092382885, -93.17289432485279 45.28068732375472, -93.17288720912401 45.280265431486754))
-poly2	poly2	POLYGON((-93.26592485308495 45.18931973506328, -93.26373519655886 45.18933815615675, -93.2637828223868 45.18660121752107, -93.26280973893772 45.18656958194617, -93.2603275028686 45.186488876325654, -93.25976682936536 45.18646929139094, -93.25877703935303 45.18686109057519, -93.25788401039608 45.18633824889261, -93.25713811973642 45.186864792015704, -93.25660115549654 45.18628640445176, -93.24081325108644 45.18609354693712, -93.2356823133177 45.1860308697061, -93.23474944979115 45.186019474019865, -93.23478565684188 45.18266103967549, -93.23072066106351 45.18267669158043, -93.22480340476464 45.18267437402639, -93.21952101307244 45.18267371221728, -93.21950131879755 45.184689058075534, -93.21950381582634 45.18590104693386, -93.21950547892035 45.186708829298695, -93.21948324866376 45.18808573281868, -93.21947477056304 45.188619717930756, -93.2194751507154 45.1899146284615, -93.22390334137022 45.18991091026497, -93.2245904557543 45.18993775453468, -93.2245784309098 45.190287
 02856576, -93.2245932424241 45.19081834295508, -93.22460314163764 45.19137779927979, -93.22459067695124 45.19162607300785, -93.22458367100289 45.19176562022696, -93.22354968949122 45.191760188521705, -93.22131530006368 45.19175468785821, -93.22018302807493 45.19175762419069, -93.21965635944291 45.19175898704962, -93.21824735047468 45.191762639857636, -93.21840068968908 45.191840907619024, -93.21858279007587 45.191950538176606, -93.21874378970492 45.19205449060312, -93.21893581214327 45.192204972059955, -93.21911499957261 45.19238205879934, -93.21934767139433 45.192628269473076, -93.21954522989743 45.1928508489684, -93.21972003978802 45.19304459976245, -93.21997538064213 45.19332124206717, -93.22011354045264 45.193470928079385, -93.22046875034326 45.19384479955501, -93.2206469058326 45.19404172922978, -93.22079845082156 45.194244494502364, -93.2209416400795 45.19447508772328, -93.22107397875365 45.19474417974581, -93.2211368505518 45.19490985928749, -93.22118231976518 45.195047277731
 625, -93.22124659963487 45.19525315038074, -93.22128314962913 45.195396480693944, -93.22130715028514 45.195564823375, -93.22131862069979 45.195757013030224, -93.22130704484326 45.19599065847414, -93.22127083850016 45.19622942989826, -93.22124456959293 45.19636257994296, -93.22120917947201 45.19651471803614, -93.22115328972328 45.196774039833144, -93.22110053150747 45.19700410181286, -93.22105123806169 45.19721904984113, -93.21939747849284 45.19720754776318, -93.21658707902952 45.19719901749774, -93.21405492494755 45.19718389708806, -93.21060961905127 45.19716332241369, -93.20846870851273 45.19715738191871, -93.20635420918421 45.19714993030806, -93.20384995444252 45.19713947337882, -93.20382099935851 45.195915480832355, -93.20379040854755 45.195493880093856, -93.20373937951182 45.19525460196455, -93.20366799901262 45.194730001052676, -93.20359944927 45.194273469702246, -93.20351980946141 45.19386975065817, -93.20336890147132 45.1933312322322, -93.20348773988103 45.19317805926476, -93
 .20364964522179 45.19294381603321, -93.20373782170354 45.192758795441485, -93.20378634041538 45.1925589245846, -93.20378780054193 45.1924118820702, -93.20373224993294 45.192246366644895, -93.20366678053941 45.192063182244134, -93.20349712021084 45.19164111034226, -93.20336402335359 45.191262445660406, -93.20333661484061 45.19107258136713, -93.20334012614478 45.19082850506992, -93.20338500114326 45.190584969374704, -93.20346313590359 45.19035226093307, -93.20353125074365 45.19015096025676, -93.20337886118753 45.19012069933683, -93.20280004152556 45.18999823901699, -93.20236430223584 45.1898748712581, -93.20223796285948 45.18983446401002, -93.20171338128353 45.189666689690526, -93.20105175026708 45.18940210042135, -93.20059509118217 45.18937347081525, -93.20014399997638 45.18935951962055, -93.1999096512546 45.18934032171285, -93.19969162075753 45.18934030912719, -93.19953079227915 45.18938062079311, -93.19930724128803 45.189471810355066, -93.19836742091539 45.18954495845859, -93.19790
 904174889 45.189755310346555, -93.19770094626355 45.18978905045578, -93.19728573057267 45.1898563687543, -93.19706717806918 45.18978234280038, -93.1961191012612 45.18980511056629, -93.19583707702907 45.18977039110604, -93.19495714548943 45.18966207098092, -93.19409949054268 45.18955648989894, -93.19361391124465 45.18954758129998, -93.19142135137997 45.189507349701145, -93.18867729058191 45.18943758222878, -93.18766468614145 45.18941183701645, -93.1869063815807 45.18939255950494, -93.18676117212036 45.18939312363656, -93.18583601993124 45.18939673056086, -93.18362870083628 45.18940533739182, -93.18015920861117 45.189432919714875, -93.17748344774633 45.18940274982507, -93.17100678798263 45.18934067185518, -93.1680509570817 45.18931686702863, -93.16712265967519 45.189309389152754, -93.1632729184803 45.189289560128074, -93.1524420382428 45.189137301470666, -93.1488330300988 45.189087681208825, -93.14258337454692 45.18900953614207, -93.1425728385595 45.18964797148711, -93.14257129908563 
 45.19044710129245, -93.14256839076815 45.191380659844974, -93.14257549009486 45.192639988690985, -93.14256591028126 45.193624481846925, -93.1425562203409 45.19475816134898, -93.14254671019609 45.19564806883362, -93.14253591314012 45.19592629600891, -93.1425191002932 45.19635953895129, -93.14240307328147 45.20366956427245, -93.14239731024965 45.20842345007226, -93.14246141142196 45.2144183909345, -93.14198170032972 45.23994442974387, -93.14597353942523 45.240012030562795, -93.14892151981124 45.24004509174428, -93.15151768504401 45.24003827478177, -93.15470331907811 45.2400299112851, -93.15641781022819 45.240063720104146, -93.15847245794774 45.24007548756677, -93.16253551804624 45.24018481776239, -93.16296586932476 45.24019639699945, -93.16296093749654 45.240539543608094, -93.16295567833508 45.24077659970959, -93.16294559992268 45.24173110984731, -93.16294931429802 45.242313107885224, -93.16296371061823 45.24456989801016, -93.16297766989932 45.24481356907269, -93.16296319587042 45.245
 04668430867, -93.16296267909655 45.24536222031531, -93.16296756070733 45.24580785775435, -93.16295754084666 45.24621538734816, -93.16294315030365 45.24641950970948, -93.1629421699368 45.246633444731216, -93.16298326866249 45.24685970478054, -93.16302280494743 45.24701074802872, -93.1630346343297 45.247139320093076, -93.16303000914128 45.24727503858908, -93.16301519072017 45.24747862874394, -93.16301622062082 45.247670019373224, -93.16301002844395 45.24802483903903, -93.16296010836595 45.248250609285236, -93.16288288941641 45.248626979189, -93.16286421036493 45.24918153632857, -93.16282236866641 45.25042383853131, -93.16275001793326 45.25104184745623, -93.16265874011768 45.251876269431015, -93.1626048141941 45.25465385517585, -93.162568780952 45.25650987775294, -93.16253090903855 45.25861572819838, -93.16247264162719 45.261955487720506, -93.16246809047925 45.26571735738526, -93.16241263022145 45.267693939529536, -93.16242125944353 45.26894469986081, -93.16242684956876 45.269277499432
 015, -93.16247902269161 45.26952793567272, -93.16254025984375 45.269768259020054, -93.1625248689828 45.26996728874923, -93.16248176954191 45.27027930739088, -93.16247917649272 45.270869996810376, -93.16247840915516 45.27104490906511, -93.16247877426206 45.27127651283899, -93.162479560911 45.27177208702322, -93.16249869026827 45.272467959171365, -93.16249147172434 45.27291248854739, -93.16247688682598 45.27318968296259, -93.16246680083795 45.27338141702519, -93.1624671298516 45.27470105775956, -93.16246893968787 45.276279379505084, -93.1624737063593 45.2764111771935, -93.16249244905424 45.276929488819604, -93.16363037995181 45.27688204948932, -93.16581262202895 45.276844043452684, -93.16722651010657 45.27681941864911, -93.17218124072862 45.27674700948904, -93.1722224784459 45.27757776899891, -93.17229737034532 45.279497570305445, -93.17232269933695 45.28027246109518, -93.17288721010608 45.28026543129147, -93.1728943187817 45.2806873180744, -93.17290447218495 45.28141008817547, -93.17
 290904002667 45.28216703008146, -93.17292159084371 45.28269913830247, -93.17292468118433 45.283275608616165, -93.17291828224536 45.28387769767021, -93.1717122127579 45.283910797244246, -93.16251273143365 45.28416325629099, -93.16251820094257 45.28601279797615, -93.16252493935717 45.287811833132764, -93.16304669905364 45.28779811692505, -93.16348868871324 45.28778563925035, -93.16373011962693 45.28780774767522, -93.16422830587629 45.28780835110865, -93.1643101699488 45.28833437868018, -93.16447213914093 45.289375147768524, -93.16430369361024 45.28941153310711, -93.16413761723706 45.28944740219967, -93.16350507286433 45.289402832527344, -93.16252705964098 45.289320683284735, -93.16248365939401 45.29016961156254, -93.16243543831087 45.29031475002342, -93.16224903970826 45.2904560215217, -93.16125915934788 45.29101149209126, -93.16237192796683 45.291513661220456, -93.16242412151107 45.29340170072084, -93.16251838980172 45.29748044313293, -93.16292479370829 45.29748376064082, -93.1863909
 4534673 45.29767533425263, -93.18833342032521 45.29769119188229, -93.1925428426471 45.29770437859642, -93.19474753040078 45.29771128804242, -93.19765740975974 45.29769541872667, -93.20297591868295 45.29776263827187, -93.20683144906876 45.29774197003572, -93.20883497923562 45.297766559466794, -93.21546742887979 45.297768422222155, -93.22617724980643 45.29791971794424, -93.23408017640227 45.298023690859175, -93.2343080073169 45.288444186545625, -93.23432525195352 45.287995322205425, -93.23469515647318 45.269279712377234, -93.23475627635968 45.266203358381446, -93.23560542207227 45.26619551047824, -93.23899176558338 45.26613779367068, -93.24250527367546 45.26608234822973, -93.243445378056 45.26606503829342, -93.24512861083372 45.2660344570852, -93.24588057830995 45.26602026067889, -93.24713274287363 45.26599455787498, -93.25036838013868 45.26592734514467, -93.25172461510564 45.265900698298395, -93.25236738024864 45.265888260809106, -93.25481754173921 45.26583307838667, -93.255713579529
 06 45.265819559899164, -93.2594981489083 45.26575415212897, -93.26098138766197 45.265754375486374, -93.26155216698102 45.26565612540643, -93.26170097145753 45.26562288963898, -93.26208574477789 45.26553876835043, -93.26245875524685 45.265434673708015, -93.26277275191426 45.265316250819595, -93.26311663127117 45.26517251314189, -93.26346212923646 45.26500240317637, -93.26393572774133 45.26477558787491, -93.2651820516718 45.26406759657772, -93.26518110226205 45.26337226279194, -93.26515218908767 45.26311636791454, -93.26518703008779 45.262871689663605, -93.2652064900752 45.26265582104258, -93.2652110298225 45.26215614194132, -93.26522443086994 45.26112430402238, -93.26522989950563 45.260703199933474, -93.26524872191168 45.25930812973533, -93.26525187087448 45.258897852775995, -93.26525857049303 45.258025812056765, -93.26527734826267 45.256675072153314, -93.26528081766433 45.25612813038996, -93.265287399575 45.25512698071874, -93.26530031054412 45.253711671615115, -93.26531490547187 45
 .25273002640574, -93.26532214123614 45.252243491267, -93.26533817105908 45.25062180123498, -93.26535413994274 45.24906421173263, -93.26536141910549 45.24841165046578, -93.26536638602661 45.24796649509243, -93.26537318826473 45.24735637067748, -93.26539798003012 45.24589779189643, -93.265404909549 45.24454674190931, -93.2654060939449 45.24296904311022, -93.26540624905046 45.24276127146885, -93.26540843815205 45.2420263885843, -93.26541275006169 45.240577352345994, -93.2654375717671 45.238843301612725, -93.26544518264211 45.237906888690105, -93.26544940933664 45.23738688110566, -93.26546966016808 45.236093591927926, -93.2654781584622 45.235359229961944, -93.26548338867605 45.23490715107922, -93.26553582901259 45.23354268990693, -93.26554071996831 45.23330119833777, -93.26555987026248 45.2323552839169, -93.26557251955711 45.23173040973764, -93.26556626032777 45.22975235185782, -93.26556606661761 45.229367333607186, -93.26556579189545 45.228823722705066, -93.26562882232702 45.2268722061
 76665, -93.26571073971922 45.224335971082276, -93.26574560622672 45.22192222321787, -93.26574836877063 45.22173093256304, -93.26577033227747 45.22021043432355, -93.26578588443306 45.21913391123174, -93.26580662128347 45.21769799745153, -93.26580983179628 45.217475736026664, -93.26581322607608 45.217240685631346, -93.26590715360736 45.210737684073244, -93.26591966090616 45.209871711997586, -93.2659016992406 45.20722015227932, -93.26587484243684 45.203254836571126, -93.26585637174348 45.20052765082941, -93.26585684827346 45.19841676076085, -93.26587786763154 45.19732741144391, -93.2658624676632 45.1970879109074, -93.2659274100303 45.194004979577755, -93.26595017983325 45.191531890895845, -93.26595423366354 45.19092534610275, -93.26593099287571 45.190637988686554, -93.2659274057232 45.18986823069059, -93.26592485308495 45.18931973506328))
\ No newline at end of file


[40/50] [abbrv] lucene-solr git commit: Fix tests to randomized BKD parameters in tests (like TestPointQueries does).

Posted by ho...@apache.org.
Fix tests to randomized BKD parameters in tests (like TestPointQueries does).

Otherwise, even things like range queries are not tested well unless tests use thousands of documents.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/502b8800
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/502b8800
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/502b8800

Branch: refs/heads/jira/SOLR-445
Commit: 502b8800fca18e2735d4ecba35af548885bed42b
Parents: dc39fc3
Author: Robert Muir <rm...@apache.org>
Authored: Mon Feb 29 20:29:51 2016 -0500
Committer: Robert Muir <rm...@apache.org>
Committed: Mon Feb 29 20:29:51 2016 -0500

----------------------------------------------------------------------
 .../codecs/asserting/AssertingPointFormat.java  | 17 ++++++++-
 .../org/apache/lucene/index/RandomCodec.java    | 37 +++++++++++++++++++-
 2 files changed, 52 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/502b8800/lucene/test-framework/src/java/org/apache/lucene/codecs/asserting/AssertingPointFormat.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/codecs/asserting/AssertingPointFormat.java b/lucene/test-framework/src/java/org/apache/lucene/codecs/asserting/AssertingPointFormat.java
index e2d1b07..3411c7b 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/codecs/asserting/AssertingPointFormat.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/codecs/asserting/AssertingPointFormat.java
@@ -34,7 +34,22 @@ import org.apache.lucene.util.TestUtil;
  */
 
 public final class AssertingPointFormat extends PointFormat {
-  private final PointFormat in = TestUtil.getDefaultCodec().pointFormat();
+  private final PointFormat in;
+
+  /** Create a new AssertingPointFormat */
+  public AssertingPointFormat() {
+    this(TestUtil.getDefaultCodec().pointFormat());
+  }
+
+  /**
+   * Expert: Create an AssertingPointFormat.
+   * This is only intended to pass special parameters for testing.
+   */
+  // TODO: can we randomize this a cleaner way? e.g. stored fields and vectors do
+  // this with a separate codec...
+  public AssertingPointFormat(PointFormat in) {
+    this.in = in;
+  }
   
   @Override
   public PointWriter fieldsWriter(SegmentWriteState state) throws IOException {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/502b8800/lucene/test-framework/src/java/org/apache/lucene/index/RandomCodec.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/index/RandomCodec.java b/lucene/test-framework/src/java/org/apache/lucene/index/RandomCodec.java
index 986dd34..5b04b00 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/index/RandomCodec.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/index/RandomCodec.java
@@ -16,6 +16,7 @@
  */
 package org.apache.lucene.index;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -27,15 +28,21 @@ import java.util.Random;
 import java.util.Set;
 
 import org.apache.lucene.codecs.DocValuesFormat;
+import org.apache.lucene.codecs.PointFormat;
+import org.apache.lucene.codecs.PointReader;
+import org.apache.lucene.codecs.PointWriter;
 import org.apache.lucene.codecs.PostingsFormat;
 import org.apache.lucene.codecs.asserting.AssertingCodec;
 import org.apache.lucene.codecs.asserting.AssertingDocValuesFormat;
+import org.apache.lucene.codecs.asserting.AssertingPointFormat;
 import org.apache.lucene.codecs.asserting.AssertingPostingsFormat;
 import org.apache.lucene.codecs.blockterms.LuceneFixedGap;
 import org.apache.lucene.codecs.blockterms.LuceneVarGapDocFreqInterval;
 import org.apache.lucene.codecs.blockterms.LuceneVarGapFixedInterval;
 import org.apache.lucene.codecs.blocktreeords.BlockTreeOrdsPostingsFormat;
 import org.apache.lucene.codecs.bloom.TestBloomFilteredLucenePostings;
+import org.apache.lucene.codecs.lucene60.Lucene60PointReader;
+import org.apache.lucene.codecs.lucene60.Lucene60PointWriter;
 import org.apache.lucene.codecs.memory.DirectDocValuesFormat;
 import org.apache.lucene.codecs.memory.DirectPostingsFormat;
 import org.apache.lucene.codecs.memory.FSTOrdPostingsFormat;
@@ -80,6 +87,28 @@ public class RandomCodec extends AssertingCodec {
   private Map<String,DocValuesFormat> previousDVMappings = Collections.synchronizedMap(new HashMap<String,DocValuesFormat>());
   private final int perFieldSeed;
 
+  // a little messy: randomize the default codec's parameters here.
+  // with the default values, we have e,g, 1024 points in leaf nodes,
+  // which is less effective for testing.
+  // TODO: improve how we randomize this...
+  private final int maxPointsInLeafNode;
+  private final double maxMBSortInHeap;
+
+  @Override
+  public PointFormat pointFormat() {
+    return new AssertingPointFormat(new PointFormat() {
+      @Override
+      public PointWriter fieldsWriter(SegmentWriteState writeState) throws IOException {
+        return new Lucene60PointWriter(writeState, maxPointsInLeafNode, maxMBSortInHeap);
+      }
+
+      @Override
+      public PointReader fieldsReader(SegmentReadState readState) throws IOException {
+        return new Lucene60PointReader(readState);
+      }
+    });
+  }
+
   @Override
   public PostingsFormat getPostingsFormatForField(String name) {
     PostingsFormat codec = previousMappings.get(name);
@@ -121,6 +150,9 @@ public class RandomCodec extends AssertingCodec {
     int maxItemsPerBlock = 2*(Math.max(2, minItemsPerBlock-1)) + random.nextInt(100);
     int lowFreqCutoff = TestUtil.nextInt(random, 2, 100);
 
+    maxPointsInLeafNode = TestUtil.nextInt(random, 16, 2048);
+    maxMBSortInHeap = 4.0 + (3*random.nextDouble());
+
     add(avoidCodecs,
         TestUtil.getDefaultPostingsFormat(minItemsPerBlock, maxItemsPerBlock),
         new FSTPostingsFormat(),
@@ -184,6 +216,9 @@ public class RandomCodec extends AssertingCodec {
 
   @Override
   public String toString() {
-    return super.toString() + ": " + previousMappings.toString() + ", docValues:" + previousDVMappings.toString();
+    return super.toString() + ": " + previousMappings.toString() +
+           ", docValues:" + previousDVMappings.toString() +
+           ", maxPointsInLeafNode=" + maxPointsInLeafNode +
+           ", maxMBSortInHeap=" + maxMBSortInHeap;
   }
 }


[02/50] [abbrv] lucene-solr git commit: SOLR-8758: Add SolrCloudTestCase base class

Posted by ho...@apache.org.
SOLR-8758: Add SolrCloudTestCase base class


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/9a3458f6
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/9a3458f6
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/9a3458f6

Branch: refs/heads/jira/SOLR-445
Commit: 9a3458f69328045a8c62acc826f3012edeb154c6
Parents: a0e72f1
Author: Alan Woodward <ro...@apache.org>
Authored: Mon Feb 29 18:16:36 2016 +0000
Committer: Alan Woodward <ro...@apache.org>
Committed: Mon Feb 29 18:44:27 2016 +0000

----------------------------------------------------------------------
 solr/CHANGES.txt                                |   3 +
 .../apache/solr/cloud/SolrCloudTestCase.java    | 163 +++++++++++++++++++
 2 files changed, 166 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9a3458f6/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 99ae09e..24501bb 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -340,6 +340,9 @@ Other Changes
 * SOLR-8713: new UI and example solrconfig files point to Reference Guide for Solr Query Syntax instead 
   of the wiki. (Marius Grama via Tomás Fernández Löbbe)
 
+* SOLR-8758: Add a new SolrCloudTestCase class, using MiniSolrCloudCluster (Alan
+  Woodward)
+
 ==================  5.5.1 ==================
 
 Bug Fixes

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9a3458f6/solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java b/solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java
new file mode 100644
index 0000000..615365e
--- /dev/null
+++ b/solr/test-framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java
@@ -0,0 +1,163 @@
+/*
+ * 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.solr.cloud;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.client.solrj.embedded.JettyConfig;
+import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.junit.AfterClass;
+import org.junit.Before;
+
+/**
+ * Base class for SolrCloud tests
+ *
+ * Derived tests should call {@link #configureCluster(int)} in a {@code BeforeClass}
+ * static method.  This configures and starts a {@link MiniSolrCloudCluster}, available
+ * via the {@code cluster} variable.  Cluster shutdown is handled automatically.
+ *
+ * <pre>
+ *   <code>
+ *   {@literal @}BeforeClass
+ *   public static void setupCluster() {
+ *     configureCluster(NUM_NODES)
+ *        .addConfig("configname", pathToConfig)
+ *        .configure();
+ *   }
+ *   </code>
+ * </pre>
+ */
+public class SolrCloudTestCase extends SolrTestCaseJ4 {
+
+  private static class Config {
+    final String name;
+    final Path path;
+
+    private Config(String name, Path path) {
+      this.name = name;
+      this.path = path;
+    }
+  }
+
+  /**
+   * Builder class for a MiniSolrCloudCluster
+   */
+  protected static class Builder {
+
+    private final int nodeCount;
+    private final Path baseDir;
+    private String solrxml = MiniSolrCloudCluster.DEFAULT_CLOUD_SOLR_XML;
+    private JettyConfig jettyConfig = buildJettyConfig("/solr");
+
+    private List<Config> configs = new ArrayList<>();
+
+    /**
+     * Create a builder
+     * @param nodeCount the number of nodes in the cluster
+     * @param baseDir   a base directory for the cluster
+     */
+    public Builder(int nodeCount, Path baseDir) {
+      this.nodeCount = nodeCount;
+      this.baseDir = baseDir;
+    }
+
+    /**
+     * Use a {@link JettyConfig} to configure the cluster's jetty servers
+     */
+    public Builder withJettyConfig(JettyConfig jettyConfig) {
+      this.jettyConfig = jettyConfig;
+      return this;
+    }
+
+    /**
+     * Use the provided string as solr.xml content
+     */
+    public Builder withSolrXml(String solrXml) {
+      this.solrxml = solrXml;
+      return this;
+    }
+
+    /**
+     * Read solr.xml from the provided path
+     */
+    public Builder withSolrXml(Path solrXml) {
+      try {
+        this.solrxml = new String(Files.readAllBytes(solrXml), Charset.defaultCharset());
+      } catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+      return this;
+    }
+
+    /**
+     * Upload a collection config before tests start
+     * @param configName the config name
+     * @param configPath the path to the config files
+     */
+    public Builder addConfig(String configName, Path configPath) {
+      this.configs.add(new Config(configName, configPath));
+      return this;
+    }
+
+    /**
+     * Configure and run the {@link MiniSolrCloudCluster}
+     * @throws Exception if an error occurs on startup
+     */
+    public void configure() throws Exception {
+      cluster = new MiniSolrCloudCluster(nodeCount, baseDir, solrxml, jettyConfig);
+      CloudSolrClient client = cluster.getSolrClient();
+      for (Config config : configs) {
+        client.uploadConfig(config.path, config.name);
+      }
+    }
+
+  }
+
+  /** The cluster */
+  protected static MiniSolrCloudCluster cluster;
+
+  /**
+   * Call this to configure a cluster of n nodes.
+   *
+   * NB you must call {@link Builder#configure()} to start the cluster
+   *
+   * @param nodeCount the number of nodes
+   */
+  protected static Builder configureCluster(int nodeCount) {
+    return new Builder(nodeCount, createTempDir());
+  }
+
+  @AfterClass
+  public static void shutdownCluster() throws Exception {
+    if (cluster != null)
+      cluster.shutdown();
+  }
+
+  @Before
+  public void checkClusterConfiguration() {
+    if (cluster == null)
+      throw new RuntimeException("MiniSolrCloudCluster not configured - have you called configureCluster().configure()?");
+  }
+
+}


[50/50] [abbrv] lucene-solr git commit: SOLR-445 Merge branch 'master' into jira/SOLR-445 (pick up SOLR-8738 changes)

Posted by ho...@apache.org.
SOLR-445 Merge branch 'master' into jira/SOLR-445 (pick up SOLR-8738 changes)


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/2401c949
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/2401c949
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/2401c949

Branch: refs/heads/jira/SOLR-445
Commit: 2401c9495319e1b5065b05ef3a36ee586f06b6d4
Parents: ad34d3b ff6557c
Author: Chris Hostetter <ho...@apache.org>
Authored: Tue Mar 1 10:02:27 2016 -0700
Committer: Chris Hostetter <ho...@apache.org>
Committed: Tue Mar 1 10:02:27 2016 -0700

----------------------------------------------------------------------
 .../apache/lucene/search/TestPointQueries.java  |   2 +-
 .../org/apache/lucene/document/LatLonPoint.java | 212 ++++++++++------
 .../document/LatLonPointDistanceQuery.java      | 193 +++++++++++++++
 .../document/LatLonPointInPolygonQuery.java     | 226 +++++++++++++++++
 .../org/apache/lucene/document/package.html     |   7 +-
 .../lucene/search/PointDistanceQuery.java       | 179 --------------
 .../lucene/search/PointInPolygonQuery.java      | 207 ----------------
 .../apache/lucene/document/TestLatLonPoint.java | 197 ++++++++-------
 .../document/TestLatLonPointDistanceQuery.java  | 190 ++++++++++++++
 .../lucene/search/TestLatLonPointQueries.java   |  62 ++---
 .../org/apache/lucene/spatial/package-info.java |  21 --
 .../java/org/apache/lucene/spatial/package.html |  26 ++
 .../lucene/spatial/util/package-info.java       |  21 --
 .../org/apache/lucene/spatial/util/package.html |  26 ++
 .../codecs/asserting/AssertingPointFormat.java  |  17 +-
 .../org/apache/lucene/index/RandomCodec.java    |  37 ++-
 .../java/org/apache/lucene/util/TestUtil.java   |   1 +
 solr/CHANGES.txt                                |   5 +
 .../apache/solr/cloud/rule/ReplicaAssigner.java |   9 +-
 .../processor/DistributedUpdateProcessor.java   |   2 +-
 .../solr/cloud/TestCloudDeleteByQuery.java      | 245 +++++++++++++++++++
 solr/example/files/conf/params.json             |   6 +-
 solr/example/files/conf/solrconfig.xml          |  11 +-
 23 files changed, 1241 insertions(+), 661 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2401c949/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java
----------------------------------------------------------------------


[08/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test-files/data/world-cities-points.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test-files/data/world-cities-points.txt b/lucene/spatial/src/test-files/data/world-cities-points.txt
deleted file mode 100644
index 59a7cd5..0000000
--- a/lucene/spatial/src/test-files/data/world-cities-points.txt
+++ /dev/null
@@ -1,2680 +0,0 @@
-#id	name	shape	
-G292223	Dubai	POINT(55.280000 25.252220)	
-G292672	Sharjah	POINT(55.391110 25.362220)	
-G292913	Al ‘Ayn	POINT(55.760560 24.191670)	
-G292932	`Ajmān	POINT(55.435040 25.411110)	
-G292968	Abu Dhabi	POINT(54.366670 24.466670)	
-G1133616	Mazār-e Sharīf	POINT(67.110870 36.709040)	
-G1135689	Kunduz	POINT(68.857000 36.728960)	
-G1138336	Kandahār	POINT(65.710130 31.613320)	
-G1138958	Kabul	POINT(69.172330 34.528130)	
-G1139715	Jalālābād	POINT(70.451530 34.426470)	
-G1140026	Herāt	POINT(62.199670 34.348170)	
-G3183875	Tirana	POINT(19.818890 41.327500)	
-G616052	Yerevan	POINT(44.513610 40.181110)	
-G2240449	Luanda	POINT(13.234440 -8.838330)	
-G3347939	Lobito	POINT(13.545560 -12.348060)	
-G3348313	Huambo	POINT(15.739170 -12.776110)	
-G3351663	Benguela	POINT(13.407220 -12.578330)	
-G3429577	Resistencia	POINT(-58.983330 -27.450000)	
-G3429652	Quilmes	POINT(-58.269440 -34.720280)	
-G3429886	Posadas	POINT(-55.883330 -27.383330)	
-G3430863	Mar del Plata	POINT(-57.550000 -38.000000)	
-G3432043	La Plata	POINT(-57.948890 -34.931390)	
-G3433899	Formosa	POINT(-58.183330 -26.183330)	
-G3435217	Corrientes	POINT(-58.833330 -27.466670)	
-G3435910	Buenos Aires	POINT(-58.377230 -34.613150)	
-G3835869	Santiago del Estero	POINT(-64.266670 -27.783330)	
-G3836277	Santa Fe de la Vera Cruz	POINT(-60.700000 -31.633330)	
-G3836564	San Salvador de Jujuy	POINT(-65.300000 -24.183330)	
-G3836873	San Miguel de Tucumán	POINT(-65.216670 -26.816670)	
-G3837056	San Luis	POINT(-66.350000 -33.300000)	
-G3837213	San Juan	POINT(-68.536390 -31.537500)	
-G3837702	San Fernando del Valle de Catamarca	POINT(-65.783330 -28.466670)	
-G3838233	Salta	POINT(-65.416670 -24.783330)	
-G3838583	Rosario	POINT(-60.666390 -32.951110)	
-G3838874	Río Cuarto	POINT(-64.350000 -33.133330)	
-G3841956	Paraná	POINT(-60.533330 -31.733330)	
-G3843123	Neuquén	POINT(-68.066670 -38.950000)	
-G3844421	Mendoza	POINT(-68.816670 -32.883330)	
-G3848950	La Rioja	POINT(-66.850000 -29.433330)	
-G3860259	Córdoba	POINT(-64.183330 -31.400000)	
-G3865086	Bahía Blanca	POINT(-62.283330 -38.716670)	
-G2761369	Vienna	POINT(16.372080 48.208490)	
-G2766824	Salzburg	POINT(13.043990 47.799410)	
-G2772400	Linz	POINT(14.286110 48.306390)	
-G2778067	Graz	POINT(15.450000 47.066670)	
-G7279909	Linz-Wels-Steyr	POINT(14.183690 48.154580)	
-G2063523	Perth	POINT(115.833330 -31.933330)	
-G2078025	Adelaide	POINT(138.600000 -34.933330)	
-G2147714	Sydney	POINT(151.207320 -33.867850)	
-G2155472	Newcastle	POINT(151.776470 -32.927150)	
-G2158177	Melbourne	POINT(144.963320 -37.814000)	
-G2165087	Gold Coast	POINT(153.433330 -28.000000)	
-G2165796	Geelong West	POINT(144.350000 -38.133330)	
-G2165798	Geelong	POINT(144.360690 -38.147110)	
-G2171507	Wollongong	POINT(150.883330 -34.433330)	
-G2172517	Canberra	POINT(149.128070 -35.283460)	
-G2172797	Cairns	POINT(145.766670 -16.916670)	
-G2174003	Brisbane	POINT(153.028090 -27.467940)	
-G7280463	North Shore	POINT(152.901850 -31.402370)	
-G7281838	Logan City	POINT(153.109440 -27.639170)	
-G584923	Sumqayıt	POINT(49.668610 40.589720)	
-G586523	Kirowabad	POINT(46.360560 40.682780)	
-G587084	Baku	POINT(49.892010 40.377670)	
-G3186573	Zenica	POINT(17.906390 44.201390)	
-G3191281	Sarajevo	POINT(18.356440 43.848640)	
-G3204541	Banja Luka	POINT(17.185560 44.775830)	
-G1185098	Tungi	POINT(90.405830 23.890000)	
-G1185099	Sylhet	POINT(91.871670 24.896670)	
-G1185106	Jamālpur	POINT(89.933330 24.916670)	
-G1185117	Narsingdi	POINT(90.718060 23.920830)	
-G1185128	Rājshāhi	POINT(88.600000 24.366670)	
-G1185155	Nārāyanganj	POINT(90.501110 23.623330)	
-G1185162	Mymensingh	POINT(90.400000 24.750000)	
-G1185186	Comilla	POINT(91.204440 23.457780)	
-G1185188	Rangpur	POINT(89.250000 25.750000)	
-G1185241	Dhaka	POINT(90.407440 23.710400)	
-G1192366	Pār Naogaon	POINT(88.950840 24.802870)	
-G1203891	Dinājpur	POINT(88.638640 25.627150)	
-G1205733	Chittagong	POINT(91.836390 22.333060)	
-G1336134	Cox’s Bāzār	POINT(91.979770 21.453240)	
-G1336135	Khulna	POINT(89.567230 22.813480)	
-G1336137	Barisāl	POINT(90.371110 22.701940)	
-G1336140	Jessore	POINT(89.213150 23.168690)	
-G1336144	Tāngāil	POINT(89.916670 24.250000)	
-G1337233	Bogra	POINT(89.366670 24.850000)	
-G6545349	Saidpur	POINT(88.891690 25.777690)	
-G2792413	Liège	POINT(5.567490 50.633730)	
-G2797656	Gent	POINT(3.716670 51.050000)	
-G2800481	Charleroi	POINT(4.452480 50.409470)	
-G2800866	Brussels	POINT(4.348780 50.850450)	
-G2803138	Antwerpen	POINT(4.403460 51.219890)	
-G2357048	Ouagadougou	POINT(-1.538340 12.364230)	
-G2362344	Bobo-Dioulasso	POINT(-4.297900 11.177150)	
-G726050	Varna	POINT(27.916670 43.216670)	
-G727011	Sofia	POINT(23.324150 42.697510)	
-G727523	Ruse	POINT(25.970830 43.856390)	
-G728193	Plovdiv	POINT(24.750000 42.150000)	
-G732770	Burgas	POINT(27.467810 42.506060)	
-G425378	Bujumbura	POINT(29.364400 -3.382200)	
-G2392087	Porto-Novo	POINT(2.603590 6.496460)	
-G2392204	Parakou	POINT(2.616670 9.350000)	
-G2394560	Djougou	POINT(1.666940 9.705000)	
-G2394819	Cotonou	POINT(2.433330 6.350000)	
-G2395914	Abomey-Calavi	POINT(2.350000 6.450000)	
-G3903320	Tarija	POINT(-64.729560 -21.535490)	
-G3903987	Sucre	POINT(-65.262740 -19.033320)	
-G3904906	Santa Cruz de la Sierra	POINT(-63.166670 -17.800000)	
-G3909234	Oruro	POINT(-67.150000 -17.983330)	
-G3911925	La Paz	POINT(-68.150000 -16.500000)	
-G3919968	Cochabamba	POINT(-66.156800 -17.389500)	
-G3386496	Teresina	POINT(-42.801940 -5.089170)	
-G3387296	Sobral	POINT(-40.349720 -3.686110)	
-G3388368	São Luís	POINT(-44.302780 -2.529720)	
-G3389353	Santarém	POINT(-54.708330 -2.443060)	
-G3390760	Recife	POINT(-34.881110 -8.053890)	
-G3392242	Petrolina	POINT(-40.500830 -9.398610)	
-G3392740	Paulista	POINT(-34.873060 -7.940830)	
-G3392998	Parnamirim	POINT(-35.262780 -5.915560)	
-G3393536	Olinda	POINT(-34.855280 -8.008890)	
-G3394023	Natal	POINT(-35.209440 -5.795000)	
-G3394682	Mossoró	POINT(-37.344170 -5.187500)	
-G3395473	Maracanaú	POINT(-38.625560 -3.876670)	
-G3395981	Maceió	POINT(-35.735280 -9.665830)	
-G3396016	Macapá	POINT(-51.066390 0.038890)	
-G3397147	Juazeiro do Norte	POINT(-39.315280 -7.213060)	
-G3397277	João Pessoa	POINT(-34.863060 -7.115000)	
-G3397838	Jaboatão	POINT(-35.001390 -8.180280)	
-G3398269	Imperatriz	POINT(-47.491670 -5.526390)	
-G3399415	Fortaleza	POINT(-38.543060 -3.717220)	
-G3402429	Caucaia	POINT(-38.653060 -3.736110)	
-G3402655	Caruaru	POINT(-35.976110 -8.283330)	
-G3403642	Campina Grande	POINT(-35.881110 -7.230560)	
-G3405870	Belém	POINT(-48.504440 -1.455830)	
-G3407327	Arapiraca	POINT(-36.661110 -9.752500)	
-G3407669	Ananindeua	POINT(-48.372220 -1.365560)	
-G3444876	Volta Redonda	POINT(-44.104170 -22.523060)	
-G3444914	Vitória da Conquista	POINT(-40.839440 -14.866110)	
-G3444924	Vitória	POINT(-40.337780 -20.319440)	
-G3445026	Vila Velha	POINT(-40.292500 -20.329720)	
-G3445156	Viamão	POINT(-51.023330 -30.081110)	
-G3445451	Várzea Grande	POINT(-56.132500 -15.646670)	
-G3445831	Uberlândia	POINT(-48.277220 -18.918610)	
-G3445839	Uberaba	POINT(-47.931940 -19.748330)	
-G3446682	Taubaté	POINT(-45.555280 -23.026390)	
-G3447186	Taboão da Serra	POINT(-46.791670 -23.626110)	
-G3447212	Suzano	POINT(-46.310830 -23.542500)	
-G3447259	Sumaré	POINT(-47.266940 -22.821940)	
-G3447399	Sorocaba	POINT(-47.458060 -23.501670)	
-G3447624	Sete Lagoas	POINT(-44.246670 -19.465830)	
-G3447779	Serra	POINT(-40.307780 -20.128610)	
-G3448136	São Vicente	POINT(-46.391940 -23.963060)	
-G3448439	São Paulo	POINT(-46.636110 -23.547500)	
-G3448622	São Leopoldo	POINT(-51.147220 -29.760280)	
-G3448636	São José dos Campos	POINT(-45.886940 -23.179440)	
-G3448639	São José do Rio Preto	POINT(-49.379440 -20.819720)	
-G3448742	São José	POINT(-49.166670 -28.233330)	
-G3448877	São João de Meriti	POINT(-43.372220 -22.803890)	
-G3449319	São Carlos	POINT(-47.890830 -22.017500)	
-G3449344	São Bernardo do Campo	POINT(-46.565000 -23.693890)	
-G3449433	Santos	POINT(-46.333610 -23.960830)	
-G3449701	Santo André	POINT(-46.538330 -23.663890)	
-G3450083	Santa Maria	POINT(-53.806940 -29.684170)	
-G3450144	Santa Luzia	POINT(-43.851390 -19.769720)	
-G3450404	Santa Bárbara d'Oeste	POINT(-47.413610 -22.753610)	
-G3450554	Salvador	POINT(-38.510830 -12.971110)	
-G3450909	Rondonópolis	POINT(-54.635560 -16.470830)	
-G3451138	Rio Grande	POINT(-52.098610 -32.035000)	
-G3451190	Rio de Janeiro	POINT(-43.207500 -22.902780)	
-G3451234	Rio Claro	POINT(-47.561390 -22.411390)	
-G3451328	Ribeirão Preto	POINT(-47.810280 -21.177500)	
-G3451353	Ribeirão das Neves	POINT(-44.086670 -19.766940)	
-G3452324	Presidente Prudente	POINT(-51.388890 -22.125560)	
-G3452465	Praia Grande	POINT(-46.402780 -24.005830)	
-G3452925	Porto Alegre	POINT(-51.230000 -30.033060)	
-G3453186	Ponta Grossa	POINT(-50.161940 -25.095000)	
-G3453643	Piracicaba	POINT(-47.649170 -22.725280)	
-G3454031	Petrópolis	POINT(-43.178610 -22.505000)	
-G3454244	Pelotas	POINT(-52.342500 -31.771940)	
-G3454857	Passo Fundo	POINT(-52.406670 -28.262780)	
-G3455775	Osasco	POINT(-46.791670 -23.532500)	
-G3456068	Novo Hamburgo	POINT(-51.130560 -29.678330)	
-G3456160	Nova Iguaçu	POINT(-43.451110 -22.759170)	
-G3456166	Nova Friburgo	POINT(-42.531110 -22.281940)	
-G3456223	Nossa Senhora do Socorro	POINT(-37.126110 -10.855000)	
-G3456283	Niterói	POINT(-43.103610 -22.883330)	
-G3456814	Montes Claros	POINT(-43.861670 -16.735000)	
-G3457001	Mogi das Cruzes	POINT(-46.188330 -23.522780)	
-G3457381	Mauá	POINT(-46.461390 -23.667780)	
-G3457671	Maringá	POINT(-51.938610 -23.425280)	
-G3457692	Marília	POINT(-49.945830 -22.213890)	
-G3458449	Londrina	POINT(-51.162780 -23.310280)	
-G3458575	Limeira	POINT(-47.401670 -22.564720)	
-G3458930	Lages	POINT(-50.326110 -27.816110)	
-G3459462	Jundiaí	POINT(-46.884170 -23.186390)	
-G3459505	Juiz de Fora	POINT(-43.350280 -21.764170)	
-G3459712	Joinville	POINT(-48.845560 -26.304440)	
-G3460370	Jacareí	POINT(-45.965830 -23.305280)	
-G3460644	Itaquaquecetuba	POINT(-46.348330 -23.486110)	
-G3460718	Itapevi	POINT(-46.934170 -23.548890)	
-G3460748	Itapecerica da Serra	POINT(-46.849170 -23.716940)	
-G3460845	Itajaí	POINT(-48.661940 -26.907780)	
-G3460949	Itabuna	POINT(-39.280280 -14.785560)	
-G3460950	Itaboraí	POINT(-42.859440 -22.744440)	
-G3461144	Ipatinga	POINT(-42.536670 -19.468330)	
-G3461311	Indaiatuba	POINT(-47.218060 -23.090280)	
-G3461408	Ilhéus	POINT(-39.049440 -14.788890)	
-G3461655	Hortolândia	POINT(-47.220000 -22.858330)	
-G3461786	Guarulhos	POINT(-46.533330 -23.462780)	
-G3461789	Guarujá	POINT(-46.256390 -23.993060)	
-G3461879	Guarapuava	POINT(-51.458060 -25.395280)	
-G3462089	Gravataí	POINT(-50.991940 -29.944440)	
-G3462315	Governador Valadares	POINT(-41.949440 -18.851110)	
-G3462377	Goiânia	POINT(-49.253890 -16.678610)	
-G3462980	Francisco Morato	POINT(-46.745280 -23.281670)	
-G3463011	Franca	POINT(-47.400830 -20.538610)	
-G3463030	Foz do Iguaçu	POINT(-54.588060 -25.547780)	
-G3463237	Florianópolis	POINT(-48.549170 -27.596670)	
-G3463422	Ferraz de Vasconcelos	POINT(-46.368610 -23.540830)	
-G3463478	Feira de Santana	POINT(-38.966670 -12.266670)	
-G3464305	Embu	POINT(-46.852220 -23.648890)	
-G3464374	Duque de Caxias	POINT(-43.311670 -22.785560)	
-G3464460	Dourados	POINT(-54.805560 -22.221110)	
-G3464688	Divinópolis	POINT(-44.883890 -20.138890)	
-G3464739	Diadema	POINT(-46.622780 -23.686110)	
-G3464975	Curitiba	POINT(-49.273060 -25.427780)	
-G3465038	Cuiabá	POINT(-56.096670 -15.596110)	
-G3465196	Criciúma	POINT(-49.369720 -28.677500)	
-G3465284	Cotia	POINT(-46.919170 -23.603890)	
-G3465624	Contagem	POINT(-44.053610 -19.931670)	
-G3465927	Colombo	POINT(-49.224170 -25.291670)	
-G3466296	Chapecó	POINT(-52.618330 -27.096390)	
-G3466537	Caxias do Sul	POINT(-51.179440 -29.168060)	
-G3466779	Cascavel	POINT(-53.455280 -24.955830)	
-G3466998	Carapicuíba	POINT(-46.835560 -23.522500)	
-G3467467	Canoas	POINT(-51.183610 -29.917780)	
-G3467693	Campos	POINT(-41.300000 -21.750000)	
-G3467747	Campo Grande	POINT(-54.646390 -20.442780)	
-G3467865	Campinas	POINT(-47.060830 -22.905560)	
-G3468031	Camaçari	POINT(-38.324170 -12.697500)	
-G3468376	Cachoeiro de Itapemirim	POINT(-41.112780 -20.848890)	
-G3469058	Brasília	POINT(-47.929720 -15.779720)	
-G3469968	Blumenau	POINT(-49.066110 -26.919440)	
-G3470044	Betim	POINT(-44.198330 -19.967780)	
-G3470127	Belo Horizonte	POINT(-43.937780 -19.920830)	
-G3470142	Belford Roxo	POINT(-43.399440 -22.764170)	
-G3470279	Bauru	POINT(-49.060560 -22.314720)	
-G3470353	Barueri	POINT(-46.876110 -23.510560)	
-G3470583	Barreiras	POINT(-44.990000 -12.152780)	
-G3470636	Barra Mansa	POINT(-44.171390 -22.544170)	
-G3471766	Araraquara	POINT(-48.175560 -21.794440)	
-G3471859	Araçatuba	POINT(-50.432780 -21.208890)	
-G3471872	Aracaju	POINT(-37.071670 -10.911110)	
-G3472177	Angra dos Reis	POINT(-44.318060 -23.006670)	
-G3472287	Anápolis	POINT(-48.952780 -16.326670)	
-G3472343	Americana	POINT(-47.331390 -22.739170)	
-G3474574	Palmas	POINT(-48.360280 -10.212780)	
-G3662574	Rio Branco	POINT(-67.810000 -9.974720)	
-G3662762	Porto Velho	POINT(-63.903890 -8.761940)	
-G3663517	Manaus	POINT(-60.025000 -3.101940)	
-G3664980	Boa Vista	POINT(-60.673330 2.819720)	
-G6316406	Aparecida de Goiânia	POINT(-49.243890 -16.823330)	
-G6317344	Jaboatão dos Guararapes	POINT(-35.014720 -8.112780)	
-G3571824	Nassau	POINT(-77.343060 25.058230)	
-G933773	Gaborone	POINT(25.908590 -24.654510)	
-G620127	Vitsyebsk	POINT(30.194440 55.192500)	
-G625144	Minsk	POINT(27.566670 53.900000)	
-G625665	Mahilyow	POINT(30.336390 53.913890)	
-G627904	Hrodna	POINT(23.814720 53.681390)	
-G627907	Homyel’	POINT(30.983330 52.441670)	
-G629634	Brest	POINT(23.700000 52.100000)	
-G630429	Baranavichy	POINT(26.033330 53.133330)	
-G630468	Babruysk	POINT(29.233330 53.150000)	
-G5881791	Abbotsford	POINT(-122.252570 49.057980)	
-G5894171	Barrie	POINT(-79.666340 44.400110)	
-G5907364	Brampton	POINT(-79.766330 43.683410)	
-G5911592	Burlington	POINT(-79.837130 43.386210)	
-G5911606	Burnaby	POINT(-122.952630 49.266360)	
-G5913490	Calgary	POINT(-114.085290 51.050110)	
-G5946768	Edmonton	POINT(-113.468710 53.550140)	
-G5959974	Gatineau	POINT(-75.701640 45.477230)	
-G5964700	Greater Sudbury	POINT(-80.990010 46.490000)	
-G5969785	Hamilton	POINT(-79.949640 43.233410)	
-G5992996	Kitchener	POINT(-80.482990 43.450100)	
-G6050610	Laval	POINT(-73.692000 45.569950)	
-G6058560	London	POINT(-81.233040 42.983390)	
-G6059891	Longueuil	POINT(-73.518060 45.531210)	
-G6075357	Mississauga	POINT(-79.658300 43.578900)	
-G6077243	Montréal	POINT(-73.587810 45.508840)	
-G6091104	North York	POINT(-79.416300 43.766810)	
-G6094578	Oshawa	POINT(-78.849570 43.900120)	
-G6094817	Ottawa	POINT(-75.698120 45.411170)	
-G6119109	Regina	POINT(-104.617800 50.450080)	
-G6122085	Richmond	POINT(-123.136830 49.170030)	
-G6141256	Saskatoon	POINT(-106.634520 52.116790)	
-G6159905	Surrey	POINT(-122.825090 49.106350)	
-G6167865	Toronto	POINT(-79.416300 43.700110)	
-G6173331	Vancouver	POINT(-123.119340 49.249660)	
-G6173577	Vaughan	POINT(-79.532910 43.833410)	
-G6174041	Victoria	POINT(-123.369300 48.432940)	
-G6182962	Windsor	POINT(-83.016540 42.300080)	
-G6183235	Winnipeg	POINT(-97.147040 49.884400)	
-G6324729	Halifax	POINT(-63.572390 44.645330)	
-G6325494	Québec	POINT(-71.214540 46.812280)	
-G7602078	Ladner	POINT(-123.082410 49.089380)	
-G204405	Uvira	POINT(29.145830 -3.406670)	
-G204953	Tshikapa	POINT(20.800000 -6.416670)	
-G207570	Mwene-Ditu	POINT(23.450000 -7.000000)	
-G209228	Mbuji-Mayi	POINT(23.600000 -6.150000)	
-G212730	Kisangani	POINT(25.200000 0.516670)	
-G214481	Kananga	POINT(22.417780 -5.895830)	
-G216449	Gandajika	POINT(23.950000 -6.750000)	
-G217562	Butembo	POINT(29.283330 0.150000)	
-G217831	Bukavu	POINT(28.860830 -2.508330)	
-G922704	Lubumbashi	POINT(27.466670 -11.666670)	
-G922741	Likasi	POINT(26.733330 -10.981390)	
-G922773	Kolwezi	POINT(25.472500 -10.716670)	
-G2312895	Mbandaka	POINT(18.266670 0.066670)	
-G2313002	Matadi	POINT(13.450000 -5.816670)	
-G2314302	Kinshasa	POINT(15.321460 -4.324590)	
-G2314705	Kikwit	POINT(18.818060 -5.038610)	
-G2593460	Masina	POINT(15.391390 -4.383610)	
-G2389853	Bangui	POINT(18.554960 4.361220)	
-G2255414	Pointe-Noire	POINT(11.846110 -4.794720)	
-G2260535	Brazzaville	POINT(15.283270 -4.266900)	
-G2657896	Zürich	POINT(8.550000 47.366670)	
-G2660646	Genève	POINT(6.145690 46.202220)	
-G2661604	Basel	POINT(7.600000 47.566670)	
-G2279755	Yamoussoukro	POINT(-5.283330 6.816670)	
-G2282006	San-Pédro	POINT(-6.616670 4.733330)	
-G2286304	Korhogo	POINT(-5.633330 9.450000)	
-G2290486	Daloa	POINT(-6.451940 6.874720)	
-G2290956	Bouaké	POINT(-5.033060 7.683330)	
-G2293521	Abobo	POINT(-4.020560 5.418890)	
-G2293538	Abidjan	POINT(-4.028060 5.341110)	
-G3868121	Viña del Mar	POINT(-71.551830 -33.024570)	
-G3868626	Valparaíso	POINT(-71.627250 -33.039320)	
-G3870011	Temuco	POINT(-72.600000 -38.733330)	
-G3870282	Talcahuano	POINT(-73.116670 -36.716670)	
-G3870294	Talca	POINT(-71.666670 -35.433330)	
-G3871336	Santiago	POINT(-70.566560 -33.426280)	
-G3872348	San Bernardo	POINT(-70.716670 -33.600000)	
-G3873775	Rancagua	POINT(-70.744440 -34.170830)	
-G3874960	Puerto Montt	POINT(-72.936940 -41.471670)	
-G3875024	Puente Alto	POINT(-70.583330 -33.616670)	
-G3884373	La Serena	POINT(-71.254170 -29.907780)	
-G3887127	Iquique	POINT(-70.143060 -20.220830)	
-G3893629	Coquimbo	POINT(-71.343610 -29.953330)	
-G3893894	Concepción	POINT(-73.049770 -36.826990)	
-G3895088	Chillán	POINT(-72.103440 -36.606640)	
-G3899361	Arica	POINT(-70.304170 -18.475000)	
-G3899539	Antofagasta	POINT(-70.400000 -23.650000)	
-G7281017	La Pintana	POINT(-70.634190 -33.583310)	
-G2220957	Yaoundé	POINT(11.516670 3.866670)	
-G2224827	Ngaoundéré	POINT(13.583330 7.316670)	
-G2226275	Mokolo	POINT(13.801880 10.739780)	
-G2228373	Maroua	POINT(14.315920 10.590950)	
-G2229152	Loum	POINT(9.735100 4.718200)	
-G2229798	Kousséri	POINT(15.030630 12.076890)	
-G2231320	Garoua	POINT(13.400000 9.300000)	
-G2232239	Edéa	POINT(10.133330 3.800000)	
-G2232593	Douala	POINT(9.708400 4.046900)	
-G2234359	Bertoua	POINT(13.683330 4.583330)	
-G2234974	Bamenda	POINT(10.158240 5.952660)	
-G2235189	Bafoussam	POINT(10.417860 5.473660)	
-G1280849	Kashi	POINT(75.979720 39.454720)	
-G1529102	Urunchi	POINT(87.583330 43.800000)	
-G1529114	Turpan	POINT(89.166670 42.933330)	
-G1529195	Shihezi	POINT(86.033330 44.300000)	
-G1529376	Korla	POINT(86.146940 41.759720)	
-G1529569	Changji	POINT(87.316670 44.016670)	
-G1529641	Aral	POINT(81.263610 40.515560)	
-G1529660	Aksu	POINT(80.264440 41.123060)	
-G1783621	Zunyi	POINT(106.907220 27.686670)	
-G1783633	Zoucheng	POINT(116.965560 35.400560)	
-G1783745	Zigong	POINT(104.776890 29.341620)	
-G1783763	Zhuzhou	POINT(113.150000 27.833330)	
-G1783873	Zhumadian	POINT(114.029440 32.979440)	
-G1783934	Shangqiu	POINT(115.650000 34.450000)	
-G1784130	Zhoukou	POINT(114.633330 33.633330)	
-G1784554	Zhicheng	POINT(111.504720 30.295560)	
-G1784580	Yizheng	POINT(119.178890 32.269170)	
-G1784642	Zhenjiang	POINT(119.434170 32.209170)	
-G1784658	Zhengzhou	POINT(113.648610 34.757780)	
-G1784853	Zhaoqing	POINT(112.459720 23.051160)	
-G1784990	Zhanjiang	POINT(110.342710 21.281450)	
-G1785018	Zhangzhou	POINT(117.655560 24.513330)	
-G1785286	Zibo	POINT(118.063330 36.790560)	
-G1785294	Anyang	POINT(114.328890 36.099440)	
-G1785453	Zaozhuang	POINT(117.554170 34.864720)	
-G1785462	Zaoyang	POINT(112.754170 32.127220)	
-G1785725	Yunfu	POINT(112.037300 22.930560)	
-G1785738	Yuncheng	POINT(110.992780 35.023060)	
-G1785974	Yuci	POINT(112.731940 37.680280)	
-G1786067	Yuanlin	POINT(112.885950 30.415130)	
-G1786640	Yingcheng	POINT(113.550000 30.950000)	
-G1786657	Yinchuan	POINT(106.273060 38.468060)	
-G1786746	Yichun	POINT(114.400000 27.833330)	
-G1786764	Yichang	POINT(111.284720 30.714440)	
-G1786770	Yibin	POINT(104.623830 28.766670)	
-G1787093	Yantai	POINT(121.400000 37.533330)	
-G1787227	Yangzhou	POINT(119.435830 32.397220)	
-G1787323	Yangshuo	POINT(110.489670 24.780810)	
-G1787351	Yangquan	POINT(113.563330 37.857500)	
-G1787746	Yancheng	POINT(120.125280 33.385560)	
-G1787824	Tongshan	POINT(117.157070 34.180450)	
-G1787858	Xuri	POINT(117.966670 28.466670)	
-G1788046	Xuchang	POINT(113.816670 34.016670)	
-G1788450	Xinzhou	POINT(112.733330 38.409170)	
-G1788534	Xinyang	POINT(114.065560 32.122780)	
-G1788572	Xinxiang	POINT(113.867220 35.308890)	
-G1788618	Xintai	POINT(117.751940 35.900560)	
-G1788694	Xinpu	POINT(119.159440 34.599720)	
-G1788852	Xining	POINT(101.766670 36.616670)	
-G1788927	Xingtai	POINT(114.494170 37.063060)	
-G1789137	Xindi	POINT(113.466670 29.816670)	
-G1789273	Sanshui	POINT(112.891610 23.154860)	
-G1790254	Xiaogan	POINT(113.900000 30.916670)	
-G1790353	Xianyang	POINT(108.702610 34.337780)	
-G1790371	Xiantao	POINT(113.400000 30.383330)	
-G1790396	Xianning	POINT(114.216670 29.883330)	
-G1790437	Zhuhai	POINT(113.567780 22.276940)	
-G1790492	Xiangtan	POINT(112.900000 27.850000)	
-G1790587	Xiangfan	POINT(112.145000 32.041670)	
-G1790630	Xi’an	POINT(108.928610 34.258330)	
-G1790645	Xiamen	POINT(118.081870 24.479790)	
-G1790840	Wuzhou	POINT(111.316670 23.483330)	
-G1790894	Wuxue	POINT(115.552500 29.850580)	
-G1790923	Wuxi	POINT(120.288570 31.568870)	
-G1791121	Changde	POINT(111.678060 29.032220)	
-G1791236	Wuhu	POINT(118.375480 31.336570)	
-G1791247	Wuhan	POINT(114.266670 30.583330)	
-G1791249	Wuhai	POINT(106.812220 39.664720)	
-G1791388	Wenzhou	POINT(120.666820 27.999420)	
-G1791636	Weinan	POINT(109.508910 34.503550)	
-G1791673	Weihai	POINT(122.113610 37.501670)	
-G1791681	Weifang	POINT(119.101940 36.710000)	
-G1791748	Wanxian	POINT(108.389720 30.803890)	
-G1792260	Wafangdian	POINT(122.008060 39.618330)	
-G1792520	Tongzhou	POINT(116.599440 39.905280)	
-G1792621	Wusong	POINT(117.783330 30.950000)	
-G1792947	Tianjin	POINT(117.176670 39.142220)	
-G1793346	Tangshan	POINT(118.183330 39.633330)	
-G1793424	Tanggu	POINT(117.646940 39.021110)	
-G1793505	Taizhou	POINT(119.910630 32.493330)	
-G1793511	Taiyuan	POINT(112.560280 37.869440)	
-G1793724	Tai’an	POINT(117.120000 36.185280)	
-G1793743	Suzhou	POINT(116.978890 33.636110)	
-G1793879	Suizhou	POINT(113.363060 31.711110)	
-G1794903	Shiyan	POINT(110.778060 32.647500)	
-G1794904	Shiyan	POINT(110.783330 32.566670)	
-G1795060	Shiqi	POINT(113.385210 22.516820)	
-G1795196	Tongchuan	POINT(109.089720 35.080560)	
-G1795270	Shijiazhuang	POINT(114.478610 38.041390)	
-G1795565	Shenzhen	POINT(114.068300 22.545540)	
-G1795816	Shashi	POINT(112.244720 30.307220)	
-G1795855	Shaoxing	POINT(120.581110 30.001670)	
-G1795874	Shaoguan	POINT(113.583330 24.800000)	
-G1795928	Shanwei	POINT(115.347500 22.781990)	
-G1795940	Shantou	POINT(116.714790 23.368140)	
-G1796236	Shanghai	POINT(121.458060 31.222220)	
-G1796663	Sanming	POINT(117.618610 26.248610)	
-G1797121	Jieyang	POINT(116.364160 23.528860)	
-G1797132	Rizhao	POINT(119.455280 35.427500)	
-G1797353	Quanzhou	POINT(118.585830 24.913890)	
-G1797595	Qinhuangdao	POINT(119.588330 39.931670)	
-G1797873	Huaiyin	POINT(119.019170 33.588610)	
-G1797929	Qingdao	POINT(120.371940 36.098610)	
-G1797945	Qingyuan	POINT(113.033330 23.700000)	
-G1798422	Puyang	POINT(115.005280 35.702780)	
-G1798425	Puyang	POINT(119.886110 29.460280)	
-G1798449	Putian	POINT(119.010280 25.439440)	
-G1798654	Pingxiang	POINT(113.850000 27.616670)	
-G1798827	Pingdingshan	POINT(113.301190 33.738470)	
-G1798998	Dadukou	POINT(101.705390 26.547900)	
-G1799397	Ningbo	POINT(121.549450 29.878190)	
-G1799491	Neijiang	POINT(105.062160 29.583540)	
-G1799629	Nanyang	POINT(112.532780 32.994720)	
-G1799722	Nantong	POINT(120.874720 32.030280)	
-G1799846	Nanping	POINT(118.173610 26.645000)	
-G1799869	Nanning	POINT(108.316670 22.816670)	
-G1799962	Nanjing	POINT(118.777780 32.061670)	
-G1800146	Nanchong	POINT(106.084740 30.795080)	
-G1800163	Nanchang	POINT(115.883330 28.683330)	
-G1800627	Mianyang	POINT(104.754240 31.459340)	
-G1800657	Mentougou	POINT(116.091670 39.939170)	
-G1801757	Luqiao	POINT(121.377150 28.580840)	
-G1801792	Luoyang	POINT(112.453610 34.683610)	
-G1801934	Luohe	POINT(114.035280 33.571670)	
-G1802204	Luancheng	POINT(114.651670 37.879170)	
-G1802238	Loudi	POINT(111.994440 27.734440)	
-G1802875	Liuyang	POINT(113.633330 28.150000)	
-G1803318	Linyi	POINT(118.342780 35.063060)	
-G1803331	Linxia	POINT(103.206390 35.600280)	
-G1803422	Linhai	POINT(121.116670 28.850000)	
-G1803567	Linfen	POINT(111.518890 36.088890)	
-G1803791	Licheng	POINT(113.828360 23.295540)	
-G1803834	Liaocheng	POINT(115.964720 36.443890)	
-G1804153	Leshan	POINT(103.763860 29.562280)	
-G1804386	Laohekou	POINT(111.667780 32.385830)	
-G1804430	Lanzhou	POINT(103.792220 36.056390)	
-G1804540	Langfang	POINT(116.694720 39.509720)	
-G1804586	Laiyang	POINT(120.713610 36.975830)	
-G1804651	Kunming	POINT(102.718330 25.038890)	
-G1804850	Kaiyuan	POINT(103.303720 23.697670)	
-G1804879	Kaifeng	POINT(114.348330 34.791110)	
-G1805179	Jiujiang	POINT(115.983330 29.733330)	
-G1805298	Jinzhou	POINT(121.716670 39.100000)	
-G1805518	Jining	POINT(116.581390 35.405000)	
-G1805540	Jingzhou	POINT(112.190280 30.350280)	
-G1805611	Jingmen	POINT(112.204720 31.033610)	
-G1805618	Jingling	POINT(113.100000 30.650000)	
-G1805680	Jingdezhen	POINT(117.207890 29.294700)	
-G1805741	Jincheng	POINT(112.832780 35.502220)	
-G1805753	Jinan	POINT(116.997220 36.668330)	
-G1805953	Jiaxing	POINT(120.748330 30.765560)	
-G1805987	Jiaozuo	POINT(113.233060 35.239720)	
-G1806096	Jiaozhou	POINT(120.003330 36.283890)	
-G1806299	Jiangmen	POINT(113.083330 22.583330)	
-G1806408	Yangjiang	POINT(111.966670 21.850000)	
-G1806445	Ji’an	POINT(114.979270 27.117160)	
-G1806466	Guangyuan	POINT(105.823000 32.442020)	
-G1806535	Huzhou	POINT(120.096390 30.866110)	
-G1806696	Humen	POINT(113.673060 22.818980)	
-G1806776	Huizhou	POINT(114.400000 23.083330)	
-G1806882	Xinhui	POINT(113.048200 22.456000)	
-G1807143	Huangyan	POINT(121.259440 28.647780)	
-G1807234	Huangshi	POINT(115.100000 30.216670)	
-G1807508	Huanggang	POINT(116.999610 23.677040)	
-G1807681	Huainan	POINT(116.996940 32.626390)	
-G1807700	Huaibei	POINT(116.791670 33.974440)	
-G1808198	Heze	POINT(115.441110 35.243060)	
-G1808316	Yiyang	POINT(112.328330 28.589170)	
-G1808370	Hengyang	POINT(112.615000 26.888060)	
-G1808392	Hengshui	POINT(115.701110 37.732220)	
-G1808722	Hefei	POINT(117.280830 31.863890)	
-G1808770	Hebi	POINT(114.192500 35.899170)	
-G1808926	Hangzhou	POINT(120.168890 30.255280)	
-G1808931	Hangu	POINT(117.789170 39.248890)	
-G1808963	Handan	POINT(114.467780 36.600560)	
-G1809061	Jiaojiang	POINT(121.442780 28.680280)	
-G1809078	Haikou	POINT(110.341670 20.045830)	
-G1809412	Guli	POINT(120.033330 28.883330)	
-G1809461	Guiyang	POINT(106.716670 26.583330)	
-G1809498	Guilin	POINT(110.286390 25.281940)	
-G1809858	Guangzhou	POINT(113.250000 23.116670)	
-G1809879	Guangshui	POINT(113.997800 31.619900)	
-G1810295	Gaozhou	POINT(110.846070 21.939240)	
-G1810437	Gaoping	POINT(106.102940 30.775760)	
-G1810458	Gaomi	POINT(119.752780 36.383330)	
-G1810821	Fuzhou	POINT(119.306110 26.061390)	
-G1810845	Fuyang	POINT(115.816670 32.900000)	
-G1810979	Fuling	POINT(107.391940 29.702220)	
-G1811103	Foshan	POINT(113.131480 23.026770)	
-G1811619	Ezhou	POINT(114.833330 30.400000)	
-G1812101	Dongying	POINT(118.485560 37.456390)	
-G1812521	Donghai	POINT(115.642040 22.945940)	
-G1812545	Dongguan	POINT(113.744720 23.048890)	
-G1812728	Dingzhou	POINT(114.995560 38.513060)	
-G1812955	Dezhou	POINT(116.292500 37.448610)	
-G1812961	Deyang	POINT(104.381980 31.130190)	
-G1813253	Dayan	POINT(100.220720 26.868790)	
-G1814082	Daliang	POINT(113.247010 22.850420)	
-G1814087	Dalian	POINT(121.602220 38.912220)	
-G1814757	Chuzhou	POINT(118.297780 32.321940)	
-G1814786	Yangchun	POINT(111.783330 22.166670)	
-G1814906	Chongqing	POINT(106.552780 29.562780)	
-G1815059	Chenzhou	POINT(113.033330 25.800000)	
-G1815286	Chengdu	POINT(104.066670 30.666670)	
-G1815302	Chenghua	POINT(116.770070 23.461320)	
-G1815395	Chaozhou	POINT(116.637860 23.665130)	
-G1815456	Changzhou	POINT(119.966670 31.783330)	
-G1815463	Changzhi	POINT(111.738610 35.208890)	
-G1815577	Changsha	POINT(112.966670 28.200000)	
-G1816080	Cangzhou	POINT(116.866670 38.316670)	
-G1816234	Bozhou	POINT(115.770280 33.877220)	
-G1816265	Boshan	POINT(117.833330 36.483330)	
-G1816440	Bengbu	POINT(117.360830 32.940830)	
-G1816670	Beijing	POINT(116.397230 39.907500)	
-G1816705	Beihai	POINT(109.100000 21.483330)	
-G1816971	Baoding	POINT(115.490280 38.851110)	
-G1817240	Baiyin	POINT(104.208060 36.558330)	
-G1817720	Shangyu	POINT(120.871110 30.015560)	
-G1817968	Anshun	POINT(105.933330 26.250000)	
-G1817993	Anqing	POINT(117.050560 30.509170)	
-G1818116	Anbu	POINT(116.680920 23.448950)	
-G1886760	Suzhou	POINT(120.618060 31.311390)	
-G1915223	Zhongshan	POINT(110.582910 21.322560)	
-G1919014	Lianghu	POINT(120.898450 29.991520)	
-G1927639	Yueyang	POINT(113.091940 29.333330)	
-G2033168	Zhaodong	POINT(125.983330 46.083330)	
-G2033196	Zhangjiakou	POINT(114.879440 40.810000)	
-G2033370	Yingkou	POINT(122.224720 40.668060)	
-G2033413	Yichun	POINT(128.900000 47.700000)	
-G2033467	Yanji	POINT(129.507780 42.907500)	
-G2033574	Xuanhua	POINT(115.044720 40.610280)	
-G2034312	Ulan Hot	POINT(122.083330 46.083330)	
-G2034400	Tongliao	POINT(122.265280 43.612500)	
-G2034439	Tieling	POINT(123.841390 42.293060)	
-G2034655	Suihua	POINT(126.996940 46.640560)	
-G2034714	Siping	POINT(124.368610 43.163330)	
-G2034786	Shuangyashan	POINT(131.153890 46.636110)	
-G2034937	Shenyang	POINT(123.432780 41.792220)	
-G2035225	Ranghulu	POINT(124.866670 46.650000)	
-G2035261	Qitaihe	POINT(130.850000 45.800000)	
-G2035265	Qiqihar	POINT(123.967220 47.340830)	
-G2035513	Panshan	POINT(122.049440 41.188060)	
-G2035644	Nanpiao	POINT(120.747920 41.098220)	
-G2035715	Mudanjiang	POINT(129.600000 44.583330)	
-G2035980	Longfeng	POINT(125.116670 46.550000)	
-G2036109	Liaoyuan	POINT(125.135830 42.903610)	
-G2036113	Liaoyang	POINT(123.173060 41.271940)	
-G2036389	Jixi	POINT(130.966670 45.300000)	
-G2036401	Jiutai	POINT(125.832780 44.152500)	
-G2036427	Jinzhou	POINT(121.141670 41.107780)	
-G2036434	Lianshan	POINT(120.853270 40.764320)	
-G2036458	Jining	POINT(113.105830 41.027500)	
-G2036502	Jilin	POINT(126.560280 43.850830)	
-G2036581	Jiamusi	POINT(130.350000 46.833330)	
-G2036670	Hulan Ergi	POINT(123.633330 47.204170)	
-G2036892	Hohhot	POINT(111.652220 40.810560)	
-G2036920	Hengshan	POINT(130.916670 45.200000)	
-G2036986	Hegang	POINT(130.366670 47.400000)	
-G2037013	Harbin	POINT(126.650000 45.750000)	
-G2037078	Hailar	POINT(119.700000 49.200000)	
-G2037086	Haicheng	POINT(122.741670 40.851940)	
-G2037346	Fuxin	POINT(121.658890 42.015560)	
-G2037355	Fushun	POINT(123.923330 41.855830)	
-G2037620	Dongling	POINT(123.575830 41.814440)	
-G2037799	Datong	POINT(113.291390 40.093610)	
-G2037860	Daqing	POINT(125.000000 46.583330)	
-G2037886	Dandong	POINT(124.394720 40.129170)	
-G2038067	Chifeng	POINT(118.963610 42.268330)	
-G2038087	Chengde	POINT(117.936110 40.972500)	
-G2038120	Chaoyang	POINT(120.458610 41.570280)	
-G2038180	Changchun	POINT(125.322780 43.880000)	
-G2038300	Benxi	POINT(123.765000 41.288610)	
-G2038342	Beipiao	POINT(120.779170 41.791940)	
-G2038432	Baotou	POINT(109.822220 40.652220)	
-G2038569	Baicheng	POINT(122.816670 45.616670)	
-G2038584	Baishan	POINT(126.428610 41.943060)	
-G2038632	Anshan	POINT(122.990000 41.123610)	
-G2038650	Anda	POINT(125.316670 46.400000)	
-G7158935	东海岛	POINT(110.396130 21.024480)	
-G7283386	Changshu City	POINT(120.742210 31.646150)	
-G7304020	Fenghuang	POINT(109.599610 27.935570)	
-G7602670	Zhu Cheng City	POINT(119.402590 35.995020)	
-G3665900	Villavicencio	POINT(-73.626640 4.142000)	
-G3666304	Valledupar	POINT(-73.250560 10.476940)	
-G3666645	Tuluá	POINT(-76.200000 4.086670)	
-G3667849	Soledad	POINT(-74.766670 10.917220)	
-G3667905	Soacha	POINT(-74.221390 4.587220)	
-G3667983	Sincelejo	POINT(-75.397780 9.304720)	
-G3668605	Santa Marta	POINT(-74.201670 11.247220)	
-G3671916	Popayán	POINT(-76.613160 2.438230)	
-G3672486	Pereira	POINT(-75.696110 4.813330)	
-G3672778	Pasto	POINT(-77.281110 1.213610)	
-G3673164	Palmira	POINT(-76.303610 3.539440)	
-G3673899	Neiva	POINT(-75.281880 2.927300)	
-G3674453	Montería	POINT(-75.890000 8.757500)	
-G3674962	Medellín	POINT(-75.536110 6.291390)	
-G3675443	Manizales	POINT(-75.520560 5.070000)	
-G3680450	Itagüí	POINT(-75.611390 6.171940)	
-G3680656	Ibagué	POINT(-75.232220 4.438890)	
-G3682385	Floridablanca	POINT(-73.089720 7.064720)	
-G3682631	Envigado	POINT(-75.563890 6.173060)	
-G3685095	Dos Quebradas	POINT(-75.672500 4.834720)	
-G3685533	Cúcuta	POINT(-72.505280 7.883330)	
-G3687238	Cartagena	POINT(-75.514440 10.399720)	
-G3687925	Cali	POINT(-76.522500 3.437220)	
-G3688451	Buenaventura	POINT(-77.069720 3.893330)	
-G3688465	Bucaramanga	POINT(-73.125830 7.129720)	
-G3688689	Bogotá	POINT(-74.081750 4.609710)	
-G3688928	Bello	POINT(-75.562220 6.338890)	
-G3689147	Barranquilla	POINT(-74.796390 10.963890)	
-G3689169	Barrancabermeja	POINT(-73.854720 7.065280)	
-G3689560	Armenia	POINT(-75.681110 4.533890)	
-G3621849	San José	POINT(-84.083330 9.933330)	
-G3536729	Santiago de Cuba	POINT(-75.821940 20.024720)	
-G3537906	Santa Clara	POINT(-79.966670 22.400000)	
-G3544091	Pinar del Río	POINT(-83.698060 22.417500)	
-G3550598	Las Tunas	POINT(-76.951110 20.961670)	
-G3553478	Havana	POINT(-82.383040 23.133020)	
-G3556969	Holguín	POINT(-76.263060 20.887220)	
-G3557689	Guantánamo	POINT(-75.209170 20.144440)	
-G3564124	Cienfuegos	POINT(-80.435560 22.146110)	
-G3566067	Camagüey	POINT(-77.916940 21.380830)	
-G3567597	Bayamo	POINT(-76.643330 20.379170)	
-G146268	Nicosia	POINT(33.366670 35.166670)	
-G146384	Limassol	POINT(33.033330 34.675000)	
-G3067696	Praha	POINT(14.420760 50.088040)	
-G3068160	Plzeň	POINT(13.377590 49.747470)	
-G3068799	Ostrava	POINT(18.282040 49.834650)	
-G3078610	Brno	POINT(16.607960 49.195220)	
-G2805753	Wuppertal	POINT(7.183330 51.266670)	
-G2809346	Wiesbaden	POINT(8.250000 50.083330)	
-G2825297	Stuttgart	POINT(9.177020 48.782320)	
-G2831580	Solingen	POINT(7.083330 51.183330)	
-G2842647	Saarbrücken	POINT(7.000000 49.233330)	
-G2844588	Rostock	POINT(12.140490 54.088700)	
-G2848756	Berlin Reinickendorf	POINT(13.333330 52.566670)	
-G2855598	Berlin Pankow	POINT(13.401860 52.569260)	
-G2856883	Osnabrück	POINT(8.050000 52.266670)	
-G2857458	Oldenburg	POINT(8.200000 53.166670)	
-G2860410	Oberhausen	POINT(6.850000 51.466670)	
-G2861650	Nuremberg	POINT(11.068330 49.447780)	
-G2864072	Neue Neustadt	POINT(11.633330 52.150000)	
-G2864118	Neuß	POINT(6.683330 51.200000)	
-G2867543	Münster	POINT(7.625710 51.962360)	
-G2867714	München	POINT(11.575490 48.137430)	
-G2867838	Mülheim an der Ruhr	POINT(6.883330 51.433330)	
-G2869894	Mönchengladbach	POINT(6.433330 51.200000)	
-G2873891	Mannheim	POINT(8.464720 49.488330)	
-G2874225	Mainz	POINT(8.271110 50.000000)	
-G2874545	Magdeburg	POINT(11.666670 52.166670)	
-G2875376	Ludwigshafen am Rhein	POINT(8.435280 49.481110)	
-G2875601	Lübeck	POINT(10.687290 53.868930)	
-G2878234	Leverkusen	POINT(7.000000 51.033330)	
-G2879139	Leipzig	POINT(12.371290 51.339620)	
-G2884509	Krefeld	POINT(6.566670 51.333330)	
-G2886242	Köln	POINT(6.950000 50.933330)	
-G2891122	Kiel	POINT(10.134890 54.321330)	
-G2892518	Kassel	POINT(9.500000 51.316670)	
-G2892794	Karlsruhe	POINT(8.385830 49.004720)	
-G2905891	Herne	POINT(7.216670 51.550000)	
-G2910685	Harburg	POINT(9.983330 53.466670)	
-G2910831	Hannover	POINT(9.733220 52.370520)	
-G2911240	Hamm	POINT(7.820890 51.680330)	
-G2911285	Wandsbek	POINT(10.100000 53.566670)	
-G2911287	Marienthal	POINT(10.083330 53.566670)	
-G2911293	Eimsbüttel	POINT(9.983330 53.566670)	
-G2911296	Altona	POINT(9.933330 53.550000)	
-G2911298	Hamburg	POINT(10.000000 53.550000)	
-G2911522	Halle	POINT(12.000000 51.500000)	
-G2912621	Hagen	POINT(7.466670 51.350000)	
-G2921466	Gelsenkirchen	POINT(7.050000 51.516670)	
-G2925177	Freiburg	POINT(7.852220 47.995900)	
-G2925533	Frankfurt am Main	POINT(8.683330 50.116670)	
-G2928810	Essen	POINT(7.016670 51.450000)	
-G2929670	Erfurt	POINT(11.033330 50.983330)	
-G2934246	Düsseldorf	POINT(6.776160 51.221720)	
-G2934691	Duisburg	POINT(6.750000 51.433330)	
-G2935022	Dresden	POINT(13.738320 51.050890)	
-G2935517	Dortmund	POINT(7.450000 51.516670)	
-G2940132	Chemnitz	POINT(12.916670 50.833330)	
-G2944388	Bremen	POINT(8.807770 53.075160)	
-G2945024	Braunschweig	POINT(10.533330 52.266670)	
-G2946447	Bonn	POINT(7.100000 50.733330)	
-G2947416	Bochum	POINT(7.216670 51.483330)	
-G2949186	Bielefeld	POINT(8.533330 52.033330)	
-G2950159	Berlin	POINT(13.410530 52.524370)	
-G2954172	Augsburg	POINT(10.883330 48.366670)	
-G3247449	Aachen	POINT(6.083420 50.776640)	
-G6545310	Berlin Mitte	POINT(13.404890 52.520030)	
-G6941055	Bochum-Hordel	POINT(7.175600 51.501680)	
-G7289614	Halle Neustadt	POINT(11.916050 51.479240)	
-G7290245	Berlin Steglitz Zehlendorf	POINT(13.241830 52.434850)	
-G7290251	Berlin Wilmersdorf	POINT(13.290970 52.500970)	
-G7290252	Berlin Spandau	POINT(13.199210 52.551100)	
-G223817	Djibouti	POINT(43.144680 11.587670)	
-G2618425	Copenhagen	POINT(12.565530 55.675940)	
-G2624652	Århus	POINT(10.210760 56.156740)	
-G3492908	Santo Domingo	POINT(-69.988570 18.500120)	
-G3492914	Santiago de los Caballeros	POINT(-70.700000 19.450000)	
-G3493032	San Pedro de Macorís	POINT(-69.297180 18.461560)	
-G3500957	La Romana	POINT(-68.972850 18.427340)	
-G3511540	San Cristóbal	POINT(-70.100000 18.416670)	
-G2474141	Boumerdas	POINT(3.477170 36.766390)	
-G2479536	Skikda	POINT(6.909210 36.876170)	
-G2481007	Sidi Bel Abbès	POINT(-0.630850 35.189940)	
-G2485926	Oran	POINT(-0.641670 35.691110)	
-G2498766	El Achir	POINT(4.627440 36.063860)	
-G2498954	Ech Chettia	POINT(1.255380 36.195910)	
-G2501152	Constantine	POINT(6.614720 36.365000)	
-G2505329	Bejaïa	POINT(5.084330 36.755870)	
-G2505572	Batna	POINT(6.174140 35.555970)	
-G2505854	Bab Ezzouar	POINT(3.182910 36.726150)	
-G2506999	Annaba	POINT(7.766670 36.900000)	
-G2507480	Algiers	POINT(3.041970 36.752500)	
-G3651297	Santo Domingo de los Colorados	POINT(-79.150000 -0.250000)	
-G3652462	Quito	POINT(-78.524950 -0.229850)	
-G3652941	Portoviejo	POINT(-80.450000 -1.050000)	
-G3654410	Manta	POINT(-80.733330 -0.950000)	
-G3654533	Machala	POINT(-79.966670 -3.266670)	
-G3657509	Guayaquil	POINT(-79.900000 -2.166670)	
-G3658192	Durán	POINT(-79.833330 -2.200000)	
-G3658666	Cuenca	POINT(-78.983330 -2.883330)	
-G3660689	Ambato	POINT(-78.616750 -1.249080)	
-G588409	Tallinn	POINT(24.753530 59.436960)	
-G347497	Tanda	POINT(30.998060 30.791110)	
-G347591	Ṭalkha	POINT(31.373890 31.053060)	
-G347796	Sūhāj	POINT(31.700000 26.550000)	
-G350550	Qinā	POINT(32.727220 26.170000)	
-G354775	Kafr ad Dawwār	POINT(30.128430 31.133850)	
-G355795	Hilwan	POINT(31.333330 29.850000)	
-G358448	Damanhûr	POINT(30.466670 31.033330)	
-G358619	Port Said	POINT(32.307500 31.280560)	
-G359173	Banī Suwayf	POINT(31.088890 29.063890)	
-G359280	Banhā	POINT(31.187500 30.460830)	
-G359493	Az Zaqāzīq	POINT(31.510280 30.591390)	
-G359783	Asyūţ	POINT(31.182780 27.182780)	
-G359792	Aswān	POINT(32.898890 24.087500)	
-G359796	Suez	POINT(32.550000 29.966670)	
-G360502	Luxor	POINT(32.642100 25.698930)	
-G360630	Cairo	POINT(31.249670 30.062630)	
-G360686	Al Minyā	POINT(30.744440 28.119440)	
-G360761	Al Manşūrah	POINT(31.376670 31.043060)	
-G360829	Al Maḩallah al Kubrá	POINT(31.166940 30.976110)	
-G360995	Al Jīzah	POINT(31.212220 30.008610)	
-G361055	Ismailia	POINT(32.277220 30.605280)	
-G361058	Alexandria	POINT(29.919170 31.198060)	
-G361320	Al Fayyūm	POINT(30.840000 29.307780)	
-G411165	Idfu	POINT(32.874720 24.980280)	
-G2462881	Laâyoune / El Aaiún	POINT(-13.203150 27.162240)	
-G343300	Asmara	POINT(38.933330 15.333330)	
-G2509954	Valencia	POINT(-0.377390 39.469750)	
-G2510911	Sevilla	POINT(-5.986940 37.377220)	
-G2511174	Santa Cruz de Tenerife	POINT(-16.254620 28.468240)	
-G2511401	La Laguna	POINT(-16.316670 28.483330)	
-G2512989	Palma	POINT(2.650240 39.569390)	
-G2513416	Murcia	POINT(-1.116670 37.983330)	
-G2514256	Málaga	POINT(-4.420340 36.720160)	
-G2515270	Las Palmas de Gran Canaria	POINT(-15.416670 28.100000)	
-G2516326	Jerez de la Frontera	POINT(-6.133330 36.683330)	
-G2517117	Granada	POINT(-3.606670 37.188170)	
-G2518559	Elx	POINT(-0.701070 38.262180)	
-G2519240	Córdoba	POINT(-4.766670 37.883330)	
-G2519752	Castelló de la Plana	POINT(-0.033330 39.983330)	
-G2520058	Cartagena	POINT(-0.983330 37.600000)	
-G2521886	Almería	POINT(-2.459740 36.838140)	
-G2521978	Alicante	POINT(-0.481490 38.345170)	
-G2522258	Albacete	POINT(-1.850000 38.983330)	
-G3104324	Zaragoza	POINT(-0.877340 41.656060)	
-G3104499	Vitoria-Gasteiz	POINT(-2.666670 42.850000)	
-G3105976	Vigo	POINT(-8.716670 42.233330)	
-G3106672	Valladolid	POINT(-4.716670 41.650000)	
-G3108286	Terrassa	POINT(2.016670 41.566670)	
-G3109718	Santander	POINT(-3.804440 43.464720)	
-G3110044	San Sebastián	POINT(-1.974990 43.312830)	
-G3111108	Salamanca	POINT(-5.650000 40.966670)	
-G3111199	Sabadell	POINT(2.109420 41.543290)	
-G3114472	Pamplona	POINT(-1.643230 42.816870)	
-G3114711	Oviedo	POINT(-5.844760 43.360290)	
-G3116025	Móstoles	POINT(-3.864960 40.322340)	
-G3117735	Madrid	POINT(-3.702560 40.416500)	
-G3118150	Logroño	POINT(-2.450000 42.466670)	
-G3118594	Leganés	POINT(-3.763500 40.327180)	
-G3119841	A Coruña	POINT(-8.396000 43.371350)	
-G3120619	L'Hospitalet de Llobregat	POINT(2.100280 41.359670)	
-G3121424	Gijón	POINT(-5.664440 43.541110)	
-G3121437	Getafe	POINT(-3.732950 40.305710)	
-G3121960	Fuenlabrada	POINT(-3.800000 40.283330)	
-G3127461	Burgos	POINT(-3.700000 42.350000)	
-G3128026	Bilbao	POINT(-2.925280 43.262710)	
-G3128760	Barcelona	POINT(2.158990 41.388790)	
-G3129028	Badalona	POINT(2.247410 41.450040)	
-G3130564	Alcorcón	POINT(-3.824870 40.345820)	
-G3130616	Alcalá de Henares	POINT(-3.366670 40.483330)	
-G6252065	Nou Barris	POINT(2.177270 41.441630)	
-G6544100	Eixample	POINT(2.161790 41.388960)	
-G6544105	Sant Martí	POINT(2.199330 41.418140)	
-G330186	Nazrēt	POINT(39.266670 8.550000)	
-G331180	Mek’elē	POINT(39.475280 13.496670)	
-G336014	Gonder	POINT(37.466670 12.600000)	
-G338832	Dirē Dawa	POINT(41.866110 9.593060)	
-G342884	Bahir Dar	POINT(37.383330 11.600000)	
-G344979	Addis Ababa	POINT(38.746890 9.024970)	
-G632453	Vantaa	POINT(25.040990 60.294140)	
-G633679	Turku	POINT(22.268690 60.451480)	
-G634963	Tampere	POINT(23.787120 61.499110)	
-G658225	Helsinki	POINT(24.935450 60.169520)	
-G660158	Espoo	POINT(24.652200 60.205200)	
-G2972315	Toulouse	POINT(1.443670 43.604260)	
-G2972328	Toulon	POINT(5.933330 43.116670)	
-G2973783	Strasbourg	POINT(7.742960 48.583420)	
-G2980291	Saint-Étienne	POINT(4.400000 45.433330)	
-G2983990	Rennes	POINT(-1.683330 48.083330)	
-G2984114	Reims	POINT(4.033330 49.250000)	
-G2988507	Paris	POINT(2.348800 48.853410)	
-G2990440	Nice	POINT(7.266080 43.703130)	
-G2990969	Nantes	POINT(-1.553360 47.217250)	
-G2992166	Montpellier	POINT(3.883330 43.600000)	
-G2995469	Marseille	POINT(5.381070 43.296950)	
-G2996944	Lyon	POINT(4.850000 45.750000)	
-G2998324	Lille	POINT(3.066670 50.633330)	
-G3003796	Le Havre	POINT(0.107670 49.493800)	
-G3014728	Grenoble	POINT(5.716670 45.166670)	
-G3031582	Bordeaux	POINT(-0.566670 44.833330)	
-G3037656	Angers	POINT(-0.550000 47.466670)	
-G2399697	Libreville	POINT(9.450000 0.383330)	
-G2633691	Wolverhampton	POINT(-2.122960 52.585470)	
-G2634853	Walsall	POINT(-1.983960 52.585280)	
-G2636389	Swindon	POINT(-1.781160 51.557970)	
-G2636432	Swansea	POINT(-3.943230 51.620790)	
-G2636503	Sutton	POINT(-0.200000 51.350000)	
-G2636531	Sunderland	POINT(-1.382220 54.904650)	
-G2636841	Stoke-on-Trent	POINT(-2.185380 53.004150)	
-G2637433	Southend-on-Sea	POINT(0.714330 51.537820)	
-G2637487	Southampton	POINT(-1.404280 50.903950)	
-G2638077	Sheffield	POINT(-1.465900 53.382970)	
-G2639577	Reading	POINT(-0.971130 51.456250)	
-G2639912	Preston	POINT(-2.716670 53.766670)	
-G2639996	Portsmouth	POINT(-1.091250 50.798990)	
-G2640101	Poole	POINT(-2.000000 50.716670)	
-G2640194	Plymouth	POINT(-4.143050 50.371530)	
-G2640729	Oxford	POINT(-1.255960 51.752220)	
-G2641170	Nottingham	POINT(-1.150470 52.953600)	
-G2641181	Norwich	POINT(1.298340 52.627830)	
-G2641430	Northampton	POINT(-0.883330 52.250000)	
-G2641673	Newcastle upon Tyne	POINT(-1.613960 54.973280)	
-G2642465	Milton Keynes	POINT(-0.755830 52.041720)	
-G2643123	Manchester	POINT(-2.237430 53.480950)	
-G2643339	Luton	POINT(-0.417480 51.879670)	
-G2643741	City of London	POINT(-0.091840 51.512790)	
-G2643743	London	POINT(-0.125740 51.508530)	
-G2644210	Liverpool	POINT(-2.977940 53.410580)	
-G2644668	Leicester	POINT(-1.131690 52.638600)	
-G2644688	Leeds	POINT(-1.547850 53.796480)	
-G2645425	Hull	POINT(-0.335250 53.744600)	
-G2646003	Islington	POINT(-0.103040 51.536220)	
-G2648579	Glasgow	POINT(-4.257630 55.865150)	
-G2650225	Edinburgh	POINT(-3.196480 55.952060)	
-G2650752	Dundee	POINT(-2.966670 56.500000)	
-G2650839	Dudley	POINT(-2.083330 52.500000)	
-G2651347	Derby	POINT(-1.476630 52.922770)	
-G2652221	Coventry	POINT(-1.512170 52.406560)	
-G2653822	Cardiff	POINT(-3.180000 51.480000)	
-G2654675	Bristol	POINT(-2.596650 51.455230)	
-G2654993	Bradford	POINT(-1.752060 53.793910)	
-G2655095	Bournemouth	POINT(-1.879500 50.720480)	
-G2655603	Birmingham	POINT(-1.899830 52.481420)	
-G2655984	Belfast	POINT(-5.933330 54.583330)	
-G2657832	Aberdeen	POINT(-2.098140 57.143690)	
-G7535661	London Borough of Harrow	POINT(-0.333330 51.566670)	
-G611717	Tbilisi	POINT(44.833680 41.694110)	
-G613607	K'ut'aisi	POINT(42.699740 42.249610)	
-G2294700	Tema	POINT(-0.016670 5.616670)	
-G2294877	Tamale	POINT(-0.833330 9.400000)	
-G2294915	Takoradi	POINT(-1.750000 4.883330)	
-G2298890	Kumasi	POINT(-1.616670 6.683330)	
-G2306079	Achiaman	POINT(-0.333330 5.700000)	
-G2306104	Accra	POINT(-0.196900 5.556020)	
-G2422465	Conakry	POINT(-13.677290 9.537950)	
-G2422488	Camayenne	POINT(-13.687780 9.535000)	
-G2309527	Malabo	POINT(8.783330 3.750000)	
-G2310046	Bata	POINT(9.750000 1.850000)	
-G255274	Piraeus	POINT(23.637080 37.947450)	
-G255683	Pátrai	POINT(21.734440 38.244440)	
-G264371	Athens	POINT(23.716220 37.979450)	
-G734077	Thessaloníki	POINT(22.943890 40.640280)	
-G3587902	Villa Nueva	POINT(-90.587500 14.526940)	
-G3592519	Mixco	POINT(-90.606390 14.633330)	
-G3598132	Guatemala City	POINT(-90.513270 14.640720)	
-G2374775	Bissau	POINT(-15.583330 11.850000)	
-G3378644	Georgetown	POINT(-58.155270 6.804480)	
-G1819609	Kowloon	POINT(114.183330 22.316670)	
-G1819729	Hong Kong	POINT(114.157690 22.285520)	
-G3600949	Tegucigalpa	POINT(-87.206810 14.081800)	
-G3601782	San Pedro Sula	POINT(-88.033330 15.500000)	
-G3186886	Zagreb	POINT(15.977980 45.814440)	
-G3190261	Split	POINT(16.439150 43.508910)	
-G6618983	Zagreb - Centar	POINT(15.977530 45.813130)	
-G3718426	Port-au-Prince	POINT(-72.335000 18.539170)	
-G3719028	Pétionville	POINT(-72.285280 18.512500)	
-G3726786	Delmas 73	POINT(-72.302780 18.544720)	
-G3727135	Croix des Bouquets	POINT(-72.225000 18.575000)	
-G3728338	Carrefour	POINT(-72.399220 18.541140)	
-G715429	Szeged	POINT(20.148240 46.253000)	
-G717582	Miskolc	POINT(20.783330 48.100000)	
-G721472	Debrecen	POINT(21.633330 47.533330)	
-G3046526	Pécs	POINT(18.233330 46.083330)	
-G3054643	Budapest	POINT(19.039910 47.498010)	
-G6942354	Nagyvárad	POINT(21.927340 47.060530)	
-G1213614	Sunggal	POINT(98.615100 3.576500)	
-G1214189	Percut	POINT(98.864000 3.625300)	
-G1214191	Perbaungan	POINT(98.956000 3.567900)	
-G1214204	Pematangsiantar	POINT(99.068700 2.959500)	
-G1214520	Medan	POINT(98.666670 3.583330)	
-G1215355	Binjai	POINT(98.485400 3.600100)	
-G1215502	Banda Aceh	POINT(95.322200 5.557700)	
-G1621177	Yogyakarta	POINT(110.360830 -7.782780)	
-G1622786	Makassar	POINT(119.422100 -5.140000)	
-G1624494	Tegal	POINT(109.140200 -6.869400)	
-G1624647	Tasikmalaya	POINT(108.200000 -7.333330)	
-G1624917	Bandarlampung	POINT(105.258030 -5.425440)	
-G1625084	Tangerang	POINT(106.630000 -6.178060)	
-G1625812	Surakarta	POINT(110.831670 -7.556110)	
-G1625822	Surabaya	POINT(112.750830 -7.249170)	
-G1626100	Sumedang Utara	POINT(107.916670 -6.850000)	
-G1626381	Sukabumi	POINT(106.926670 -6.918060)	
-G1626560	Soreang	POINT(107.518330 -7.033060)	
-G1626801	Situbondo	POINT(114.009760 -7.706230)	
-G1627549	Serang	POINT(106.150200 -6.114900)	
-G1627896	Semarang	POINT(110.420300 -6.993200)	
-G1629001	Samarinda	POINT(117.150000 -0.500000)	
-G1629131	Salatiga	POINT(110.492780 -7.331940)	
-G1629710	Rengasdengklok	POINT(107.298060 -6.159170)	
-G1630328	Purwokerto	POINT(109.234440 -7.421390)	
-G1630333	Purwodadi	POINT(110.915800 -7.086800)	
-G1630341	Purwakarta	POINT(107.443330 -6.556940)	
-G1630634	Probolinggo	POINT(113.215900 -7.754300)	
-G1630789	Pontianak	POINT(109.333330 -0.033330)	
-G1630997	Plumbon	POINT(108.472780 -6.705000)	
-G1631648	Pemalang	POINT(109.366670 -6.900000)	
-G1631761	Pekanbaru	POINT(101.450000 0.533330)	
-G1631766	Pekalongan	POINT(109.675300 -6.888600)	
-G1632033	Pasuruan	POINT(112.907500 -7.645300)	
-G1632228	Pasarkemis	POINT(106.530280 -6.170280)	
-G1632276	Parung	POINT(106.733060 -6.421390)	
-G1632937	Pamulang	POINT(106.738330 -6.342780)	
-G1633034	Palu	POINT(119.870700 -0.891700)	
-G1633070	Palembang	POINT(104.745800 -2.916730)	
-G1633419	Padang	POINT(100.354270 -0.949240)	
-G1635882	Mataram	POINT(116.116670 -8.583330)	
-G1636544	Manado	POINT(124.845500 1.487000)	
-G1636556	Mamuju	POINT(118.888500 -2.674800)	
-G1636722	Malang	POINT(112.630400 -7.979700)	
-G1636930	Madiun	POINT(111.523900 -7.629800)	
-G1637510	Loa Janan	POINT(117.095030 -0.582950)	
-G1638063	Lembang	POINT(107.617500 -6.811670)	
-G1638284	Lawang	POINT(112.694700 -7.835300)	
-G1638868	Labuhanbajo	POINT(119.887700 -8.496400)	
-G1640344	Kendari	POINT(122.498890 -3.945000)	
-G1640660	Kediri	POINT(112.016670 -7.816670)	
-G1642588	Jember	POINT(113.703170 -8.166040)	
-G1642858	Jambi	POINT(103.616670 -1.600000)	
-G1642911	Jakarta	POINT(106.845130 -6.214620)	
-G1645524	Depok	POINT(106.818610 -6.400000)	
-G1645528	Denpasar	POINT(115.216670 -8.650000)	
-G1645895	Curug	POINT(106.556390 -6.265830)	
-G1646170	Cirebon	POINT(108.557000 -6.706300)	
-G1646194	Ciputat	POINT(106.695560 -6.237500)	
-G1646448	Cimahi	POINT(107.542500 -6.872220)	
-G1646494	Cileungsi	POINT(106.959170 -6.394720)	
-G1647003	Cibinong	POINT(106.854170 -6.481670)	
-G1647383	Ciampea	POINT(106.700830 -6.554720)	
-G1648473	Bogor	POINT(106.789170 -6.594440)	
-G1649150	Bengkulu	POINT(102.265540 -3.800440)	
-G1649378	Bekasi	POINT(106.989600 -6.234900)	
-G1650213	Banjarmasin	POINT(114.591000 -3.324420)	
-G1650227	Banjaran	POINT(107.587780 -7.045280)	
-G1650357	Bandung	POINT(107.618610 -6.903890)	
-G1650527	Balikpapan	POINT(116.828870 -1.267530)	
-G1651531	Ambon	POINT(128.200000 -3.716670)	
-G1985663	Cikupa	POINT(106.508330 -6.236390)	
-G2057087	Kupang	POINT(123.583330 -10.166670)	
-G2964506	Dún Laoghaire	POINT(-6.135860 53.293950)	
-G2964574	Dublin	POINT(-6.267190 53.343990)	
-G2965140	Cork	POINT(-8.470610 51.897970)	
-G281184	Jerusalem	POINT(35.225300 31.779020)	
-G293397	Tel Aviv	POINT(34.766670 32.066670)	
-G293703	Rishon LeẔiyyon	POINT(34.804440 31.964170)	
-G294071	Netanya	POINT(34.857780 32.333610)	
-G294751	H̱olon	POINT(34.772220 32.011390)	
-G294801	Haifa	POINT(34.989170 32.815560)	
-G295530	Beersheba	POINT(34.791300 31.251810)	
-G295629	Ashdod	POINT(34.650000 31.816670)	
-G6693674	Petah Tikva	POINT(34.885030 32.091740)	
-G7498240	West Jerusalem	POINT(35.219610 31.781990)	
-G1252797	Yamunānagar	POINT(77.283330 30.100000)	
-G1252948	Warangal	POINT(79.583330 18.000000)	
-G1253084	Vizianagaram	POINT(83.416670 18.116670)	
-G1253102	Vishākhapatnam	POINT(83.300000 17.700000)	
-G1253133	Virār	POINT(72.800000 19.466670)	
-G1253184	Vijayawāda	POINT(80.616670 16.516670)	
-G1253237	Verāval	POINT(70.366670 20.900000)	
-G1253286	Vellore	POINT(79.133330 12.933330)	
-G1253405	Benares	POINT(83.000000 25.333330)	
-G1253573	Vadodara	POINT(73.200000 22.300000)	
-G1253747	Unnāo	POINT(80.500000 26.533330)	
-G1253894	Ulhāsnagar	POINT(73.150000 19.216670)	
-G1253914	Ujjain	POINT(75.766670 23.183330)	
-G1253986	Udaipur	POINT(73.691830 24.571170)	
-G1254089	Tumkūr	POINT(77.101670 13.342220)	
-G1254163	Thiruvananthapuram	POINT(76.916670 8.483330)	
-G1254187	Trichūr	POINT(76.216670 10.516670)	
-G1254241	Tonk	POINT(75.783330 26.166670)	
-G1254348	Tiruppūr	POINT(77.350000 11.100000)	
-G1254360	Tirupati	POINT(79.416670 13.650000)	
-G1254361	Tirunelveli	POINT(77.700000 8.733330)	
-G1254388	Tiruchchirāppalli	POINT(78.683330 10.816670)	
-G1254649	Thanjāvūr	POINT(79.150000 10.800000)	
-G1254661	Thāne	POINT(72.966670 19.200000)	
-G1254745	Teni	POINT(77.483330 10.000000)	
-G1255349	Surendranagar	POINT(71.683330 22.700000)	
-G1255364	Sūrat	POINT(72.833330 21.166670)	
-G1255634	Srīnagar	POINT(74.816670 34.083330)	
-G1255744	Sonīpat	POINT(77.016670 28.983330)	
-G1255969	Sītāpur	POINT(80.683330 27.566670)	
-G1256052	Sirsa	POINT(75.016670 29.533330)	
-G1256237	Shimla	POINT(77.166670 31.100000)	
-G1256287	Silchar	POINT(92.800000 24.816670)	
-G1256320	Sīkar	POINT(75.150000 27.616670)	
-G1256422	Shrīrāmpur	POINT(88.342220 22.752780)	
-G1256436	Solāpur	POINT(75.916670 17.683330)	
-G1256451	Shivpurī	POINT(77.650000 25.433330)	
-G1256515	Shimoga	POINT(75.566670 13.916670)	
-G1256525	Shiliguri	POINT(88.433330 26.700000)	
-G1256728	Shāhjahānpur	POINT(79.916670 27.883330)	
-G1257022	Satna	POINT(80.833330 24.583330)	
-G1257416	Sāngli	POINT(74.564170 16.854380)	
-G1257540	Sambhal	POINT(78.550000 28.583330)	
-G1257542	Sambalpur	POINT(83.966670 21.450000)	
-G1257629	Salem	POINT(78.166670 11.650000)	
-G1257806	Sahāranpur	POINT(77.550000 29.966670)	
-G1257845	Sāgar	POINT(78.716670 23.833330)	
-G1258076	Rohtak	POINT(76.566670 28.900000)	
-G1258182	Rewa	POINT(81.300000 24.533330)	
-G1258342	Ratlām	POINT(75.066670 23.316670)	
-G1258526	Rānchī	POINT(85.333330 23.350000)	
-G1258599	Rāmpur	POINT(79.033330 28.816670)	
-G1258831	Rāj Nāndgaon	POINT(81.033330 21.100000)	
-G1258847	Rājkot	POINT(70.783330 22.300000)	
-G1258932	Rājahmundry	POINT(81.783330 16.983330)	
-G1258980	Raipur	POINT(81.633330 21.233330)	
-G1259004	Raigarh Fort	POINT(73.433330 18.250000)	
-G1259009	Rāiganj	POINT(88.116670 25.616670)	
-G1259012	Rāichūr	POINT(77.366670 16.200000)	
-G1259064	Rāe Bareli	POINT(81.233330 26.216670)	
-G1259091	Quilon	POINT(76.600000 8.883330)	
-G1259166	Pūrnia	POINT(87.466670 25.783330)	
-G1259184	Puri	POINT(85.850000 19.800000)	
-G1259229	Pune	POINT(73.855350 18.519570)	
-G1259239	Punāsa	POINT(76.400000 22.233330)	
-G1259312	Proddatūr	POINT(78.550000 14.733330)	
-G1259425	Pondicherry	POINT(79.830000 11.930000)	
-G1259652	Pimpri	POINT(73.800000 18.616670)	
-G1260086	Patna	POINT(85.116670 25.600000)	
-G1260107	Patiāla	POINT(76.400280 30.326670)	
-G1260137	Pathānkot	POINT(75.650000 32.283330)	
-G1260341	Parbhani	POINT(76.783330 19.266670)	
-G1260476	Pānīpat	POINT(76.968060 29.388890)	
-G1260482	Pānihāti	POINT(88.374440 22.694170)	
-G1260692	Pallāvaram	POINT(80.183610 12.976110)	
-G1260716	Pāli	POINT(73.333330 25.766670)	
-G1261039	Orai	POINT(79.466670 25.983330)	
-G1261045	Ongole	POINT(80.050000 15.500000)	
-G1261258	Nizāmābād	POINT(78.116670 18.666670)	
-G1261481	New Delhi	POINT(77.224450 28.635760)	
-G1261529	Nellore	POINT(79.966670 14.433330)	
-G1261731	Nāsik	POINT(73.800000 19.983330)	
-G1261913	Nāngloi Jāt	POINT(77.066670 28.683330)	
-G1261927	Nandyāl	POINT(78.483330 15.483330)	
-G1262131	Naihāti	POINT(88.416940 22.902780)	
-G1262180	Nāgpur	POINT(79.100000 21.150000)	
-G1262204	Nāgercoil	POINT(77.433330 8.166670)	
-G1262292	Nadiād	POINT(72.866670 22.700000)	
-G1262321	Mysore	POINT(76.649720 12.307220)	
-G1262330	Muzaffarpur	POINT(85.400000 26.116670)	
-G1262332	Muzaffarnagar	POINT(77.683330 29.466670)	
-G1262395	Murwāra	POINT(80.400000 23.850000)	
-G1262482	Munger	POINT(86.466670 25.383330)	
-G1262771	Morena	POINT(78.000000 26.496940)	
-G1262801	Morādābād	POINT(78.783330 28.833330)	
-G1262995	Mirzāpur	POINT(82.583330 25.150000)	
-G1263214	Meerut	POINT(77.700000 28.983330)	
-G1263220	Medinīpur	POINT(87.333330 22.433330)	
-G1263311	Mau	POINT(83.550000 25.950000)	
-G1263364	Mathura	POINT(77.683330 27.500000)	
-G1263780	Mangalore	POINT(74.883330 12.866670)	
-G1264115	Mālegaon	POINT(74.533330 20.550000)	
-G1264521	Madurai	POINT(78.116670 9.933330)	
-G1264527	Chennai	POINT(80.278470 13.087840)	
-G1264543	Madhyamgram	POINT(88.450000 22.700000)	
-G1264637	Machilīpatnam	POINT(81.133330 16.166670)	
-G1264728	Ludhiāna	POINT(75.850000 30.900000)	
-G1264733	Lucknow	POINT(80.916670 26.850000)	
-G1264773	Loni	POINT(77.283330 28.750000)	
-G1265014	Lātūr	POINT(76.583330 18.400000)	
-G1265711	Kulti	POINT(86.850000 23.733330)	
-G1265767	Kūkatpalli	POINT(78.416670 17.483330)	
-G1265873	Calicut	POINT(75.766670 11.250000)	
-G1266049	Kota	POINT(75.833330 25.183330)	
-G1266122	Korba	POINT(82.683330 22.350000)	
-G1266285	Kolhāpur	POINT(74.216670 16.700000)	
-G1266976	Kharagpur	POINT(87.333330 22.333330)	
-G1267031	Khandwa	POINT(76.333330 21.833330)	
-G1267076	Khammam	POINT(80.150000 17.250000)	
-G1267480	Katihār	POINT(87.583330 25.533330)	
-G1267708	Karnāl	POINT(76.983330 29.683330)	
-G1267755	Karīmnagar	POINT(79.150000 18.433330)	
-G1267995	Kānpur	POINT(80.350000 26.466670)	
-G1268159	Kānchipuram	POINT(79.716670 12.833330)	
-G1268257	Kāmārhāti	POINT(88.374720 22.671110)	
-G1268295	Kalyān	POINT(73.150000 19.250000)	
-G1268561	Kākināda	POINT(82.216670 16.933330)	
-G1268773	Jūnāgadh	POINT(70.466670 21.516670)	
-G1268782	Jalandhar	POINT(75.579170 31.325560)	
-G1268865	Jodhpur	POINT(73.030000 26.286670)	
-G1268907	Jīnd	POINT(76.316670 29.316670)	
-G1269006	Jhānsi	POINT(78.583330 25.433330)	
-G1269135	Jaunpur	POINT(82.683330 25.733330)	
-G1269280	Jāmuria	POINT(87.083330 23.700000)	
-G1269300	Jamshedpur	POINT(86.183330 22.800000)	
-G1269317	Jāmnagar	POINT(70.066670 22.466670)	
-G1269321	Jammu	POINT(74.866670 32.733330)	
-G1269395	Jālna	POINT(75.883330 19.833330)	
-G1269407	Jālgaon	POINT(75.566670 21.016670)	
-G1269515	Jaipur	POINT(75.816670 26.916670)	
-G1269633	Jabalpur	POINT(79.950060 23.166970)	
-G1269723	Ingrāj Bāzār	POINT(88.150000 25.000000)	
-G1269743	Indore	POINT(75.833300 22.717920)	
-G1269771	Imphāl	POINT(93.950000 24.816670)	
-G1269834	Ichalkaranji	POINT(74.466670 16.700000)	
-G1269843	Hyderābād	POINT(78.474440 17.375280)	
-G1269910	Hugli	POINT(88.402500 22.895560)	
-G1269920	Hubli	POINT(75.166670 15.350000)	
-G1269935	Hospet	POINT(76.400000 15.266670)	
-G1269937	Hoshiārpur	POINT(75.917220 31.532220)	
-G1270022	Hisār	POINT(75.716670 29.166670)	
-G1270351	Haridwār	POINT(78.166670 29.966670)	
-G1270393	Hāpur	POINT(77.783330 28.716670)	
-G1270396	Hāora	POINT(88.310280 22.589170)	
-G1270407	Hanumāngarh	POINT(74.316670 29.583330)	
-G1270583	Gwalior	POINT(78.179170 26.223610)	
-G1270642	Gurgaon	POINT(77.033330 28.466670)	
-G1270668	Guntūr	POINT(80.450000 16.300000)	
-G1270711	Guna	POINT(77.316670 24.650000)	
-G1270752	Gulbarga	POINT(76.833330 17.333330)	
-G1270926	Gorakhpur	POINT(75.683330 29.450000)	
-G1270927	Gorakhpur	POINT(83.373890 26.755000)	
-G1271308	Ghāziābād	POINT(77.433330 28.666670)	
-G1271439	Gaya	POINT(85.000000 24.783330)	
-G1271476	Guwāhāti	POINT(91.750950 26.186170)	
-G1271685	Gangānagar	POINT(73.883330 29.916670)	
-G1271715	Gāndhīnagar	POINT(72.683330 23.216670)	
-G1271850	Gadag	POINT(75.616670 15.416670)	
-G1271885	Fīrozābād	POINT(78.416670 27.150000)	
-G1271912	Fatehpur	POINT(80.800000 25.933330)	
-G1271942	Farrukhābād	POINT(79.566670 27.400000)	
-G1271951	Farīdābād	POINT(77.316670 28.433330)	
-G1271976	Faizābād	POINT(82.133330 26.783330)	
-G1271987	Etāwah	POINT(79.023900 26.776900)	
-G1272051	Elūru	POINT(81.100000 16.700000)	
-G1272175	Durgāpur	POINT(87.316670 23.483330)	
-G1272181	Durg	POINT(81.283330 21.183330)	
-G1272423	Dombivli	POINT(73.083330 19.216670)	
-G1272543	Dindigul	POINT(77.950000 10.350000)	
-G1272691	Dhule	POINT(74.783330 20.900000)	
-G1272979	Dhanbād	POINT(86.450000 23.800000)	
-G1273066	Dewās	POINT(76.066670 22.966670)	
-G1273294	Delhi	POINT(77.216670 28.666670)	
-G1273313	Dehra Dūn	POINT(78.033330 30.316670)	
-G1273491	Darbhanga	POINT(85.900000 26.166670)	
-G1273581	Dānāpur	POINT(85.050000 25.633330)	
-G1273780	Cuttack	POINT(85.879270 20.464970)	
-G1273802	Cuddalore	POINT(79.750000 11.750000)	
-G1273865	Coimbatore	POINT(76.966670 11.000000)	
-G1273874	Cochin	POINT(76.233330 9.966670)	
-G1274693	Chandrapur	POINT(79.300000 19.950000)	
-G1274746	Chandīgarh	POINT(76.793300 30.734300)	
-G1274784	Chandannagar	POINT(88.377220 22.869170)	
-G1275004	Calcutta	POINT(88.369720 22.569720)	
-G1275068	Burhānpur	POINT(76.233330 21.300000)	
-G1275120	Bulandshahr	POINT(77.850000 28.400000)	
-G1275163	Budaun	POINT(79.116670 28.050000)	
-G1275198	Brahmapur	POINT(84.783330 19.316670)	
-G1275248	Borivli	POINT(72.850000 19.233330)	
-G1275339	Mumbai	POINT(72.847940 19.014410)	
-G1275362	Bokāro	POINT(85.966670 23.783330)	
-G1275637	Bilāspur	POINT(82.150000 22.083330)	
-G1275665	Bīkāner	POINT(73.300000 28.016670)	
-G1275701	Bijāpur	POINT(75.700000 16.833330)	
-G1275716	Bihār Sharīf	POINT(85.516670 25.183330)	
-G1275738	Bīdar	POINT(77.550000 17.900000)	
-G1275778	Bhusāwal	POINT(75.766670 21.050000)	
-G1275817	Bhubaneshwar	POINT(85.833330 20.233330)	
-G1275841	Bhopāl	POINT(77.400000 23.266670)	
-G1275899	Bhiwāni	POINT(76.133330 28.783330)	
-G1275901	Bhiwandi	POINT(73.066670 19.300000)	
-G1275926	Bhind	POINT(78.788330 26.564170)	
-G1275960	Bhīlwāra	POINT(74.633330 25.350000)	
-G1275971	Bhilai	POINT(81.433330 21.216670)	
-G1276032	Bhāvnagar	POINT(72.150000 21.766670)	
-G1276058	Bhātpāra	POINT(88.408890 22.871390)	
-G1276070	Bhatinda	POINT(74.950000 30.200000)	
-G1276100	Bharūch	POINT(72.966670 21.700000)	
-G1276128	Bharatpur	POINT(77.483330 27.216670)	
-G1276300	Bhāgalpur	POINT(87.000000 25.250000)	
-G1276321	Bhadrāvati	POINT(75.716670 13.866670)	
-G1276509	Bellary	POINT(76.933330 15.150000)	
-G1276533	Belgaum	POINT(74.500000 15.866670)	
-G1277013	Bareilly	POINT(79.416670 28.350000)	
-G1277029	Barddhamān	POINT(87.850000 23.250000)	
-G1277065	Bārāsat	POINT(88.516670 22.716670)	
-G1277082	Baranagar	POINT(88.365280 22.643330)	
-G1277333	Bengalore	POINT(77.603290 12.976230)	
-G1277397	Bānda	POINT(80.333330 25.483330)	
-G1277539	Bāli	POINT(88.340280 22.646110)	
-G1277799	Bahraich	POINT(81.600000 27.583330)	
-G1277820	Baharampur	POINT(88.250000 24.100000)	
-G1277835	Bahādurgarh	POINT(76.916670 28.683330)	
-G1278130	Āvadi	POINT(80.101670 13.115560)	
-G1278149	Aurangābād	POINT(75.333330 19.883330)	
-G1278314	Āsansol	POINT(86.983330 23.683330)	
-G1278483	Ara	POINT(84.666670 25.566670)	
-G1278672	Anantapur	POINT(77.600000 14.683330)	
-G1278708	Amroha	POINT(78.466670 28.916670)	
-G1278710	Amritsar	POINT(74.865560 31.633060)	
-G1278718	Amrāvati	POINT(77.750000 20.933330)	
-G1278840	Ambattūr	POINT(80.162220 13.098330)	
-G1278903	Amarnāth	POINT(73.166670 19.200000)	
-G1278946	Alwar	POINT(76.600000 27.566670)	
-G1278985	Alleppey	POINT(76.326400 9.490040)	
-G1278994	Allahābād	POINT(81.850000 25.450000)	
-G1279017	Alīgarh	POINT(78.083330 27.883330)	
-G1279064	Alandur	POINT(80.206110 13.002500)	
-G1279105	Akola	POINT(77.000000 20.733330)	
-G1279159	Ajmer	POINT(74.633330 26.450000)	
-G1279186	Āīzawl	POINT(92.716670 23.733330)	
-G1279228	Ahmadnagar	POINT(74.733330 19.083330)	
-G1279233	Ahmadābād	POINT(72.616670 23.033330)	
-G1279259	Āgra	POINT(78.016670 27.183330)	
-G1279290	Agartala	POINT(91.275000 23.836390)	
-G1279335	Ādoni	POINT(77.283330 15.633330)	
-G1344377	Haldia	POINT(88.109750 22.060460)	
-G1348818	Nangi	POINT(88.215280 22.508330)	
-G6943660	Shivaji Nagar	POINT(73.852630 18.530170)	
-G7279746	Noida	POINT(77.330000 28.580000)	
-G7279754	Singrauli	POINT(82.675350 24.199730)	
-G7284820	Jaigaon	POINT(89.375580 26.847660)	
-G7302826	Lal Bahadur Nagar	POINT(78.557570 17.347690)	
-G7302833	Gajuwaka	POINT(83.216670 17.700000)	
-G7302845	Quthbullapur	POINT(78.458180 17.501070)	
-G7302856	Serilingampalle	POINT(78.301960 17.493130)	
-G91597	Sāmarrā’	POINT(43.875620 34.200960)	
-G94787	Kirkuk	POINT(44.392220 35.468060)	
-G94824	Karbalā’	POINT(44.008470 32.611440)	
-G95446	Arbīl	POINT(44.010620 36.192570)	
-G97990	Ba‘qūbah	POINT(44.655450 33.748460)	
-G98182	Baghdad	POINT(44.400880 33.340580)	
-G98463	As Sulaymānīyah	POINT(45.437490 35.561130)	
-G98530	As Samāwah	POINT(45.294400 31.331980)	
-G98717	Ar Ramādī	POINT(43.305840 33.422570)	
-G98854	An Nāşirīyah	POINT(46.261020 31.052050)	
-G98860	An Najaf al Ashraf	POINT(44.339760 31.998540)	
-G99071	Al Mawşil al Jadīdah	POINT(43.097770 36.334640)	
-G99072	Mosul	POINT(43.118890 36.335000)	
-G99131	Al Kūt	POINT(45.819020 32.514700)	
-G99347	Al Ḩillah	POINT(44.435260 32.480140)	
-G99454	Al Fallūjah	POINT(43.779510 33.353800)	
-G99532	Al Başrah	POINT(47.788850 30.534880)	
-G99608	Al ‘Amārah	POINT(47.139600 31.840640)	
-G99762	Ad Dīwānīyah	POINT(44.930630 31.990510)	
-G100077	Abū Ghurayb	POINT(44.185000 33.308330)	
-G388349	Al Başrat al Qadīmah	POINT(47.814910 30.497210)	
-G14256	Āzādshahr	POINT(48.570730 34.790880)	
-G23814	Kahrīz	POINT(47.055300 34.383800)	
-G32767	Qarchak	POINT(51.568890 35.439440)	
-G111453	Zanjān	POINT(48.478700 36.673600)	
-G111822	Yazd	POINT(54.367500 31.897220)	
-G112214	Varāmīn	POINT(51.645700 35.324200)	
-G112931	Tehrān	POINT(51.421510 35.694390)	
-G113646	Tabrīz	POINT(46.291900 38.080000)	
-G114259	Sīrjān	POINT(55.681400 29.452000)	
-G115019	Shīrāz	POINT(52.538800 29.603600)	
-G116667	Sāveh	POINT(50.356600 35.021300)	
-G116996	Shari-i-Tajan	POINT(53.056520 36.562970)	
-G117392	Saqqez	POINT(46.273500 36.249920)	
-G117574	Sanandaj	POINT(46.992300 35.314400)	
-G118063	Sabzevār	POINT(57.681910 36.212600)	
-G118743	Rasht	POINT(49.583190 37.280770)	
-G119208	Qom	POINT(50.876400 34.640100)	
-G119505	Qazvīn	POINT(50.004900 36.279700)	
-G121801	Orūmīyeh	POINT(45.076050 37.552740)	
-G122285	Neyshābūr	POINT(58.795760 36.213290)	
-G122438	Naz̧arābād	POINT(50.607500 35.952100)	
-G124665	Mashhad	POINT(59.606200 36.297000)	
-G125185	Malāyer	POINT(48.823500 34.296900)	
-G125446	Mahābād	POINT(45.722200 36.763100)	
-G126972	Khvoy	POINT(44.952100 38.550300)	
-G127319	Khorramshahr	POINT(48.166400 30.439700)	
-G127349	Khorramābād	POINT(48.355830 33.487780)	
-G128226	Kermānshāh	POINT(47.065000 34.314170)	
-G128234	Kermān	POINT(57.081230 30.293680)	
-G128477	Kāshān	POINT(51.436440 33.983080)	
-G128747	Karaj	POINT(51.010300 35.835500)	
-G132144	Hamadān	POINT(48.514560 34.799220)	
-G132892	Gorgān	POINT(54.434750 36.838660)	
-G139817	Bandar Būshehr	POINT(50.838500 28.968400)	
-G139889	Būkān	POINT(46.208900 36.521000)	
-G140044	Borūjerd	POINT(48.751600 33.897300)	
-G140380	Bojnūrd	POINT(57.329030 37.474730)	
-G140463	Bīrjand	POINT(59.221140 32.866280)	
-G141681	Bandar ‘Abbās	POINT(56.280800 27.186500)	
-G142363	Bābol	POINT(52.678950 36.551320)	
-G143083	Ardabīl	POINT(48.293300 38.249800)	
-G143127	Arāk	POINT(49.689160 34.091740)	
-G143534	Āmol	POINT(52.350720 36.469610)	
-G144448	Ahvāz	POINT(48.669300 31.320300)	
-G145459	Ābādān	POINT(48.304300 30.339200)	
-G418606	Najafābād	POINT(51.366800 32.634400)	
-G418710	Khomeynī Shahr	POINT(51.521130 32.700180)	
-G418863	Eşfahān	POINT(51.677610 32.657220)	
-G1159301	Zāhedān	POINT(60.862900 29.496300)	
-G2523630	Reggio di Calabria	POINT(15.661290 38.110470)	
-G2523920	Palermo	POINT(13.359760 38.115820)	
-G2524170	Messina	POINT(15.549690 38.193270)	
-G2525068	Catania	POINT(15.087190 37.502130)	
-G2525473	Cagliari	POINT(9.134620 39.207380)	
-G3164527	Verona	POINT(10.997790 45.434190)	
-G3164603	Venice	POINT(12.326670 45.438610)	
-G3165185	Trieste	POINT(13.780000 45.648610)	
-G3165524	Torino	POINT(7.686820 45.070490)	
-G3165926	Taranto	POINT(17.229720 40.476110)	
-G3169070	Roma	POINT(12.483900 41.894740)	
-G3169921	Prato	POINT(11.090920 43.884250)	
-G3171457	Parma	POINT(10.328980 44.802660)	
-G3171728	Padova	POINT(11.881810 45.415190)	
-G3172394	Napoli	POINT(14.250000 40.833330)	
-G3173331	Modena	POINT(10.925390 44.647830)	
-G3173435	Milano	POINT(9.189510 45.464270)	
-G3173529	Mestre	POINT(12.242500 45.490280)	
-G3174659	Livorno	POINT(10.316000 43.542640)	
-G3176219	Genova	POINT(8.933860 44.406320)	
-G3176885	Foggia	POINT(15.549250 41.460930)	
-G3176959	Florence	POINT(11.250000 43.766670)	
-G3181554	Brescia	POINT(10.227270 45.524780)	
-G3181928	Bologna	POINT(11.338750 44.493810)	
-G3182351	Bari	POINT(16.851180 41.117730)	
-G3489297	New Kingston	POINT(-76.783190 18.007470)	
-G3489854	Kingston	POINT(-76.793580 17.997020)	
-G246013	Wādī as Sīr	POINT(35.816670 31.950000)	
-G248946	Irbid	POINT(35.850000 32.555560)	
-G250090	Az Zarqā’	POINT(36.087960 32.072750)	
-G250441	Amman	POINT(35.945030 31.955220)	
-G1847963	Atsugi	POINT(139.359720 35.438890)	
-G1847966	Akashi	POINT(134.983330 34.633330)	
-G1848254	Yono	POINT(139.633330 35.883330)	
-G1848313	Yokosuka	POINT(139.667220 35.283610)	
-G1848354	Yokohama-shi	POINT(139.642500 35.447780)	
-G1848373	Yokkaichi	POINT(136.616670 34.966670)	
-G1848522	Yao	POINT(135.600000 34.616670)	
-G1849053	Utsunomiya-shi	POINT(139.883610 36.565830)	
-G1849372	Uji	POINT(135.800000 34.883330)	
-G1849498	Ube	POINT(131.251110 33.943060)	
-G1849796	Tsu-shi	POINT(136.508610 34.730280)	
-G1849814	Toyota	POINT(137.150000 35.083330)	
-G1849837	Toyonaka	POINT(135.469320 34.782440)	
-G1849846	Toyohashi	POINT(137.383330 34.766670)	
-G1849876	Toyama-shi	POINT(137.211390 36.695280)	
-G1849892	Tottori	POINT(134.233330 35.500000)	
-G1850147	Tokyo	POINT(139.581300 35.614880)	
-G1850158	Tokushima-shi	POINT(134.559440 34.065830)	
-G1850181	Tokorozawa	POINT(139.469030 35.799160)	
-G1850692	Nishi-Tokyo-shi	POINT(139.538300 35.725260)	
-G1850910	Takatsuki	POINT(135.616780 34.848330)	
-G1851002	Takasaki	POINT(139.016670 36.333330)	
-G1851012	Takarazuka	POINT(135.356970 34.799360)	
-G1851032	Takaoka	POINT(137.016670 36.750000)	
-G1851100	Takamatsu-shi	POINT(134.043330 34.340280)	
-G1851307	Tachikawa	POINT(139.418060 35.692780)	
-G1851348	Suzuka	POINT(136.583330 34.883330)	
-G1851483	Suita	POINT(135.515670 34.761430)	
-G1851604	Sōka	POINT(139.804440 35.820280)	
-G1851717	Shizuoka-shi	POINT(138.383060 34.976940)	
-G1852140	Shinagawa-ku	POINT(139.730170 35.609020)	
-G1852225	Shimonoseki	POINT(130.950000 33.950000)	
-G1852383	Shimminatochō	POINT(135.200000 34.183330)	
-G1852899	Sasebo	POINT(129.722780 33.159170)	
-G1853195	Sakai	POINT(135.466670 34.583330)	
-G1853295	Sagamihara	POINT(139.354440 35.553060)	
-G1853303	Saga-shi	POINT(130.298800 33.249320)	
-G1853483	Oyama	POINT(139.800000 36.300000)	
-G1853574	Ōtsu-shi	POINT(135.868330 35.004440)	
-G1853677	Ōta	POINT(139.366670 36.300000)	
-G1853909	Ōsaka-shi	POINT(135.502180 34.693740)	
-G1854376	Okazaki	POINT(137.166670 34.950000)	
-G1854383	Okayama-shi	POINT(133.935000 34.661670)	
-G1854487	Ōita-shi	POINT(131.612500 33.238060)	
-G1854703	Ōgaki	POINT(136.616670 35.350000)	
-G1854747	Odawara	POINT(139.159720 35.255560)	
-G1854902	Numazu	POINT(138.866670 35.100000)	
-G1855207	Nishinomiya	POINT(135.333330 34.716670)	
-G1855431	Niigata-shi	POINT(139.023610 37.902220)	
-G1855503	Nerima	POINT(139.650000 35.733330)	
-G1855612	Nara-shi	POINT(135.804850 34.685050)	
-G1856035	Naha-shi	POINT(127.681110 26.212500)	
-G1856057	Nagoya-shi	POINT(136.906410 35.181470)	
-G1856177	Nagasaki-shi	POINT(129.873610 32.744720)	
-G1856184	Nagareyama	POINT(139.902660 35.856300)	
-G1856199	Nagaoka	POINT(138.850000 37.450000)	
-G1856215	Nagano-shi	POINT(138.181110 36.651390)	
-G1856717	Miyazaki-shi	POINT(131.423890 31.911110)	
-G1856942	Mitaka-shi	POINT(139.559630 35.683510)	
-G1857144	Minami-rinkan	POINT(139.450000 35.483330)	
-G1857519	Matsumoto	POINT(137.966670 36.233330)	
-G1857550	Matsue-shi	POINT(133.050560 35.472220)	
-G1857553	Matsudo	POINT(139.900000 35.783330)	
-G1857843	Maebashi-shi	POINT(139.060830 36.391110)	
-G1857871	Machida	POINT(139.450830 35.540280)	
-G1857910	Kyoto	POINT(135.753850 35.021070)	
-G1858088	Kurume	POINT(130.516670 33.316670)	
-G1858296	Kure	POINT(132.566670 34.233330)	
-G1858311	Kurashiki	POINT(133.766670 34.583330)	
-G1858421	Kumamoto-shi	POINT(130.741670 32.789720)	
-G1858428	Kumagaya	POINT(139.383330 36.133330)	
-G1858729	Koshigaya	POINT(139.783330 35.883330)	
-G1858926	Komaki	POINT(136.916670 35.283330)	
-G1859100	Kōfu-shi	POINT(138.568330 35.663890)	
-G1859116	Kodaira	POINT(139.483890 35.726390)	
-G1859146	Kōchi-shi	POINT(133.531110 33.559720)	
-G1859171	Kōbe-shi	POINT(135.183000 34.691300)	
-G1859307	Kitakyūshū	POINT(130.833330 33.833330)	
-G1859383	Kishiwada	POINT(135.366670 34.466670)	
-G1859642	Kawasaki	POINT(139.717220 35.520560)	
-G1859675	Kawanishi	POINT(135.416670 34.816670)	
-G1859730	Kawaguchi	POINT(139.720560 35.805000)	
-G1859740	Kawagoe	POINT(139.485280 35.908610)	
-G1859884	Kasukabe	POINT(139.753610 35.976390)	
-G1859891	Kasugai	POINT(136.972290 35.247620)	
-G1859924	Kashiwa	POINT(139.968890 35.854440)	
-G1860243	Kanazawa-shi	POINT(136.625560 36.594440)	
-G1860437	Kami-renjaku	POINT(139.550000 35.683330)	
-G1860672	Kamakura	POINT(139.550280 35.308890)	
-G1860704	Kakogawa	POINT(134.850000 34.766670)	
-G1860827	Kagoshima-shi	POINT(130.558140 31.560180)	
-G1861107	Izumi	POINT(135.433330 34.483330)	
-G1861310	Itami	POINT(135.401260 34.784270)	
-G1861949	Ichinomiya	POINT(136.800000 35.300000)	
-G1861968	Ichikawa	POINT(139.924720 35.719720)	
-G1862033	Ibaraki	POINT(135.568280 34.816410)	
-G1862415	Hiroshima-shi	POINT(132.459370 34.396270)	
-G1862462	Hiratsuka	POINT(139.342220 35.323060)	
-G1862540	Hirakata	POINT(135.649140 34.813520)	
-G1862599	Hino	POINT(139.400280 35.673060)	
-G1862627	Himeji	POINT(134.700000 34.816670)	
-G1863289	Hamamatsu	POINT(137.733330 34.700000)	
-G1863431	Hadano	POINT(139.223610 35.371110)	
-G1863440	Hachiōji	POINT(139.323890 35.655830)	
-G1863641	Gifu-shi	POINT(136.760390 35.422910)	
-G1863905	Funabashi	POINT(139.983330 35.693060)	
-G1863917	Fukuyama	POINT(133.366670 34.483330)	
-G1863967	Fukuoka-shi	POINT(130.418060 33.606390)	
-G1863985	Fukui-shi	POINT(136.222570 36.064430)	
-G1864092	Fujisawa	POINT(139.470000 35.341940)	
-G1864134	Fuji	POINT(138.683330 35.166670)	
-G1864154	Fuchū	POINT(139.483330 35.666670)	
-G1864518	Chōfu	POINT(139.552220 35.655560)	
-G1864624	Chigasaki	POINT(139.403890 35.326110)	
-G1865005	Ashikaga	POINT(139.450000 36.333330)	
-G1865294	Anjō	POINT(137.080540 34.958280)	
-G1865387	Amagasaki	POINT(135.416670 34.716670)	
-G1865714	Ageo	POINT(139.588610 35.969720)	
-G1907146	Sayama	POINT(139.412120 35.852950)	
-G1926004	Wakayama-shi	POINT(135.167500 34.226110)	
-G1926099	Matsuyama-shi	POINT(132.765740 33.839160)	
-G2110556	Yamagata-shi	POINT(140.363330 38.240560)	
-G2110683	Tsukuba	POINT(140.100000 36.200000)	
-G2111149	Sendai-shi	POINT(140.871940 38.268890)	
-G2111220	Sakura	POINT(140.233330 35.716670)	
-G2111687	Narashino	POINT(140.033330 35.683330)	
-G2111834	Morioka-shi	POINT(141.152500 39.703610)	
-G2111901	Mito-shi	POINT(140.446670 36.341390)	
-G2112141	Kōriyama	POINT(140.383330 37.400000)	
-G2112312	Katsuta	POINT(140.533330 36.383330)	
-G2112539	Iwaki	POINT(140.883330 37.050000)	
-G2112664	Ichihara	POINT(140.083330 35.516670)	
-G2112708	Hitachi	POINT(140.650000 36.600000)	
-G2112923	Fukushima-shi	POINT(140.467780 37.750000)	
-G2113015	Chiba-shi	POINT(140.123330 35.604720)	
-G2113126	Akita	POINT(140.116670 39.716670)	
-G2113719	Akita-shi	POINT(140.103330 39.718060)	
-G2127733	Tomakomai	POINT(141.603330 42.636940)	
-G2128295	Sapporo-shi	POINT(141.346940 43.064170)	
-G2128815	Obihiro	POINT(143.204440 42.917220)	
-G2129376	Kushiro	POINT(144.374720 42.975000)	
-G2130057	Hirosaki	POINT(140.472500 40.593060)	
-G2130188	Hakodate	POINT(140.736670 41.775830)	
-G2130203	Hachinohe	POINT(141.500000 40.500000)	
-G2130629	Asahikawa	POINT(142.370280 43.767780)	
-G2130658	Aomori-shi	POINT(140.740000 40.824440)	
-G6697563	Neyagawa	POINT(135.627590 34.766150)	
-G6822096	Hitachi-Naka	POINT(140.534790 36.396590)	
-G6825489	Jōetsu	POINT(138.236420 37.148280)	
-G6940394	Saitama	POINT(139.656570 35.908070)	
-G7279570	Higashimurayama-shi	POINT(139.468520 35.754590)	
-G184622	Nakuru	POINT(36.066670 -0.283330)	
-G184745	Nairobi	POINT(36.816670 -1.283330)	
-G186301	Mombasa	POINT(39.660500 -4.055000)	
-G191245	Kisumu	POINT(34.750000 -0.100000)	
-G198629	Eldoret	POINT(35.269920 0.520360)	
-G1527534	Osh	POINT(72.790000 40.529440)	
-G1528675	Bishkek	POINT(74.590000 42.870000)	
-G1821306	Phnom Penh	POINT(104.916010 11.562450)	
-G1831142	Sihanoukville	POINT(103.529580 10.609320)	
-G1831797	Bătdâmbâng	POINT(103.198220 13.102710)	
-G1866923	Wŏnsan	POINT(127.443610 39.152780)	
-G1869446	Songnim	POINT(125.645000 38.754170)	
-G1870883	Sariwŏn	POINT(125.755830 38.507220)	
-G1871859	Pyongyang	POINT(125.754320 39.033850)	
-G1873757	Namp’o	POINT(125.407780 38.737500)	
-G1876373	Kaesŏng	POINT(126.554440 37.970830)	
-G1877030	Hŭngnam	POINT(127.618610 39.831670)	
-G1877449	Hamhŭng	POINT(127.536390 39.918330)	
-G1877615	Haeju	POINT(125.714720 38.040560)	
-G2040893	Sinŭiju	POINT(124.398060 40.100560)	
-G2043572	Kanggye-si	POINT(126.585230 40.969460)	
-G2044757	Ch’ŏngjin	POINT(129.775830 41.795560)	
-G1832157	Yŏsu	POINT(127.737780 34.744170)	
-G1832847	Yangju	POINT(127.061690 37.833110)	
-G1833105	Wŏnju	POINT(127.945280 37.351390)	
-G1833747	Ulsan	POINT(129.316670 35.537220)	
-G1833788	Ŭijŏngbu	POINT(127.047400 37.741500)	
-G1835235	Taejŏn	POINT(127.419720 36.321390)	
-G1835329	Taegu	POINT(128.591110 35.870280)	
-G1835553	Suwŏn	POINT(127.008890 37.291110)	
-G1835648	Sunch’ŏn	POINT(127.489470 34.948080)	
-G1835848	Seoul	POINT(126.977830 37.568260)	
-G1838524	Pusan	POINT(129.040280 35.102780)	
-G1838716	Puch’ŏn	POINT(126.783060 37.498890)	
-G1839071	P’ohang	POINT(129.365000 36.032220)	
-G1839652	Osan	POINT(127.070560 37.152220)	
-G1841066	Mokp’o	POINT(126.388610 34.793610)	
-G1841245	Masan	POINT(128.572500 35.208060)	
-G1841603	Kyŏngju	POINT(129.211670 35.842780)	
-G1841811	Kwangju	POINT(126.915560 35.154720)	
-G1841988	Kuri	POINT(127.139400 37.598600)	
-G1842025	Kunsan	POINT(126.711390 35.978610)	
-G1842225	Kumi	POINT(128.336000 36.113600)	
-G1842485	Goyang	POINT(126.835000 37.656390)	
-G1842943	Kimhae	POINT(128.881110 35.234170)	
-G1843137	Kangnŭng	POINT(128.896110 37.755560)	
-G1843491	Iksan	POINT(126.954440 35.943890)	
-G1843564	Inch’ŏn	POINT(126.731670 37.453610)	
-G1843702	Ich'ŏn	POINT(127.442500 37.279170)	
-G1843847	Hwaseong	POINT(126.816900 37.206820)	
-G1845136	Ch’unch’ŏn	POINT(127.734170 37.874720)	
-G1845457	Chŏnju	POINT(127.148890 35.821940)	
-G1845604	Ch’ŏngju	POINT(127.489720 36.637220)	
-G1845759	Ch’ŏnan	POINT(127.152200 36.806500)	
-G1846052	Chinju	POINT(128.084720 35.192780)	
-G1846266	Cheju	POINT(126.521940 33.509720)	
-G1846326	Ch’angwŏn	POINT(128.681110 35.228060)	
-G1846898	Anyang	POINT(126.926940 37.392500)	
-G1846918	Ansan	POINT(126.821940 37.323610)	
-G1897000	Sŏngnam	POINT(127.137780 37.438610)	
-G1948005	Kwangmyŏng	POINT(126.866390 37.477220)	
-G608668	Oral	POINT(51.366670 51.233330)	
-G609655	Karagandy	POINT(54.866670 50.066670)	
-G610529	Atyrau	POINT(51.883330 47.116670)	
-G610611	Aqtöbe	POINT(57.207180 50.279690)	
-G1516905	Taraz	POINT(71.366670 42.900000)	
-G1518262	Temirtau	POINT(72.948330 50.054440)	
-G1518543	Taldyqorghan	POINT(77.916670 45.000000)	
-G1518980	Shymkent	POINT(69.600000 42.300000)	
-G1519422	Semey	POINT(80.227500 50.411110)	
-G1519922	Qyzylorda	POINT(65.509170 44.852780)	
-G1519928	Qostanay	POINT(63.583330 53.166670)	
-G1519942	Qaraghandy	POINT(73.099440 49.798890)	
-G1520172	Petropavlovsk	POINT(69.162780 54.875280)	
-G1520240	Pavlodar	POINT(76.950000 52.300000)	
-G1520316	Ust’-Kamenogorsk	POINT(82.610280 49.978890)	
-G1526273	Astana	POINT(71.445980 51.180100)	
-G1526384	Almaty	POINT(76.950000 43.250000)	
-G1651944	Vientiane	POINT(102.600000 17.966670)	
-G266826	Tripoli	POINT(35.849720 34.436670)	
-G268064	Sidon	POINT(35.368890 33.563060)	
-G268743	Ra’s Bayrūt	POINT(35.483330 33.900000)	
-G276781	Beirut	POINT(35.494420 33.888940)	
-G1234633	Moratuwa	POINT(79.881600 6.773000)	
-G1242833	Jaffna	POINT(80.013700 9.656700)	
-G1246321	Galkissa	POINT(79.863000 6.829300)	
-G1248991	Colombo	POINT(79.847780 6.931940)	
-G2274895	Monrovia	POINT(-10.796900 6.300540)	
-G593116	Vilnius	POINT(25.279800 54.689160)	
-G598098	Klaipėda	POINT(21.117500 55.717220)	
-G598316	Kaunas	POINT(23.900000 54.900000)	
-G456172	Riga	POINT(24.105890 56.946000)	
-G88319	Banghāzī	POINT(20.066670 32.116670)	
-G89055	Al Bayḑā’	POINT(21.755060 32.762720)	
-G2210221	Tarhūnah	POINT(13.633200 32.435020)	
-G2210247	Tripoli	POINT(13.187460 32.875190)	
-G2214846	Mişrātah	POINT(15.092540 32.375350)	
-G2216885	Ḩārat az Zāwiyah	POINT(12.715000 32.763060)	
-G2219905	Al Khums	POINT(14.266670 32.650000)	
-G2528910	Tétouan	POINT(-5.372420 35.571090)	
-G2530335	Tangier	POINT(-5.813650 35.780580)	
-G2537763	Salé	POINT(-6.816600 34.038920)	
-G2537881	Safi	POINT(-9.237180 32.299390)	
-G2538475	Rabat	POINT(-6.832550 34.013250)	
-G2540483	Oujda	POINT(-1.907640 34.680520)	
-G2542051	Mohammedia	POINT(-7.394420 33.706590)	
-G2542715	Meknès	POINT(-5.547270 33.893520)	
-G2542997	Marrakech	POINT(-8.008280 31.631480)	
-G2544248	Khouribga	POINT(-6.906300 32.881080)	
-G2544571	Kenitra	POINT(-6.580200 34.261010)	
-G2548885	Fès	POINT(-4.999800 34.037150)	
-G2553604	Casablanca	POINT(-7.619160 33.592780)	
-G2555745	Beni Mellal	POINT(-6.349840 32.337250)	
-G2561668	Agadir	POINT(-9.598150 30.420180)	
-G617239	Tiraspol	POINT(29.643330 46.840280)	
-G618426	Chişinău	POINT(28.857500 47.005560)	
-G1053384	Toamasina	POINT(49.383330 -18.166670)	
-G1062663	Mahajanga	POINT(46.316670 -15.716670)	
-G1064890	Fianarantsoa	POINT(47.083330 -21.433330)	
-G1070940	Antananarivo	POINT(47.530980 -18.914330)	
-G785842	Skopje	POINT(21.433330 42.000000)	
-G2460596	Bamako	POINT(-8.000000 12.650000)	
-G1293960	Taunggyi	POINT(97.033330 20.783330)	
-G1295765	Akyab	POINT(92.900000 20.150000)	
-G1298824	Rangoon	POINT(96.156110 16.805280)	
-G1300466	Bago	POINT(96.479720 17.336670)	
-G1308465	Mawlamyine	POINT(97.625560 16.491390)	
-G1308522	Monywa	POINT(95.133330 22.116670)	
-G1309611	Myeik	POINT(98.600000 12.433330)	
-G1309793	Meiktila	POINT(95.866670 20.866670)	
-G1311874	Mandalay	POINT(96.083590 21.974730)	
-G1328421	Pathein	POINT(94.733330 16.783330)	
-G6611854	Nay Pyi Taw	POINT(96.129720 19.745000)	
-G2028462	Ulaanbaatar	POINT(106.883240 47.907710)	
-G1821274	Macau	POINT(113.546110 22.200560)	
-G2377450	Nouakchott	POINT(-15.949750 18.100330)	
-G934154	Port Louis	POINT(57.498890 -20.161940)	
-G927967	Lilongwe	POINT(33.783330 -13.983330)	
-G931755	Blantyre	POINT(35.013870 -15.786820)	
-G3514450	Xochimilco	POINT(-99.107500 19.262220)	
-G3514519	Xico	POINT(-98.933330 19.266670)	
-G3514663	Alvaro Obregón	POINT(-99.225000 19.373330)	
-G3514670	Villahermosa	POINT(-92.916670 17.983330)	
-G3514674	Gustavo A. Madero	POINT(-99.095830 19.478610)	
-G3514783	Veracruz	POINT(-96.133330 19.200000)	
-G3515001	Tuxtla Gutiérrez	POINT(-93.116670 16.750000)	
-G3515302	Toluca	POINT(-99.667220 19.288330)	
-G3515428	Tlalpan	POINT(-99.166670 19.283330)	
-G3515431	Tlalnepantla	POINT(-99.221670 19.526940)	
-G3515463	Tlahuac	POINT(-99.003330 19.281670)	
-G3515807	Cuautitlán Izcalli	POINT(-99.246670 19.646940)	
-G3516109	Tehuacán	POINT(-97.383330 18.450000)	
-G3516266	Tapachula	POINT(-92.283330 14.900000)	
-G3516355	Tampico	POINT(-97.850000 22.216670)	
-G3518135	San Pablo de las Salinas	POINT(-99.096390 19.665830)	
-G3520339	Reynosa	POINT(-98.283330 26.083330)	
-G3521081	Puebla de Zaragoza	POINT(-98.200000 19.050000)	
-G3521168	Poza Rica de Hidalgo	POINT(-97.459460 20.533150)	
-G3522210	Pachuca de Soto	POINT(-98.733290 20.116970)	
-G3522507	Oaxaca de Juárez	POINT(-96.716670 17.050000)	
-G3522551	Nuevo Laredo	POINT(-99.516670 27.500000)	
-G3522732	Nicolás Romero	POINT(-99.313060 19.621940)	
-G3522790	Naucalpan de Juárez	POINT(-99.239630 19.478510)	
-G3523183	Minatitlán	POINT(-94.516670 17.983330)	
-G3523303	Metepec	POINT(-99.607780 19.253610)	
-G3523349	Mérida	POINT(-89.616670 20.966670)	
-G3523466	Heroica Matamoros	POINT(-97.500000 25.883330)	
-G3523760	Magdalena Contreras	POINT(-99.233330 19.283330)	
-G3523908	Los Reyes	POINT(-98.966670 19.350000)	
-G3526485	Jiutepec	POINT(-99.183330 18.866670)	
-G3526617	Jalapa Enríquez	POINT(-96.916670 19.533330)	
-G3526682	Ixtapaluca	POINT(-98.883330 19.316670)	
-G3526683	Iztapalapa	POINT(-99.051940 19.351110)	
-G3526700	Iztacalco	POINT(-99.084720 19.396670)	
-G3529612	Ecatepec	POINT(-99.052500 19.601110)	
-G3529947	Cuernavaca	POINT(-99.250000 18.916670)	
-G3530049	Cuajimalpa	POINT(-99.301110 19.355830)	
-G3530139	Coyoacán	POINT(-99.160280 19.328890)	
-G3530517	Coatzacoalcos	POINT(-94.416670 18.150000)	
-G3530569	Coacalco	POINT(-99.110280 19.631670)	
-G3530580	Ciudad Victoria	POINT(-99.133330 23.733330)	
-G3530589	Ciudad Nezahualcóyotl	POINT(-99.033060 19.413610)	
-G3530594	Ciudad Madero	POINT(-97.833330 22.266670)	
-G3530597	Mexico City	POINT(-99.127660 19.428470)	
-G3530757	Cholula	POINT(-98.303520 19.064060)	
-G3530870	Chilpancingo de los Bravos	POINT(-99.500000 17.550000)	
-G3531200	Chalco de Díaz Covarrubias	POINT(-98.900000 19.266670)	
-G3531673	Cancún	POINT(-86.846560 21.174290)	
-G3531732	Campeche	POINT(-90.533330 19.850000)	
-G3532497	Azcapotzalco	POINT(-99.183610 19.488890)	
-G3532624	Ciudad López Mateos	POINT(-99.261390 19.558330)	
-G3533462	Acapulco de Juárez	POINT(-99.890100 16.863360)	
-G3827406	Benito Juarez	POINT(-99.165000 19.385000)	
-G3827407	Venustiano Carranza	POINT(-99.099170 19.430000)	
-G3827408	Miguel Hidalgo	POINT(-99.202780 19.422500)	
-G3827409	Cuauhtémoc	POINT(-99.156940 19.417220)	
-G3979770	Zapopan	POINT(-103.400000 20.716670)	
-G3980760	Uruapan del Progreso	POINT(-102.066670 19.416670)	
-G3981254	Torreón	POINT(-103.433330 25.550000)	
-G3981369	Tonalá	POINT(-103.233330 20.616670)	
-G3981461	Tlaquepaque	POINT(-103.316670 20.650000)	
-G3981609	Tijuana	POINT(-117.016670 32.533330)	
-G3981941	Tepic	POINT(-104.900000 21.500000)	
-G3982912	Soledad Díez Gutiérrez	POINT(-100.950000 22.200000)	
-G3984583	Santa Catarina	POINT(-100.458130 25.673250)	
-G3985241	San Nicolás de los Garza	POINT(-100.300000 25.750000)	
-G3985606	San Luis Potosí	POINT(-100.983330 22.150000)	
-G3988086	Saltillo	POINT(-101.000000 25.416670)	
-G3991164	Querétaro	POINT(-100.383330 20.600000)	
-G3991328	Puerto Vallarta	POINT(-105.230660 20.620410)	
-G3995402	Morelia	POINT(-101.184430 19.700780)	
-G3995465	Monterrey	POINT(-100.316670 25.666670)	
-G3995523	Monclova	POINT(-101.416670 26.900000)	
-G3996069	Mexicali	POINT(-115.468330 32.651940)	
-G3996322	Mazatlán	POINT(-106.416670 23.216670)	
-G3997479	Los Mochis	POINT(-108.966670 25.766670)	
-G3998655	León	POINT(-101.666670 21.116670)	
-G4000900	La Paz	POINT(-110.300000 24.166670)	
-G4004330	Irapuato	POINT(-101.350000 20.683330)	
-G4004886	Heroica Nogales	POINT(-110.933330 31.333330)	
-G4004898	Hermosillo	POINT(-110.966670 29.066670)	
-G4005492	Guadalupe	POINT(-100.250000 25.683330)	
-G4005539	Guadalajara	POINT(-103.333330 20.666670)	
-G4005775	Gómez Palacio	POINT(-103.500000 25.566670)	
-G4005867	General Escobedo	POINT(-100.333330 25.816670)	
-G4006702	Ensenada	POINT(-116.616670 31.866670)	
-G4011743	Durango	POINT(-104.666670 24.033330)	
-G4012176	Culiacán	POINT(-107.389720 24.799440)	
-G4013704	Ciudad Obregón	POINT(-109.933330 27.483330)	
-G4013708	Ciudad Juárez	POINT(-106.483330 31.733330)	
-G4014338	Chihuahua	POINT(-106.083330 28.633330)	
-G4014875	Celaya	POINT(-100.816670 20.516670)	
-G4018390	Apodaca	POINT(-100.200000 25.766670)	
-G4019233	Aguascalientes	POINT(-102.300000 21.883330)	
-G7280708	Colonia del Valle	POINT(-99.162040 19.386110)	
-G1732687	Batu Pahat	POINT(102.933330 1.850000)	
-G1732745	Sekudai	POINT(103.666670 1.533330)	
-G1732752	Johor Bahru	POINT(103.757800 1.465500)	
-G1732811	Kluang	POINT(103.332800 2.025100)	
-G1732903	Shah Alam	POINT(101.532810 3.085070)	
-G1732905	Klang	POINT(101.450000 3.033330)	
-G1733432	Kota Kinabalu	POINT(116.066670 5.983330)	
-G1734052	Sandakan	POINT(118.117900 5.840200)	
-G1734199	Tawau	POINT(117.900000 4.250000)	
-G1734393	Kulim	POINT(100.561770 5.364990)	
-G1734586	Taiping	POINT(100.733330 4.850000)	
-G1734634	Ipoh	POINT(101.082900 4.584100)	
-G1734705	Kuala Terengganu	POINT(103.140800 5.330200)	
-G1734759	Melaka	POINT(102.248060 2.196940)	
-G1734810	Seremban	POINT(101.933330 2.716670)	
-G1735079	Bukit Mertajam	POINT(100.466700 5.363010)	
-G1735106	George Town	POINT(100.335430 5.411230)	
-G1735158	Petaling Jaya	POINT(101.606710 3.107260)	
-G1735161	Kuala Lumpur	POINT(101.686530 3.141200)	
-G1735227	Kuantan	POINT(103.326000 3.807700)	
-G1735498	Sungai Petani	POINT(100.487720 5.647000)	
-G1735634	Kuching	POINT(110.333330 1.550000)	
-G1735902	Sibu	POINT(111.816670 2.300000)	
-G1736309	Alor Setar	POINT(100.360140 6.121040)	
-G1736376	Kota Bharu	POINT(102.238600 6.133280)	
-G1737486	Bintulu	POINT(113.033330 3.166670)	
-G1738050	Miri	POINT(113.983330 4.383330)	
-G1771023	Kampung Baru Subang	POINT(101.533330 3.150000)	
-G1028434	Quelimane	POINT(36.888330 -17.878610)	
-G1033356	Nampula	POINT(39.266600 -15.116460)	
-G1035025	Cidade de Nacala	POINT(40.672780 -14.542780)	
-G1039854	Matola	POINT(32.458890 -25.962220)	
-G1040652	Maputo	POINT(32.589170 -25.965280)	
-G1049261	Chimoio	POINT(33.483330 -19.116390)	
-G1052373	Beira	POINT(34.838890 -19.843610)	
-G3352136	Windhoek	POINT(17.083230 -22.559410)	
-G2437798	Zinder	POINT(8.988370 13.804870)	
-G2440485	Niamey	POINT(2.111780 13.512500)	
-G2441291	Maradi	POINT(7.101740 13.500000)	
-G2317765	Zaria	POINT(7.725180 11.113240)	
-G2319133	Warri	POINT(5.750000 5.516670)	
-G2320576	Umuahia	POINT(7.489590 5.526270)	
-G2320831	Ugep	POINT(8.081200 5.808600)	
-G2322794	Abuja	POINT(7.180830 9.175830)	
-G2322911	Sokoto	POINT(5.239020 13.060920)	
-G2323390	Saki	POINT(3.383330 8.666670)	
-G2323411	Shagamu	POINT(3.647760 6.843230)	
-G2323675	Sapele	POINT(5.676660 5.894050)	
-G2324774	Port Harcourt	POINT(7.013400 4.777420)	
-G2325200	Oyo	POINT(3.933330 7.850000)	
-G2325314	Owo	POINT(5.586810 7.196200)	
-G2325330	Owerri	POINT(7.030410 5.483330)	
-G2326016	Onitsha	POINT(6.788450 6.145430)	
-G2326171	Ondo	POINT(4.833330 7.100000)	

<TRUNCATED>

[41/50] [abbrv] lucene-solr git commit: SOLR-8698: changes the example config to reflect the new behavior

Posted by ho...@apache.org.
SOLR-8698: changes the example config to reflect the new behavior


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/1734d03e
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/1734d03e
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/1734d03e

Branch: refs/heads/jira/SOLR-445
Commit: 1734d03eb9f92d53f99b5652e239064519e1ba79
Parents: 6c08461
Author: Noble Paul <no...@apache.org>
Authored: Tue Mar 1 09:29:30 2016 +0530
Committer: Noble Paul <no...@apache.org>
Committed: Tue Mar 1 09:29:30 2016 +0530

----------------------------------------------------------------------
 solr/example/files/conf/params.json    |  6 +++++-
 solr/example/files/conf/solrconfig.xml | 11 ++---------
 2 files changed, 7 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/1734d03e/solr/example/files/conf/params.json
----------------------------------------------------------------------
diff --git a/solr/example/files/conf/params.json b/solr/example/files/conf/params.json
index d93c1d9..22aadcc 100644
--- a/solr/example/files/conf/params.json
+++ b/solr/example/files/conf/params.json
@@ -22,9 +22,13 @@
     "debug":"true",
     "hl.simple.pre":"HL_START",
     "hl.simple.post":"HL_END",
+    "echoParams": "explicit",
+    "_appends_": {
+      "fq": "{!switch v=$type tag=type case='*:*' case.all='*:*' case.unknown='-doc_type:[* TO *]' default=$type_fq}"
+    },
     "":{"v":0}},
   "velocity":{
     "wt":"velocity",
     "v.template":"browse",
     "v.layout":"layout",
-    "":{"v":0}}}}
\ No newline at end of file
+    "":{"v":0}}}}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/1734d03e/solr/example/files/conf/solrconfig.xml
----------------------------------------------------------------------
diff --git a/solr/example/files/conf/solrconfig.xml b/solr/example/files/conf/solrconfig.xml
index 638e013..9f0bd38 100644
--- a/solr/example/files/conf/solrconfig.xml
+++ b/solr/example/files/conf/solrconfig.xml
@@ -804,15 +804,8 @@
   </requestHandler>
 
 
-  <requestHandler name="/browse" class="solr.SearchHandler" useParams="query,facets,velocity,browse">
-    <lst name="defaults">
-      <str name="echoParams">explicit</str>
-    </lst>
-
-    <lst name="appends">
-      <str name="fq">{!switch v=$type tag=type case='*:*' case.all='*:*' case.unknown='-doc_type:[* TO *]' default=$type_fq}</str>
-    </lst>
-  </requestHandler>
+  <!--These useParams values are available in params.json-->
+  <requestHandler name="/browse" class="solr.SearchHandler" useParams="query,facets,velocity,browse"/>
 
 
   <initParams path="/update/**,/query,/select,/tvrh,/elevate,/spell,/browse">


[48/50] [abbrv] lucene-solr git commit: SOLR-8738: Fixed false success response when invalid deleteByQuery requests intially hit non-leader cloud nodes

Posted by ho...@apache.org.
SOLR-8738: Fixed false success response when invalid deleteByQuery requests intially hit non-leader cloud nodes


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/ff6557cb
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/ff6557cb
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/ff6557cb

Branch: refs/heads/jira/SOLR-445
Commit: ff6557cbcb5308d60f17114de1d0ad29003e9668
Parents: 2a7314b
Author: Chris Hostetter <ho...@apache.org>
Authored: Tue Mar 1 10:02:07 2016 -0700
Committer: Chris Hostetter <ho...@apache.org>
Committed: Tue Mar 1 10:02:07 2016 -0700

----------------------------------------------------------------------
 solr/CHANGES.txt                                |   3 +
 .../processor/DistributedUpdateProcessor.java   |   2 +-
 .../solr/cloud/TestCloudDeleteByQuery.java      | 245 +++++++++++++++++++
 3 files changed, 249 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ff6557cb/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index fb64188..c0d3d86 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -228,6 +228,9 @@ Bug Fixes
 
 * SOLR-8375: ReplicaAssigner rejects valid nodes (Kelvin Tan, noble)
 
+* SOLR-8738: Fixed false success response when invalid deleteByQuery requests intially hit non-leader
+  cloud nodes (hossman)
+
 Optimizations
 ----------------------
 * SOLR-7876: Speed up queries and operations that use many terms when timeAllowed has not been

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ff6557cb/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java
index c68445c..365de6c 100644
--- a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java
+++ b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java
@@ -1284,7 +1284,7 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor {
           // don't forward to ourself
           leaderForAnyShard = true;
         } else {
-          leaders.add(new StdNode(coreLeaderProps, collection, sliceName));
+          leaders.add(new RetryNode(coreLeaderProps, zkController.getZkStateReader(), collection, sliceName));
         }
       }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ff6557cb/solr/core/src/test/org/apache/solr/cloud/TestCloudDeleteByQuery.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestCloudDeleteByQuery.java b/solr/core/src/test/org/apache/solr/cloud/TestCloudDeleteByQuery.java
new file mode 100644
index 0000000..a0bb42a
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/cloud/TestCloudDeleteByQuery.java
@@ -0,0 +1,245 @@
+/*
+ * 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.solr.cloud;
+
+import java.io.File;
+import java.lang.invoke.MethodHandles;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.solr.cloud.SolrCloudTestCase;
+import org.apache.solr.client.solrj.SolrClient;
+import org.apache.solr.client.solrj.embedded.JettySolrRunner;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
+import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.request.UpdateRequest;
+import org.apache.solr.client.solrj.response.UpdateResponse;
+import org.apache.solr.common.SolrDocument;
+import org.apache.solr.common.SolrDocumentList;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.SolrInputField;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.cloud.ClusterState;
+import org.apache.solr.common.cloud.Replica;
+import org.apache.solr.common.cloud.Slice;
+import org.apache.solr.common.cloud.ZkStateReader;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.util.SimpleOrderedMap;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TestCloudDeleteByQuery extends SolrCloudTestCase {
+
+  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+  private static final int NUM_SHARDS = 2; 
+  private static final int REPLICATION_FACTOR = 2; 
+  private static final int NUM_SERVERS = 5; 
+  
+  private static final String COLLECTION_NAME = "test_col";
+  
+  /** A basic client for operations at the cloud level, default collection will be set */
+  private static CloudSolrClient CLOUD_CLIENT;
+
+  /** A client for talking directly to the leader of shard1 */
+  private static HttpSolrClient S_ONE_LEADER_CLIENT;
+  
+  /** A client for talking directly to the leader of shard2 */
+  private static HttpSolrClient S_TWO_LEADER_CLIENT;
+
+  /** A client for talking directly to a passive replica of shard1 */
+  private static HttpSolrClient S_ONE_NON_LEADER_CLIENT;
+  
+  /** A client for talking directly to a passive replica of shard2 */
+  private static HttpSolrClient S_TWO_NON_LEADER_CLIENT;
+
+  /** A client for talking directly to a node that has no piece of the collection */
+  private static HttpSolrClient NO_COLLECTION_CLIENT;
+  
+  /** id field doc routing prefix for shard1 */
+  private static final String S_ONE_PRE = "abc!";
+  
+  /** id field doc routing prefix for shard2 */
+  private static final String S_TWO_PRE = "XYZ!";
+  
+  @BeforeClass
+  private static void createMiniSolrCloudCluster() throws Exception {
+    
+    final String configName = "solrCloudCollectionConfig";
+    File configDir = new File(TEST_HOME() + File.separator + "collection1" + File.separator + "conf");
+    
+    configureCluster(NUM_SERVERS)
+      .addConfig(configName, configDir.toPath())
+      .configure();
+    
+    Map<String, String> collectionProperties = new HashMap<>();
+    collectionProperties.put("config", "solrconfig-tlog.xml");
+    collectionProperties.put("schema", "schema15.xml"); // string id for doc routing prefix
+
+    assertNotNull(cluster.createCollection(COLLECTION_NAME, NUM_SHARDS, REPLICATION_FACTOR,
+                                           configName, null, null, collectionProperties));
+    
+    CLOUD_CLIENT = cluster.getSolrClient();
+    CLOUD_CLIENT.setDefaultCollection(COLLECTION_NAME);
+    
+    ZkStateReader zkStateReader = CLOUD_CLIENT.getZkStateReader();
+    AbstractDistribZkTestBase.waitForRecoveriesToFinish(COLLECTION_NAME, zkStateReader, true, true, 330);
+
+
+    // really hackish way to get a URL for specific nodes based on shard/replica hosting
+    // inspired by TestMiniSolrCloudCluster
+    HashMap<String, String> urlMap = new HashMap<>();
+    for (JettySolrRunner jetty : cluster.getJettySolrRunners()) {
+      URL jettyURL = jetty.getBaseUrl();
+      String nodeKey = jettyURL.getHost() + ":" + jettyURL.getPort() + jettyURL.getPath().replace("/","_");
+      urlMap.put(nodeKey, jettyURL.toString());
+    }
+    zkStateReader.updateClusterState();
+    ClusterState clusterState = zkStateReader.getClusterState();
+    for (Slice slice : clusterState.getSlices(COLLECTION_NAME)) {
+      String shardName = slice.getName();
+      Replica leader = slice.getLeader();
+      assertNotNull("slice has null leader: " + slice.toString(), leader);
+      assertNotNull("slice leader has null node name: " + slice.toString(), leader.getNodeName());
+      String leaderUrl = urlMap.remove(leader.getNodeName());
+      assertNotNull("could not find URL for " + shardName + " leader: " + leader.getNodeName(),
+                    leaderUrl);
+      assertEquals("expected two total replicas for: " + slice.getName(),
+                   2, slice.getReplicas().size());
+      
+      String passiveUrl = null;
+      
+      for (Replica replica : slice.getReplicas()) {
+        if ( ! replica.equals(leader)) {
+          passiveUrl = urlMap.remove(replica.getNodeName());
+          assertNotNull("could not find URL for " + shardName + " replica: " + replica.getNodeName(),
+                        passiveUrl);
+        }
+      }
+      assertNotNull("could not find URL for " + shardName + " replica", passiveUrl);
+
+      if (shardName.equals("shard1")) {
+        S_ONE_LEADER_CLIENT = new HttpSolrClient(leaderUrl + "/" + COLLECTION_NAME + "/");
+        S_ONE_NON_LEADER_CLIENT = new HttpSolrClient(passiveUrl + "/" + COLLECTION_NAME + "/");
+      } else if (shardName.equals("shard2")) {
+        S_TWO_LEADER_CLIENT = new HttpSolrClient(leaderUrl + "/" + COLLECTION_NAME + "/");
+        S_TWO_NON_LEADER_CLIENT = new HttpSolrClient(passiveUrl + "/" + COLLECTION_NAME + "/");
+      } else {
+        fail("unexpected shard: " + shardName);
+      }
+    }
+    assertEquals("Should be exactly one server left (nost hosting either shard)", 1, urlMap.size());
+    NO_COLLECTION_CLIENT = new HttpSolrClient(urlMap.values().iterator().next() +
+                                              "/" + COLLECTION_NAME + "/");
+    
+    assertNotNull(S_ONE_LEADER_CLIENT);
+    assertNotNull(S_TWO_LEADER_CLIENT);
+    assertNotNull(S_ONE_NON_LEADER_CLIENT);
+    assertNotNull(S_TWO_NON_LEADER_CLIENT);
+    assertNotNull(NO_COLLECTION_CLIENT);
+
+    // sanity check that our S_ONE_PRE & S_TWO_PRE really do map to shard1 & shard2 with default routing
+    assertEquals(0, CLOUD_CLIENT.add(doc(f("id", S_ONE_PRE + random().nextInt()),
+                                         f("expected_shard_s", "shard1"))).getStatus());
+    assertEquals(0, CLOUD_CLIENT.add(doc(f("id", S_TWO_PRE + random().nextInt()),
+                                         f("expected_shard_s", "shard2"))).getStatus());
+    assertEquals(0, CLOUD_CLIENT.commit().getStatus());
+    SolrDocumentList docs = CLOUD_CLIENT.query(params("q", "*:*",
+                                                      "fl","id,expected_shard_s,[shard]")).getResults();
+    assertEquals(2, docs.getNumFound());
+    assertEquals(2, docs.size());
+    for (SolrDocument doc : docs) {
+      String expected = COLLECTION_NAME + "_" + doc.getFirstValue("expected_shard_s") + "_replica";
+      String docShard = doc.getFirstValue("[shard]").toString();
+      assertTrue("shard routing prefixes don't seem to be aligned anymore, " +
+                 "did someone change the default routing rules? " +
+                 "and/or the the default core name rules? " +
+                 "and/or the numShards used by this test? ... " +
+                 "couldn't find " + expected + " as substring of [shard] == '" + docShard +
+                 "' ... for docId == " + doc.getFirstValue("id"),
+                 docShard.contains(expected));
+    }
+  }
+  
+  @Before
+  private void clearCloudCollection() throws Exception {
+    assertEquals(0, CLOUD_CLIENT.deleteByQuery("*:*").getStatus());
+    assertEquals(0, CLOUD_CLIENT.commit().getStatus());
+  }
+
+  public void testMalformedDBQ(SolrClient client) throws Exception {
+    assertNotNull("client not initialized", client);
+    try {
+      UpdateResponse rsp = update(params()).deleteByQuery("foo_i:not_a_num").process(client);
+      fail("Expected DBQ failure: " + rsp.toString());
+    } catch (SolrException e) {
+      assertEquals("not the expected DBQ failure: " + e.getMessage(), 400, e.code());
+    }
+  }
+
+  //
+  public void testMalformedDBQViaCloudClient() throws Exception {
+    testMalformedDBQ(CLOUD_CLIENT);
+  }
+  public void testMalformedDBQViaShard1LeaderClient() throws Exception {
+    testMalformedDBQ(S_ONE_LEADER_CLIENT);
+  }
+  public void testMalformedDBQViaShard2LeaderClient() throws Exception {
+    testMalformedDBQ(S_TWO_LEADER_CLIENT);
+  }
+  public void testMalformedDBQViaShard1NonLeaderClient() throws Exception {
+    testMalformedDBQ(S_ONE_NON_LEADER_CLIENT);
+  }
+  public void testMalformedDBQViaShard2NonLeaderClient() throws Exception {
+    testMalformedDBQ(S_TWO_NON_LEADER_CLIENT);
+  }
+  public void testMalformedDBQViaNoCollectionClient() throws Exception {
+    testMalformedDBQ(NO_COLLECTION_CLIENT);
+  }
+
+  public static UpdateRequest update(SolrParams params, SolrInputDocument... docs) {
+    UpdateRequest r = new UpdateRequest();
+    r.setParams(new ModifiableSolrParams(params));
+    r.add(Arrays.asList(docs));
+    return r;
+  }
+  
+  public static SolrInputDocument doc(SolrInputField... fields) {
+    SolrInputDocument doc = new SolrInputDocument();
+    for (SolrInputField f : fields) {
+      doc.put(f.getName(), f);
+    }
+    return doc;
+  }
+  
+  public static SolrInputField f(String fieldName, Object... values) {
+    SolrInputField f = new SolrInputField(fieldName);
+    f.setValue(values, 1.0F);
+    return f;
+  }
+}


[25/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test-files/data/geonames-IE.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test-files/data/geonames-IE.txt b/lucene/spatial-extras/src/test-files/data/geonames-IE.txt
new file mode 100644
index 0000000..baa7b74
--- /dev/null
+++ b/lucene/spatial-extras/src/test-files/data/geonames-IE.txt
@@ -0,0 +1,22929 @@
+2652852	Cliff	Cliff		54.48333	-8.11667	S	EST	IE		U	06			0		76	Europe/Dublin	2010-08-14
+2654332	Bun Cranncha	Bun Cranncha	Buncrana	55.13333	-7.45	P	PPL	IE		U	06			5546		63	Europe/Dublin	2010-08-14
+2960863	Dromore West	Dromore West	Dromore,Dromore West	54.25167	-8.89306	P	PPL	IE	IE	C	25			0		32	Europe/Dublin	2010-08-14
+2960864	Dromore	Dromore	Dromore,Dromore House	52.93111	-8.96833	S	EST	IE	IE	M	03			0		36	Europe/Dublin	2010-08-14
+2960865	Youghal Harbour	Youghal Harbour		51.95194	-7.83972	H	HBR	IE		00	00			0		1	Europe/Dublin	2010-08-14
+2960866	Youghal Bay	Youghal Bay		52.89944	-8.30361	H	BAY	IE		M	26			0		55	Europe/Dublin	2010-08-14
+2960867	Youghal Bay	Youghal Bay		51.91	-7.81917	H	BAY	IE		00	00			0		-9999	Europe/Dublin	2010-08-14
+2960868	Youghal	Youghal		52.88861	-8.3075	P	PPL	IE		M	26			0		61	Europe/Dublin	2010-08-14
+2960869	Eochaill	Eochaill	Youghal	51.95	-7.85056	P	PPL	IE		M	04			6868		1	Europe/Dublin	2010-08-14
+2960870	Yellow River	Yellow River		54.13972	-8.02722	H	STM	IE		C	14			0		58	Europe/Dublin	2010-08-14
+2960871	Yellow River	Yellow River		54.05	-7.83333	H	STM	IE		C	14			0		76	Europe/Dublin	2010-08-14
+2960872	Yellow River	Yellow River		53.81667	-9	H	STM	IE		C	20			0		51	Europe/Dublin	2010-08-14
+2960873	Yellow River	Yellow River		53.38556	-7.08361	H	STM	IE		00	00			0		108	Europe/Dublin	2010-08-14
+2960874	Yellow Furze	Yellow Furze		53.67333	-6.57167	P	PPL	IE		L	21			0		86	Europe/Dublin	2010-08-14
+2960875	Woodville	Woodville		54.13333	-9.31667	P	PPL	IE		C	20			0		42	Europe/Dublin	2010-08-14
+2960876	Woodville	Woodville		53.85	-7.56667	S	BLDG	IE		L	18			0		71	Europe/Dublin	2010-08-14
+2960877	Wood View	Wood View		52.83333	-7.21667	S	EST	IE		L	13			0		135	Europe/Dublin	2010-08-14
+2960878	Woodtown House	Woodtown House	Woodtown,Woodtown House	53.58139	-6.98639	S	EST	IE	IE	L	21			0		92	Europe/Dublin	2010-08-14
+2960879	Woodstown	Woodstown		52.19667	-7.01	P	PPL	IE		M	27			0		75	Europe/Dublin	2010-08-14
+2960880	Woodstock House	Woodstock House	Woodstock,Woodstock House	52.47861	-7.05639	S	EST	IE	IE	L	13			0		32	Europe/Dublin	2010-08-14
+2960881	Woodsgift House	Woodsgift House	Woodsgift,Woodsgift House	52.70694	-7.515	S	EST	IE	IE	L	13			0		152	Europe/Dublin	2010-08-14
+2960882	Woodrooff House	Woodrooff House	Woodroof House,Woodrooff House	52.38222	-7.81944	S	EST	IE	IE	M	26			0		122	Europe/Dublin	2010-11-04
+2960883	Woodpark	Woodpark		53.44417	-6.48417	S	EST	IE		L	21			0		78	Europe/Dublin	2010-08-14
+2960884	Woodpark	Woodpark		52.92583	-8.45833	S	EST	IE		M	03			0		53	Europe/Dublin	2010-08-14
+2960885	Woodmount	Woodmount		53.33583	-8.16167	S	EST	IE		C	24			0		73	Europe/Dublin	2010-08-14
+2960886	Wood Lodge	Wood Lodge		54.03333	-7.16667	S	BLDG	IE		U	02			0		111	Europe/Dublin	2010-08-14
+2960887	Woodlawn Station	Woodlawn Station	Woodlawn,Woodlawn Station	53.35	-8.46667	S	RSTN	IE	IE	C	10			0		76	Europe/Dublin	2010-08-14
+2960888	Woodlawn	Woodlawn	Woodlawn,Woodlawn House	53.32889	-8.47889	S	EST	IE	IE	C	10			0		76	Europe/Dublin	2010-08-14
+2960889	Woodlands Station	Woodlands Station	Woodlands,Woodlands Station	51.55	-9.51667	S	RSTN	IE	IE	M	04			0		145	Europe/Dublin	2010-08-14
+2960890	Woodhouse	Woodhouse		52.12389	-7.475	S	EST	IE		M	27			0		1	Europe/Dublin	2010-08-14
+2960891	Wood Hill	Wood Hill		54.75944	-8.41833	S	EST	IE		U	06			0		32	Europe/Dublin	2010-08-14
+2960892	Woodfort	Woodfort	Woodfoot,Woodfort	53.88333	-6.83333	P	PPL	IE		L	21			0		111	Europe/Dublin	2010-08-10
+2960893	Woodfort	Woodfort		52.15944	-8.34139	S	EST	IE		M	04			0		40	Europe/Dublin	2010-08-14
+2960894	Woodford River	Woodford River	Rosmore,Woodford River	53.02028	-8.31639	H	STM	IE	IE	C	10			0		55	Europe/Dublin	2010-08-14
+2960895	Woodford	Woodford	An Chraig,An Chráig,An Ghraig,An Ghráig,Woodford	53.04833	-8.40028	P	PPL	IE		C	10			0		76	Europe/Dublin	2010-08-14
+2960896	Woodford	Woodford		52.05	-9.45	P	PPL	IE		M	11			0		92	Europe/Dublin	1993-12-27
+2960897	Woodfield House	Woodfield House		53.86667	-8.88333	S	EST	IE		C	20			0		70	Europe/Dublin	1993-12-27
+2960898	Woodfield House	Woodfield House		53.37028	-7.62167	S	EST	IE		L	23			0		74	Europe/Dublin	2010-08-14
+2960899	Woodfield House	Woodfield House		53.11667	-7.9	S	EST	IE		L	23			0		70	Europe/Dublin	2010-08-14
+2960900	Woodenbridge Junction Station	Woodenbridge Junction Station	Woodenbridge,Woodenbridge Junction,Woodenbridge Junction Station	52.83333	-6.23333	S	RSTN	IE	IE	L	31			0		40	Europe/Dublin	2010-08-14
+2960901	Woodenbridge	Woodenbridge		52.83222	-6.23639	P	PPL	IE		L	31			0		43	Europe/Dublin	2010-08-14
+2960902	Woodbrook House	Woodbrook House	Woodbrook,Woodbrook House	53.12944	-7.23583	S	HSEC	IE	IE	L	15			0		101	Europe/Dublin	2010-08-14
+2960903	Woodbrook	Woodbrook		52.54806	-6.73861	S	EST	IE		L	30			0		131	Europe/Dublin	2010-08-14
+2960904	Woodbrook	Woodbrook		51.71667	-9.13333	S	EST	IE		M	04			0		89	Europe/Dublin	1993-12-27
+2960905	Woodbine Hill	Woodbine Hill		51.95472	-7.82944	S	EST	IE		M	04			0		1	Europe/Dublin	2010-08-14
+2960906	Wingfield House	Wingfield House		52.7725	-6.39194	S	EST	IE		L	30			0		154	Europe/Dublin	2010-08-14
+2960907	Windy Harbour	Windy Harbour		53.74083	-6.66472	P	PPL	IE		L	21			0		130	Europe/Dublin	2010-08-14
+2960908	Windy Gap	Windy Gap		52.03333	-9.93333	T	GAP	IE		M	11			0		269	Europe/Dublin	2010-08-14
+2960909	Windgap	Windgap	Bearna na Gaoithe,Bearra na Gaoithe,Windgap	52.46556	-7.39972	P	PPL	IE		L	13			0		152	Europe/Dublin	2010-08-14
+2960910	Windfield House	Windfield House		53.43333	-8.63333	S	EST	IE		C	10			0		76	Europe/Dublin	1993-12-27
+2960911	Wilton House	Wilton House	Wilton,Wilton House	52.72222	-7.54806	S	EST	IE	IE	L	13			0		137	Europe/Dublin	2010-08-14
+2960912	Wilton Castle	Wilton Castle	Wilton Castle,Wilton House	52.45917	-6.61639	S	EST	IE	IE	L	30			0		63	Europe/Dublin	2010-08-14
+2960913	Wilmount House	Wilmount House		52.58333	-6.71667	S	EST	IE		L	30			0		150	Europe/Dublin	2010-08-14
+2960914	Wilmount House	Wilmount House		52.41667	-6.45611	S	EST	IE		L	30			0		24	Europe/Dublin	2010-08-14
+2960915	Wilmount	Wilmount		53.74833	-6.89528	S	EST	IE		L	21			0		71	Europe/Dublin	2010-08-14
+2960916	Wills Grove	Wills Grove		53.73333	-8.41667	S	RUIN	IE		C	24			0		76	Europe/Dublin	1993-12-27
+2960917	Willsbrook House	Willsbrook House		53.73333	-8.48333	S	BLDG	IE		C	24			0		74	Europe/Dublin	1993-12-27
+2960918	Willmount House	Willmount House		53.11611	-6.55833	S	HSEC	IE		L	31			0		198	Europe/Dublin	2010-08-14
+2960919	Willmount	Willmount		53.26667	-8.76667	S	EST	IE		C	10			0		30	Europe/Dublin	1993-12-27
+2960920	Willmount	Willmount		52.55472	-7.56556	S	EST	IE		M	26			0		150	Europe/Dublin	2010-08-14
+2960921	Williamstown Lodge	Williamstown Lodge		52.95	-8.33333	S	BLDG	IE		M	03			0		55	Europe/Dublin	2010-08-14
+2960922	Williamstown House	Williamstown House		53.88333	-6.41417	S	EST	IE		L	19			0		3	Europe/Dublin	2010-08-14
+2960923	Williamstown Harbour	Williamstown Harbour		52.95	-8.33333	H	HBR	IE		M	03			0		55	Europe/Dublin	2010-08-14
+2960924	Williamstown	Williamstown		53.68333	-8.58333	P	PPL	IE		C	10			0		76	Europe/Dublin	1993-12-27
+2960925	Williamstown	Williamstown		53.75222	-6.87333	S	EST	IE		L	21			0		70	Europe/Dublin	2010-08-14
+2960926	Willbrook	Willbrook		53.29361	-6.31194	P	PPL	IE		L	07			0		76	Europe/Dublin	2010-08-14
+2960927	Willbrook	Willbrook		52.93778	-9.12806	P	PPL	IE		M	03			0		95	Europe/Dublin	2010-08-14
+2960928	Wilkinstown	Wilkinstown		53.73556	-6.71306	P	PPL	IE		L	21			0		73	Europe/Dublin	2010-08-14
+2960929	Wilford House	Wilford House		52.55722	-7.55889	S	EST	IE		M	26			0		150	Europe/Dublin	2010-08-14
+2960930	Wild Bellows Rock	Wild Bellows Rock		53.34417	-10.05056	T	RK	IE		C	10			0		-9999	Europe/Dublin	1999-03-04
+2960931	Wicklow Mountains	Wicklow Mountains	Wicklow Hills,Wicklow Mountains	53.08333	-6.33333	T	MTS	IE		L	31			0		439	Europe/Dublin	2010-08-10
+2960932	Wicklow Head	Wicklow Head		52.96056	-5.99889	T	CAPE	IE		L	31			0		-9999	Europe/Dublin	2010-08-14
+2960933	Wicklow Gap	Wicklow Gap		53.04056	-6.40194	T	GAP	IE		L	31			0		528	Europe/Dublin	2010-08-14
+2960934	Wicklow Gap	Wicklow Gap		52.75667	-6.35944	T	GAP	IE		L	30			0		160	Europe/Dublin	2010-08-14
+2960935	Cill Mhantáin	Cill Mhantain	Contae Chill Mhantain,Contae Chill Mhantáin,County Wicklow,Wicklow	53	-6.41667	A	ADM2	IE		L	31			119873		371	Europe/Dublin	2010-08-14
+2960936	Cill Mhantáin	Cill Mhantain	Cill Maintain,Cill Maintainn,Cill Maintáinn,Cill Manntein,Cill Manntéin,Cill Mantan,Cill Mhanntain,Wicklow	52.975	-6.04944	P	PPLA2	IE		L	31			10461		69	Europe/Dublin	2010-08-14
+2960937	Whiting Bay	Whiting Bay		51.94694	-7.78139	H	BAY	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
+2960938	Whitfield Court	Whitfield Court	Whitfield,Whitfield Court	52.22278	-7.21722	S	EST	IE	IE	M	27			0		54	Europe/Dublin	2010-08-14
+2960939	Whitewood House	Whitewood House	Whitewood,Whitewood House	53.84139	-6.78333	S	EST	IE	IE	L	21			0		72	Europe/Dublin	2010-08-14
+2960940	Whitewell House	Whitewell House		53.43333	-7.31667	S	EST	IE		L	29			0		130	Europe/Dublin	1993-12-27
+2960941	Whites Town	Whites Town		53.99778	-6.12778	P	PPL	IE		L	19			0		1	Europe/Dublin	2010-08-14
+2960942	White River	White River		53.85972	-6.38694	H	STM	IE		L	19			0		8	Europe/Dublin	2010-08-14
+2960943	White River	White River		52.59556	-9.19361	H	STM	IE		M	16			0		15	Europe/Dublin	2010-08-14
+2960944	White Point	White Point		51.85	-8.31667	T	PT	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
+2960945	White Mountain	White Mountain		52.48333	-6.83333	T	MT	IE		L	30			0		215	Europe/Dublin	2010-08-14
+2960946	White Lough	White Lough		53.70194	-7.22	H	LK	IE		00				0		151	Europe/Dublin	1999-03-22
+2960947	Whitehill House	Whitehill House		53.73333	-7.63333	S	EST	IE		L	18			0		76	Europe/Dublin	1993-12-27
+2960948	Whitehall	Whitehall		53.75	-7.93333	P	PPL	IE		C	24			0		66	Europe/Dublin	1993-12-27
+2960949	Paulstown	Paulstown	Baile Phoil,Baile Phóil,Paulstown,Whitehall	52.68111	-7.02222	P	PPL	IE		L	13			0		55	Europe/Dublin	2010-08-14
+2960950	Whitegate	Whitegate		53.73333	-7.31667	P	PPL	IE		L	29			0		211	Europe/Dublin	1993-12-27
+2960951	Whitegate	Whitegate	An Geata Ban,An Geata Bán,Whitegate	52.94917	-8.37139	P	PPL	IE		M	03			0		56	Europe/Dublin	2010-08-14
+2960952	Whitegate	Whitegate	An Geata Ban,An Geata Bán,Whitegate	51.83056	-8.22972	P	PPL	IE		M	04			0		1	Europe/Dublin	2010-08-14
+2960953	Whitechurch	Whitechurch		52.37139	-7.39306	P	PPL	IE		L	13			0		32	Europe/Dublin	2010-08-14
+2960954	Whitechurch	Whitechurch		52.31778	-6.96611	P	PPL	IE		L	30			0		46	Europe/Dublin	2010-08-14
+2960955	Whitechurch	Whitechurch		52.10944	-7.74944	P	PPL	IE		M	27			0		62	Europe/Dublin	2010-08-14
+2960956	Whitechurch	Whitechurch		51.98139	-8.51389	P	PPL	IE		M	04			0		152	Europe/Dublin	2010-08-14
+2960957	White Castle	White Castle		55.13333	-7.16667	P	PPL	IE		U	06			0		-9999	Europe/Dublin	1993-12-27
+2960958	White Ball Head	White Ball Head		51.59667	-10.055	T	CAPE	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
+2960959	Whiddy Island	Whiddy Island	Whiddy Island	51.70139	-9.49972	T	ISL	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
+2960960	Wheelam Cross Roads	Wheelam Cross Roads		53.20278	-6.87083	P	PPL	IE		L	12			0		157	Europe/Dublin	2010-08-14
+2960961	Whale Head	Whale Head		55.0525	-7.57389	T	CAPE	IE		U	06			0		1	Europe/Dublin	2010-08-14
+2960962	Wexford Harbour	Wexford Harbour	Wexford Harbour	52.33833	-6.40417	H	HBR	IE		L	30			0		-9999	Europe/Dublin	2010-08-14
+2960963	Loch Garman	Loch Garman	Contae Loch Garman,County Wexford,Wexford	52.5	-6.66667	A	ADM2	IE		L	30			121122		76	Europe/Dublin	2010-08-14
+2960964	Loch Garman	Loch Garman	Loch Garman,Wexford	52.33417	-6.4575	P	PPLA2	IE		L	30			17708		-9999	Europe/Dublin	2010-08-14
+2960965	West Village	West Village		51.88333	-8.6	P	PPL	IE		M	04			0		66	Europe/Dublin	2010-08-14
+2960966	West Town	West Town	Baile Thiar,West Town	55.26528	-8.22583	P	PPL	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
+2960967	West Sister	West Sister	Beenhenry,West Sister	52.2	-10.43333	T	HLL	IE	IE	M	11			0		61	Europe/Dublin	2010-08-14
+2960968	Westport House	Westport House		53.8	-9.51667	S	EST	IE		C	20			0		108	Europe/Dublin	1993-12-27
+2960969	Westport Bay	Westport Bay		53.8	-9.63333	H	BAY	IE		C	20			0		-9999	Europe/Dublin	1993-12-27
+2960970	Cathair na Mart	Cathair na Mart	Westport	53.8	-9.51667	P	PPL	IE		C	20			6200		108	Europe/Dublin	2010-08-14
+2960971	Westmoreland Fort	Westmoreland Fort	Fort Westmoreland,Westmoreland Fort	51.83333	-8.28333	S	FT	IE	IE	M	04			0		-9999	Europe/Dublin	2010-08-14
+2960972	An Iarmhí	An Iarmhi	Contae na hIarmhi,Contae na hIarmhí,County Westmeath,Westmeath	53.5	-7.5	A	ADM2	IE		L	29			75298		144	Europe/Dublin	2010-08-14
+2960973	Westland Row Station	Westland Row Station	Westland Row Passenger Station	53.35	-6.25	S	RSTN	IE	IE	L	07			0		1	Europe/Dublin	2010-08-14
+2960974	Westland House	Westland House		53.785	-6.89694	S	EST	IE		L	21			0		79	Europe/Dublin	2010-08-14
+2960975	Westfield	Westfield		51.55	-9.38333	S	EST	IE		M	04			0		92	Europe/Dublin	1993-12-27
+2960976	West Cove	West Cove		51.77917	-10.07694	P	PPL	IE		M	11			0		134	Europe/Dublin	2010-08-14
+2960977	West Court	West Court		52.54917	-7.39389	S	EST	IE		L	13			0		71	Europe/Dublin	2010-08-14
+2960978	Wells House	Wells House	Wells,Wells House	52.52833	-6.34444	S	EST	IE	IE	L	30			0		58	Europe/Dublin	2010-08-14
+2960979	Wellmount House	Wellmount House		53.10472	-8.22778	S	BLDG	IE		C	10			0		77	Europe/Dublin	2010-08-14
+2960980	Wellingtonbridge	Wellingtonbridge	Wellingtonbridge	52.26333	-6.77833	P	PPL	IE		L	30			0		5	Europe/Dublin	2010-08-14
+2960981	Welchtown	Welchtown		54.81861	-7.87083	P	PPL	IE		U	06			0		84	Europe/Dublin	2010-08-14
+2960982	Webbsborough	Webbsborough	Webbsborough,Webbsborough House	52.75083	-7.23111	S	BLDG	IE	IE	L	13			0		128	Europe/Dublin	2010-08-14
+2960983	Weatherstown	Weatherstown		52.37361	-7.03944	P	PPL	IE		L	13			0		108	Europe/Dublin	2010-08-14
+2960984	Waterville	Waterville	An Coirean,An Coireán,Waterville	51.83333	-10.16667	P	PPL	IE		M	11			0		14	Europe/Dublin	2010-08-14
+2960985	Waterstown House	Waterstown House	Waterstown,Waterstown House	53.46667	-7.85	S	EST	IE		L	29			0		136	Europe/Dublin	2010-08-10
+2960986	Waterloo	Waterloo		53.93333	-7.13028	P	PPL	IE		U	02			0		171	Europe/Dublin	2010-08-14
+2960987	Watergrasshill	Watergrasshill	Cnocan na Biolrai,Cnocán na Biolraí,Watergrasshill	52.01139	-8.34417	P	PPL	IE		M	04			0		156	Europe/Dublin	2010-08-14
+2960988	Waterford North Station	Waterford North Station	Waterford,Waterford North Station	52.26667	-7.11667	S	RSTN	IE	IE	L	13			0		58	Europe/Dublin	2010-08-14
+2960989	Waterford Manor Station	Waterford Manor Station	Manor Station,Waterford Manor Station	52.25	-7.11667	S	RSTN	IE	IE	M	27			0		17	Europe/Dublin	2010-08-14
+2960990	Waterford Harbour	Waterford Harbour		52.17917	-6.93056	H	ESTY	IE		00				0		-9999	Europe/Dublin	1998-01-09
+2960991	Port Láirge	Port Lairge	Contae Phort Lairge,Contae Phort Láirge,County Waterford,Waterford	52.25	-7.5	A	ADM2	IE		M	27			104132		178	Europe/Dublin	2010-08-14
+2960992	Port Láirge	Port Lairge	Port Lairge,Port Láirge,Uoterford,Waterford,Waterford city,u~otafodo,Уотерфорд,ウォーターフォード	52.25833	-7.11194	P	PPLA2	IE		M	27			47904		8	Europe/Dublin	2010-08-14
+2960993	Waterfall	Waterfall		51.85944	-8.55917	P	PPL	IE		M	04			0		77	Europe/Dublin	2010-08-14
+2960994	Waterdale	Waterdale	Waterdale,Waterdale House	53.36667	-8.95	S	BLDG	IE		C	10			0		21	Europe/Dublin	2010-08-10
+2960995	Watch House Village	Watch House Village	Watch House,Watch House Village	52.69083	-6.63972	P	PPL	IE	IE	L	30			0		76	Europe/Dublin	2010-08-14
+2960996	Warrenstown House	Warrenstown House		53.51667	-6.61667	S	EST	IE		L	21			0		92	Europe/Dublin	1993-12-27
+2960997	Warrens Grove	Warrens Grove		51.85	-8.83333	S	EST	IE		M	04			0		79	Europe/Dublin	2010-08-14
+2960998	Warrens Court	Warrens Court		51.85472	-8.91278	S	EST	IE		M	04			0		146	Europe/Dublin	2010-08-14
+2960999	War Hill	War Hill		53.13778	-6.25389	T	MT	IE		L	31			0	685	439	Europe/Dublin	2010-08-14
+2961000	Hill of Ward	Hill of Ward	Hill of Ward	53.62444	-6.88611	T	HLL	IE		L	21			0		79	Europe/Dublin	2010-08-14
+2961001	Ward	Ward		53.43306	-6.33333	P	PPL	IE		L	07			0		66	Europe/Dublin	2010-08-14
+2961002	Walterstown	Walterstown		53.61278	-6.55306	P	PPL	IE		L	21			0		79	Europe/Dublin	2010-08-14
+2961003	Walshtown	Walshtown		51.98306	-8.18722	P	PPL	IE		M	04			0		130	Europe/Dublin	2010-08-14
+2961004	Walshpool Lough	Walshpool Lough		53.8	-9.18333	H	LK	IE		C	20			0		65	Europe/Dublin	1993-12-27
+2961005	Virginia Road	Virginia Road	Virginia Road,Virginia Road Station	53.75	-7.01667	S	RSTN	IE		L	21			0		160	Europe/Dublin	2010-08-10
+2961006	Virginia	Virginia	Achadh an Iuir,Achadh an Iúir,Virginia	53.83389	-7.07556	P	PPL	IE		U	02			0		120	Europe/Dublin	2010-08-14
+2961007	Violetstown House	Violetstown House		53.48333	-7.28333	S	EST	IE		L	29			0		124	Europe/Dublin	1993-12-27
+2961008	Violet Hill	Violet Hill		52.74444	-7.56083	S	EST	IE		L	13			0		142	Europe/Dublin	2010-08-14
+2961009	Vinegar Hill	Vinegar Hill		52.50417	-6.54611	T	HLL	IE		L	30			0		61	Europe/Dublin	2010-08-14
+2961010	Villierstown	Villierstown	An Baile Nua,Villierstown	52.08889	-7.85306	P	PPL	IE		M	27			0		75	Europe/Dublin	2010-08-14
+2961011	Vicarstown Cross Roads	Vicarstown Cross Roads	Vicarstown,Vicarstown Cross Roads	51.93333	-8.65	P	PPL	IE	IE	M	04			0		76	Europe/Dublin	2010-08-14
+2961012	Vicarstown	Vicarstown		53.04917	-7.08861	P	PPL	IE		L	15			0		71	Europe/Dublin	2010-08-14
+2961013	Ventry Harbour	Ventry Harbour		52.12278	-10.35583	H	HBR	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
+2961014	Ventry	Ventry	Ceann Tra,Ceann Trá,Ventry	52.1325	-10.36694	P	PPL	IE		M	11			0		1	Europe/Dublin	2010-08-14
+2961015	Velvetstown House	Velvetstown House		52.25	-8.66667	S	EST	IE		M	04			0		114	Europe/Dublin	1993-12-27
+2961016	Lough Vearty	Lough Vearty	Lough Vearty	54.53333	-8	H	LK	IE		00				0		177	Europe/Dublin	1998-02-19
+2961017	Lough Beagh	Lough Beagh	Lough Beagh,Lough Veagh	55.03833	-7.97167	H	LK	IE	IE	U	06			0		70	Europe/Dublin	2010-08-14
+2961018	Vartry River	Vartry River		53.00278	-6.05528	H	STM	IE		L	31			0		-9999	Europe/Dublin	2010-08-14
+2961019	Valencia River	Valencia River	Valencia River,Valentia River	51.93222	-10.27806	H	STM	IE	IE	M	11			0		-9999	Europe/Dublin	2010-08-14
+2961020	Valencia Island	Valencia Island	Valencia Island,Valentia Island	51.90833	-10.37194	T	ISL	IE	IE	M	11			0		28	Europe/Dublin	2010-08-14
+2961021	Valencia Harbour Station	Valencia Harbour Station	Valencia Harbour,Valencia Harbour Station,Valentia Harbour	51.91667	-10.28333	S	RSTN	IE	IE	M	11			0		-9999	Europe/Dublin	2010-08-14
+2961022	Valencia Harbour	Valencia Harbour	Valencia Harbour,Valentia Harbour	51.93	-10.30306	H	HBR	IE		M	11			0		35	Europe/Dublin	2010-08-14
+2961023	Urris Hills	Urris Hills		55.22389	-7.51889	T	MTS	IE		U	06			0		269	Europe/Dublin	2010-08-14
+2961024	Urrin River	Urrin River		52.49278	-6.56722	H	STM	IE		L	30			0		52	Europe/Dublin	2010-08-14
+2961025	Urlingford	Urlingford	Ath na nUrlainn,Urlingford,Áth na nUrlainn	52.72056	-7.5825	P	PPL	IE		L	13			0		143	Europe/Dublin	2010-08-14
+2961026	Urlaur Lough	Urlaur Lough		53.83333	-8.73333	H	LK	IE		C	20			0		54	Europe/Dublin	1993-12-27
+2961027	Uregare House	Uregare House	Uregare,Uregare House	52.45	-8.56667	S	EST	IE		M	16			0		75	Europe/Dublin	2010-08-10
+2961028	Urbalreagh	Urbalreagh		55.33639	-7.28528	P	PPL	IE		U	06			0		76	Europe/Dublin	2010-08-14
+2961029	Upton House	Upton House		51.79917	-8.68833	S	EST	IE		M	04			0		76	Europe/Dublin	2010-08-14
+2961030	Upton	Upton		51.79222	-8.67333	P	PPL	IE		M	04			0		76	Europe/Dublin	2010-08-14
+2961031	Upper Court	Upper Court		52.72611	-7.40667	S	EST	IE		L	13			0		128	Europe/Dublin	2010-08-14
+2961032	Upperchurch	Upperchurch	Upperchurch	52.70333	-8.0175	P	PPL	IE		M	26			0		289	Europe/Dublin	2010-11-04
+2961033	Unshin River	Unshin River		54.19139	-8.48167	H	STM	IE		C	25			0		59	Europe/Dublin	2010-08-14
+2961034	Lough Unshin	Lough Unshin		54.52028	-8.07917	H	LK	IE		U	06			0		403	Europe/Dublin	2010-08-14
+2961035	Unionhall	Unionhall	Breantra,Bréantrá,Unionhall	51.55	-9.13333	P	PPL	IE		M	04			0		28	Europe/Dublin	2010-08-14
+2961036	Umrycam	Umrycam		55.18333	-7.7	P	PPL	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
+2961037	Ummeryroe	Ummeryroe		54.11667	-8.28333	P	PPL	IE		C	25			0		142	Europe/Dublin	1993-12-27
+2961038	Umma House	Umma House		53.45	-7.7	S	EST	IE		L	29			0		76	Europe/Dublin	1993-12-27
+2961039	Umfin Island	Umfin Island		55.10194	-8.36583	T	ISL	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
+2961040	Ullard	Ullard		52.57972	-6.93083	P	PPL	IE		L	13			0		27	Europe/Dublin	2010-08-14
+2961041	Lough Ugga Beg	Lough Ugga Beg		53.27194	-9.4325	H	LK	IE		C	10			0		74	Europe/Dublin	2010-08-14
+2961042	Tyrrelstown House	Tyrrelstown House		53.4	-6.4	S	EST	IE		L	07			0		36	Europe/Dublin	2010-08-14
+2961043	Tyrrellspass	Tyrrellspass	Bealach an Tirialaigh,Tyrrellspass,Tyrrelspass	53.38889	-7.37361	P	PPL	IE		L	29			0		133	Europe/Dublin	2010-08-14
+2961044	Tyredagh Castle	Tyredagh Castle	Tyredach Castle,Tyredagh Castle	52.88472	-8.79861	S	RUIN	IE	IE	M	03			0		66	Europe/Dublin	2010-08-14
+2961045	Tyrcallen	Tyrcallen		54.82528	-7.74417	S	EST	IE		U	06			0		82	Europe/Dublin	2010-08-14
+2961046	Tynagh	Tynagh	Tine,Tynagh,Tíne	53.14944	-8.3725	P	PPL	IE	IE	C	10			0		75	Europe/Dublin	2010-08-14
+2961047	Tyholland Bridge	Tyholland Bridge	Tyholland,Tyholland Bridge	54.25	-6.9	P	PPL	IE	IE	00				0		65	Europe/Dublin	2010-08-10
+2961048	Two Rock Mountain	Two Rock Mountain		53.23472	-6.24167	T	MT	IE		L	07			0	517	453	Europe/Dublin	2010-08-14
+2961049	Twomileditch	Twomileditch		53.30389	-8.99778	P	PPL	IE		C	10			0		3	Europe/Dublin	2010-08-14
+2961050	Twomileborris	Twomileborris		52.67167	-7.72	P	PPL	IE		M	26			0		124	Europe/Dublin	2010-08-14
+2961051	The Twelve Pins	The Twelve Pins	Beanna Beola,Benna Beola,The Twelve Bens,The Twelve Pins,Twelve Pins of Bennebeola	53.5	-9.83333	T	MTS	IE	IE	C	10			0		402	Europe/Dublin	2010-08-14
+2961052	Tuskar Rock	Tuskar Rock	Tuskar Rock	52.19889	-6.19833	T	RK	IE		L	30			0		-9999	Europe/Dublin	2010-08-14
+2961053	Turvey House	Turvey House		53.49667	-6.17556	S	EST	IE		L	07			0		1	Europe/Dublin	2010-08-14
+2961054	Turners Rock	Turners Rock		51.79222	-9.58111	T	MT	IE		M	04			0		233	Europe/Dublin	2010-08-14
+2961055	Turloughmore	Turloughmore		53.37472	-8.86472	P	PPL	IE		C	10			0		27	Europe/Dublin	2010-08-14
+2961056	Turlough	Turlough	Turlach,Turlough	53.88333	-9.21667	P	PPL	IE	IE	C	20			0		38	Europe/Dublin	2010-08-14
+2961057	Turlough	Turlough		53.09222	-9.06528	P	PPL	IE		M	03			0		68	Europe/Dublin	2010-08-14
+2961058	Turkstown	Turkstown		52.32333	-7.30389	P	PPL	IE		L	13			0		13	Europe/Dublin	2010-08-14
+2961059	Turbotston	Turbotston	Turbotston,Turbotstown,Turbotstown House	53.7	-7.35	S	EST	IE	IE	L	29			0		79	Europe/Dublin	2010-08-14
+2961060	Turbot Island	Turbot Island	Talbot Island,Turbot Island	53.50194	-10.14806	T	ISL	IE	IE	C	10			0		-9999	Europe/Dublin	2010-08-14
+2961061	Tulsk	Tulsk	Tuilsce,Tulsk	53.78333	-8.25	P	PPL	IE	IE	C	24			0		75	Europe/Dublin	2010-08-14
+2961062	Tullyvin House	Tullyvin House	Tullyvin,Tullyvin House	54.05	-7.15	S	HSEC	IE	IE	U	02			0		76	Europe/Dublin	2010-08-14
+2961063	Tullyvin	Tullyvin		54.04833	-7.14472	P	PPL	IE		U	02			0		76	Europe/Dublin	2010-08-14
+2961064	Tullynascreen	Tullynascreen		54.17472	-8.28167	P	PPL	IE		C	14			0		174	Europe/Dublin	2010-08-14
+2961065	Tullynahinnera	Tullynahinnera	Tullynahinera,Tullynahinnera	54.08333	-6.8	P	PPL	IE	IE	00				0		152	Europe/Dublin	2010-08-10
+2961066	Tullymurray	Tullymurray		54.13333	-8.1	P	PPL	IE		C	14			0		58	Europe/Dublin	1993-12-27
+2961067	Tullymore	Tullymore	Tullamore,Tullymore	54.52111	-8.17806	P	PPL	IE	IE	U	06			0		67	Europe/Dublin	2010-08-14
+2961068	Tully Lough	Tully Lough	Tally Lough,Tully Lough	53.58972	-9.97972	H	LK	IE		C	10			0		15	Europe/Dublin	2010-08-14
+2961069	Tullylease	Tullylease		52.3	-8.95	P	PPL	IE		M	04			0		155	Europe/Dublin	1993-12-27
+2961070	Tullyleague	Tullyleague		52.53611	-9.30028	P	PPL	IE		M	16			0		148	Europe/Dublin	2010-08-14
+2961071	Tullyglass House	Tullyglass House	Tullyglass,Tullyglass House	51.76	-8.86361	S	BLDG	IE	IE	M	04			0		110	Europe/Dublin	2010-08-14
+2961072	Tullycreen Upper	Tullycreen Upper	Tullycreen,Tullycreen Upper,Tullycrine	52.68389	-9.35583	P	PPL	IE	IE	M	03			0		27	Europe/Dublin	2010-08-14
+2961073	Tullycreen Lower	Tullycreen Lower		52.66833	-9.32722	P	PPL	IE		M	03			0		24	Europe/Dublin	2010-08-14
+2961074	Tullycanna	Tullycanna		52.2675	-6.66861	P	PPL	IE		L	30			0		35	Europe/Dublin	2010-08-14
+2961075	Tullybrook	Tullybrook		54.63194	-8.07889	P	PPL	IE		U	06			0		53	Europe/Dublin	2010-08-14
+2961076	Tullyard	Tullyard		53.58194	-6.79333	S	EST	IE		L	21			0		77	Europe/Dublin	2010-08-14
+2961077	Tullyallen	Tullyallen	Tullyallen	53.73611	-6.42278	P	PPL	IE		L	19			0		60	Europe/Dublin	2010-08-14
+2961078	Tully	Tully		53.23333	-9.48333	P	PPL	IE		C	10			0		-9999	Europe/Dublin	1993-12-27
+2961079	Tullow	Tullow	An Tulach,Tullow	52.80028	-6.73694	P	PPL	IE		L	01			2424		86	Europe/Dublin	2010-08-14
+2961080	Tullira Castle	Tullira Castle		53.13611	-8.78444	S	HSEC	IE		C	10			0		33	Europe/Dublin	2010-08-14
+2961081	Tullig Point	Tullig Point		52.61417	-9.80417	T	PT	IE		M	03			0		2	Europe/Dublin	2010-08-14
+2961082	Tullig	Tullig		52.61472	-9.77611	P	PPL	IE		M	03			0		30	Europe/Dublin	2010-08-14
+2961083	Tullig	Tullig		52.11278	-9.85444	P	PPL	IE		M	11			0		8	Europe/Dublin	2010-08-14
+2961084	Tullaroan	Tullaroan	Tullaroan	52.66222	-7.43639	P	PPL	IE		L	13			0		152	Europe/Dublin	2010-08-14
+2961085	Tullamore River	Tullamore River	Clonmore,Tullamore River	53.27722	-7.5775	H	STM	IE	IE	L	23			0		71	Europe/Dublin	2010-08-14
+2961086	Tullamore	Tullamore	Tulach Mhor,Tulach Mhór	53.27389	-7.48889	P	PPLA2	IE		L	23			11575		73	Europe/Dublin	2010-08-14
+2961087	Tullamore	Tullamore		52.49167	-9.48778	P	PPL	IE		M	11			0		68	Europe/Dublin	2010-08-14
+2961088	Tullaher Lough	Tullaher Lough	Lough Trullaher,Tullaher Lough	52.69861	-9.54528	H	LK	IE	IE	M	03			0		1	Europe/Dublin	2010-08-14
+2961089	Tullagh Point	Tullagh Point		55.29472	-7.46722	T	PT	IE		U	06			0		2	Europe/Dublin	2010-08-14
+2961090	Tullaghought	Tullaghought		52.42194	-7.36167	P	PPL	IE		L	13			0		169	Europe/Dublin	2010-08-14
+2961091	Tullagher	Tullagher		52.43167	-7.04556	P	PPL	IE		L	13			0		134	Europe/Dublin	2010-08-14
+2961092	Tullagh Bay	Tullagh Bay		55.28639	-7.44361	H	BAY	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
+2961093	Tullaghanoge	Tullaghanoge		53.58889	-6.87222	P	PPL	IE		L	21			0		77	Europe/Dublin	2010-08-14
+2961094	Tullaghan Bay	Tullaghan Bay	Tallaghan Bay,Tullaghan Bay	54.09111	-9.86889	H	BAY	IE	IE	C	20			0		-9999	Europe/Dublin	2010-08-14
+2961095	Tullaghan	Tullaghan		54.46833	-8.33111	P	PPL	IE		C	14			0		1	Europe/Dublin	2010-08-14
+2961096	Tulla	Tulla	An Tulach,Tulla	52.86472	-8.76056	P	PPL	IE		M	03			0		152	Europe/Dublin	2010-08-14
+2961097	Tudenham Park	Tudenham Park		53.46667	-7.35	S	EST	IE		L	29			0		117	Europe/Dublin	1993-12-27
+2961098	Tubber	Tubber	Tobar,Tubber	52.99889	-8.88528	P	PPL	IE		C	10			0		47	Europe/Dublin	2010-08-14
+2961099	Tuam	Tuam	Tuaim,Tuam	53.51667	-8.85	P	PPL	IE		C	10			6130		48	Europe/Dublin	2010-08-14
+2961100	Truskmore	Truskmore		54.37639	-8.37222	T	MT	IE		00				0	646	591	Europe/Dublin	2006-01-16
+2961101	Trusk Lough	Trusk Lough		54.75722	-7.79917	H	LK	IE		U	06			0		161	Europe/Dublin	2010-08-14
+2961102	Trusklieve	Trusklieve		52.62778	-9.76444	P	PPL	IE		M	03			0		73	Europe/Dublin	2010-08-14
+2961103	Trubley Castle	Trubley Castle		53.56667	-6.71667	S	RUIN	IE		L	21			0		57	Europe/Dublin	1993-12-27
+2961104	Trough	Trough		52.73333	-8.61667	P	PPL	IE		M	03			0		79	Europe/Dublin	1993-12-27
+2961105	Triogue River	Triogue River	Tiogue River,Triogue River	53.11389	-7.28972	H	STM	IE	IE	L	15			0		107	Europe/Dublin	2010-08-14
+2961106	Trimoge River	Trimoge River		53.91667	-9.01667	H	STM	IE		C	20			0		30	Europe/Dublin	1993-12-27
+2961107	Baile Átha Troim	Baile Atha Troim	Baile Atha Troim,Baile Átha Troim,Trim	53.555	-6.79167	P	PPL	IE		L	21			1800		62	Europe/Dublin	2010-09-05
+2961108	The Triangle	The Triangle		53.76667	-9.4	P	PPLL	IE		C	20			0		137	Europe/Dublin	2010-08-14
+2961109	Tremone Bay	Tremone Bay		55.26667	-7.06667	H	BAY	IE		U	06			0		1	Europe/Dublin	1993-12-27
+2961110	Tremblestown River	Tremblestown River		53.55417	-6.83167	H	STM	IE		L	21			0		66	Europe/Dublin	2010-08-14
+2961111	Treantagh	Treantagh		54.92667	-7.4875	P	PPL	IE		U	06			0		52	Europe/Dublin	2010-08-14
+2961112	Trawmore Bay	Trawmore Bay		54.18361	-9.9575	H	BAY	IE		C	20			0		-9999	Europe/Dublin	2010-08-14
+2961113	Trawenagh Bay	Trawenagh Bay		54.89333	-8.35417	H	BAY	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
+2961114	Trawbreaga Bay	Trawbreaga Bay	Trawbreaga Bay,Trawbreaga Lough	55.285	-7.29472	H	BAY	IE	IE	U	06			0		-9999	Europe/Dublin	2010-08-14
+2961115	Traverston House	Traverston House		52.7975	-8.16444	S	EST	IE		M	26			0		118	Europe/Dublin	2010-08-14
+2961116	Tranarossan Bay	Tranarossan Bay	Tranarossan Bay,Tranrossan Bay	55.23056	-7.82444	H	BAY	IE	IE	U	06			0		-9999	Europe/Dublin	2010-08-14
+2961117	Tranagh	Tranagh		52.69472	-7.6025	P	PPL	IE		M	26			0		138	Europe/Dublin	2010-08-14
+2961118	Tramore Bay	Tramore Bay		55.18333	-8.03333	H	BAY	IE		U	06			0		-9999	Europe/Dublin	1993-12-27
+2961119	Tramore Bay	Tramore Bay		52.13917	-7.1325	H	BAY	IE		M	27			0		-9999	Europe/Dublin	2010-08-14
+2961120	Trá Mhór	Tra Mhor	Tramore	52.16235	-7.15244	P	PPL	IE		M	27			9164		2	Europe/Dublin	2010-08-14
+2961121	Tralong Bay	Tralong Bay		51.55694	-9.05861	H	BAY	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
+2961122	Tralee Bay	Tralee Bay	Tralee Bay	52.27833	-9.93139	H	BAY	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
+2961123	Trá Lí	Tra Li	Tra Li,Tralee,Trá Lí	52.27042	-9.70264	P	PPLA2	IE		M	11			22941	912	48	Europe/Dublin	2010-10-06
+2961124	Tracton	Tracton		51.76139	-8.41639	P	PPL	IE		M	04			0		76	Europe/Dublin	2010-08-14
+2961125	Tracarta	Tracarta		51.51583	-9.19389	P	PPL	IE		M	04			0		6	Europe/Dublin	2010-08-14
+2961126	Trabolgan House	Trabolgan House		51.79972	-8.23583	S	EST	IE		M	04			0		1	Europe/Dublin	2010-08-14
+2961127	Townley Hall	Townley Hall		53.72944	-6.44722	S	EST	IE		L	19			0		54	Europe/Dublin	2010-08-14
+2961128	Towerhill House	Towerhill House		53.71667	-9.2	S	EST	IE		C	20			0		46	Europe/Dublin	1993-12-27
+2961129	Tower	Tower	Tower,Tower Village	51.91667	-8.6	P	PPL	IE		M	04			3099		70	Europe/Dublin	2010-08-14
+2961130	Tourin	Tourin		52.11667	-7.86667	P	PPL	IE		M	27			0		17	Europe/Dublin	1993-12-27
+2961131	Tourig River	Tourig River		51.97778	-7.8625	H	STM	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
+2961132	Tory Sound	Tory Sound		55.21667	-8.2	H	SD	IE		U	06			0		-9999	Europe/Dublin	1993-12-27
+2961133	Toraigh	Toraigh	Toraigh,Tory Island	55.26444	-8.22111	T	ISL	IE		U	06			0		15	Europe/Dublin	2010-08-14
+2961134	The Tor Rocks	The Tor Rocks		55.43333	-7.25	T	RKS	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
+2961135	Torneady Point	Torneady Point	Tornado Point,Torneady Point	55.02167	-8.54028	T	PT	IE	IE	U	06			0		35	Europe/Dublin	2010-08-14
+2961136	Tormore Island	Tormore Island		54.76389	-8.69222	T	ISL	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
+2961137	Torc Mountain	Torc Mountain	Torc Mountain	52	-9.51667	T	MT	IE		M	11			0		189	Europe/Dublin	2010-08-10
+2961138	Torc Cascade	Torc Cascade	Torc Cascade,Tore Cascade	52	-9.5	H	FLLS	IE		M	11			0		378	Europe/Dublin	2010-08-10
+2961139	Toormore Bay	Toormore Bay		51.50194	-9.65583	H	BAY	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
+2961140	Toormore	Toormore		53.79278	-10.03417	L	LCTY	IE		C	20			0		111	Europe/Dublin	2010-08-14
+2961141	Toormore	Toormore		51.52083	-9.65611	P	PPL	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
+2961142	Toormakeady Lodge	Toormakeady Lodge	Toormakeady,Toormakeady Lodge	53.65	-9.38333	S	EST	IE		C	20			0		59	Europe/Dublin	2010-08-10
+2961143	Toormakeady	Toormakeady		53.65	-9.36667	P	PPL	IE		C	20			0		59	Europe/Dublin	1993-12-27
+2961144	Tooreeny	Tooreeny		53	-8.38333	P	PPL	IE		C	10			0		68	Europe/Dublin	2010-08-14
+2961145	Tooreens	Tooreens		51.84278	-10.02861	P	PPL	IE		M	11			0		421	Europe/Dublin	2010-08-14
+2961146	Tooreengarriv	Tooreengarriv		52.16667	-9.28333	P	PPL	IE		M	11			0		241	Europe/Dublin	1993-12-27
+2961147	Tooreendonnell	Tooreendonnell		52.495	-9.22694	P	PPL	IE		M	16			0		152	Europe/Dublin	2010-08-14
+2961148	Tooreencahill	Tooreencahill		52.15	-9.25	P	PPL	IE		M	11			0		181	Europe/Dublin	1993-12-27
+2961149	Tooreenbrien Bridge	Tooreenbrien Bridge	Tooreenbrien,Tooreenbrien Bridge	52.6925	-8.27361	P	PPL	IE	IE	M	26			0		288	Europe/Dublin	2010-11-04
+2961150	Tooreen	Tooreen		53.66667	-9.28333	P	PPL	IE		C	20			0		49	Europe/Dublin	1993-12-27
+2961151	Tooreen	Tooreen		51.55	-9.83333	P	PPL	IE		M	04			0		-9999	Europe/Dublin	1993-12-27
+2961152	Tooravoola	Tooravoola		53.05667	-8.64028	P	PPL	IE		C	10			0		146	Europe/Dublin	2010-08-14
+2961153	Tooraneena	Tooraneena		52.20222	-7.715	P	PPL	IE		M	27			0		152	Europe/Dublin	2010-08-14
+2961154	Toor	Toor		51.8	-10.16667	P	PPL	IE		M	11			0		39	Europe/Dublin	2010-08-14
+2961155	Toon River	Toon River		51.88333	-9.01667	H	STM	IE		M	04			0		104	Europe/Dublin	1993-12-27
+2961156	Toonagh House	Toonagh House		52.88778	-9.02833	S	EST	IE		M	03			0		50	Europe/Dublin	2010-08-14
+2961157	Toomyvara	Toomyvara	Toomyvara,Tuaim Ui Mheara,Tuaim Uí Mheára	52.84972	-8.03222	P	PPL	IE		M	38			0		157	Europe/Dublin	2010-11-04
+2961158	Toomona House	Toomona House		53.76667	-8.28333	S	EST	IE		C	24			0		78	Europe/Dublin	1993-12-27
+2961159	Toomard	Toomard		53.53333	-8.46667	P	PPL	IE		C	10			0		73	Europe/Dublin	1993-12-27
+2961160	Tooban Junction	Tooban Junction		55.05	-7.43333	S	RSTN	IE		U	06			0		55	Europe/Dublin	1993-12-27
+2961161	Tonlegee House	Tonlegee House	Tonlegee,Tonlegee House	52.9775	-6.98917	S	EST	IE	IE	L	15			0		59	Europe/Dublin	2010-08-14
+2961162	Tonduff	Tonduff		55.2	-7.51667	P	PPL	IE		U	06			0		62	Europe/Dublin	1993-12-27
+2961163	Tomies Mountain	Tomies Mountain		52.01667	-9.61667	T	MT	IE		M	11			0		432	Europe/Dublin	1993-12-27
+2961164	Tomhaggard	Tomhaggard		52.21194	-6.51778	P	PPL	IE		L	30			0		11	Europe/Dublin	2010-08-14
+2961165	Tuamgraney	Tuamgraney	Tomgraney,Tuaim Greine,Tuaim Gréine,Tuamgraney	52.89722	-8.53861	P	PPL	IE		M	03			0		75	Europe/Dublin	2010-08-14
+2961166	Tombrack	Tombrack		52.60278	-6.5475	P	PPL	IE		L	30			0		71	Europe/Dublin	2010-08-14
+2961167	Tomacurry	Tomacurry		52.55333	-6.56	P	PPL	IE		L	30			0		56	Europe/Dublin	2010-08-14
+2961168	Tolka River	Tolka River	An Tulca,Tolka River	53.34972	-6.23889	H	STM	IE	IE	00				0		1	Europe/Dublin	2010-08-10
+2961169	Toghermore	Toghermore		53.48333	-8.81667	S	EST	IE		C	10			0		43	Europe/Dublin	1993-12-27
+2961170	The Togher	The Togher		53.07972	-7.19972	P	PPL	IE		L	15			0		134	Europe/Dublin	2010-08-14
+2961171	Togher	Togher		53.84278	-6.30278	P	PPL	IE		L	19			0		21	Europe/Dublin	2010-08-14
+2961172	Togher	Togher		53.08167	-6.52	P	PPL	IE		L	31			0		280	Europe/Dublin	2010-08-14
+2961173	Roundwood	Roundwood	An Tochar,An Tóchar,Roundwood,Togher	53.05861	-6.22611	P	PPL	IE		L	31			0		258	Europe/Dublin	2010-08-14
+2961174	Togher	Togher		51.8775	-8.49167	P	PPL	IE		M	04			0		56	Europe/Dublin	2010-08-14
+2961175	Togher	Togher		51.78111	-9.15556	P	PPL	IE		M	04			0		145	Europe/Dublin	2010-08-14
+2961176	Toem	Toem		52.57667	-8.19611	P	PPL	IE		M	26			0		96	Europe/Dublin	2010-08-14
+2961177	Toe Head Bay	Toe Head Bay		51.49111	-9.25167	H	BAY	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
+2961178	Toe Head	Toe Head		51.48583	-9.23556	T	CAPE	IE		M	04			0		3	Europe/Dublin	2010-08-14
+2961179	Tobertynan House	Tobertynan House	Tobertynan,Tobertynan House	53.48528	-6.8575	S	EST	IE	IE	L	21			0		79	Europe/Dublin	2010-08-14
+2961180	Toberscanavan	Toberscanavan		54.16694	-8.48556	P	PPL	IE		C	25			0		66	Europe/Dublin	2010-08-14
+2961181	Toberdan	Toberdan		53.53333	-8.06667	P	PPL	IE		C	24			0		76	Europe/Dublin	1993-12-27
+2961182	Tobercurry	Tobercurry	Tobar an Choire,Tobercurry,Tubbercurry	54.05	-8.73333	P	PPL	IE		C	25			0		92	Europe/Dublin	2010-08-14
+2961183	Tober	Tober		54.21667	-8.00194	P	PPL	IE		U	02			0		158	Europe/Dublin	2010-08-14
+2961184	Tober	Tober		53.375	-7.65611	P	PPL	IE		L	23			0		73	Europe/Dublin	2010-08-14
+2961185	Tivoli House	Tivoli House		51.9	-8.43333	S	EST	IE		M	04			0		27	Europe/Dublin	2010-08-14
+2961186	Tirraboy	Tirraboy		55.25	-7.15	P	PPL	IE		U	06			0		25	Europe/Dublin	1993-12-27
+2961187	Tirneevin	Tirneevin		53.06417	-8.88306	P	PPL	IE		C	10			0		44	Europe/Dublin	2010-08-14
+2961188	Tiragarvan	Tiragarvan		53.98333	-6.76667	P	PPL	IE		00				0		99	Europe/Dublin	1993-12-27
+2961189	Tipperary South Riding	Tipperary South Riding	South Riding,Tipperary County South Riding	52.41667	-7.83333	A	ADM2	IE		00	40			80276		151	Europe/Dublin	2010-08-14
+2961190	Tipperary North Riding	Tipperary North Riding	North Riding,Tipperary County North Riding	52.75	-7.83333	A	ADM2	IE		00	38			61926		104	Europe/Dublin	2010-08-14
+2961191	County Tipperary	County Tipperary	Contae Thiobraid Arann,Contae Thiobraid Árann,County Tipperary,Tiobraid Arann,Tiobraid Árann,Tipperary	52.66667	-7.83333	A	ADMD	IE	IE	M	26			0		93	Europe/Dublin	2010-11-04
+2961192	Tiobraid Árann	Tiobraid Arann	Tipperary	52.47333	-8.15583	P	PPL	IE		M	26			4976		166	Europe/Dublin	2010-08-14
+2961193	Tintrim House	Tintrim House		52.96417	-8.34556	S	EST	IE		M	03			0		56	Europe/Dublin	2010-08-14
+2961194	Tintern Abbey	Tintern Abbey		52.23528	-6.83333	S	MSTY	IE		L	30			0		3	Europe/Dublin	2010-08-14
+2961195	Tinny Park	Tinny Park		53.68333	-8.38333	P	PPL	IE		C	24			0		76	Europe/Dublin	1993-12-27
+2961196	Tinnaslatty House	Tinnaslatty House		52.8	-7.41667	S	RUIN	IE		L	13			0		154	Europe/Dublin	2010-08-14
+2961197	Timnapark House	Timnapark House	Timnapark House,Tinnapark,Tinnapark House	53.1	-6.11667	S	HSEC	IE	IE	L	31			0		114	Europe/Dublin	2010-08-14
+2961198	Tinnahinch	Tinnahinch		52.53861	-6.94806	P	PPL	IE		L	01			0		28	Europe/Dublin	2010-08-14
+2961199	Tinnaglogh	Tinnaglogh		52.26806	-6.89722	P	PPL	IE		L	30			0		64	Europe/Dublin	2010-08-14
+2961200	Tinkerslane	Tinkerslane		53.505	-6.98111	P	PPL	IE		L	21			0		84	Europe/Dublin	2010-08-14
+2961201	Tincoora	Tincoora		52.1	-8.86667	P	PPL	IE		M	04			0		156	Europe/Dublin	1993-12-27
+2961202	Tinarana House	Tinarana House	Tinarana,Tinarana House	52.86444	-8.44917	S	EST	IE	IE	M	03			0		55	Europe/Dublin	2010-08-14
+2961203	Tinalira	Tinalira		52.18472	-7.72806	P	PPL	IE		M	27			0		133	Europe/Dublin	1997-12-15
+2961204	Tinahely	Tinahely	Tigh na hEille,Tigh na hÉille,Tinahely	52.79667	-6.46333	P	PPL	IE	IE	L	31			0		121	Europe/Dublin	2010-08-14
+2961205	Timoney Park	Timoney Park	Timaney Park,Timoney Park	52.91139	-7.72333	S	EST	IE	IE	M	26			0		153	Europe/Dublin	2010-11-04
+2961206	Timolin	Timolin		52.9825	-6.81167	P	PPL	IE		L	12			0		138	Europe/Dublin	2010-08-14
+2961207	Timoleague	Timoleague	Tigh Molaige,Timoleague	51.64222	-8.77306	P	PPL	IE	IE	M	04			0		25	Europe/Dublin	2010-08-14
+2961208	Timahoe	Timahoe		53.335	-6.83861	P	PPL	IE		L	12			0		92	Europe/Dublin	2010-08-14
+2961209	Timahoe	Timahoe	Tigh Mochua,Timahoe	52.95833	-7.20528	P	PPL	IE	IE	L	15			0		152	Europe/Dublin	2010-08-14
+2961210	Tiltinbane	Tiltinbane	Tiltinbane	54.21972	-7.85778	T	MT	IE		00				0	594	453	Europe/Dublin	2006-01-16
+2961211	Tievemore House	Tievemore House		54.59444	-7.77472	S	HSEC	IE		U	06			0		173	Europe/Dublin	2010-08-14
+2961212	Tievemore	Tievemore		54.58333	-7.76667	P	PPL	IE		00				0		330	Europe/Dublin	1993-12-27
+2961213	Tiaquin	Tiaquin		53.35972	-8.63333	P	PPL	IE		C	10			0		74	Europe/Dublin	2010-08-14
+2961214	Durlas	Durlas	Thurles	52.68194	-7.80222	P	PPL	IE		M	26			7588		98	Europe/Dublin	2010-08-14
+2961215	The Three Sisters	The Three Sisters		52.20167	-10.42194	T	HLLS	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
+2961216	The Pigeons	The Pigeons	The Pigeons,Three Jolly Pigeons	53.5	-7.81667	P	PPL	IE	IE	L	29			0		77	Europe/Dublin	2010-08-14
+2961217	Threecastles House	Threecastles House	Three Castles,Threecastles House	52.71	-7.32	S	EST	IE	IE	L	13			0		67	Europe/Dublin	2010-08-14
+2961218	Three Castle Head	Three Castle Head		51.48278	-9.83667	T	CAPE	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
+2961219	Thomastown Park	Thomastown Park	Thomastown House,Thomastown Park	53.36583	-8.07333	S	EST	IE	IE	C	24			0		123	Europe/Dublin	2010-08-14
+2961220	Thomaston Park	Thomaston Park	Thomaston Park,Thomastown House,Thomastown Park	53.13389	-7.79583	S	EST	IE	IE	L	23			0		76	Europe/Dublin	2010-08-14
+2961221	Thomastown Castle	Thomastown Castle		53.93333	-6.58333	S	EST	IE		00				0		44	Europe/Dublin	1993-12-27
+2961222	Thomastown Castle	Thomastown Castle		52.48972	-8.03222	S	EST	IE		M	26			0		79	Europe/Dublin	2010-08-14
+2961223	Thomastown	Thomastown		53.39639	-6.88417	P	PPL	IE		L	12			0		86	Europe/Dublin	2010-08-14
+2961224	Thomastown	Thomastown	Baile Mhic Andain,Baile Mhic Andáin,Thomastown	52.52667	-7.13722	P	PPL	IE		L	13			1603		52	Europe/Dublin	2010-08-14
+2961225	Thomastown	Thomastown	Thomastown,Thomastown Castle	52.49417	-8.02444	P	PPL	IE	IE	M	26			0		79	Europe/Dublin	2010-11-04
+2961226	Thomas Street	Thomas Street		53.46667	-8.21667	P	PPL	IE		C	24			0		76	Europe/Dublin	1993-12-27
+2961227	Tervoe House	Tervoe House		52.64944	-8.71139	S	EST	IE		M	16			0		3	Europe/Dublin	2010-08-14
+2961228	Terryglass	Terryglass	Terryglass	53.05028	-8.19889	P	PPL	IE		M	26			0		55	Europe/Dublin	2010-11-04
+2961229	Termon River	Termon River	Termon River	54.53333	-7.85	H	STM	IE		00				0		68	Europe/Dublin	1998-02-19
+2961230	Termon Hill	Termon Hill		54.10333	-10.09611	T	HLL	IE		C	20			0	105	2	Europe/Dublin	2010-08-14
+2961231	Termonfeckin	Termonfeckin	Tearmann Feichin,Tearmann Feichín,Termonfeckin	53.76333	-6.26778	P	PPL	IE		L	19			0		3	Europe/Dublin	2010-08-14
+2961232	Termon Cottage	Termon Cottage		53.04806	-9.06056	S	HSEC	IE		M	03			0		151	Europe/Dublin	2010-08-14
+2961233	Termoncarragh	Termoncarragh		54.25139	-10.06361	P	PPL	IE		C	20			0		57	Europe/Dublin	2010-08-14
+2961234	Termonbarry	Termonbarry		53.75	-7.91667	P	PPL	IE		00				0		66	Europe/Dublin	1993-12-27
+2961235	Terenure	Terenure	Roundtown,Terenure	53.30972	-6.28528	P	PPL	IE	IE	00				0		49	Europe/Dublin	2010-08-10
+2961236	Templetouhy	Templetouhy	Teampall Tuaithe,Templetouhy,Templetuohy	52.78722	-7.71972	P	PPL	IE	IE	M	26			0		147	Europe/Dublin	2010-11-04
+2961237	An Teampall Mór	An Teampall Mor	Templemore	52.79472	-7.83389	P	PPL	IE		M	26			2264		120	Europe/Dublin	2010-08-14
+2961238	Templehouse Lake	Templehouse Lake		54.10333	-8.58917	H	LK	IE		C	25			0		74	Europe/Dublin	2010-08-14
+2961239	Temple House	Temple House		54.11083	-8.59111	S	HSEC	IE		C	25			0		74	Europe/Dublin	2010-08-14
+2961240	Templebreedy	Templebreedy		51.78167	-8.31583	A	PRSH	IE		M	04			0		5	Europe/Dublin	2010-08-14
+2961241	Templeboy	Templeboy		54.24583	-8.8125	P	PPL	IE		C	25			0		43	Europe/Dublin	2010-08-14
+2961242	Templebodan	Templebodan		51.99861	-8.24583	P	PPL	IE		M	04			0		138	Europe/Dublin	2010-08-14
+2961243	Temple	Temple	Oriel Temple,Temple	53.78333	-6.46667	S	EST	IE	IE	00				0		152	Europe/Dublin	2010-08-10
+2961244	Temora House	Temora House		53.16667	-7.75	S	EST	IE		L	23			0		73	Europe/Dublin	2010-08-14
+2961245	Teltown House	Teltown House	Teltown,Teltown House	53.69667	-6.77861	S	BLDG	IE	IE	L	21			0		57	Europe/Dublin	2010-08-14
+2961246	Teeromoyle	Teeromoyle		51.97222	-10.07028	P	PPL	IE		M	11			0		170	Europe/Dublin	2010-08-14
+2961247	Teerelton	Teerelton		51.85139	-8.98444	P	PPL	IE		M	04			0		152	Europe/Dublin	2010-08-14
+2961248	Teeranearagh	Teeranearagh		51.86861	-10.26278	P	PPL	IE		M	11			0		263	Europe/Dublin	2010-08-14
+2961249	Teelin Bay	Teelin Bay	Teelin Bay,Teelin Harbour	54.63333	-8.63333	H	HBR	IE		U	06			0		-9999	Europe/Dublin	2010-08-10
+2961250	Teelin	Teelin		54.63472	-8.64167	P	PPL	IE		U	06			0		15	Europe/Dublin	2010-08-14
+2961251	Tedavnet	Tedavnet		54.29639	-7.01389	P	PPL	IE		U	22			0		138	Europe/Dublin	2010-08-14
+2961252	Tearaght Island	Tearaght Island	Inishteraght,Tearaght Island	52.07528	-10.65667	T	ISL	IE	IE	M	11			0		-9999	Europe/Dublin	2010-08-14
+2961253	River Tay	River Tay		52.125	-7.46222	H	STM	IE		M	27			0		-9999	Europe/Dublin	2010-08-14
+2961254	Lough Tay	Lough Tay	Loch Te,Loch Té,Lough Tay,Luggada Lake	53.10472	-6.26861	H	LK	IE	IE	L	31			0		342	Europe/Dublin	2010-08-14
+2961255	Tawnyinah	Tawnyinah		53.9	-8.76667	P	PPL	IE		C	20			0		135	Europe/Dublin	1993-12-27
+2961256	Tawny Bay	Tawny Bay		54.62167	-8.61861	H	BAY	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
+2961257	Tawnyard Lough	Tawnyard Lough		53.63333	-9.63333	H	LK	IE		C	20			0		74	Europe/Dublin	1993-12-27
+2961258	Tawny	Tawny	Tamney,Tawny	55.2	-7.68333	P	PPL	IE	IE	U	06			0		51	Europe/Dublin	2010-08-14
+2961259	Tawny	Tawny		54.62444	-8.60083	P	PPL	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
+2961260	Tawnawully Mountains	Tawnawully Mountains		54.73528	-7.98333	T	MTS	IE		U	06			0		180	Europe/Dublin	2010-08-14
+2961261	Tawin Island	Tawin Island	Tawin Island,West Tawin	53.21861	-9.03194	T	ISL	IE	IE	C	10			0		1	Europe/Dublin	2010-08-14
+2961262	Taurbeg	Taurbeg		52.23333	-9.13333	T	MT	IE		M	04			0		299	Europe/Dublin	1993-12-27
+2961263	Taur	Taur		52.23333	-9.11667	P	PPL	IE		M	04			0		291	Europe/Dublin	1993-12-27
+2961264	Tarsaghaunmore River	Tarsaghaunmore River		54.06361	-9.785	H	STM	IE		C	20			0		55	Europe/Dublin	2010-08-14
+2961265	Tarmon	Tarmon		52.53806	-9.37889	P	PPL	IE		M	11			0		76	Europe/Dublin	2010-08-14
+2961266	Tarbert House	Tarbert House		52.57833	-9.36833	S	EST	IE		M	11			0		1	Europe/Dublin	2010-08-14
+2961267	Tarbert	Tarbert	Tairbeart,Tarbert	52.57278	-9.37528	P	PPL	IE	IE	M	11			0		12	Europe/Dublin	2010-08-14
+2961268	Tara Hill	Tara Hill		52.69806	-6.21472	T	HLL	IE		L	30			0		56	Europe/Dublin	2010-08-14
+2961269	Tara Hall	Tara Hall		53.58	-6.60222	S	EST	IE		L	21			0		121	Europe/Dublin	2010-08-14
+2961270	Hill of Tara	Hill of Tara		53.57972	-6.61194	T	HLL	IE		L	21			0		135	Europe/Dublin	2010-08-14
+2961271	River Tar	River Tar		52.28333	-7.83333	H	STM	IE		00				0		48	Europe/Dublin	1993-12-27
+2961272	Lough Tap	Lough Tap		53.9	-7.98333	H	LK	IE		C	14			0		92	Europe/Dublin	1993-12-27
+2961273	Tanrego House	Tanrego House	Tanrego,Tanrego House	54.23056	-8.61222	S	HSEC	IE	IE	C	25			0		1	Europe/Dublin	2010-08-14
+2961274	Tankersley House	Tankersley House		52.82667	-6.38583	S	EST	IE		L	31			0		87	Europe/Dublin	2010-08-14
+2961275	Tang River	Tang River		53.53333	-7.83333	H	STM	IE		L	29			0		67	Europe/Dublin	1993-12-27
+2961276	Tang	Tang		53.53333	-7.78333	P	PPL	IE		L	29			0		67	Europe/Dublin	1993-12-27
+2961277	Lough Talt	Lough Talt		54.08389	-8.92139	H	LK	IE		C	25			0		182	Europe/Dublin	2010-08-14
+2961278	Tallyho Lodge	Tallyho Lodge		53.27	-8.69611	S	HSEC	IE		C	10			0		46	Europe/Dublin	2010-08-14
+2961279	Tallyho	Tallyho		52.81361	-6.36222	P	PPL	IE		L	31			0		170	Europe/Dublin	2010-08-14
+2961280	Tallow Road Station	Tallow Road Station	Tallow Road,Tallow Road Station	52.11667	-7.98333	S	RSTN	IE	IE	M	27			0		71	Europe/Dublin	2010-08-14
+2961281	Tallowbridge	Tallowbridge		52.10417	-8.00278	P	PPL	IE		M	27			0		32	Europe/Dublin	2010-08-14
+2961282	Tallow	Tallow	Tallow,Tulach an Iarainn	52.09278	-8.00806	P	PPL	IE		M	27			0		44	Europe/Dublin	2010-08-14
+2961283	Tallanstown	Tallanstown		53.92278	-6.54639	P	PPL	IE		L	19			0		36	Europe/Dublin	2010-08-14
+2961284	Tallaght	Tallaght	Tallaght	53.2859	-6.37344	P	PPL	IE	IE	L	07			64282		87	Europe/Dublin	2010-08-14
+2961285	Talbotstown House	Talbotstown House		53.22917	-6.45167	S	EST	IE		L	31			0		298	Europe/Dublin	2010-08-14
+2961286	Talbot Hall	Talbot Hall		52.38611	-6.9125	S	EST	IE		L	13			0		76	Europe/Dublin	2010-08-14
+2961287	Tahilla	Tahilla		51.83722	-9.83639	P	PPL	IE		M	11			0		62	Europe/Dublin	2010-08-14
+2961288	Tagoat	Tagoat		52.24278	-6.38028	P	PPL	IE		L	30			0		1	Europe/Dublin	2010-08-14
+2961289	Taghshinny	Taghshinny	Taghshinny	53.6	-7.71667	P	PPL	IE		L	18			0		76	Europe/Dublin	2010-08-10
+2961290	Taghsheenod	Taghsheenod		53.61667	-7.71667	P	PPL	IE		L	18			0		90	Europe/Dublin	1993-12-27
+2961291	Taghmon Castle	Taghmon Castle		53.6	-7.26667	S	BLDG	IE		L	29			0		118	Europe/Dublin	1993-12-27
+2961292	Taghmon	Taghmon	Taghmon,Teach Munna	52.32167	-6.6475	P	PPL	IE		L	30			0		73	Europe/Dublin	2010-08-14
+2961293	Tacumshin Lake	Tacumshin Lake	Tacumshin Lake,Tacumshin Lough,Tucumshin Lake	52.19528	-6.45306	H	BAY	IE	IE	L	30			0		-9999	Europe/Dublin	2010-08-14
+2961294	Lough Tacker	Lough Tacker		54.01667	-6.95	H	LK	IE		U	02			0		127	Europe/Dublin	2010-08-14
+2961295	Table Mountain	Table Mountain		53.01444	-6.48417	T	MT	IE		L	31			0	701	599	Europe/Dublin	2010-08-14
+2961296	Sybil Point	Sybil Point		52.17806	-10.47333	T	PT	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
+2961297	Swords	Swords	Sord,Swords	53.45972	-6.21806	P	PPL	IE		L	35			29816		6	Europe/Dublin	2010-11-04
+2961298	Swines Head	Swines Head		52.12972	-7.02667	T	CAPE	IE		M	27			0		-9999	Europe/Dublin	2010-08-14
+2961299	Swinford	Swinford	Beal Atha na Muice,Béal Átha na Muice,Swineford,Swinford	53.95	-8.95	P	PPL	IE		C	20			1241		68	Europe/Dublin	2010-08-14
+2961300	River Swilly	River Swilly		54.96056	-7.67778	H	STM	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
+2961301	Lough Swilly	Lough Swilly	Loch Suili,Loch Súilí,Lough Swilly,The Lake of Shadows	55.16667	-7.53333	H	INLT	IE		U	06			0		-9999	Europe/Dublin	2011-03-06
+2961302	The Sweep	The Sweep		52.21667	-7.23333	P	PPL	IE		M	27			0		49	Europe/Dublin	2010-08-14
+2961303	Swanlinbar	Swanlinbar	An Muileann Iarainn,Swanlinbar	54.19472	-7.70444	P	PPL	IE		U	02			0		74	Europe/Dublin	2010-08-14
+2961304	Swan	Swan		52.8875	-7.15972	P	PPL	IE		L	15			0		153	Europe/Dublin	2010-08-14
+2961305	Sutton	Sutton	Sutton	53.39056	-6.12167	P	PPL	IE		L	07			0		-9999	Europe/Dublin	2010-11-04
+2961306	Sunvale	Sunvale	Sun Ville,Sunvale	52.34611	-8.5175	S	EST	IE	IE	M	16			0		151	Europe/Dublin	2010-08-14
+2961307	Lough Sunderlin	Lough Sunderlin	Lough Sewdy,Lough Sunderlin	53.5	-7.66667	H	LK	IE		L	29			0		79	Europe/Dublin	2010-08-10
+2961308	Summerville	Summerville		53.8	-7.36667	P	PPL	IE		U	02			0		73	Europe/Dublin	1993-12-27
+2961309	Summerhill House	Summerhill House		53.47	-6.72556	S	EST	IE		L	21			0		78	Europe/Dublin	2010-08-14
+2961310	Summerhill House	Summerhill House		52.76306	-7.94278	S	EST	IE		M	26			0		107	Europe/Dublin	2010-08-14
+2961311	Summerhill House	Summerhill House	Summerhill House,Summerville	52.36778	-7.73889	S	EST	IE	IE	M	26			0		71	Europe/Dublin	2010-11-04
+2961312	Summerhill	Summerhill		53.47694	-6.73639	P	PPL	IE		L	21			0		77	Europe/Dublin	2010-08-14
+2961313	Summerhill	Summerhill		52.80528	-7.13722	P	PPL	IE		L	13			0		227	Europe/Dublin	2010-08-14
+2961314	Summer Cove	Summer Cove	Summer Cove,Summor Cove	51.70333	-8.50222	P	PPL	IE	IE	M	04			0		-9999	Europe/Dublin	2010-08-14
+2961315	Sullane River	Sullane River		51.88333	-8.93333	H	STM	IE		M	04			0		85	Europe/Dublin	2010-08-14
+2961316	Suir Mount	Suir Mount		52.29611	-7.79222	S	EST	IE		M	27			0		59	Europe/Dublin	2010-08-14
+2961317	Suir Island	Suir Island		52.35	-7.7	T	ISL	IE		M	27			0		132	Europe/Dublin	2010-08-14
+2961318	Suircastle House	Suircastle House		52.46167	-7.98972	S	HSEC	IE		M	26			0		73	Europe/Dublin	2010-08-14
+2961319	River Suir	River Suir	River Suir	52.27333	-6.99556	H	STM	IE		00				0		1	Europe/Dublin	2011-01-04
+2961320	Sugarloaf Mountain	Sugarloaf Mountain	Sugarloaf Mountain	51.72583	-9.63111	T	MT	IE		M	04			0		228	Europe/Dublin	2010-08-14
+2961321	Sugar Hill	Sugar Hill		52.43611	-9.16917	T	HLL	IE		M	11			0		312	Europe/Dublin	2010-08-14
+2961322	River Suck	River Suck		53.27222	-8.05306	H	STM	IE		00				0		55	Europe/Dublin	1998-08-18
+2961323	Sturrall	Sturrall		54.73667	-8.74417	T	CAPE	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
+2961324	Stuake	Stuake		51.98333	-8.76667	P	PPL	IE		M	04			0		171	Europe/Dublin	2010-08-14
+2961325	Stroove	Stroove		55.21667	-6.93333	P	PPL	IE		U	06			0		-9999	Europe/Dublin	1993-12-27
+2961326	Strokestown House	Strokestown House		53.76667	-8.1	S	EST	IE		C	24			0		71	Europe/Dublin	1993-12-27
+2961327	Strokestown	Strokestown	Beal na mBuilli,Béal na mBuillí,Strokestown	53.78333	-8.1	P	PPL	IE		C	24			0		72	Europe/Dublin	2010-08-14
+2961328	Street	Street		53.66667	-7.48333	P	PPL	IE		L	29			0		72	Europe/Dublin	1993-12-27
+2961329	Streek Head	Streek Head		51.47056	-9.70306	T	CAPE	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
+2961330	Streedagh Point	Streedagh Point		54.41194	-8.56722	T	PT	IE		C	25			0		1	Europe/Dublin	2010-08-14
+2961331	Streedagh House	Streedagh House		54.39778	-8.56389	S	HSEC	IE		C	25			0		1	Europe/Dublin	2010-08-14
+2961332	Streamstown Bay	Streamstown Bay		53.50917	-10.06833	H	BAY	IE		C	10			0		-9999	Europe/Dublin	2010-08-14
+2961333	Streamstown	Streamstown		53.52333	-10.04694	P	PPL	IE		C	10			0		76	Europe/Dublin	2010-08-14
+2961334	Streamstown	Streamstown		53.43333	-7.58333	P	PPL	IE		L	29			0		102	Europe/Dublin	1993-12-27
+2961335	Strawberryhill House	Strawberryhill House		53.23639	-7.88778	S	HSEC	IE		L	23			0		68	Europe/Dublin	2010-08-14
+2961336	Stratford	Stratford	Ath na Sraide,Stratford,Áth na Sráide	52.98583	-6.67778	P	PPL	IE		L	31			0		147	Europe/Dublin	2010-08-14
+2961337	Stranorlar	Stranorlar	Srath an Urlair,Srath an Urláir,Stranorlar	54.8	-7.76667	P	PPL	IE		U	06			0		58	Europe/Dublin	2010-08-14
+2961338	Strand	Strand		52.39556	-9.11056	P	PPL	IE		M	03			0		152	Europe/Dublin	2010-08-14
+2961339	Strancally House	Strancally House		52.01667	-7.85	S	BLDG	IE		M	04			0		71	Europe/Dublin	2010-08-14
+2961340	Strancally Castle	Strancally Castle		52.06861	-7.87694	S	EST	IE		M	27			0		36	Europe/Dublin	2010-08-14
+2961341	Straid River	Straid River		55.28333	-7.33333	H	STM	IE		U	06			0		40	Europe/Dublin	1993-12-27
+2961342	Straffan	Straffan		53.31556	-6.63472	P	PPL	IE		L	12			0		72	Europe/Dublin	2010-08-14
+2961343	Stradone House	Stradone House		53.98389	-7.25	S	EST	IE		U	02			0		134	Europe/Dublin	2010-08-14
+2961344	Stradone	Stradone	Sraith an Domhain,Stradone	53.98333	-7.23333	P	PPL	IE	IE	U	02			0		135	Europe/Dublin	2010-08-14
+2961345	Strade	Strade		53.91694	-9.13389	P	PPL	IE		C	20			0		38	Europe/Dublin	2010-08-14
+2961346	Stradbally River	Stradbally River	Bauteogue River,Stradbally River,Strade River,Straid River	53.03806	-7.08972	H	STM	IE	IE	L	15			0		72	Europe/Dublin	2010-08-14
+2961347	Stradbally Hall	Stradbally Hall		53	-7.16667	S	EST	IE		L	15			0		152	Europe/Dublin	2010-08-14
+2961348	Stradbally	Stradbally		53.21889	-8.88667	P	PPL	IE		C	10			0		2	Europe/Dublin	2010-08-14
+2961349	Stradbally	Stradbally	An Sraidbhaile,An Sráidbhaile,Stradbally	53.01556	-7.15278	P	PPL	IE		L	15			0		149	Europe/Dublin	2010-08-14
+2961350	Stradbally	Stradbally		52.24722	-10.06639	P	PPL	IE		M	11			0		81	Europe/Dublin	2010-08-14
+2961351	Stradbally	Stradbally	An tSraidbhaile,An tSráidbhaile,Stradbally	52.13	-7.46	P	PPL	IE		M	27			0		17	Europe/Dublin	2010-08-14
+2961352	Stowlin House	Stowlin House		53.18139	-8.21722	S	EST	IE		C	10			0		75	Europe/Dublin	2010-08-14
+2961353	Stookaruddan	Stookaruddan	Stockaruddan,Stookaruddan,Stookarudden	55.36972	-7.28222	T	ISLS	IE	IE	U	06			0		-9999	Europe/Dublin	2010-08-14
+2961354	Stonyford	Stonyford		52.53639	-7.22	P	PPL	IE		L	13			0		69	Europe/Dublin	2010-08-14
+2961355	Stonybatter	Stonybatter		52.76278	-6.45278	P	PPL	IE		L	31			0		159	Europe/Dublin	2010-08-14
+2961356	Stonetown	Stonetown		53.61667	-8.55	P	PPL	IE		C	10			0		76	Europe/Dublin	1993-12-27
+2961357	Stonepark	Stonepark		54.01028	-8.93722	P	PPL	IE		C	20			0		77	Europe/Dublin	2010-08-14
+2961358	Stonehall	Stonehall		52.60722	-8.87306	P	PPL	IE		M	16			0		22	Europe/Dublin	2010-08-14
+2961359	Stonefield	Stonefield		54.31	-9.82972	P	PPL	IE		C	20			0		141	Europe/Dublin	2010-08-14
+2961360	Stone Bridge	Stone Bridge		54.2	-7.16667	P	PPL	IE		U	22			0		73	Europe/Dublin	2010-08-14
+2961361	Stokestown	Stokestown	Stokestown,Stokestown Castle	52.36028	-6.98806	S	EST	IE	IE	L	30			0		13	Europe/Dublin	2010-08-14
+2961362	Stillorgan	Stillorgan		53.29049	-6.19487	P	PPL	IE		L	07			0		39	Europe/Dublin	2010-08-14
+2961363	Stephenstown House	Stephenstown House	Stephenstown,Stephenstown House	53.95806	-6.46639	S	EST	IE	IE	L	19			0		19	Europe/Dublin	2010-08-14
+2961364	Stepaside	Stepaside	Stepaside	53.2525	-6.21361	P	PPL	IE		L	07			0		140	Europe/Dublin	2010-11-04
+2961365	Station Island	Station Island		54.60833	-7.87139	T	ISL	IE		U	06			0		148	Europe/Dublin	2010-08-14
+2961366	Stamullin	Stamullin		53.62889	-6.26833	P	PPL	IE		L	21			0		48	Europe/Dublin	2010-08-14
+2961367	Stags of Broad Haven	Stags of Broad Haven	Stags,Stags of Broad Haven,The Stags	54.36639	-9.78778	T	RKS	IE	IE	C	20			0		-9999	Europe/Dublin	2010-08-14
+2961368	Stags of Bofin	Stags of Bofin		53.63194	-10.25917	T	RKS	IE		C	10			0		-9999	Europe/Dublin	2010-08-14
+2961369	The Stag Rocks	The Stag Rocks	The Stag Rocks,The Stags	55.07528	-8.47889	T	RKS	IE	IE	U	06			0		-9999	Europe/Dublin	2010-08-14
+2961370	Stacks Mountains	Stacks Mountains		52.31667	-9.56667	T	MTS	IE		M	11			0		286	Europe/Dublin	1993-12-27
+2961371	Stabannan	Stabannan	Stabannan,Stahannan	53.86472	-6.43583	P	PPL	IE	IE	L	19			0		6	Europe/Dublin	2010-08-14
+2961372	Sruwaddacon Bay	Sruwaddacon Bay	Sruwaddacon Bay,Sruwaddacon Creek	54.26667	-9.78333	H	BAY	IE		C	20			0		-9999	Europe/Dublin	2010-08-10
+2961373	Srahmore River	Srahmore River		53.95667	-9.58	H	STM	IE		C	20			0		98	Europe/Dublin	2010-08-14
+2961374	Srahmore	Srahmore		53.96028	-9.57083	P	PPL	IE		C	20			0		131	Europe/Dublin	2010-08-14
+2961375	Srahlaghy	Srahlaghy		54.235	-9.57361	P	PPL	IE		C	20			0		128	Europe/Dublin	2010-08-14
+2961376	Srahduggaun	Srahduggaun		54	-9.73333	P	PPL	IE		C	20			0		73	Europe/Dublin	1993-12-27
+2961377	Srah	Srah		54.1725	-9.93361	P	PPL	IE		C	20			0		5	Europe/Dublin	2010-08-14
+2961378	Srah	Srah		53.68333	-9.33333	P	PPL	IE		C	20			0		59	Europe/Dublin	1993-12-27
+2961379	Srah	Srah		53.28333	-7.75	P	PPL	IE		L	23			0		65	Europe/Dublin	2010-08-14
+2961380	Spring Valley	Spring Valley		53.47806	-6.71389	S	EST	IE		L	21			0		77	Europe/Dublin	2010-08-14
+2961381	Springfield Castle	Springfield Castle		52.35	-8.95	S	EST	IE		M	16			0		146	Europe/Dublin	1993-12-27
+2961382	Springfield	Springfield		53.05	-7.4	P	PPL	IE		L	15			0		138	Europe/Dublin	2010-08-14
+2961383	Springfield	Springfield		52.71556	-6.615	S	EST	IE		L	31			0		71	Europe/Dublin	2010-08-14
+2961384	Sporthouse Cross Roads	Sporthouse Cross Roads		52.19667	-7.17917	P	PPL	IE		M	27			0		77	Europe/Dublin	2010-08-14
+2961385	Spittle	Spittle		52.38	-8.3375	P	PPL	IE		M	16			0		152	Europe/Dublin	2010-08-14
+2961386	Spink	Spink		52.89944	-7.22611	P	PPL	IE		L	15			0		151	Europe/Dublin	2010-08-14
+2961387	Spike Island	Spike Island		51.83861	-8.28889	T	ISL	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
+2961388	Spiddal	Spiddal	An Spideal,An Spidéal,Spiddal,Spiddle	53.24667	-9.30278	P	PPL	IE		C	10			0		1	Europe/Dublin	2010-08-14
+2961389	Spear Vale	Spear Vale		53.91667	-7	P	PPL	IE		U	02			0		187	Europe/Dublin	1993-12-27
+2961390	Spanish Point	Spanish Point		52.84972	-9.44722	T	PT	IE		M	03			0		-9999	Europe/Dublin	2010-08-14
+2961391	Spancelhill	Spancelhill		52.86667	-8.9	P	PPL	IE		M	03			0		119	Europe/Dublin	1993-12-27
+2961392	Spa	Spa		52.28333	-9.78333	P	PPL	IE		M	11			0		39	Europe/Dublin	2010-08-14
+2961393	River Sow	River Sow		52.37778	-6.45139	H	STM	IE		L	30			0		4	Europe/Dublin	2010-08-14
+2961394	Sovereign Islands	Sovereign Islands	Big Sovereign,Sovereign Islands	51.67667	-8.45556	T	ISLS	IE	IE	M	04			0		-9999	Europe/Dublin	2010-08-14
+2961395	Sovereign Island	Sovereign Island	Little Sovereign,Sovereign Island	51.68389	-8.4425	T	ISL	IE	IE	M	04			0		-9999	Europe/Dublin	2010-08-14
+2961396	South Sound	South Sound		53.04167	-9.46583	H	SD	IE		M	03			0		-9999	Europe/Dublin	2010-08-14
+2961397	Southpark House	Southpark House		53.76667	-8.43333	S	EST	IE		C	24			0		77	Europe/Dublin	1993-12-27
+2961398	South Hill	South Hill		53.60861	-7.07167	S	EST	IE		L	29			0		109	Europe/Dublin	2010-08-14
+2961399	Sorrel House	Sorrel House		52.75	-9.23333	S	BLDG	IE		M	03			0		96	Europe/Dublin	1993-12-27
+2961400	Sorrelhill House	Sorrelhill House		52.83333	-7.75	S	EST	IE		M	26			0		150	Europe/Dublin	2010-08-14
+2961401	Sopwell Hall	Sopwell Hall		52.99194	-8.04806	S	EST	IE		M	26			0		119	Europe/Dublin	2010-08-14
+2961402	Soppog	Soppog		55.06472	-7.32111	P	PPL	IE		U	06			0		63	Europe/Dublin	2010-08-14
+2961403	Sonna House	Sonna House		53.56667	-7.46667	S	EST	IE		L	29			0		123	Europe/Dublin	1993-12-27
+2961404	Somerville House	Somerville House	Somerville,Somerville House	53.63139	-6.51167	S	EST	IE	IE	L	21			0		57	Europe/Dublin	2010-08-14
+2961405	Somerset House	Somerset House		53.24778	-8.22694	S	EST	IE		C	10			0		76	Europe/Dublin	2010-08-14
+2961406	Solsborough House	Solsborough House	Solsborough,Solsborough House	52.52861	-6.52	S	EST	IE	IE	L	30			0		64	Europe/Dublin	2010-08-14
+2961407	Snowhill House	Snowhill House		52.27278	-7.02028	S	EST	IE		L	13			0		1	Europe/Dublin	2010-08-14
+2961408	Sneem Harbour	Sneem Harbour		51.8	-9.88333	H	INLT	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
+2961409	Sneem	Sneem	An Snaidhm,An tSnaidhm,Sneem	51.83333	-9.9	P	PPL	IE		M	11			0		25	Europe/Dublin	2010-08-14
+2961410	Slieve Snaght	Slieve Snaght	Sliabh Sneachta,Slieve Snaght	55.19639	-7.33528	T	MT	IE		U	06			0	615	573	Europe/Dublin	2010-08-14
+2961411	Slieve Snaght	Slieve Snaght		54.98083	-8.11778	T	MT	IE		U	06			0		466	Europe/Dublin	2010-08-14
+2961412	Smithstown House	Smithstown House		52.98333	-9.26667	S	EST	IE		M	03			0		75	Europe/Dublin	1993-12-27
+2961413	Smithborough	Smithborough		54.22333	-7.09083	P	PPL	IE		U	22			0		74	Europe/Dublin	2010-08-14
+2961414	Smerwick Harbour	Smerwick Harbour		52.19222	-10.4025	H	HBR	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
+2961415	Smerwick	Smerwick		52.19444	-10.42333	P	PPL	IE		M	11			0		30	Europe/Dublin	2010-08-14
+2961416	Smearlagh River	Smearlagh River		52.43917	-9.42889	H	STM	IE		M	11			0		74	Europe/Dublin	2010-08-14
+2961417	Smarmore Castle	Smarmore Castle		53.81722	-6.56667	S	EST	IE		L	19			0		75	Europe/Dublin	2010-08-14
+2961418	Slyne Head	Slyne Head		53.40056	-10.23528	T	CAPE	IE		C	10			0		-9999	Europe/Dublin	2010-08-14
+2961419	Slugga	Slugga		54.30278	-9.86556	T	RK	IE		C	20			0		-9999	Europe/Dublin	2010-08-14
+2961420	Slish Wood	Slish Wood		54.23333	-8.38333	V	FRST	IE		C	25			0		149	Europe/Dublin	2010-08-14
+2961421	Sligo Bay	Sligo Bay		54.3	-8.7	H	BAY	IE		C	25			0		-9999	Europe/Dublin	1998-09-01
+2961422	Sligeach	Sligeach	Contae Shligigh,County Sligo,Sligo	54.25	-8.66667	A	ADM2	IE		C	25			58900		5	Europe/Dublin	2010-08-14
+2961423	Sligeach	Sligeach	Slajgou,Sligeach,Sligo,suraigo,Слайгоу,スライゴ	54.26969	-8.46943	P	PPLA2	IE		C	25			20228	13	5	Europe/Dublin	2010-08-14
+2961424	Slievetooey	Slievetooey		54.76278	-8.60722	T	MT	IE		U	06			0		329	Europe/Dublin	2010-08-14
+2961425	Slieveroe	Slieveroe		52.28056	-7.08667	P	PPL	IE		L	13			0		59	Europe/Dublin	2010-08-14
+2961426	Slievenamuck	Slievenamuck		52.4275	-8.23194	T	MT	IE		M	26			0		156	Europe/Dublin	2010-08-14
+2961427	Slievenamon	Slievenamon	Slievenaman,Slievenamon	52.42778	-7.56111	T	MT	IE		M	26			0	721	568	Europe/Dublin	2010-11-04
+2961428	Slievenakilla	Slievenakilla		54.15	-7.93333	P	PPL	IE		C	14			0		315	Europe/Dublin	1993-12-27
+2961429	Slievemore Point	Slievemore Point		54.01667	-10.05	T	PT	IE		C	20			0		73	Europe/Dublin	1993-12-27
+2961430	Slievemore	Slievemore		53.99611	-10.07056	P	PPLL	IE		C	20			0		149	Europe/Dublin	2010-08-14
+2961431	Slievemore	Slievemore		54.0075	-10.0625	T	MT	IE		C	20			0	671	269	Europe/Dublin	2010-08-14
+2961432	Slieve Miskish Mountains	Slieve Miskish Mountains	Slieve Miskish Mountains	51.66722	-9.95306	T	MTS	IE		M	04			0		188	Europe/Dublin	2010-08-14
+2961433	Slieve Mish Mountains	Slieve Mish Mountains	Slieve Mish Mountains	52.2	-9.76667	T	MTS	IE		M	11			0		224	Europe/Dublin	2010-08-14
+2961434	Slievekimalta	Slievekimalta	Keeper Hill,Slievekimalta	52.74972	-8.26028	T	MT	IE	IE	M	26			0		421	Europe/Dublin	2010-11-04
+2961435	Slieveglass	Slieveglass		52.27861	-10.20667	T	MT	IE		M	11			0		143	Europe/Dublin	2010-08-14
+2961436	Slievefelim Mountains	Slievefelim Mountains		52.67167	-8.3075	T	MTS	IE		M	16			0		315	Europe/Dublin	2010-08-14
+2961437	Slievecarran	Slievecarran		53.09583	-9.00639	T	MT	IE		M	03			0		154	Europe/Dublin	2010-08-14
+2961438	Slievecallan	Slievecallan		52.84056	-9.26861	T	MT	IE		M	03			0		279	Europe/Dublin	2010-08-14
+2961439	Slieveboy	Slieveboy		52.65639	-6.48861	T	MT	IE		L	30			0	422	266	Europe/Dublin	2010-08-14
+2961440	Slieve Bloom Mountains	Slieve Bloom Mountains	Slieve Bloom,Slieve Bloom Mountains	53.09333	-7.56722	T	MTS	IE		L	15			0		326	Europe/Dublin	2010-08-10
+2961441	Slievebane Bay	Slievebane Bay		55.36667	-7.33333	H	BAY	IE		U	06			0		1	Europe/Dublin	2010-08-14
+2961442	Slieve Aughty Mountains	Slieve Aughty Mountains	Slieve Aughty Mountains	53.04611	-8.51111	T	MTS	IE		C	10			0		151	Europe/Dublin	2010-08-14
+2961443	Slieveardagh Hills	Slieveardagh Hills	Slievardagh Region,Slieveardagh Hills	52.65278	-7.52056	T	HLLS	IE	IE	00				0		152	Europe/Dublin	2010-08-10
+2961444	Slevoir House	Slevoir House		53.06139	-8.18111	S	EST	IE		M	26			0		56	Europe/Dublin	2010-08-14
+2961445	Sleatygraigue	Sleatygraigue		52.84472	-6.97167	P	PPL	IE		L	15			0		39	Europe/Dublin	2010-08-14
+2961446	Slea Head	Slea Head		52.09639	-10.45917	T	CAPE	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
+2961447	Slate River	Slate River		53.195	-7.09417	H	STM	IE		L	23			0		75	Europe/Dublin	1999-02-24
+2961448	River Slaney	River Slaney		52.33806	-6.45306	H	STM	IE		L	30			0		-9999	Europe/Dublin	2010-08-14
+2961449	Slane Castle	Slane Castle		53.70944	-6.5825	S	EST	IE		L	21			0		37	Europe/Dublin	2010-08-14
+2961450	Slane	Slane	Baile Shlaine,Baile Shláine,Slane	53.71	-6.54333	P	PPL	IE		L	21			0		58	Europe/Dublin	2010-08-14
+2961451	Slaheny River	Slaheny River		51.9	-9.45	H	STM	IE		M	11			0		86	Europe/Dublin	1993-12-27
+2961452	Slade	Slade		52.1325	-6.90444	P	PPL	IE		L	30			0		-9999	Europe/Dublin	2010-08-14
+2961453	Skycur House	Skycur House	Skycur,Skycur House	53.22139	-8.23472	S	EST	IE	IE	C	10			0		76	Europe/Dublin	2010-08-14
+2961454	Skull Harbour	Skull Harbour		51.52528	-9.53833	H	HBR	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
+2961455	Skull	Skull	An Scoil,Schull,Skull	51.53333	-9.53333	P	PPL	IE		M	04			0		44	Europe/Dublin	2010-08-14
+2961456	Skreeny House	Skreeny House		54.315	-8.16722	S	RUIN	IE		C	14			0		76	Europe/Dublin	2010-08-14
+2961457	Skreen	Skreen		54.24333	-8.73111	P	PPL	IE		C	25			0		55	Europe/Dublin	2010-08-14
+2961458	Screen	Screen	Screen,Skreen	52.41361	-6.4125	P	PPL	IE	IE	L	30			0		22	Europe/Dublin	2010-08-14
+2961459	An Sciobairin	An Sciobairin	Skibbereen	51.55	-9.26667	P	PPL	IE		M	04			2098		98	Europe/Dublin	2010-08-14
+2961460	Skerries Islands	Skerries Islands		53.58333	-6.08333	T	ISLS	IE		00				0		-9999	Europe/Dublin	1993-12-27
+2961461	Skerries	Skerries	Na Sceiri,Na Sceirí,Skerries	53.58278	-6.10833	P	PPL	IE		L	35			10014		-9999	Europe/Dublin	2010-11-04
+2961462	Skenakilla Cross Roads	Skenakilla Cross Roads		52.19306	-8.51778	P	PPL	IE		M	04			0		76	Europe/Dublin	2010-08-14
+2961463	Skellig Rocks	Skellig Rocks	Skellig Rocks,The Skelligs	51.76667	-10.51667	T	RKS	IE	IE	M	11			0		-9999	Europe/Dublin	2010-08-14
+2961464	Skehanagh	Skehanagh		53.41389	-8.63417	P	PPL	IE		C	10			0		72	Europe/Dublin	2010-08-14
+2961465	Lough Skean	Lough Skean		54.06222	-8.21528	H	LK	IE		00				0		55	Europe/Dublin	1998-09-01
+2961466	Skeagh Lough Upper	Skeagh Lough Upper	Skeagh Lough,Skeagh Lough Upper	53.95	-7	H	LK	IE	IE	U	02			0		150	Europe/Dublin	2010-08-14
+2961467	Skeagh	Skeagh		51.58639	-9.35472	P	PPL	IE		M	04			0		79	Europe/Dublin	2010-08-14
+2961468	Skeaf House	Skeaf House		51.6775	-8.78111	S	EST	IE		M	04			0		75	Europe/Dublin	2010-08-14
+2961469	Lough Skannive	Lough Skannive		53.33083	-9.78722	H	LK	IE		C	10			0		65	Europe/Dublin	2010-08-14
+2961470	Sixmilebridge	Sixmilebridge	Droichead Abhann O gCearnaigh,Droíchead Abhann Ó gCearnaigh,Sixmilebridge	52.74139	-8.77417	P	PPL	IE		M	03			0		43	Europe/Dublin	2010-08-14
+2961471	Single Street	Single Street		54.48306	-8.26417	P	PPL	IE		U	06			0		1	Europe/Dublin	2010-08-14
+2961472	Silver Stream	Silver Stream		54.26667	-6.91667	P	PPL	IE		00				0		66	Europe/Dublin	1993-12-27
+2961473	Silver River	Silver River		53.2925	-7.62889	H	STM	IE		L	23			0		70	Europe/Dublin	2010-08-14
+2961474	Silver River	Silver River		53.24333	-7.79139	H	STM	IE		L	23			0		63	Europe/Dublin	2010-08-14
+2961475	Silvermines	Silvermines	Beal Atha Gabhann,Béal Átha Gabhann,Silvermines	52.79028	-8.23417	P	PPL	IE		M	38			0		188	Europe/Dublin	2010-11-04
+2961476	Silvermine Mountains	Silvermine Mountains	Silvermine Mountains,Silvermines Mountains	52.77583	-8.24889	T	MTS	IE	IE	M	26			0		345	Europe/Dublin	2010-11-04
+2961477	Silver Hill	Silver Hill		54.76944	-8.14722	T	MT	IE		U	06			0		423	Europe/Dublin	2010-08-14
+2961478	Lough Sillan	Lough Sillan		54.00222	-6.92222	H	LK	IE		U	02			0		149	Europe/Dublin	2010-08-14
+2961479	Siddan	Siddan		53.80972	-6.65639	P	PPL	IE		L	21			0		61	Europe/Dublin	2010-08-14
+2961480	Shrule Castle	Shrule Castle		52.87694	-6.95111	S	BLDG	IE		L	15			0		48	Europe/Dublin	2010-08-14
+2961481	Shrule	Shrule	Shrule,Shruthair,Sruthair	53.51681	-9.08902	P	PPL	IE		C	20			0		59	Europe/Dublin	2010-08-14
+2961482	Shronowen	Shronowen		52.50389	-9.45361	P	PPL	IE		M	11			0		69	Europe/Dublin	2010-08-14
+2961483	Shronell	Shronell		52.47222	-8.23472	P	PPL	IE		M	26			0		136	Europe/Dublin	2010-08-14
+2961484	Shrone	Shrone		52.525	-9.49	P	PPL	IE		M	11			0		57	Europe/Dublin	2010-08-14
+2961485	Shot Head	Shot Head		51.67667	-9.67611	T	CAPE	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
+2961486	Shiven River	Shiven River	Kingstown River,Shiven River	53.51667	-8.45	H	STM	IE		C	10			0		72	Europe/Dublin	2010-08-10
+2961487	Shiven River	Shiven River		53.5	-8.28333	H	STM	IE		00				0		69	Europe/Dublin	1993-12-27
+2961488	Shippool	Shippool	Shippool,Shippool Castle	51.75111	-8.62889	S	RUIN	IE	IE	M	04			0		72	Europe/Dublin	2010-08-14
+2961489	Shinrone	Shinrone	Shinrone,Sui an Roin,Suí an Róin	52.9825	-7.92444	P	PPL	IE	IE	L	23			0		84	Europe/Dublin	2010-08-14
+2961490	Lough Shindilla	Lough Shindilla		53.45	-9.56667	H	LK	IE		C	10			0		58	Europe/Dublin	1993-12-27
+2961491	Shillelagh	Shillelagh	Shillelagh,Siol Ealaigh,Síol Éalaigh	52.75389	-6.53722	P	PPL	IE	IE	L	31			0		76	Europe/Dublin	2010-08-14
+2961492	Sheskin Lodge	Sheskin Lodge		54.17028	-9.615	S	HSE	IE		C	20			0		146	Europe/Dublin	2010-08-14
+2961493	Sheshia	Sheshia		53.1	-9.06667	P	PPL	IE		M	03			0		57	Europe/Dublin	1993-12-27
+2961494	Sherky Island	Sherky Island		51.7975	-9.905	T	ISL	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
+2961495	Sherkin Island	Sherkin Island	Sherkin Island	51.4775	-9.42694	T	ISL	IE		M	04			0		1	Europe/Dublin	2010-08-14
+2961496	Sheriffhill	Sheriffhill		52.95	-6.80278	P	PPL	IE		L	12			0		143	Europe/Dublin	2010-08-14
+2961497	Shercock	Shercock	Searcog,Searcóg,Shercock	54	-6.9	P	PPL	IE	IE	U	02			0		153	Europe/Dublin	2010-08-14
+2961498	Shenicks Island	Shenicks Island		53.57472	-6.08444	T	ISL	IE		L	07			0		-9999	Europe/Dublin	2010-08-14
+2961499	Shelton Abbey	Shelton Abbey		52.815	-6.18278	S	EST	IE		L	31			0		43	Europe/Dublin	2010-08-14
+2961500	Shehy Mountain	Shehy Mountain		51.81778	-9.28722	T	MT	IE		M	04			0		334	Europe/Dublin	2010-08-14
+2961501	Sheffield	Sheffield	Sheffield,Sheffield House	53.00417	-7.26806	S	EST	IE	IE	L	15			0		150	Europe/Dublin	2010-08-14
+2961502	Sheep Haven	Sheep Haven	Cuan na gCaorach,Sheep Haven	55.2	-7.9	H	BAY	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
+2961503	Sheen River	Sheen River		51.86667	-9.56667	H	STM	IE		M	11			0		61	Europe/Dublin	1993-12-27
+2961504	Lough Sheelin	Lough Sheelin		53.8	-7.31667	H	LK	IE		L	21			0		73	Europe/Dublin	1993-12-27
+2961505	Sheehills House	Sheehills House		52.93278	-7.76861	S	EST	IE		M	26			0		135	Europe/Dublin	2010-08-14
+2961506	Sheeanamore	Sheeanamore		52.885	-6.37694	P	PPL	IE		L	31			0		269	Europe/Dublin	2010-08-14
+2961507	Shark Head	Shark Head	Shark Head,Stark Head	53.60167	-10.295	T	CAPE	IE	IE	C	10			0		-9999	Europe/Dublin	2010-08-14
+2961508	Shanvally	Shanvally		53.78333	-7.91667	P	PPL	IE		C	24			0		67	Europe/Dublin	1993-12-27
+2961509	Shantonagh	Shantonagh		54.05028	-6.85056	P	PPL	IE		U	22			0		147	Europe/Dublin	2010-08-14
+2961510	Shanow River	Shanow River		52.36667	-9.65	H	STM	IE		M	11			0		70	Europe/Dublin	1993-12-27
+2961511	Shannon View	Shannon View		52.61667	-8.98333	S	EST	IE		M	16			0		3	Europe/Dublin	1993-12-27
+2961512	Shannon Harbour	Shannon Harbour	Shannon Harbour	53.22056	-7.94833	P	PPL	IE		L	23			0		73	Europe/Dublin	2010-08-14
+2961513	Shannon Hall	Shannon Hall	Shannon Hall,Shannonvale House	52.90417	-8.28056	S	BLDG	IE	IE	M	26			0		51	Europe/Dublin	2010-11-04
+2961514	Shannongrove House	Shannongrove House	Shannongrove,Shannongrove House	52.66	-8.86417	S	EST	IE	IE	M	16			0		1	Europe/Dublin	2010-08-14
+2961515	Shannon Grove	Shannon Grove		53.19861	-8.04806	S	EST	IE		C	10			0		55	Europe/Dublin	2010-08-14
+2961516	Shannonbridge	Shannonbridge	Droichead na Sionainne,Shannonbridge	53.27778	-8.03722	P	PPL	IE		L	23			0		56	Europe/Dublin	2010-08-14
+2961517	River Shannon	River Shannon		52.58194	-9.68167	H	STM	IE		00				0		-9999	Europe/Dublin	1998-05-05
+2961518	Mouth of the Shannon	Mouth of the Shannon		52.50167	-9.81694	H	STMM	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
+2961519	Shannaghmore	Shannaghmore		53.6	-8.6	P	PPL	IE		C	10			0		76	Europe/Dublin	1993-12-27
+2961520	Shanlis Cross Roads	Shanlis Cross Roads	Shanlis,Shanlis Cross Roads	53.83778	-6.57111	P	PPL	IE	IE	L	19			0		49	Europe/Dublin	2010-08-14
+2961521	Shanlaragh	Shanlaragh		51.79556	-9.07889	P	PPL	IE		M	04			0		152	Europe/Dublin	2010-08-14
+2961522	Shankill Castle	Shankill Castle		52.68611	-7.02111	S	EST	IE		L	13			0		60	Europe/Dublin	2010-08-14
+2961523	Shankill	Shankill	Shankill	53.22611	-6.12444	P	PPL	IE		L	07			0		1	Europe/Dublin	2010-11-04
+2961524	Shanid Castle	Shanid Castle		52.55	-9.11667	S	BLDG	IE		M	16			0		117	Europe/Dublin	1993-12-27
+2961525	Shanganagh Junction	Shanganagh Junction		53.21667	-6.1	S	RSTN	IE		00				0		-9999	Europe/Dublin	1993-12-27
+2961526	Shanganagh Castle	Shanganagh Castle		53.22583	-6.11972	S	EST	IE		L	07			0		1	Europe/Dublin	2010-08-14
+2961527	Shanballymore	Shanballymore	An Seanbhaile Mor,An Seanbhaile Mór,Shanballymore	52.22028	-8.50139	P	PPL	IE		M	04			0		70	Europe/Dublin	2010-08-14
+2961528	Shanbally House	Shanbally House	Shanbally,Shanbally House	52.85722	-8.09167	S	EST	IE	IE	M	26			0		105	Europe/Dublin	2010-11-04
+2961529	Shanbally Castle	Shanbally Castle		52.29361	-8.04361	S	EST	IE		M	26			0		75	Europe/Dublin	2010-08-14
+2961530	Shanbally	Shanbally		51.8325	-8.3575	P	PPL	IE		M	04			0		11	Europe/Dublin	2010-08-14
+2961531	Shanagolden	Shanagolden	Seanghualainn,Shanagolden	52.5725	-9.1025	P	PPL	IE	IE	M	16			0		67	Europe/Dublin	2010-08-14
+2961532	Shanagh	Shanagh	Shanagh,Shunagh	51.58222	-8.71889	P	PPL	IE	IE	M	04			0		13	Europe/Dublin	2010-08-14
+2961533	Shanagarry	Shanagarry	Shanagarry	51.85444	-8.07083	P	PPL	IE		M	04			0		51	Europe/Dublin	2010-08-14
+2961534	Shallee River	Shallee River		52.87056	-8.99528	H	STM	IE		M	03			0		24	Europe/Dublin	2010-08-14
+2961535	Shaen House	Shaen House	Shaen,Shaen House	53.06667	-7.25	S	EST	IE	IE	L	15			0		141	Europe/Dublin	2010-08-14
+2961536	Shad Lough	Shad Lough		53.73333	-8.26667	H	LK	IE		C	24			0		76	Europe/Dublin	1993-12-27
+2961537	The Seven Stars	The Seven Stars		53.05722	-6.88028	L	LCTY	IE		L	12			0		108	Europe/Dublin	2010-08-14
+2961538	The Seven Hogs	The Seven Hogs	Magharee Islands,The Seven Hogs	52.32194	-10.03528	T	ISLS	IE	IE	M	11			0		-9999	Europe/Dublin	2010-08-14
+2961539	Seven Heads Bay	Seven Heads Bay		51.59444	-8.7	H	BAY	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
+2961540	Seven Heads	Seven Heads		51.56889	-8.7275	T	CAPE	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
+2961541	Seven Fathom Bank	Seven Fathom Bank		52.8	-6	H	BNK	IE		L	31			0		-9999	Europe/Dublin	1993-12-27
+2961542	Sevenchurches	Sevenchurches	Camaderry,Sevenchurches	53.02389	-6.39306	S	RUIN	IE	IE	L	31			0		588	Europe/Dublin	2010-08-14
+2961543	The Seven Arches	The Seven Arches	Seven Arches,The Seven Arches	55.21667	-7.6	S	CAVE	IE		U	06			0		-9999	Europe/Dublin	2010-08-10
+2961544	Seskinryan	Seskinryan		52.68222	-6.93167	P	PPL	IE		L	01			0		115	Europe/Dublin	2010-08-14
+2961545	Seskinrea	Seskinrea		52.76778	-7.06833	P	PPL	IE		L	01			0		191	Europe/Dublin	2010-08-14
+2961546	Seltannaveeny	Seltannaveeny	Seltannaveeny,Seltannavenny	54.1	-8.11667	P	PPL	IE		C	24			0		145	Europe/Dublin	2010-08-10
+2961547	Sellerna Bay	Sellerna Bay	Sellerna Bay,Sillerna Bay	53.55	-10.13333	H	BAY	IE		C	10			0		61	Europe/Dublin	2010-08-10
+2961548	Seershin	Seershin		53.26667	-9.21667	P	PPL	IE		C	10			0		57	Europe/Dublin	2010-08-14
+2961549	Seaweed Point	Seaweed Point		53.24889	-9.10944	T	PT	IE		C	10			0		-9999	Europe/Dublin	2010-08-14
+2961550	Seaview House	Seaview House	Seaview,Seaview House	52.02472	-7.58556	S	EST	IE	IE	M	27			0		2	Europe/Dublin	2010-08-14
+2961551	Seapark Point	Seapark Point		52.93333	-6.01667	T	PT	IE		L	31			0		-9999	Europe/Dublin	2010-08-14
+2961552	Sea Mount	Sea Mount		53.44278	-6.14	P	PPL	IE		L	07			0		1	Europe/Dublin	2010-08-14
+2961553	Seal Rocks	Seal Rocks		54.33667	-8.68722	T	RKS	IE		C	25			0		-9999	Europe/Dublin	2010-08-14
+2961554	Seafield House	Seafield House	Seafield,Seafield House	52.67417	-6.21444	S	EST	IE	IE	L	30			0		-9999	Europe/Dublin	2010-08-14
+2961555	Scurmore House	Scurmore House	Scarmore House,Scurmore House	54.19667	-9.11556	S	HSEC	IE	IE	C	25			0		3	Europe/Dublin	2010-08-14
+2961556	Lough Scur	Lough Scur	Lough Scur,Lough Seur	54.02667	-7.95222	H	LK	IE	IE	C	14			0		65	Europe/Dublin	2010-08-14
+2961557	Scullogue Gap	Scullogue Gap	Sculloge Gap,Scullogue Gap	52.57306	-6.7875	T	GAP	IE	IE	L	01			0		286	Europe/Dublin	2010-08-14
+2961558	Scullane Point	Scullane Point		51.49139	-9.21139	T	PT	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
+2961559	Scregg West	Scregg West		53.53333	-8.58333	P	PPL	IE		C	10			0		76	Europe/Dublin	1993-12-27
+2961560	Scregg House	Scregg House		53.55	-8.1	S	EST	IE		C	24			0		76	Europe/Dublin	1993-12-27
+2961561	Scregg East	Scregg East		53.53333	-8.56667	P	PPL	IE		C	10			0		76	Europe/Dublin	1993-12-27
+2961562	Screeb Lodge	Screeb Lodge	Screeb,Screeb Lodge	53.38694	-9.5525	S	HSEC	IE	IE	C	10			0		69	Europe/Dublin	2010-08-14
+2961563	Scramore Loughs	Scramore Loughs		54.3	-8.35	H	LKS	IE		00				0		284	Europe/Dublin	1993-12-27
+2961564	Scramoge	Scramoge		53.76667	-8.05	P	PPL	IE		C	24			0		76	Europe/Dublin	1993-12-27
+2961565	Scrahan	Scrahan		52.4	-9.36667	P	PPL	IE		M	11			0		143	Europe/Dublin	1993-12-27
+2961566	Scrabby	Scrabby		53.86667	-7.53333	P	PPL	IE		U	02			0		70	Europe/Dublin	1993-12-27
+2961567	Scotstown	Scotstown	Baile an Scotaigh,Scotstown	54.2775	-7.065	P	PPL	IE		U	22			0		81	Europe/Dublin	2010-08-14
+2961568	Scotshouse	Scotshouse		54.12194	-7.2475	P	PPL	IE		U	22			0		78	Europe/Dublin	2010-08-14
+2961569	Scilly	Scilly		51.70639	-8.52167	P	PPL	IE		M	04			0		1	Europe/Dublin	2010-08-14
+2961570	Scattery Island	Scattery Island		52.61222	-9.51944	T	ISL	IE		M	03			0		-9999	Europe/Dublin	2010-08-14
+2961571	Scartaglin	Scartaglin	Scartaglen,Scartaglin,Seartaglin	52.18333	-9.4	P	PPL	IE		M	11			0		149	Europe/Dublin	2010-08-10
+2961572	Scarriff Bay	Scarriff Bay	Scariff Bay,Scarriff Bay	52.90333	-8.48694	H	BAY	IE	IE	M	03			0		55	Europe/Dublin	2010-08-14
+2961573	River Scarriff	River Scarriff		52.9	-8.5	H	STM	IE		M	03			0		55	Europe/Dublin	1993-12-27
+2961574	Scarriff	Scarriff	An Scairbh,Scariff,Scarriff	52.89889	-8.50917	P	PPL	IE		M	03			0		82	Europe/Dublin	2010-08-14
+2961575	Scariff Island	Scariff Island	Great Hog Island,Scariff Island	51.73556	-10.25333	T	ISL	IE	IE	M	11			0		47	Europe/Dublin	2010-08-14
+2961576	Scardaun	Scardaun		53.65	-9	P	PPL	IE		C	20			0		120	Europe/Dublin	1993-12-27
+2961577	Lough Scannive	Lough Scannive		53.43528	-9.9525	H	LK	IE		C	10			0		81	Europe/Dublin	2010-08-14
+2961578	Scalp Mountain	Scalp Mountain		55.08917	-7.36611	T	MT	IE		U	06			0	484	352	Europe/Dublin	2010-08-14
+2961579	The Scalp	The Scalp	An Scailp,The Scalp	53.21611	-6.17944	T	GAP	IE	IE	00				0		151	Europe/Dublin	2010-08-10
+2961580	Scalp	Scalp		53.08333	-6.58333	P	PPL	IE		L	31			0		304	Europe/Dublin	2010-08-14
+2961581	Scalp	Scalp		52.99139	-8.48972	T	MT	IE		C	10			0		304	Europe/Dublin	2010-08-14
+2961582	Saundersville	Saundersville		52.96667	-6.68333	P	PPL	IE		L	31			0		156	Europe/Dublin	1993-12-27
+2961583	Saunders Court	Saunders Court		52.36611	-6.49333	S	EST	IE		L	30			0		1	Europe/Dublin	2010-08-14
+2961584	Sarsfieldscourt House	Sarsfieldscourt House	Sarsfieldcourt,Sarsfieldscourt House	51.95139	-8.4025	S	HSEC	IE	IE	M	04			0		89	Europe/Dublin	2010-08-14
+2961585	Sarnaght	Sarnaght		53.89056	-9.31389	P	PPL	IE		C	20			0		104	Europe/Dublin	2010-08-14
+2961586	Sarahville	Sarahville		52.16667	-7.46667	S	EST	IE		M	27			0		78	Europe/Dublin	1993-12-27
+2961587	Santry	Santry		53.39812	-6.25268	P	PPL	IE		L	07			0		12	Europe/Dublin	2010-08-14
+2961588	Sandymount	Sandymount		53.97139	-6.36194	P	PPL	IE		L	19			0		-9999	Europe/Dublin	2010-08-14
+2961589	Sandymount	Sandymount		53.335	-6.21139	P	PPL	IE		L	07			0		-9999	Europe/Dublin	2010-08-14
+2961590	Sandy Ford	Sandy Ford		52.85194	-6.46139	P	PPL	IE		L	31			0		289	Europe/Dublin	2010-08-14
+2961591	Sandy Cove	Sandy Cove		51.67694	-8.54917	P	PPL	IE		M	04			0		72	Europe/Dublin	2010-08-14
+2961592	Sandeel Bay	Sandeel Bay		52.1575	-6.87	H	BAY	IE		L	30			0		-9999	Europe/Dublin	2010-08-14
+2961593	Samphire Island	Samphire Island		52.27167	-9.865	T	ISL	IE		M	11			0		-9999	Europe/Dublin	2010-08-14
+2961594	Saltmills	Saltmills		52.22194	-6.82667	P	PPL	IE		L	30			0		-9999	Europe/Dublin	2010-08-14
+2961595	Salt Hill	Salt Hill		53.26139	-9.06944	P	PPL	IE		C	10			0		1	Europe/Dublin	2010-08-14
+2961596	Salt Hill	Salt Hill		54.63111	-8.21111	S	EST	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
+2961597	Salterstown	Salterstown		53.87167	-6.30694	P	PPL	IE		L	19			0		1	Europe/Dublin	2010-08-14
+2961598	Saltee Islands	Saltee Islands	Saltee Islands	52.125	-6.59722	T	ISLS	IE		L	30			0		-9999	Europe/Dublin	2010-08-14
+2961599	Little Saltee	Little Saltee	Little Saltee,North Saltee,Saltee Island Little	52.13333	-6.61667	T	ISL	IE	IE	L	30			0		-9999	Europe/Dublin	2010-08-14
+2961600	Great Saltee	Great Saltee	Great Saltee,Saltee Island Great,South Saltee	52.11667	-6.61667	T	ISL	IE	IE	L	30			0		-9999	Europe/Dublin	2010-08-14
+2961601	Lough Salt	Lough Salt		55.08278	-7.80611	H	LK	IE		U	06			0		340	Europe/Dublin	2010-08-14
+2961602	Salrock	Salrock		53.6	-9.85	P	PPL	IE		C	10			0		144	Europe/Dublin	1993-12-27
+2961603	Sallymount House	Sallymount House	Sallymount,Sallymount House	53.12222	-6.70972	S	EST	IE	IE	L	12			0		151	Europe/Dublin	2010-08-14
+2961604	Sally Gap	Sally Gap	Sally Gap,Sully Gap	53.13611	-6.31306	T	GAP	IE	IE	L	31			0		460	Europe/Dublin	2010-08-14
+2961605	Sallybrook Station	Sallybrook Station	Sallybrook,Sallybrook Station	54.95	-7.56667	S	RSTN	IE		U	06			0		86	Europe/Dublin	2010-08-10
+2961606	Sallybrook	Sallybrook	Sallybrook	51.935	-8.38639	P	PPL	IE		M	04			0		76	Europe/Dublin	2010-08-14
+2961607	Sallins	Sallins	Na Sollain,Na Solláin,Sallins	53.24889	-6.66611	P	PPL	IE		L	12			3164		97	Europe/Dublin	2010-08-14
+2961608	Salisbury Lodge	Salisbury Lodge		53.65	-8	S	EST	IE		L	18			0		79	Europe/Dublin	1993-12-27
+2961609	Salia	Salia		53.95111	-9.94806	P	PPL	IE		C	20			0		26	Europe/Dublin	2010-08-14
+2961610	Saleen Harbour	Saleen Harbour	Saleen Bay,Saleen Harbour	54.18361	-10.03	H	HBR	IE	IE	C	20			0		-9999	Europe/Dublin	2010-08-14
+2961611	Saleen	Saleen		52.55861	-9.46444	P	PPL	IE		M	11			0		11	Europe/Dublin	2010-08-14
+2961612	Saleen	Saleen		51.86333	-8.16556	P	PPL	IE		M	04			0		74	Europe/Dublin	2010-08-14
+2961613	Saivnose River	Saivnose River		51.61278	-9.27	H	STM	IE		M	04			0		56	Europe/Dublin	2010-08-14
+2961614	Saint Thomas Island	Saint Thomas Island		52.69	-8.62	T	ISL	IE		M	03			0		2	Europe/Dublin	2010-08-14
+2961615	Saint Stephens Green Park	Saint Stephens Green Park		53.33784	-6.25813	L	PRK	IE		L	07			0		5	Europe/Dublin	2010-08-14
+2961616	Saints Island	Saints Island		54.61528	-7.88639	T	ISL	IE		U	06			0		152	Europe/Dublin	2010-08-14
+2961617	Patrickswell	Patrickswell	Patrickswell,Saint Patrickswell,Tobar Phadraig,Tobar Phádraig	52.59722	-8.70889	P	PPL	IE		M	16			0		55	Europe/Dublin	2010-08-14
+2961618	Saint Patricks Island	Saint Patricks Island		53.58833	-6.07389	T	ISL	IE		L	07			0		-9999	Europe/Dublin	2010-08-14
+2961619	Saint Mullins	Saint Mullins		52.49278	-6.92306	P	PPL	IE		L	01			0		45	Europe/Dublin	2010-08-14
+2961620	Saint Margarets House	Saint Margarets House		52.20083	-6.34472	S	BLDG	IE		L	30			0		-9999	Europe/Dublin	2010-08-14
+2961621	Saint Macdaras Island	Saint Macdaras Island	Macdara,Saint Macdaras Island	53.305	-9.91889	T	ISL	IE	IE	C	10			0		-9999	Europe/Dublin	2010-08-14
+2961622	Saint Johnstown	Saint Johnstown	Baile Suingean,Saint Johnston,Saint Johnstown	54.93333	-7.45	P	PPL	IE		U	06			0		1	Europe/Dublin	2010-08-14
+2961623	Saint Johns Port	Saint Johns Port		54.33333	-8.6	P	PPL	IE		C	25			0		-9999	Europe/Dublin	1993-12-27
+2961624	Saint John’s Point	Saint John's Point		54.56667	-8.46667	T	PT	IE		U	06			0		-9999	Europe/Dublin	2010-08-14
+2961625	Saint Johns Lough	Saint Johns Lough		54.04028	-7.86167	H	LK	IE		C	14			0		70	Europe/Dublin	2010-08-14
+2961626	Saint Johns House	Saint Johns House		52.48833	-6.56944	S	EST	IE		L	30			0		51	Europe/Dublin	2010-08-14
+2961627	Saint Finans Bay	Saint Finans Bay	Saint Finans Bay,Saint Finian Bay,Saint Finnans Bay	51.81667	-10.36667	H	BAY	IE	IE	M	11			0		-9999	Europe/Dublin	2010-08-14
+2961628	Saint Edmonds	Saint Edmonds		52.38333	-6.48333	S	EST	IE		L	30			0		1	Europe/Dublin	2010-08-14
+2961629	Saint Doolaghs	Saint Doolaghs		53.41639	-6.18056	P	PPL	IE		L	07			0		3	Europe/Dublin	2010-08-14
+2961630	Saint Clerans	Saint Clerans	Saint Clerans,Saint Clernans	53.22667	-8.65778	S	EST	IE	IE	C	10			0		51	Europe/Dublin	2010-08-14
+2961631	Saint Catherines	Saint Catherines	Saint Catharine's,Saint Catharine’s,Saint Catherines	52.86667	-8.6	P	PPL	IE		M	03			0		76	Europe/Dublin	2010-08-10
+2961632	Saint Brendans House	Saint Brendans House		53.53333	-8.4	S	EST	IE		C	10			0		69	Europe/Dublin	1993-12-27
+2961633	Saint Brendans	Saint Brendans	Saint Bredan's,Saint Bredan’s,Saint Brendans	53.23417	-8.06083	S	EST	IE	IE	C	10			0		61	Europe/Dublin	2010-08-14
+2961634	Saint Anns Wells	Saint Anns Wells		53.23333	-6.35	P	PPL	IE		00				0		300	Europe/Dublin	2007-05-30
+2961635	Saint Anns Hill	Saint Anns Hill	Saint Ann's,Saint Anne's Hill,Saint Anne’s Hill,Saint Anns Hill,Saint Ann’s	51.93333	-8.6	P	PPL	IE	IE	M	04			0		68	Europe/Dublin	2010-08-14
+2961636	Saggart	Saggart	Saggart,Teach Sagard	53.28028	-6.44444	P	PPL	IE	IE	L	07			0		150	Europe/Dublin	2010-11-04
+2961637	Safe Harbour	Safe Harbour		53.53333	-8	H	COVE	IE		C	24			0		62	Europe/Dublin	1993-12-27
+2961638	Saddle Hill	Saddle Hill		54.34861	-8.12917	T	MT	IE		C	14			0	379	310	Europe/Dublin	2010-08-14
+2961639	Saddle Head	Saddle Head	Gubroenacoragh,Saddle Head	54.01222	-10.18889	T	CAPE	IE	IE	C	20			0		45	Europe/Dublin	2010-08-14
+2961640	Ryves Castle	Ryves Castle		52.42306	-8.36611	S	EST	IE		M	16			0		121	Europe/Dublin	2010-08-14
+2961641	Ryndville	Ryndville		53.43667	-6.82306	S	EST	IE		L	21			0		86	Europe/Dublin	2010-08-14
+2961642	Rylane Cross	Rylane Cross	Rylane,Rylane Cross	51.98333	-8.83333	P	PPL	IE	IE	M	04			0		191	Europe/Dublin	2010-08-14
+2961643	Rye Water	Rye Water	An Ri,Rye Water	53.365	-6.49111	H	STM	IE	IE	00				0		47	Europe/Dublin	2010-08-10
+2961644	Ryehill	Ryehill		53.39889	-8.69222	S	EST	IE		C	10			0		76	Europe/Dublin	2010-08-14
+2961645	Ryefield	Ryefield		53.78806	-7.05861	P	PPL	IE		U	02			0		126	Europe/Dublin	2010-08-14
+2961646	Rutland Island	Rutland Island		54.97667	-8.45722	T	ISL	IE		U	06			0		1	Europe/Dublin	2010-08-14
+2961647	Russborough House	Russborough House	Russborough,Russborough House	53.14111	-6.56806	S	HSEC	IE	IE	L	31			0		181	Europe/Dublin	2010-08-14
+2961648	Rushin House	Rushin House		53.01778	-7.49528	S	EST	IE		L	15			0		129	Europe/Dublin	2010-08-14
+2961649	Slieve Rushen	Slieve Rushen	Slieve Rushen	54.15	-7.63333	T	MT	IE		U	02			0		309	Europe/Dublin	1998-02-13
+2961650	Rushbrooke	Rushbrooke	Rushbrooke	51.85	-8.31667	P	PPL	IE		M	04			0		-9999	Europe/Dublin	2010-08-14
+2961651	An Ros	An Ros	Rush	53.5223	-6.09308	P	PPL	IE		L	07			7294		1	Europe/Dublin	2010-08-14
+2961652	Runnamoat House	Runnamoat House	Runnamoat,Runnamoat House	53.68333	-8.31667	S	EST	IE		C	24			0		77	Europe/Dublin	2010-08-10
+2961653	Rue Point	Rue Point	Bankmore Point,Rue Point	54.43639	-8.64583	T	PT	IE	IE	C	25			0		-9999	Europe/Dublin	2010-08-14
+2961654	Ruan	Ruan		52.93056	-8.98972	P	PPL	IE		M	03			0		38	Europe/Dublin	2010-08-14
+2961655	Royaloak	Royaloak		52.7	-6.98667	P	PPL	IE		L	01			0		40	Europe/Dublin	2010-08-14
+2961656	Royal Canal	Royal Canal	An Chanail Rioga,Royal Canal	53.35	-6.23333	H	CNL	IE	IE	00				0		1	Europe/Dublin	2010-08-10
+2961657	Roy	Roy		54.08028	-9.94528	P	PPLL	IE		C	20			0		1	Europe/Dublin	2010-08-14
+2961658	Roxborough House	Roxborough House	Roxborough,Roxborough House	53.65	-8.18333	S	EST	IE		C	24			0		75	Europe/Dublin	2010-08-10
+2961659	Roxborough House	Roxborough House	Roxborough,Roxborough House	52.61306	-8.615	S	EST	IE	IE	M	16			0		56	Europe/Dublin	2010-08-14
+2961660	Roxborough	Roxborough		53.16694	-8.69528	S	EST	IE		C	10			0		76	Europe/Dublin	2010-08-14
+2961661	Rowls Aldworth	Rowls Aldworth		52.3	-9.01667	S	BLDG	IE		M	04	

<TRUNCATED>

[38/50] [abbrv] lucene-solr git commit: LUCENE-7015: "fix" package-info/javadocs issues across duplicated packages.

Posted by ho...@apache.org.
LUCENE-7015: "fix" package-info/javadocs issues across duplicated packages.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/dc39fc3e
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/dc39fc3e
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/dc39fc3e

Branch: refs/heads/jira/SOLR-445
Commit: dc39fc3e5a99e70aebf70fa565f7868e2544e9ca
Parents: 89db495
Author: Robert Muir <rm...@apache.org>
Authored: Mon Feb 29 19:49:29 2016 -0500
Committer: Robert Muir <rm...@apache.org>
Committed: Mon Feb 29 19:49:29 2016 -0500

----------------------------------------------------------------------
 .../org/apache/lucene/spatial/package-info.java | 21 ----------------
 .../java/org/apache/lucene/spatial/package.html | 26 ++++++++++++++++++++
 .../lucene/spatial/util/package-info.java       | 21 ----------------
 .../org/apache/lucene/spatial/util/package.html | 26 ++++++++++++++++++++
 4 files changed, 52 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/dc39fc3e/lucene/spatial-extras/src/java/org/apache/lucene/spatial/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/package-info.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/package-info.java
deleted file mode 100644
index c86bc6e..0000000
--- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/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.
- */
-
-/**
- * Lucene advanced spatial search
- */
-package org.apache.lucene.spatial;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/dc39fc3e/lucene/spatial-extras/src/java/org/apache/lucene/spatial/package.html
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/package.html b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/package.html
new file mode 100644
index 0000000..b109f3a
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/package.html
@@ -0,0 +1,26 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<!--
+ 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.
+-->
+<!-- not a package-info.java, because we already defined this package in spatial/ -->
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</head>
+<body>
+Lucene advanced spatial search
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/dc39fc3e/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/package-info.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/package-info.java
deleted file mode 100644
index 08a872a..0000000
--- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/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.
- */
-
-/**
- * Advanced spatial utilities.
- */
-package org.apache.lucene.spatial.util;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/dc39fc3e/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/package.html
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/package.html b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/package.html
new file mode 100644
index 0000000..83d9975
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/package.html
@@ -0,0 +1,26 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<!--
+ 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.
+-->
+<!-- not a package-info.java, because we already defined this package in spatial/ -->
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</head>
+<body>
+Advanced spatial utilities. 
+</body>
+</html>


[37/50] [abbrv] lucene-solr git commit: SOLR-445: refactor test to subclass SolrCloudTestCase

Posted by ho...@apache.org.
SOLR-445: refactor test to subclass SolrCloudTestCase


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/5fab8bc3
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/5fab8bc3
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/5fab8bc3

Branch: refs/heads/jira/SOLR-445
Commit: 5fab8bc34c4a66e1f935463631439ab8f505bb30
Parents: 18804d6
Author: Chris Hostetter <ho...@apache.org>
Authored: Mon Feb 29 17:48:27 2016 -0700
Committer: Chris Hostetter <ho...@apache.org>
Committed: Mon Feb 29 17:48:27 2016 -0700

----------------------------------------------------------------------
 .../cloud/TestTolerantUpdateProcessorCloud.java | 58 ++++----------------
 1 file changed, 12 insertions(+), 46 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5fab8bc3/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java b/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
index 38db3ac..016a897 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
@@ -27,14 +27,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
-import org.apache.lucene.util.LuceneTestCase;
-import org.apache.lucene.util.LuceneTestCase.SuppressSysoutChecks;
-import org.apache.solr.SolrTestCaseJ4;
-import static org.apache.solr.SolrTestCaseJ4.params;
+import org.apache.solr.cloud.SolrCloudTestCase;
 import org.apache.solr.client.solrj.SolrClient;
-import org.apache.solr.client.solrj.embedded.JettyConfig;
-import org.apache.solr.client.solrj.embedded.JettyConfig.Builder;
 import org.apache.solr.client.solrj.embedded.JettySolrRunner;
 import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
@@ -54,14 +48,10 @@ import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.util.RevertDefaultThreadHandlerRule;
 
-import org.junit.ClassRule;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.rules.RuleChain;
-import org.junit.rules.TestRule;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -88,8 +78,7 @@ import org.slf4j.LoggerFactory;
  * - randomized # nodes, shards, replicas
  * - random updates contain rand # of docs with rand # failures to a random client
  */
-@SuppressSysoutChecks(bugUrl = "Solr logs to JUL")
-public class TestTolerantUpdateProcessorCloud extends LuceneTestCase {
+public class TestTolerantUpdateProcessorCloud extends SolrCloudTestCase {
 
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
@@ -99,8 +88,6 @@ public class TestTolerantUpdateProcessorCloud extends LuceneTestCase {
   
   private static final String COLLECTION_NAME = "test_col";
   
-  private static MiniSolrCloudCluster SOLR_CLUSTER;
-
   /** A basic client for operations at the cloud level, default collection will be set */
   private static CloudSolrClient CLOUD_CLIENT;
 
@@ -125,37 +112,24 @@ public class TestTolerantUpdateProcessorCloud extends LuceneTestCase {
   /** id field doc routing prefix for shard2 */
   private static final String S_TWO_PRE = "XYZ!";
   
-  
-  @Rule
-  public TestRule solrTestRules = RuleChain.outerRule(new SystemPropertiesRestoreRule());
-  
-  @ClassRule
-  public static TestRule solrClassRules = RuleChain.outerRule
-    (new SystemPropertiesRestoreRule()).around(new RevertDefaultThreadHandlerRule());
-
   @BeforeClass
   private static void createMiniSolrCloudCluster() throws Exception {
-    // nocommit: should we just be subclassing SolrTestCaseJ4 and get this for free?
-    SolrTestCaseJ4.chooseMPForMP();
     
-    Builder jettyConfig = JettyConfig.builder();
-    jettyConfig.waitForLoadingCoresToFinish(null);
-    SOLR_CLUSTER = new MiniSolrCloudCluster(NUM_SERVERS, createTempDir(), jettyConfig.build());
-    
-    String configName = "solrCloudCollectionConfig";
-    File configDir = new File(SolrTestCaseJ4.TEST_HOME() + File.separator + "collection1" + File.separator + "conf");
-    SOLR_CLUSTER.uploadConfigDir(configDir, configName);
+    final String configName = "solrCloudCollectionConfig";
+    final File configDir = new File(TEST_HOME() + File.separator + "collection1" + File.separator + "conf");
 
-    SolrTestCaseJ4.newRandomConfig();
+    configureCluster(NUM_SERVERS)
+      .addConfig(configName, configDir.toPath())
+      .configure();
     
     Map<String, String> collectionProperties = new HashMap<>();
     collectionProperties.put("config", "solrconfig-distrib-update-processor-chains.xml");
     collectionProperties.put("schema", "schema15.xml"); // string id for doc routing prefix
 
-    assertNotNull(SOLR_CLUSTER.createCollection(COLLECTION_NAME, NUM_SHARDS, REPLICATION_FACTOR,
-                                                configName, null, null, collectionProperties));
+    assertNotNull(cluster.createCollection(COLLECTION_NAME, NUM_SHARDS, REPLICATION_FACTOR,
+                                           configName, null, null, collectionProperties));
     
-    CLOUD_CLIENT = SOLR_CLUSTER.getSolrClient();
+    CLOUD_CLIENT = cluster.getSolrClient();
     CLOUD_CLIENT.setDefaultCollection(COLLECTION_NAME);
     
     ZkStateReader zkStateReader = CLOUD_CLIENT.getZkStateReader();
@@ -165,7 +139,7 @@ public class TestTolerantUpdateProcessorCloud extends LuceneTestCase {
     // really hackish way to get a URL for specific nodes based on shard/replica hosting
     // inspired by TestMiniSolrCloudCluster
     HashMap<String, String> urlMap = new HashMap<>();
-    for (JettySolrRunner jetty : SOLR_CLUSTER.getJettySolrRunners()) {
+    for (JettySolrRunner jetty : cluster.getJettySolrRunners()) {
       URL jettyURL = jetty.getBaseUrl();
       String nodeKey = jettyURL.getHost() + ":" + jettyURL.getPort() + jettyURL.getPath().replace("/","_");
       urlMap.put(nodeKey, jettyURL.toString());
@@ -237,16 +211,8 @@ public class TestTolerantUpdateProcessorCloud extends LuceneTestCase {
     }
   }
   
-  @AfterClass
-  private static void shutdownMiniSolrCloudCluster() throws Exception {
-    SOLR_CLUSTER.shutdown();
-
-    // nocommit: should we just be subclassing SolrTestCaseJ4 and get this for free?
-    SolrTestCaseJ4.unchooseMPForMP();
-  }
-  
   @Before
-  private void clearIndex() throws Exception {
+  private void clearCollection() throws Exception {
     assertEquals(0, CLOUD_CLIENT.deleteByQuery("*:*").getStatus());
     assertEquals(0, CLOUD_CLIENT.commit().getStatus());
   }


[30/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/Cell.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/Cell.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/Cell.java
new file mode 100644
index 0000000..fe3846d
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/Cell.java
@@ -0,0 +1,109 @@
+/*
+ * 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.prefix.tree;
+
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.SpatialRelation;
+import org.apache.lucene.util.BytesRef;
+
+/**
+ * Represents a grid cell. Cell instances are generally very transient and may be re-used
+ * internally.  To get an instance, you could start with {@link SpatialPrefixTree#getWorldCell()}.
+ * And from there you could either traverse down the tree with {@link #getNextLevelCells(com.spatial4j.core.shape.Shape)},
+ * or you could read an indexed term via {@link SpatialPrefixTree#readCell(org.apache.lucene.util.BytesRef,Cell)}.
+ * When a cell is read from a term, it is comprised of just the base bytes plus optionally a leaf flag.
+ *
+ * @lucene.experimental
+ */
+public interface Cell {
+
+//  If we bring this back; perhaps do so as a method that un-shares its internal state: void unshare();
+//  /** Resets the state of this cell such that it is identical to {@code source}. This can be used for
+//   * cloning a cell to have a safe copy, and it also might be used to position this cell
+//   * before calling {@link #readCell(org.apache.lucene.util.BytesRef)} in a loop if you know the first term
+//   * is going to be close to some other cell, thereby saving some computations. */
+//  void copyFrom(Cell source);
+
+  /** Gets the relationship this cell has with the shape from which it was filtered from, assuming it came from a
+   * {@link CellIterator}. Arguably it belongs there but it's very convenient here. */
+  SpatialRelation getShapeRel();
+
+  /** See {@link #getShapeRel()}.
+   * @lucene.internal */
+  void setShapeRel(SpatialRelation rel);
+
+  /**
+   * Some cells are flagged as leaves, which are indexed as such. A leaf cell is either within some
+   * shape or it both intersects and the cell is at an accuracy threshold such that no smaller cells
+   * for the shape will be represented.
+   */
+  boolean isLeaf();
+
+  /** Set this cell to be a leaf. Warning: never call on a cell
+   * initialized to reference the same bytes from termsEnum, which should be treated as immutable.
+   * Note: not supported at level 0.
+   * @lucene.internal */
+  void setLeaf();
+
+  /**
+   * Returns the bytes for this cell, with a leaf byte <em>if this is a leaf cell</em>.
+   * The result param is used to save object allocation, though its bytes aren't used.
+   * @param result where the result goes, or null to create new
+   */
+  BytesRef getTokenBytesWithLeaf(BytesRef result);
+
+  /**
+   * Returns the bytes for this cell, without a leaf set. The bytes should sort before
+   * {@link #getTokenBytesWithLeaf(org.apache.lucene.util.BytesRef)}.
+   * The result param is used to save object allocation, though its bytes aren't used.
+   * @param result where the result goes, or null to create new
+   */
+  BytesRef getTokenBytesNoLeaf(BytesRef result);
+
+  /** Level 0 is the world (and has no parent), from then on a higher level means a smaller
+   * cell than the level before it.
+   */
+  int getLevel();
+
+  /**
+   * Gets the cells at the next grid cell level underneath this one, optionally filtered by
+   * {@code shapeFilter}. The returned cells should have {@link #getShapeRel()} set to
+   * their relation with {@code shapeFilter}.  In addition, for non-points {@link #isLeaf()}
+   * must be true when that relation is WITHIN.
+   * <p>
+   * IMPORTANT: Cells returned from this iterator can be shared, as well as the bytes.
+   * <p>
+   * Precondition: Never called when getLevel() == maxLevel.
+   *
+   * @param shapeFilter an optional filter for the returned cells.
+   * @return A set of cells (no dups), sorted. Not Modifiable.
+   */
+  CellIterator getNextLevelCells(Shape shapeFilter);
+
+  /** Gets the shape for this cell; typically a Rectangle. */
+  Shape getShape();
+
+  /**
+   * Returns if the target term is within/underneath this cell; not necessarily a direct
+   * descendant.
+   * @param c the term
+   */
+  boolean isPrefixOf(Cell c);
+
+  /** Equivalent to {@code this.getTokenBytesNoLeaf(null).compareTo(fromCell.getTokenBytesNoLeaf(null))}. */
+  int compareToNoLeaf(Cell fromCell);
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/CellIterator.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/CellIterator.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/CellIterator.java
new file mode 100644
index 0000000..1cef37a
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/CellIterator.java
@@ -0,0 +1,76 @@
+/*
+ * 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.prefix.tree;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * An Iterator of SpatialPrefixTree Cells. The order is always sorted without duplicates.
+ *
+ * @lucene.experimental
+ */
+public abstract class CellIterator implements Iterator<Cell> {
+
+  //note: nextCell or thisCell can be non-null but neither at the same time. That's
+  // because they might return the same instance when re-used!
+
+  protected Cell nextCell;//to be returned by next(), and null'ed after
+  protected Cell thisCell;//see next() & thisCell(). Should be cleared in hasNext().
+
+  /** Returns the cell last returned from {@link #next()}. It's cleared by hasNext(). */
+  public Cell thisCell() {
+    assert thisCell != null : "Only call thisCell() after next(), not hasNext()";
+    return thisCell;
+  }
+
+  // Arguably this belongs here and not on Cell
+  //public SpatialRelation getShapeRel()
+
+  /**
+   * Gets the next cell that is &gt;= {@code fromCell}, compared using non-leaf bytes. If it returns null then
+   * the iterator is exhausted.
+   */
+  public Cell nextFrom(Cell fromCell) {
+    while (true) {
+      if (!hasNext())
+        return null;
+      Cell c = next();//will update thisCell
+      if (c.compareToNoLeaf(fromCell) >= 0) {
+        return c;
+      }
+    }
+  }
+
+  /** This prevents sub-cells (those underneath the current cell) from being iterated to,
+   *  if applicable, otherwise a NO-OP. */
+  @Override
+  public void remove() {
+    assert thisCell != null;
+  }
+
+  @Override
+  public Cell next() {
+    if (nextCell == null) {
+      if (!hasNext())
+        throw new NoSuchElementException();
+    }
+    thisCell = nextCell;
+    nextCell = null;
+    return thisCell;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTree.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTree.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTree.java
new file mode 100644
index 0000000..13281f3
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/DateRangePrefixTree.java
@@ -0,0 +1,444 @@
+/*
+ * 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.prefix.tree;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import com.spatial4j.core.shape.Shape;
+
+/**
+ * A PrefixTree for date ranges in which the levels of the tree occur at natural periods of time (e.g. years,
+ * months, ...). You pass in {@link Calendar} objects with the desired fields set and the unspecified
+ * fields unset, which conveys the precision.  The implementation makes some optimization assumptions about a
+ * {@link java.util.GregorianCalendar}; others could probably be supported easily.
+ * <p>
+ * Warning: If you construct a Calendar and then get something from the object like a field (e.g. year) or
+ * milliseconds, then every field is fully set by side-effect. So after setting the fields, pass it to this
+ * API first.
+ * @lucene.experimental
+ */
+public class DateRangePrefixTree extends NumberRangePrefixTree {
+
+  /*
+    WARNING  java.util.Calendar is tricky to work with:
+    * If you "get" any field value, every field becomes "set". This can introduce a Heisenbug effect,
+        when in a debugger in some cases. Fortunately, Calendar.toString() doesn't apply.
+    * Beware Calendar underflow of the underlying long.  If you create a Calendar from LONG.MIN_VALUE, and clear
+     a field, it will underflow and appear close to LONG.MAX_VALUE (BC to AD).
+
+    There are no doubt other reasons but those two were hard fought lessons here.
+
+    TODO Improvements:
+    * Make max precision configurable (i.e. to SECOND).
+    * Make min & max year span configurable. Use that to remove pointless top levels of the SPT.
+        If year span is > 10k, then add 1k year level. If year span is > 10k of 1k levels, add 1M level.
+    * NumberRangePrefixTree: override getTreeCellIterator for optimized case where the shape isn't a date span; use
+      FilterCellIterator of the cell stack.
+
+  */
+
+  private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
+  private static Calendar CAL_TMP;//template
+  static {
+    CAL_TMP = Calendar.getInstance(UTC, Locale.ROOT);
+    CAL_TMP.clear();
+  }
+
+  private static final Calendar MINCAL = (Calendar) CAL_TMP.clone();
+  private static final Calendar MAXCAL = (Calendar) CAL_TMP.clone();
+  static {
+    MINCAL.setTimeInMillis(Long.MIN_VALUE);
+    MAXCAL.setTimeInMillis(Long.MAX_VALUE);
+  }
+  //BC years are decreasing, remember.  Yet ActualMaximum is the numerically high value, ActualMinimum is 1.
+  private static final int BC_FIRSTYEAR = MINCAL.getActualMaximum(Calendar.YEAR);
+  private static final int BC_LASTYEAR = MINCAL.getActualMinimum(Calendar.YEAR);//1
+  private static final int BC_YEARS = BC_FIRSTYEAR - BC_LASTYEAR + 1;
+  private static final int AD_FIRSTYEAR = MAXCAL.getActualMinimum(Calendar.YEAR);//1
+  private static final int AD_LASTYEAR = MAXCAL.getActualMaximum(Calendar.YEAR);
+  private static final int AD_YEAR_BASE =  (((BC_YEARS-1) / 1000_000)+1) * 1000_000;
+  static { assert BC_LASTYEAR == 1 && AD_FIRSTYEAR == 1; }
+
+  //how many million years are there?
+  private static final int NUM_MYEARS = (AD_YEAR_BASE + AD_LASTYEAR) / 1000_000;
+
+  private static int calFieldLen(int field) {
+    return CAL_TMP.getMaximum(field) - CAL_TMP.getMinimum(field) + 1;
+  }
+
+  private static final int[] FIELD_BY_LEVEL = {
+      -1/*unused*/, -1, -1, Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH,
+      Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND};
+  private static final int yearLevel = 3;
+
+  public static final DateRangePrefixTree INSTANCE = new DateRangePrefixTree();
+
+  private final UnitNRShape minLV, maxLV;
+  private final UnitNRShape gregorianChangeDateLV;
+
+  protected DateRangePrefixTree() {
+    super(new int[]{//sublevels by level
+        NUM_MYEARS,
+        1000,//1 thousand thousand-years in a million years
+        1000,//1 thousand years in a thousand-year
+        calFieldLen(Calendar.MONTH),
+        calFieldLen(Calendar.DAY_OF_MONTH),
+        calFieldLen(Calendar.HOUR_OF_DAY),
+        calFieldLen(Calendar.MINUTE),
+        calFieldLen(Calendar.SECOND),
+        calFieldLen(Calendar.MILLISECOND),
+    });
+    maxLV = toShape((Calendar)MAXCAL.clone());
+    minLV = toShape((Calendar)MINCAL.clone());
+    if (MAXCAL instanceof GregorianCalendar) {
+      //TODO this should be a configurable param by passing a Calendar serving as a template.
+      GregorianCalendar gCal = (GregorianCalendar)MAXCAL;
+      gregorianChangeDateLV = toUnitShape(gCal.getGregorianChange());
+    } else {
+      gregorianChangeDateLV = null;
+    }
+  }
+
+  @Override
+  public int getNumSubCells(UnitNRShape lv) {
+    int cmp = comparePrefix(lv, maxLV);
+    assert cmp <= 0;
+    if (cmp == 0)//edge case (literally!)
+      return maxLV.getValAtLevel(lv.getLevel()+1);
+
+    // if using GregorianCalendar and we're after the "Gregorian change date" then we'll compute
+    //  the sub-cells ourselves more efficiently without the need to construct a Calendar.
+    cmp = gregorianChangeDateLV != null ? comparePrefix(lv, gregorianChangeDateLV) : -1;
+    //TODO consider also doing fast-path if field is <= hours even if before greg change date
+    if (cmp >= 0) {
+      int result = fastSubCells(lv);
+      assert result == slowSubCells(lv) : "fast/slow numSubCells inconsistency";
+      return result;
+    } else {
+      return slowSubCells(lv);
+    }
+  }
+
+  private int fastSubCells(UnitNRShape lv) {
+    if (lv.getLevel() == yearLevel+1) {//month
+      switch (lv.getValAtLevel(lv.getLevel())) {
+        case Calendar.SEPTEMBER:
+        case Calendar.APRIL:
+        case Calendar.JUNE:
+        case Calendar.NOVEMBER:
+          return 30;
+        case Calendar.FEBRUARY:
+          //get the year (negative numbers for BC)
+          int yearAdj = lv.getValAtLevel(1) * 1_000_000;
+          yearAdj += lv.getValAtLevel(2) * 1000;
+          yearAdj += lv.getValAtLevel(3);
+          int year = yearAdj - AD_YEAR_BASE;
+          if (year % 4 == 0 && !(year % 100 == 0 && year % 400 != 0) )//leap year
+            return 29;
+          else
+            return 28;
+        default:
+          return 31;
+      }
+    } else {//typical:
+      return super.getNumSubCells(lv);
+    }
+  }
+
+  private int slowSubCells(UnitNRShape lv) {
+    int field = FIELD_BY_LEVEL[lv.getLevel()+1];
+    //short-circuit optimization (GregorianCalendar assumptions)
+    if (field == -1 || field == Calendar.YEAR || field >= Calendar.HOUR_OF_DAY)//TODO make configurable
+      return super.getNumSubCells(lv);
+    Calendar cal = toCalendar(lv);//somewhat heavyweight op; ideally should be stored on UnitNRShape somehow
+    return cal.getActualMaximum(field) - cal.getActualMinimum(field) + 1;
+  }
+
+  /** Calendar utility method:
+   * Returns a new {@link Calendar} in UTC TimeZone, ROOT Locale, with all fields cleared. */
+  public Calendar newCal() {
+    return (Calendar) CAL_TMP.clone();
+  }
+
+  /** Calendar utility method:
+   * Returns the spatial prefix tree level for the corresponding {@link java.util.Calendar} field, such as
+   * {@link java.util.Calendar#YEAR}.  If there's no match, the next greatest level is returned as a negative value.
+   */
+  public int getTreeLevelForCalendarField(int calField) {
+    for (int i = yearLevel; i < FIELD_BY_LEVEL.length; i++) {
+      if (FIELD_BY_LEVEL[i] == calField) {
+        return i;
+      } else if (FIELD_BY_LEVEL[i] > calField) {
+        return -1 * i;
+      }
+    }
+    throw new IllegalArgumentException("Bad calendar field?: " + calField);
+  }
+
+  /** Calendar utility method:
+   * Gets the Calendar field code of the last field that is set prior to an unset field. It only
+   * examines fields relevant to the prefix tree. If no fields are set, it returns -1. */
+  public int getCalPrecisionField(Calendar cal) {
+    int lastField = -1;
+    for (int level = yearLevel; level < FIELD_BY_LEVEL.length; level++) {
+      int field = FIELD_BY_LEVEL[level];
+      if (!cal.isSet(field))
+        break;
+      lastField = field;
+    }
+    return lastField;
+  }
+
+  /** Calendar utility method:
+   * Calls {@link Calendar#clear(int)} for every field after {@code field}. Beware of Calendar underflow. */
+  public void clearFieldsAfter(Calendar cal, int field) {
+    if (field == -1) {
+      cal.clear();
+      return;
+    }
+    int assertEra = -1;
+    assert (assertEra = (((Calendar)cal.clone()).get(Calendar.ERA))) >= 0;//a trick to only get this if assert enabled
+    for (int f = field+1; f < Calendar.FIELD_COUNT; f++) {
+      cal.clear(f);
+    }
+    assert ((Calendar)cal.clone()).get(Calendar.ERA) == assertEra : "Calendar underflow";
+  }
+
+  /** Converts {@code value} from a {@link Calendar} or {@link Date} to a {@link Shape}. Other arguments
+   * result in a {@link java.lang.IllegalArgumentException}.
+   */
+  @Override
+  public UnitNRShape toUnitShape(Object value) {
+    if (value instanceof Calendar) {
+      return toShape((Calendar) value);
+    } else if (value instanceof Date) {
+      Calendar cal = newCal();
+      cal.setTime((Date)value);
+      return toShape(cal);
+    }
+    throw new IllegalArgumentException("Expecting Calendar or Date but got: "+value.getClass());
+  }
+
+  /** Converts the Calendar into a Shape.
+   * The isSet() state of the Calendar is re-instated when done. */
+  public UnitNRShape toShape(Calendar cal) {
+    // Convert a Calendar into a stack of cell numbers
+    final int calPrecField = getCalPrecisionField(cal);//must call first; getters set all fields
+    try {
+      int[] valStack = new int[maxLevels];//starts at level 1, not 0
+      int len = 0;
+      if (calPrecField >= Calendar.YEAR) {//year or better precision
+        int year = cal.get(Calendar.YEAR);
+        int yearAdj = cal.get(Calendar.ERA) == 0 ? AD_YEAR_BASE - (year - 1) : AD_YEAR_BASE + year;
+
+        valStack[len++] = yearAdj / 1000_000;
+        yearAdj -= valStack[len-1] * 1000_000;
+        valStack[len++] = yearAdj / 1000;
+        yearAdj -= valStack[len-1] * 1000;
+        valStack[len++] = yearAdj;
+        for (int level = yearLevel+1; level < FIELD_BY_LEVEL.length; level++) {
+          int field = FIELD_BY_LEVEL[level];
+          if (field > calPrecField)
+            break;
+          valStack[len++] = cal.get(field) - cal.getActualMinimum(field);
+        }
+      }
+
+      return toShape(valStack, len);
+    } finally {
+      clearFieldsAfter(cal, calPrecField);//restore precision state modified by get()
+    }
+  }
+
+  /** Calls {@link #toCalendar(org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape)}. */
+  @Override
+  public Object toObject(UnitNRShape shape) {
+    return toCalendar(shape);
+  }
+
+  /** Converts the {@link org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape} shape to a
+   * corresponding Calendar that is cleared below its level. */
+  public Calendar toCalendar(UnitNRShape lv) {
+    if (lv.getLevel() == 0)
+      return newCal();
+    if (comparePrefix(lv, minLV) <= 0) {//shouldn't typically happen; sometimes in a debugger
+      return (Calendar) MINCAL.clone();//full precision; truncation would cause underflow
+    }
+    assert comparePrefix(lv, maxLV) <= 0;
+    Calendar cal = newCal();
+
+    int yearAdj = lv.getValAtLevel(1) * 1_000_000;
+    if (lv.getLevel() > 1) {
+      yearAdj += lv.getValAtLevel(2) * 1000;
+      if (lv.getLevel() > 2) {
+        yearAdj += lv.getValAtLevel(3);
+      }
+    }
+    if (yearAdj > AD_YEAR_BASE) {
+      cal.set(Calendar.ERA, 1);
+      cal.set(Calendar.YEAR, yearAdj - AD_YEAR_BASE);//setting the year resets the era
+    } else {
+      cal.set(Calendar.ERA, 0);//we assert this "sticks" at the end
+      cal.set(Calendar.YEAR, (AD_YEAR_BASE - yearAdj) + 1);
+    }
+    for (int level = yearLevel+1; level <= lv.getLevel(); level++) {
+      int field = FIELD_BY_LEVEL[level];
+      cal.set(field, lv.getValAtLevel(level) + cal.getActualMinimum(field));
+    }
+    assert yearAdj > AD_YEAR_BASE || ((Calendar)cal.clone()).get(Calendar.ERA) == 0 : "ERA / YEAR underflow";
+    return cal;
+  }
+
+  @Override
+  protected String toString(UnitNRShape lv) {
+    return toString(toCalendar(lv));
+  }
+
+  /** Calendar utility method:
+   * Formats the calendar to ISO-8601 format, to include proper BC handling (1BC is "0000", 2BC is "-0001", etc.);
+   * and WITHOUT a trailing 'Z'.
+   * A fully cleared calendar will yield the string "*".
+   * The isSet() state of the Calendar is re-instated when done. */
+   @SuppressWarnings("fallthrough")
+  public String toString(Calendar cal) {
+    final int calPrecField = getCalPrecisionField(cal);//must call first; getters set all fields
+    if (calPrecField == -1)
+      return "*";
+    try {
+      //TODO not fully optimized; but it's at least not used in 'search'.
+      //TODO maybe borrow code from Solr DateUtil (put in Lucene util somewhere), and have it reference this back?
+      String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS";
+      int ptnLen = 0;
+      switch (calPrecField) {//switch fall-through is deliberate
+        case Calendar.MILLISECOND: ptnLen += 4;
+        case Calendar.SECOND: ptnLen += 3;
+        case Calendar.MINUTE: ptnLen += 3;
+        case Calendar.HOUR_OF_DAY: ptnLen += 5;
+        case Calendar.DAY_OF_MONTH: ptnLen += 3;
+        case Calendar.MONTH: ptnLen += 3;
+        case Calendar.YEAR: ptnLen += 4;
+        break;
+        default: throw new IllegalStateException(""+calPrecField);
+      }
+      pattern = pattern.substring(0, ptnLen);
+      SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.ROOT);
+      format.setTimeZone(cal.getTimeZone());
+      if (cal.get(Calendar.ERA) == 0) {//BC
+        //SDF doesn't do this properly according to ISO-8601
+        // Example: 1BC == "0000" (actually 0 AD), 2BC == "-0001", 3BC == "-0002", ...
+        final int yearOrig = cal.get(Calendar.YEAR);
+        cal.set(Calendar.YEAR, yearOrig-1);
+        String str;
+        try {
+          str = format.format(cal.getTime());
+        } finally {
+          //reset to what it was
+          cal.set(Calendar.ERA, 0);//necessary!
+          cal.set(Calendar.YEAR, yearOrig);
+        }
+        if (yearOrig > 1)
+          return "-" + str;
+        else
+          return "0000" + str.substring(4);
+      }
+      return format.format(cal.getTime());
+    } finally {
+      clearFieldsAfter(cal, calPrecField);//restore precision state modified by get()
+    }
+  }
+
+  @Override
+  protected UnitNRShape parseUnitShape(String str) throws ParseException {
+    return toShape(parseCalendar(str));
+  }
+
+  /** Calendar utility method:
+   * The reverse of {@link #toString(java.util.Calendar)}. It will only set the fields found, leaving
+   * the remainder in an un-set state. A leading '-' or '+' is optional (positive assumed), and a
+   * trailing 'Z' is also optional.
+   * @param str not null and not empty
+   * @return not null
+   */
+  public Calendar parseCalendar(String str) throws ParseException {
+    // example: +2014-10-23T21:22:33.159Z
+    if (str == null || str.isEmpty())
+      throw new IllegalArgumentException("str is null or blank");
+    Calendar cal = newCal();
+    if (str.equals("*"))
+      return cal;
+    int offset = 0;//a pointer
+    try {
+      //year & era:
+      int lastOffset = str.charAt(str.length()-1) == 'Z' ? str.length() - 1 : str.length();
+      int hyphenIdx = str.indexOf('-', 1);//look past possible leading hyphen
+      if (hyphenIdx < 0)
+        hyphenIdx = lastOffset;
+      int year = Integer.parseInt(str.substring(offset, hyphenIdx));
+      cal.set(Calendar.ERA, year <= 0 ? 0 : 1);
+      cal.set(Calendar.YEAR, year <= 0 ? -1*year + 1 : year);
+      offset = hyphenIdx + 1;
+      if (lastOffset < offset)
+        return cal;
+
+      //NOTE: We aren't validating separator chars, and we unintentionally accept leading +/-.
+      // The str.substring()'s hopefully get optimized to be stack-allocated.
+
+      //month:
+      cal.set(Calendar.MONTH, Integer.parseInt(str.substring(offset, offset+2)) - 1);//starts at 0
+      offset += 3;
+      if (lastOffset < offset)
+        return cal;
+      //day:
+      cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(str.substring(offset, offset+2)));
+      offset += 3;
+      if (lastOffset < offset)
+        return cal;
+      //hour:
+      cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(str.substring(offset, offset+2)));
+      offset += 3;
+      if (lastOffset < offset)
+        return cal;
+      //minute:
+      cal.set(Calendar.MINUTE, Integer.parseInt(str.substring(offset, offset+2)));
+      offset += 3;
+      if (lastOffset < offset)
+        return cal;
+      //second:
+      cal.set(Calendar.SECOND, Integer.parseInt(str.substring(offset, offset+2)));
+      offset += 3;
+      if (lastOffset < offset)
+        return cal;
+      //ms:
+      cal.set(Calendar.MILLISECOND, Integer.parseInt(str.substring(offset, offset+3)));
+      offset += 3;//last one, move to next char
+      if (lastOffset == offset)
+        return cal;
+    } catch (Exception e) {
+      ParseException pe = new ParseException("Improperly formatted date: "+str, offset);
+      pe.initCause(e);
+      throw pe;
+    }
+    throw new ParseException("Improperly formatted date: "+str, offset);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/FilterCellIterator.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/FilterCellIterator.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/FilterCellIterator.java
new file mode 100644
index 0000000..e4f50e0
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/FilterCellIterator.java
@@ -0,0 +1,61 @@
+/*
+ * 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.prefix.tree;
+
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.SpatialRelation;
+
+import java.util.Iterator;
+
+/**
+ * A filtering iterator of Cells. Those not matching the provided shape (disjoint) are
+ * skipped. If {@code shapeFilter} is null then all cells are returned.
+ *
+ * @lucene.internal
+ */
+class FilterCellIterator extends CellIterator {
+  final Iterator<Cell> baseIter;
+  final Shape shapeFilter;
+
+  FilterCellIterator(Iterator<Cell> baseIter, Shape shapeFilter) {
+    this.baseIter = baseIter;
+    this.shapeFilter = shapeFilter;
+  }
+
+  @Override
+  public boolean hasNext() {
+    thisCell = null;
+    if (nextCell != null)//calling hasNext twice in a row
+      return true;
+    while (baseIter.hasNext()) {
+      nextCell = baseIter.next();
+      if (shapeFilter == null) {
+        return true;
+      } else {
+        SpatialRelation rel = nextCell.getShape().relate(shapeFilter);
+        if (rel.intersects()) {
+          nextCell.setShapeRel(rel);
+          if (rel == SpatialRelation.WITHIN)
+            nextCell.setLeaf();
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/GeohashPrefixTree.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/GeohashPrefixTree.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/GeohashPrefixTree.java
new file mode 100644
index 0000000..fa4e987
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/GeohashPrefixTree.java
@@ -0,0 +1,162 @@
+/*
+ * 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.prefix.tree;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.io.GeohashUtils;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.util.BytesRef;
+
+/**
+ * A {@link SpatialPrefixTree} based on
+ * <a href="http://en.wikipedia.org/wiki/Geohash">Geohashes</a>.
+ * Uses {@link GeohashUtils} to do all the geohash work.
+ *
+ * @lucene.experimental
+ */
+public class GeohashPrefixTree extends LegacyPrefixTree {
+
+  /**
+   * Factory for creating {@link GeohashPrefixTree} instances with useful defaults
+   */
+  public static class Factory extends SpatialPrefixTreeFactory {
+
+    @Override
+    protected int getLevelForDistance(double degrees) {
+      GeohashPrefixTree grid = new GeohashPrefixTree(ctx, GeohashPrefixTree.getMaxLevelsPossible());
+      return grid.getLevelForDistance(degrees);
+    }
+
+    @Override
+    protected SpatialPrefixTree newSPT() {
+      return new GeohashPrefixTree(ctx,
+          maxLevels != null ? maxLevels : GeohashPrefixTree.getMaxLevelsPossible());
+    }
+  }
+
+  public GeohashPrefixTree(SpatialContext ctx, int maxLevels) {
+    super(ctx, maxLevels);
+    Rectangle bounds = ctx.getWorldBounds();
+    if (bounds.getMinX() != -180)
+      throw new IllegalArgumentException("Geohash only supports lat-lon world bounds. Got "+bounds);
+    int MAXP = getMaxLevelsPossible();
+    if (maxLevels <= 0 || maxLevels > MAXP)
+      throw new IllegalArgumentException("maxLevels must be [1-"+MAXP+"] but got "+ maxLevels);
+  }
+
+  /** Any more than this and there's no point (double lat and lon are the same). */
+  public static int getMaxLevelsPossible() {
+    return GeohashUtils.MAX_PRECISION;
+  }
+
+  @Override
+  public Cell getWorldCell() {
+    return new GhCell(BytesRef.EMPTY_BYTES, 0, 0);
+  }
+
+  @Override
+  public int getLevelForDistance(double dist) {
+    if (dist == 0)
+      return maxLevels;//short circuit
+    final int level = GeohashUtils.lookupHashLenForWidthHeight(dist, dist);
+    return Math.max(Math.min(level, maxLevels), 1);
+  }
+
+  @Override
+  protected Cell getCell(Point p, int level) {
+    return new GhCell(GeohashUtils.encodeLatLon(p.getY(), p.getX(), level));//args are lat,lon (y,x)
+  }
+
+  private static byte[] stringToBytesPlus1(String token) {
+    //copy ASCII token to byte array with one extra spot for eventual LEAF_BYTE if needed
+    byte[] bytes = new byte[token.length() + 1];
+    for (int i = 0; i < token.length(); i++) {
+      bytes[i] = (byte) token.charAt(i);
+    }
+    return bytes;
+  }
+
+  private class GhCell extends LegacyCell {
+
+    private String geohash;//cache; never has leaf byte, simply a geohash
+
+    GhCell(String geohash) {
+      super(stringToBytesPlus1(geohash), 0, geohash.length());
+      this.geohash = geohash;
+      if (isLeaf() && getLevel() < getMaxLevels())//we don't have a leaf byte at max levels (an opt)
+        this.geohash = geohash.substring(0, geohash.length() - 1);
+    }
+
+    GhCell(byte[] bytes, int off, int len) {
+      super(bytes, off, len);
+    }
+
+    @Override
+    protected GeohashPrefixTree getGrid() { return GeohashPrefixTree.this; }
+
+    @Override
+    protected int getMaxLevels() { return maxLevels; }
+
+    @Override
+    protected void readCell(BytesRef bytesRef) {
+      super.readCell(bytesRef);
+      geohash = null;
+    }
+
+    @Override
+    public Collection<Cell> getSubCells() {
+      String[] hashes = GeohashUtils.getSubGeohashes(getGeohash());//sorted
+      List<Cell> cells = new ArrayList<>(hashes.length);
+      for (String hash : hashes) {
+        cells.add(new GhCell(hash));
+      }
+      return cells;
+    }
+
+    @Override
+    public int getSubCellsSize() {
+      return 32;//8x4
+    }
+
+    @Override
+    protected GhCell getSubCell(Point p) {
+      return (GhCell) getGrid().getCell(p, getLevel() + 1);//not performant!
+    }
+
+    @Override
+    public Shape getShape() {
+      if (shape == null) {
+        shape = GeohashUtils.decodeBoundary(getGeohash(), getGrid().getSpatialContext());
+      }
+      return shape;
+    }
+
+    private String getGeohash() {
+      if (geohash == null)
+        geohash = getTokenBytesNoLeaf(null).utf8ToString();
+      return geohash;
+    }
+
+  }//class GhCell
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/LegacyCell.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/LegacyCell.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/LegacyCell.java
new file mode 100644
index 0000000..27c56a7
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/LegacyCell.java
@@ -0,0 +1,242 @@
+/*
+ * 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.prefix.tree;
+
+import java.util.Collection;
+
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.SpatialRelation;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.StringHelper;
+
+/** The base for the original two SPT's: Geohash and Quad. Don't subclass this for new SPTs.
+ * @lucene.internal */
+//public for RPT pruneLeafyBranches code
+public abstract class LegacyCell implements Cell {
+
+  // Important: A LegacyCell doesn't share state for getNextLevelCells(), and
+  //  LegacySpatialPrefixTree assumes this in its simplify tree logic.
+
+  private static final byte LEAF_BYTE = '+';//NOTE: must sort before letters & numbers
+
+  //Arguably we could simply use a BytesRef, using an extra Object.
+  protected byte[] bytes;//generally bigger to potentially hold a leaf
+  protected int b_off;
+  protected int b_len;//doesn't reflect leaf; same as getLevel()
+
+  protected boolean isLeaf;
+
+  /**
+   * When set via getSubCells(filter), it is the relationship between this cell
+   * and the given shape filter. Doesn't participate in shape equality.
+   */
+  protected SpatialRelation shapeRel;
+
+  protected Shape shape;//cached
+
+  /** Warning: Refers to the same bytes (no copy). If {@link #setLeaf()} is subsequently called then it
+   * may modify bytes. */
+  protected LegacyCell(byte[] bytes, int off, int len) {
+    this.bytes = bytes;
+    this.b_off = off;
+    this.b_len = len;
+    readLeafAdjust();
+  }
+
+  protected void readCell(BytesRef bytes) {
+    shapeRel = null;
+    shape = null;
+    this.bytes = bytes.bytes;
+    this.b_off = bytes.offset;
+    this.b_len = (short) bytes.length;
+    readLeafAdjust();
+  }
+
+  protected void readLeafAdjust() {
+    isLeaf = (b_len > 0 && bytes[b_off + b_len - 1] == LEAF_BYTE);
+    if (isLeaf)
+      b_len--;
+    if (getLevel() == getMaxLevels())
+      isLeaf = true;
+  }
+
+  protected abstract SpatialPrefixTree getGrid();
+
+  protected abstract int getMaxLevels();
+
+  @Override
+  public SpatialRelation getShapeRel() {
+    return shapeRel;
+  }
+
+  @Override
+  public void setShapeRel(SpatialRelation rel) {
+    this.shapeRel = rel;
+  }
+
+  @Override
+  public boolean isLeaf() {
+    return isLeaf;
+  }
+
+  @Override
+  public void setLeaf() {
+    isLeaf = true;
+  }
+
+  @Override
+  public BytesRef getTokenBytesWithLeaf(BytesRef result) {
+    result = getTokenBytesNoLeaf(result);
+    if (!isLeaf || getLevel() == getMaxLevels())
+      return result;
+    if (result.bytes.length < result.offset + result.length + 1) {
+      assert false : "Not supposed to happen; performance bug";
+      byte[] copy = new byte[result.length + 1];
+      System.arraycopy(result.bytes, result.offset, copy, 0, result.length - 1);
+      result.bytes = copy;
+      result.offset = 0;
+    }
+    result.bytes[result.offset + result.length++] = LEAF_BYTE;
+    return result;
+  }
+
+  @Override
+  public BytesRef getTokenBytesNoLeaf(BytesRef result) {
+    if (result == null)
+      return new BytesRef(bytes, b_off, b_len);
+    result.bytes = bytes;
+    result.offset = b_off;
+    result.length = b_len;
+    return result;
+  }
+
+  @Override
+  public int getLevel() {
+    return b_len;
+  }
+
+  @Override
+  public CellIterator getNextLevelCells(Shape shapeFilter) {
+    assert getLevel() < getGrid().getMaxLevels();
+    if (shapeFilter instanceof Point) {
+      LegacyCell cell = getSubCell((Point) shapeFilter);
+      cell.shapeRel = SpatialRelation.CONTAINS;
+      return new SingletonCellIterator(cell);
+    } else {
+      return new FilterCellIterator(getSubCells().iterator(), shapeFilter);
+    }
+  }
+
+  /**
+   * Performant implementations are expected to implement this efficiently by
+   * considering the current cell's boundary.
+   * <p>
+   * Precondition: Never called when getLevel() == maxLevel.
+   * Precondition: this.getShape().relate(p) != DISJOINT.
+   */
+  protected abstract LegacyCell getSubCell(Point p);
+
+  /**
+   * Gets the cells at the next grid cell level that covers this cell.
+   * Precondition: Never called when getLevel() == maxLevel.
+   *
+   * @return A set of cells (no dups), sorted, modifiable, not empty, not null.
+   */
+  protected abstract Collection<Cell> getSubCells();
+
+  /**
+   * {@link #getSubCells()}.size() -- usually a constant. Should be &gt;=2
+   */
+  public abstract int getSubCellsSize();
+
+  @Override
+  public boolean isPrefixOf(Cell c) {
+    //Note: this only works when each level uses a whole number of bytes.
+    LegacyCell cell = (LegacyCell)c;
+    boolean result = sliceEquals(cell.bytes, cell.b_off, cell.b_len, bytes, b_off, b_len);
+    assert result == StringHelper.startsWith(c.getTokenBytesNoLeaf(null), getTokenBytesNoLeaf(null));
+    return result;
+  }
+
+  /** Copied from {@link org.apache.lucene.util.StringHelper#startsWith(BytesRef, BytesRef)}
+   *  which calls this. This is to avoid creating a BytesRef.  */
+  private static boolean sliceEquals(byte[] sliceToTest_bytes, int sliceToTest_offset, int sliceToTest_length,
+                                     byte[] other_bytes, int other_offset, int other_length) {
+    if (sliceToTest_length < other_length) {
+      return false;
+    }
+    int i = sliceToTest_offset;
+    int j = other_offset;
+    final int k = other_offset + other_length;
+
+    while (j < k) {
+      if (sliceToTest_bytes[i++] != other_bytes[j++]) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  @Override
+  public int compareToNoLeaf(Cell fromCell) {
+    LegacyCell b = (LegacyCell) fromCell;
+    return compare(bytes, b_off, b_len, b.bytes, b.b_off, b.b_len);
+  }
+
+  /** Copied from {@link BytesRef#compareTo(BytesRef)}.
+   * This is to avoid creating a BytesRef. */
+  protected static int compare(byte[] aBytes, int aUpto, int a_length, byte[] bBytes, int bUpto, int b_length) {
+    final int aStop = aUpto + Math.min(a_length, b_length);
+    while(aUpto < aStop) {
+      int aByte = aBytes[aUpto++] & 0xff;
+      int bByte = bBytes[bUpto++] & 0xff;
+
+      int diff = aByte - bByte;
+      if (diff != 0) {
+        return diff;
+      }
+    }
+
+    // One is a prefix of the other, or, they are equal:
+    return a_length - b_length;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    //this method isn't "normally" called; just in asserts/tests
+    if (obj instanceof Cell) {
+      Cell cell = (Cell) obj;
+      return getTokenBytesWithLeaf(null).equals(cell.getTokenBytesWithLeaf(null));
+    } else {
+      return false;
+    }
+  }
+
+  @Override
+  public int hashCode() {
+    return getTokenBytesWithLeaf(null).hashCode();
+  }
+
+  @Override
+  public String toString() {
+    //this method isn't "normally" called; just in asserts/tests
+    return getTokenBytesWithLeaf(null).utf8ToString();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/LegacyPrefixTree.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/LegacyPrefixTree.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/LegacyPrefixTree.java
new file mode 100644
index 0000000..672c2fe
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/LegacyPrefixTree.java
@@ -0,0 +1,84 @@
+/*
+ * 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.prefix.tree;
+
+import java.util.Arrays;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.util.BytesRef;
+
+/** The base for the original two SPT's: Geohash and Quad. Don't subclass this for new SPTs.
+ * @lucene.internal */
+abstract class LegacyPrefixTree extends SpatialPrefixTree {
+  public LegacyPrefixTree(SpatialContext ctx, int maxLevels) {
+    super(ctx, maxLevels);
+  }
+
+  public double getDistanceForLevel(int level) {
+    if (level < 1 || level > getMaxLevels())
+      throw new IllegalArgumentException("Level must be in 1 to maxLevels range");
+    //TODO cache for each level
+    Cell cell = getCell(ctx.getWorldBounds().getCenter(), level);
+    Rectangle bbox = cell.getShape().getBoundingBox();
+    double width = bbox.getWidth();
+    double height = bbox.getHeight();
+    //Use standard cartesian hypotenuse. For geospatial, this answer is larger
+    // than the correct one but it's okay to over-estimate.
+    return Math.sqrt(width * width + height * height);
+  }
+
+  /**
+   * Returns the cell containing point {@code p} at the specified {@code level}.
+   */
+  protected abstract Cell getCell(Point p, int level);
+
+  @Override
+  public Cell readCell(BytesRef term, Cell scratch) {
+    LegacyCell cell = (LegacyCell) scratch;
+    if (cell == null)
+      cell = (LegacyCell) getWorldCell();
+    cell.readCell(term);
+    return cell;
+  }
+
+  @Override
+  public CellIterator getTreeCellIterator(Shape shape, int detailLevel) {
+    if (!(shape instanceof Point))
+      return super.getTreeCellIterator(shape, detailLevel);
+
+    //This specialization is here because the legacy implementations don't have a fast implementation of
+    // cell.getSubCells(point). It's fastest here to encode the full bytes for detailLevel, and create
+    // subcells from the bytesRef in a loop. This avoids an O(N^2) encode, and we have O(N) instead.
+
+    Cell cell = getCell((Point) shape, detailLevel);
+    assert cell instanceof LegacyCell;
+    BytesRef fullBytes = cell.getTokenBytesNoLeaf(null);
+    //fill in reverse order to be sorted
+    Cell[] cells = new Cell[detailLevel];
+    for (int i = 1; i < detailLevel; i++) {
+      fullBytes.length = i;
+      Cell parentCell = readCell(fullBytes, null);
+      cells[i-1] = parentCell;
+    }
+    cells[detailLevel-1] = cell;
+    return new FilterCellIterator(Arrays.asList(cells).iterator(), null);//null filter
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/NumberRangePrefixTree.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/NumberRangePrefixTree.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/NumberRangePrefixTree.java
new file mode 100644
index 0000000..40e80bc
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/NumberRangePrefixTree.java
@@ -0,0 +1,989 @@
+/*
+ * 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.prefix.tree;
+
+import java.text.ParseException;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.context.SpatialContextFactory;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.SpatialRelation;
+import com.spatial4j.core.shape.impl.RectangleImpl;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.StringHelper;
+
+/**
+ * A SpatialPrefixTree for single-dimensional numbers and number ranges of fixed precision values (not floating point).
+ * Despite its name, the indexed values (and queries) need not actually be ranges, they can be unit instance/values.
+ * <p>
+ * Why might you use this instead of Lucene's built-in integer/long support?  Here are some reasons with features based
+ * on code in this class, <em>or are possible based on this class but require a subclass to fully realize it</em>.
+ * <ul>
+ *   <li>Index ranges, not just unit instances. This is especially useful when the requirement calls for a
+ *   multi-valued range.</li>
+ *   <li>Instead of a fixed "precisionStep", this prefixTree can have a customizable number of child values for any
+ *   prefix (up to 32768). This allows exact alignment of the prefix-tree with typical/expected values, which
+ *   results in better performance.  For example in a Date implementation, every month can get its own dedicated prefix,
+ *   every day, etc., even though months vary in duration.</li>
+ *   <li>Arbitrary precision, like {@link java.math.BigDecimal}.</li>
+ *   <li>Standard Lucene integer/long indexing always indexes the full precision of those data types but this one
+ *   is customizable.</li>
+ * </ul>
+ *
+ * Unlike "normal" spatial components in this module, this special-purpose one only works with {@link Shape}s
+ * created by the methods on this class, not from any {@link com.spatial4j.core.context.SpatialContext}.
+ *
+ * @see org.apache.lucene.spatial.prefix.NumberRangePrefixTreeStrategy
+ * @see <a href="https://issues.apache.org/jira/browse/LUCENE-5648">LUCENE-5648</a>
+ * @lucene.experimental
+ */
+public abstract class NumberRangePrefixTree extends SpatialPrefixTree {
+
+  //
+  //    Dummy SpatialContext
+  //
+
+  private static final SpatialContext DUMMY_CTX;
+  static {
+    SpatialContextFactory factory = new SpatialContextFactory();
+    factory.geo = false;
+    factory.worldBounds = new RectangleImpl(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 0L, 0L, null);
+    DUMMY_CTX = factory.newSpatialContext();
+  }
+
+  /** Base interface for {@link Shape}s this prefix tree supports. It extends {@link Shape} (Spatial4j) for compatibility
+   * with the spatial API even though it doesn't intermix with conventional 2D shapes.
+   * @lucene.experimental
+   */
+  public static interface NRShape extends Shape, Cloneable {
+    /** The result should be parseable by {@link #parseShape(String)}. */
+    abstract String toString();
+
+    /** Returns this shape rounded to the target level. If we are already more course than the level then the shape is
+     * simply returned.  The result may refer to internal state of the argument so you may want to clone it.
+     */
+    public NRShape roundToLevel(int targetLevel);
+  }
+
+  //
+  //  Factory / Conversions / parsing relating to NRShapes
+  //
+
+  /** Converts the value to a unit shape. Doesn't parse strings; see {@link #parseShape(String)} for
+   * that. This is the reverse of {@link #toObject(org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape)}. */
+  public abstract UnitNRShape toUnitShape(Object value);
+
+  /** Returns a shape that represents the continuous range between {@code start} and {@code end}. It will
+   * be normalized, and so sometimes a {@link org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape}
+   * will be returned, other times a
+   * {@link org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.SpanUnitsNRShape} will be.
+   *
+   * @throws IllegalArgumentException if the arguments are in the wrong order, or if either contains the other (yet they
+   * aren't equal).
+   */
+  public NRShape toRangeShape(UnitNRShape startUnit, UnitNRShape endUnit) {
+    //note: this normalization/optimization process is actually REQUIRED based on assumptions elsewhere.
+    //Normalize start & end
+    startUnit = startUnit.getShapeAtLevel(truncateStartVals(startUnit, 0)); // chops off trailing min-vals (zeroes)
+    endUnit = endUnit.getShapeAtLevel(truncateEndVals(endUnit, 0)); // chops off trailing max-vals
+    //Optimize to just start or end if it's equivalent, e.g. April to April 1st is April 1st.
+    int cmp = comparePrefix(startUnit, endUnit);
+    if (cmp > 0) {
+      throw new IllegalArgumentException("Wrong order: "+ startUnit +" TO "+ endUnit);
+    }
+    if (cmp == 0) {//one is a prefix of the other
+      if (startUnit.getLevel() == endUnit.getLevel()) {
+        //same
+        return startUnit;
+      } else if (endUnit.getLevel() > startUnit.getLevel()) {
+        // e.g. April to April 1st
+        if (truncateStartVals(endUnit, startUnit.getLevel()) == startUnit.getLevel()) {
+          return endUnit;
+        }
+      } else {//minLV level > maxLV level
+        // e.g. April 30 to April
+        if (truncateEndVals(startUnit, endUnit.getLevel()) == endUnit.getLevel()) {
+          return startUnit;
+        }
+      }
+    }
+    return new SpanUnitsNRShape(startUnit, endUnit);
+  }
+
+  /** From lv.getLevel on up, it returns the first Level seen with val != 0. It doesn't check past endLevel. */
+  private int truncateStartVals(UnitNRShape lv, int endLevel) {
+    for (int level = lv.getLevel(); level > endLevel; level--) {
+      if (lv.getValAtLevel(level) != 0)
+        return level;
+    }
+    return endLevel;
+  }
+
+  private int truncateEndVals(UnitNRShape lv, int endLevel) {
+    for (int level = lv.getLevel(); level > endLevel; level--) {
+      int max = getNumSubCells(lv.getShapeAtLevel(level - 1)) - 1;
+      if (lv.getValAtLevel(level) != max)
+        return level;
+    }
+    return endLevel;
+  }
+
+  /** Converts a UnitNRShape shape to the corresponding type supported by this class, such as a Calendar/BigDecimal.
+   * This is the reverse of {@link #toUnitShape(Object)}.
+   */
+  public abstract Object toObject(UnitNRShape shape);
+
+  /** A string representation of the UnitNRShape that is parse-able by {@link #parseUnitShape(String)}. */
+  protected abstract String toString(UnitNRShape lv);
+
+  protected static String toStringUnitRaw(UnitNRShape lv) {
+    StringBuilder buf = new StringBuilder(100);
+    buf.append('[');
+    for (int level = 1; level <= lv.getLevel(); level++) {
+      buf.append(lv.getValAtLevel(level)).append(',');
+    }
+    buf.setLength(buf.length()-1);//chop off ','
+    buf.append(']');
+    return buf.toString();
+  }
+
+  /** Detects a range pattern and parses it, otherwise it's parsed as one shape via
+   * {@link #parseUnitShape(String)}.  The range pattern looks like this BNF:
+   * <pre>
+   *   '[' + parseShapeLV + ' TO ' + parseShapeLV + ']'
+   * </pre>
+   * It's the same thing as the toString() of the range shape, notwithstanding range optimization.
+   *
+   * @param str not null or empty
+   * @return not null
+   * @throws java.text.ParseException If there is a problem
+   */
+  public NRShape parseShape(String str) throws ParseException {
+    if (str == null || str.isEmpty())
+      throw new IllegalArgumentException("str is null or blank");
+    if (str.charAt(0) == '[') {
+      if (str.charAt(str.length()-1) != ']')
+        throw new ParseException("If starts with [ must end with ]; got "+str, str.length()-1);
+      int middle = str.indexOf(" TO ");
+      if (middle < 0)
+        throw new ParseException("If starts with [ must contain ' TO '; got "+str, -1);
+      String leftStr = str.substring(1, middle);
+      String rightStr = str.substring(middle + " TO ".length(), str.length()-1);
+      return toRangeShape(parseUnitShape(leftStr), parseUnitShape(rightStr));
+    } else if (str.charAt(0) == '{') {
+      throw new ParseException("Exclusive ranges not supported; got "+str, 0);
+    } else {
+      return parseUnitShape(str);
+    }
+  }
+
+  /** Parse a String to a UnitNRShape. "*" should be the full-range (level 0 shape). */
+  protected abstract UnitNRShape parseUnitShape(String str) throws ParseException;
+
+
+  //
+  //    UnitNRShape
+  //
+
+  /**
+   * A unit value Shape implemented as a stack of numbers, one for each level in the prefix tree. It directly
+   * corresponds to a {@link Cell}.  Spatially speaking, it's analogous to a Point but 1D and has some precision width.
+   * @lucene.experimental
+   */
+  public static interface UnitNRShape extends NRShape, Comparable<UnitNRShape> {
+    //note: formerly known as LevelledValue; thus some variables still use 'lv'
+
+    /** Get the prefix tree level, the higher the more precise. 0 means the world (universe). */
+    int getLevel();
+    /** Gets the value at the specified level of this unit. level must be &gt;= 0 and &lt;= getLevel(). */
+    int getValAtLevel(int level);
+    /** Gets an ancestor at the specified level. It shares state, so you may want to clone() it. */
+    UnitNRShape getShapeAtLevel(int level);
+    @Override
+    UnitNRShape roundToLevel(int targetLevel);
+
+    /** Deep clone */
+    UnitNRShape clone();
+  }
+
+  /** Compares a to b, returning less than 0, 0, or greater than 0, if a is less than, equal to, or
+   * greater than b, respectively, up to their common prefix (i.e. only min(a.levels,b.levels) are compared).
+   * @lucene.internal */
+  protected static int comparePrefix(UnitNRShape a, UnitNRShape b) {
+    int minLevel = Math.min(a.getLevel(), b.getLevel());
+    for (int level = 1; level <= minLevel; level++) {
+      int diff = a.getValAtLevel(level) - b.getValAtLevel(level);
+      if (diff != 0)
+        return diff;
+    }
+    return 0;
+  }
+
+
+  //
+  //    SpanUnitsNRShape
+  //
+
+  /** A range Shape; based on a pair of {@link org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape}.
+   * Spatially speaking, it's analogous to a Rectangle but 1D. It might have been named with Range in the name but it
+   * may be confusing since even the {@link org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape}
+   * is in some sense a range.
+   * @lucene.experimental */
+  public class SpanUnitsNRShape implements NRShape {
+
+    private final UnitNRShape minLV, maxLV;
+    private final int lastLevelInCommon;//computed; not part of identity
+
+    /** Don't call directly; see
+     * {@link #toRangeShape(org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape, org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape)}. */
+    private SpanUnitsNRShape(UnitNRShape minLV, UnitNRShape maxLV) {
+      this.minLV = minLV;
+      this.maxLV = maxLV;
+
+      //calc lastLevelInCommon
+      int level = 1;
+      for (; level <= minLV.getLevel() && level <= maxLV.getLevel(); level++) {
+        if (minLV.getValAtLevel(level) != maxLV.getValAtLevel(level))
+          break;
+      }
+      lastLevelInCommon = level - 1;
+    }
+
+    @Override
+    public SpatialContext getContext() {
+      return DUMMY_CTX;
+    }
+
+    public UnitNRShape getMinUnit() { return minLV; }
+
+    public UnitNRShape getMaxUnit() { return maxLV; }
+
+    /** How many levels are in common between minUnit and maxUnit, not including level 0. */
+    private int getLevelsInCommon() { return lastLevelInCommon; }
+
+    @Override
+    public NRShape roundToLevel(int targetLevel) {
+      return toRangeShape(minLV.roundToLevel(targetLevel), maxLV.roundToLevel(targetLevel));
+    }
+
+    @Override
+    public SpatialRelation relate(Shape shape) {
+//      if (shape instanceof UnitNRShape)
+//        return relate((UnitNRShape)shape);
+      if (shape instanceof SpanUnitsNRShape)
+        return relate((SpanUnitsNRShape) shape);
+      return shape.relate(this).transpose();//probably a UnitNRShape
+    }
+
+    public SpatialRelation relate(SpanUnitsNRShape ext) {
+      //This logic somewhat mirrors RectangleImpl.relate_range()
+      int extMin_intMax = comparePrefix(ext.getMinUnit(), getMaxUnit());
+      if (extMin_intMax > 0)
+        return SpatialRelation.DISJOINT;
+      int extMax_intMin = comparePrefix(ext.getMaxUnit(), getMinUnit());
+      if (extMax_intMin < 0)
+        return SpatialRelation.DISJOINT;
+      int extMin_intMin = comparePrefix(ext.getMinUnit(), getMinUnit());
+      int extMax_intMax = comparePrefix(ext.getMaxUnit(), getMaxUnit());
+      if ((extMin_intMin > 0 || extMin_intMin == 0 && ext.getMinUnit().getLevel() >= getMinUnit().getLevel())
+          && (extMax_intMax < 0 || extMax_intMax == 0 && ext.getMaxUnit().getLevel() >= getMaxUnit().getLevel()))
+        return SpatialRelation.CONTAINS;
+      if ((extMin_intMin < 0 || extMin_intMin == 0 && ext.getMinUnit().getLevel() <= getMinUnit().getLevel())
+          && (extMax_intMax > 0 || extMax_intMax == 0 && ext.getMaxUnit().getLevel() <= getMaxUnit().getLevel()))
+        return SpatialRelation.WITHIN;
+      return SpatialRelation.INTERSECTS;
+    }
+
+    @Override
+    public Rectangle getBoundingBox() { throw new UnsupportedOperationException(); }
+
+    @Override
+    public boolean hasArea() { return true; }
+
+    @Override
+    public double getArea(SpatialContext spatialContext) { throw new UnsupportedOperationException(); }
+
+    @Override
+    public Point getCenter() { throw new UnsupportedOperationException(); }
+
+    @Override
+    public Shape getBuffered(double v, SpatialContext spatialContext) { throw new UnsupportedOperationException(); }
+
+    @Override
+    public boolean isEmpty() { return false; }
+
+    /** A deep clone. */
+    @Override
+    public SpanUnitsNRShape clone() {
+      return new SpanUnitsNRShape(minLV.clone(), maxLV.clone());
+    }
+
+    @Override
+    public String toString() {
+      return "[" + NumberRangePrefixTree.this.toString(minLV) + " TO "
+          + NumberRangePrefixTree.this.toString(maxLV) + "]";
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+
+      SpanUnitsNRShape spanShape = (SpanUnitsNRShape) o;
+
+      if (!maxLV.equals(spanShape.maxLV)) return false;
+      if (!minLV.equals(spanShape.minLV)) return false;
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int result = minLV.hashCode();
+      result = 31 * result + maxLV.hashCode();
+      return result;
+    }
+  }// class SpanUnitsNRShape
+
+  //
+  //    NumberRangePrefixTree
+  //
+
+  protected final int[] maxSubCellsByLevel;
+  protected final int[] termLenByLevel;
+  protected final int[] levelByTermLen;
+  protected final int maxTermLen; // how long could cell.getToken... (that is a leaf) possibly be?
+
+  protected NumberRangePrefixTree(int[] maxSubCellsByLevel) {
+    super(DUMMY_CTX, maxSubCellsByLevel.length);
+    this.maxSubCellsByLevel = maxSubCellsByLevel;
+
+    // Fill termLenByLevel
+    this.termLenByLevel = new int[maxLevels + 1];
+    termLenByLevel[0] = 0;
+    final int MAX_STATES = 1 << 15;//1 bit less than 2 bytes
+    for (int level = 1; level <= maxLevels; level++) {
+      final int states = maxSubCellsByLevel[level - 1];
+      if (states >= MAX_STATES || states <= 1) {
+        throw new IllegalArgumentException("Max states is "+MAX_STATES+", given "+states+" at level "+level);
+      }
+      boolean twoBytes = states >= 256;
+      termLenByLevel[level] = termLenByLevel[level-1] + (twoBytes ? 2 : 1);
+    }
+    maxTermLen = termLenByLevel[maxLevels] + 1;// + 1 for leaf byte
+
+    // Fill levelByTermLen
+    levelByTermLen = new int[maxTermLen];
+    levelByTermLen[0] = 0;
+    for (int level = 1; level < termLenByLevel.length; level++) {
+      int termLen = termLenByLevel[level];
+      int prevTermLen = termLenByLevel[level-1];
+      if (termLen - prevTermLen == 2) {//2 byte delta
+        //if the term doesn't completely cover this cell then it must be a leaf of the prior.
+        levelByTermLen[termLen-1] = -1;//won't be used; otherwise erroneous
+        levelByTermLen[termLen] = level;
+      } else {//1 byte delta
+        assert termLen - prevTermLen == 1;
+        levelByTermLen[termLen] = level;
+      }
+    }
+
+  }
+
+  @Override
+  public String toString() {
+    return getClass().getSimpleName();
+  }
+
+  @Override
+  public int getLevelForDistance(double dist) {
+    //note: it might be useful to compute which level has a raw width (counted in
+    // bottom units, e.g. milliseconds), that covers the provided dist in those units?
+    return maxLevels; // thus always use full precision. We don't do approximations in this tree/strategy.
+    //throw new UnsupportedOperationException("Not applicable.");
+  }
+
+  @Override
+  public double getDistanceForLevel(int level) {
+    //note: we could compute this... should we?
+    throw new UnsupportedOperationException("Not applicable.");
+  }
+
+  protected UnitNRShape toShape(int[] valStack, int len) {
+    final NRCell[] cellStack = newCellStack(len);
+    for (int i = 0; i < len; i++) {
+      cellStack[i+1].resetCellWithCellNum(valStack[i]);
+    }
+    return cellStack[len];
+  }
+
+  @Override
+  public Cell getWorldCell() {
+    return newCellStack(maxLevels)[0];
+  }
+
+  protected NRCell[] newCellStack(int levels) {
+    final NRCell[] cellsByLevel = new NRCell[levels + 1];
+    final BytesRef term = new BytesRef(maxTermLen);
+    for (int level = 0; level <= levels; level++) {
+      cellsByLevel[level] = new NRCell(cellsByLevel,term,level);
+    }
+    return cellsByLevel;
+  }
+
+  @Override
+  public Cell readCell(BytesRef term, Cell scratch) {
+    if (scratch == null)
+      scratch = getWorldCell();
+
+    //We decode level #, leaf boolean, and populate bytes by reference. We don't decode the stack.
+
+    //reverse lookup term length to the level and hence the cell
+    NRCell[] cellsByLevel = ((NRCell) scratch).cellsByLevel;
+    boolean isLeaf = term.bytes[term.offset + term.length - 1] == 0;
+    int lenNoLeaf = isLeaf ? term.length - 1 : term.length;
+
+    NRCell result = cellsByLevel[levelByTermLen[lenNoLeaf]];
+    if (cellsByLevel[0].termBuf == null)
+      cellsByLevel[0].termBuf = result.term.bytes;//a kluge; see cell.ensureOwnTermBytes()
+    result.term.bytes = term.bytes;
+    result.term.offset = term.offset;
+    result.term.length = lenNoLeaf;//technically this isn't used but may help debugging
+    result.reset();
+    if (isLeaf)
+      result.setLeaf();
+
+    result.cellNumber = -1;//lazy decode flag
+
+    return result;
+  }
+
+  /** Returns the number of sub-cells beneath the given UnitNRShape. */
+  public int getNumSubCells(UnitNRShape lv) {
+    return maxSubCellsByLevel[lv.getLevel()];
+  }
+
+  //
+  //    NRCell
+  //
+
+  /** Most of the PrefixTree implementation is in this one class, which is both
+   * the Cell, the CellIterator, and the Shape to reduce object allocation. It's implemented as a re-used array/stack
+   * of Cells at adjacent levels, that all have a reference back to the cell array to traverse. They also share a common
+   * BytesRef for the term.
+   * @lucene.internal */
+  protected class NRCell extends CellIterator implements Cell, UnitNRShape {
+
+    //Shared: (TODO put this in a new class)
+    final NRCell[] cellsByLevel;
+    final BytesRef term;//AKA the token
+    byte[] termBuf;// see ensureOwnTermBytes(), only for cell0
+
+    //Cell state...
+    final int cellLevel; // assert levelStack[cellLevel] == this
+    int cellNumber; //relative to parent cell. It's unused for level 0. Starts at 0.
+
+    SpatialRelation cellShapeRel;
+    boolean cellIsLeaf;
+
+    //CellIterator state is defined further below
+
+    NRCell(NRCell[] cellsByLevel, BytesRef term, int cellLevel) {
+      this.cellsByLevel = cellsByLevel;
+      this.term = term;
+      this.cellLevel = cellLevel;
+      this.cellNumber = cellLevel == 0 ? 0 : -1;
+      this.cellIsLeaf = false;
+      assert cellsByLevel[cellLevel] == null;
+    }
+
+    /** Ensure we own term.bytes so that it's safe to modify. We detect via a kluge in which cellsByLevel[0].termBuf
+     * is non-null, which is a pre-allocated for use to replace term.bytes. */
+    void ensureOwnTermBytes() {
+      NRCell cell0 = cellsByLevel[0];
+      if (cell0.termBuf == null)
+        return;//we already own the bytes
+      System.arraycopy(term.bytes, term.offset, cell0.termBuf, 0, term.length);
+      term.bytes = cell0.termBuf;
+      term.offset = 0;
+      cell0.termBuf = null;
+    }
+
+    private void reset() {
+      this.cellIsLeaf = false;
+      this.cellShapeRel = null;
+    }
+
+    private void resetCellWithCellNum(int cellNumber) {
+      reset();
+
+      //update bytes
+      //  note: see lazyInitCellNumsFromBytes() for the reverse
+      if (cellNumber >= 0) {//valid
+        ensureOwnTermBytes();
+        int termLen = termLenByLevel[getLevel()];
+        boolean twoBytes = (termLen - termLenByLevel[getLevel()-1]) > 1;
+        if (twoBytes) {
+          //right 7 bits, plus 1 (may overflow to 8th bit which is okay)
+          term.bytes[termLen-2] = (byte) (cellNumber >> 7);
+          term.bytes[termLen-1] = (byte) ((cellNumber & 0x7F) + 1);
+        } else {
+          term.bytes[termLen-1] = (byte) (cellNumber+1);
+        }
+        assert term.bytes[termLen-1] != 0;
+        term.length = termLen;
+      }
+      this.cellNumber = cellNumber;
+    }
+
+    private void ensureDecoded() {
+      if (cellNumber >= 0)
+        return;
+      //Decode cell numbers from bytes. This is the inverse of resetCellWithCellNum().
+      for (int level = 1; level <= getLevel(); level++) {
+        NRCell cell = cellsByLevel[level];
+        int termLen = termLenByLevel[level];
+        boolean twoBytes = (termLen - termLenByLevel[level-1]) > 1;
+        if (twoBytes) {
+          int byteH = (term.bytes[term.offset + termLen - 2] & 0xFF);
+          int byteL = (term.bytes[term.offset + termLen - 1] & 0xFF);
+          assert byteL - 1 < (1<<7);
+          cell.cellNumber = (byteH << 7) + (byteL-1);
+          assert cell.cellNumber < 1<<15;
+        } else {
+          cell.cellNumber = (term.bytes[term.offset + termLen - 1] & 0xFF) - 1;
+          assert cell.cellNumber < 255;
+        }
+        cell.assertDecoded();
+      }
+    }
+
+    private void assertDecoded() {
+      assert cellNumber >= 0 : "Illegal state; ensureDecoded() wasn't called";
+    }
+
+    @Override // for Cell & for UnitNRShape
+    public int getLevel() {
+      return cellLevel;
+    }
+
+    @Override
+    public SpatialRelation getShapeRel() {
+      return cellShapeRel;
+    }
+
+    @Override
+    public void setShapeRel(SpatialRelation rel) {
+      cellShapeRel = rel;
+    }
+
+    @Override
+    public boolean isLeaf() {
+      return cellIsLeaf;
+    }
+
+    @Override
+    public void setLeaf() {
+      cellIsLeaf = true;
+    }
+
+    @Override
+    public UnitNRShape getShape() {
+      ensureDecoded();
+      return this;
+    }
+
+    @Override
+    public BytesRef getTokenBytesNoLeaf(BytesRef result) {
+      if (result == null)
+        result = new BytesRef();
+      result.bytes = term.bytes;
+      result.offset = term.offset;
+      result.length = termLenByLevel[cellLevel];
+      assert result.length <= term.length;
+      return result;
+    }
+
+    @Override
+    public BytesRef getTokenBytesWithLeaf(BytesRef result) {
+      ensureOwnTermBytes();//normally shouldn't do anything
+      result = getTokenBytesNoLeaf(result);
+      if (isLeaf()) {
+        result.bytes[result.length++] = 0;
+      }
+      return result;
+    }
+
+    @Override
+    public boolean isPrefixOf(Cell c) {
+      NRCell otherCell = (NRCell) c;
+      assert term != otherCell.term;
+      //trick to re-use bytesref; provided that we re-instate it
+      int myLastLen = term.length;
+      term.length = termLenByLevel[getLevel()];
+      int otherLastLen = otherCell.term.length;
+      otherCell.term.length = termLenByLevel[otherCell.getLevel()];
+      boolean answer = StringHelper.startsWith(otherCell.term, term);
+      term.length = myLastLen;
+      otherCell.term.length = otherLastLen;
+      return answer;
+    }
+
+    @Override
+    public int compareToNoLeaf(Cell fromCell) {
+      final NRCell nrCell = (NRCell) fromCell;
+      assert term != nrCell.term;
+      //trick to re-use bytesref; provided that we re-instate it
+      int myLastLen = term.length;
+      int otherLastLen = nrCell.term.length;
+      term.length = termLenByLevel[getLevel()];
+      nrCell.term.length = termLenByLevel[nrCell.getLevel()];
+      int answer = term.compareTo(nrCell.term);
+      term.length = myLastLen;
+      nrCell.term.length = otherLastLen;
+      return answer;
+    }
+
+    @Override
+    public CellIterator getNextLevelCells(Shape shapeFilter) {
+      ensureDecoded();
+      NRCell subCell = cellsByLevel[cellLevel + 1];
+      subCell.initIter(shapeFilter);
+      return subCell;
+    }
+
+    //----------- CellIterator
+
+    Shape iterFilter;//UnitNRShape or NRShape
+    boolean iterFirstIsIntersects;
+    boolean iterLastIsIntersects;
+    int iterFirstCellNumber;
+    int iterLastCellNumber;
+
+    private void initIter(Shape filter) {
+      cellNumber = -1;
+      if (filter instanceof UnitNRShape && ((UnitNRShape) filter).getLevel() == 0)
+        filter = null;//world means everything -- no filter
+      iterFilter = filter;
+
+      NRCell parent = getShapeAtLevel(getLevel() - 1);
+
+      // Initialize iter* members.
+
+      //no filter means all subcells
+      if (filter == null) {
+        iterFirstCellNumber = 0;
+        iterFirstIsIntersects = false;
+        iterLastCellNumber = getNumSubCells(parent) - 1;
+        iterLastIsIntersects = false;
+        return;
+      }
+
+      final UnitNRShape minLV;
+      final UnitNRShape maxLV;
+      final int lastLevelInCommon;//between minLV & maxLV
+      if (filter instanceof SpanUnitsNRShape) {
+        SpanUnitsNRShape spanShape = (SpanUnitsNRShape) iterFilter;
+        minLV = spanShape.getMinUnit();
+        maxLV = spanShape.getMaxUnit();
+        lastLevelInCommon = spanShape.getLevelsInCommon();
+      } else {
+        minLV = (UnitNRShape) iterFilter;
+        maxLV = minLV;
+        lastLevelInCommon = minLV.getLevel();
+      }
+
+      //fast path optimization that is usually true, but never first level
+      if (iterFilter == parent.iterFilter &&
+          (getLevel() <= lastLevelInCommon || parent.iterFirstCellNumber != parent.iterLastCellNumber)) {
+        //TODO benchmark if this optimization pays off. We avoid two comparePrefixLV calls.
+        if (parent.iterFirstIsIntersects && parent.cellNumber == parent.iterFirstCellNumber
+            && minLV.getLevel() >= getLevel()) {
+          iterFirstCellNumber = minLV.getValAtLevel(getLevel());
+          iterFirstIsIntersects = (minLV.getLevel() > getLevel());
+        } else {
+          iterFirstCellNumber = 0;
+          iterFirstIsIntersects = false;
+        }
+        if (parent.iterLastIsIntersects && parent.cellNumber == parent.iterLastCellNumber
+            && maxLV.getLevel() >= getLevel()) {
+          iterLastCellNumber = maxLV.getValAtLevel(getLevel());
+          iterLastIsIntersects = (maxLV.getLevel() > getLevel());
+        } else {
+          iterLastCellNumber = getNumSubCells(parent) - 1;
+          iterLastIsIntersects = false;
+        }
+        if (iterFirstCellNumber == iterLastCellNumber) {
+          if (iterLastIsIntersects)
+            iterFirstIsIntersects = true;
+          else if (iterFirstIsIntersects)
+            iterLastIsIntersects = true;
+        }
+        return;
+      }
+
+      //not common to get here, except for level 1 which always happens
+
+      int startCmp = comparePrefix(minLV, parent);
+      if (startCmp > 0) {//start comes after this cell
+        iterFirstCellNumber = 0;
+        iterFirstIsIntersects = false;
+        iterLastCellNumber = -1;//so ends early (no cells)
+        iterLastIsIntersects = false;
+        return;
+      }
+      int endCmp = comparePrefix(maxLV, parent);//compare to end cell
+      if (endCmp < 0) {//end comes before this cell
+        iterFirstCellNumber = 0;
+        iterFirstIsIntersects = false;
+        iterLastCellNumber = -1;//so ends early (no cells)
+        iterLastIsIntersects = false;
+        return;
+      }
+      if (startCmp < 0 || minLV.getLevel() < getLevel()) {
+        //start comes before...
+        iterFirstCellNumber = 0;
+        iterFirstIsIntersects = false;
+      } else {
+        iterFirstCellNumber = minLV.getValAtLevel(getLevel());
+        iterFirstIsIntersects = (minLV.getLevel() > getLevel());
+      }
+      if (endCmp > 0 || maxLV.getLevel() < getLevel()) {
+        //end comes after...
+        iterLastCellNumber = getNumSubCells(parent) - 1;
+        iterLastIsIntersects = false;
+      } else {
+        iterLastCellNumber = maxLV.getValAtLevel(getLevel());
+        iterLastIsIntersects = (maxLV.getLevel() > getLevel());
+      }
+      if (iterFirstCellNumber == iterLastCellNumber) {
+        if (iterLastIsIntersects)
+          iterFirstIsIntersects = true;
+        else if (iterFirstIsIntersects)
+          iterLastIsIntersects = true;
+      }
+    }
+
+    @Override
+    public boolean hasNext() {
+      thisCell = null;
+      if (nextCell != null)//calling hasNext twice in a row
+        return true;
+
+      if (cellNumber >= iterLastCellNumber)
+        return false;
+
+      resetCellWithCellNum(cellNumber < iterFirstCellNumber ? iterFirstCellNumber : cellNumber + 1);
+
+      boolean hasChildren =
+          (cellNumber == iterFirstCellNumber && iterFirstIsIntersects)
+              || (cellNumber == iterLastCellNumber && iterLastIsIntersects);
+
+      if (!hasChildren) {
+        setLeaf();
+        setShapeRel(SpatialRelation.WITHIN);
+      } else if (iterFirstCellNumber == iterLastCellNumber) {
+        setShapeRel(SpatialRelation.CONTAINS);
+      } else {
+        setShapeRel(SpatialRelation.INTERSECTS);
+      }
+
+      nextCell = this;
+      return true;
+    }
+
+    //TODO override nextFrom to be more efficient
+
+    //----------- UnitNRShape
+
+    @Override
+    public int getValAtLevel(int level) {
+      final int result = cellsByLevel[level].cellNumber;
+      assert result >= 0;//initialized (decoded)
+      return result;
+    }
+
+    @Override
+    public NRCell getShapeAtLevel(int level) {
+      assert level <= cellLevel;
+      return cellsByLevel[level];
+    }
+
+    @Override
+    public UnitNRShape roundToLevel(int targetLevel) {
+      if (getLevel() <= targetLevel) {
+        return this;
+      } else {
+        return getShapeAtLevel(targetLevel);
+      }
+    }
+
+    @Override
+    public SpatialRelation relate(Shape shape) {
+      assertDecoded();
+      if (shape == iterFilter && cellShapeRel != null)
+        return cellShapeRel;
+      if (shape instanceof UnitNRShape)
+        return relate((UnitNRShape)shape);
+      if (shape instanceof SpanUnitsNRShape)
+        return relate((SpanUnitsNRShape)shape);
+      return shape.relate(this).transpose();
+    }
+
+    public SpatialRelation relate(UnitNRShape lv) {
+      assertDecoded();
+      int cmp = comparePrefix(this, lv);
+      if (cmp != 0)
+        return SpatialRelation.DISJOINT;
+      if (getLevel() > lv.getLevel())
+        return SpatialRelation.WITHIN;
+      return SpatialRelation.CONTAINS;//or equals
+      //no INTERSECTS; that won't happen.
+    }
+
+    public SpatialRelation relate(SpanUnitsNRShape spanShape) {
+      assertDecoded();
+      int startCmp = comparePrefix(spanShape.getMinUnit(), this);
+      if (startCmp > 0) {//start comes after this cell
+        return SpatialRelation.DISJOINT;
+      }
+      int endCmp = comparePrefix(spanShape.getMaxUnit(), this);
+      if (endCmp < 0) {//end comes before this cell
+        return SpatialRelation.DISJOINT;
+      }
+      int nrMinLevel = spanShape.getMinUnit().getLevel();
+      int nrMaxLevel = spanShape.getMaxUnit().getLevel();
+      if ((startCmp < 0 || startCmp == 0 && nrMinLevel <= getLevel())
+          && (endCmp > 0 || endCmp == 0 && nrMaxLevel <= getLevel()))
+        return SpatialRelation.WITHIN;//or equals
+      //At this point it's Contains or Within.
+      if (startCmp != 0 || endCmp != 0)
+        return SpatialRelation.INTERSECTS;
+      //if min or max Level is less, it might be on the equivalent edge.
+      for (;nrMinLevel < getLevel(); nrMinLevel++) {
+        if (getValAtLevel(nrMinLevel + 1) != 0)
+          return SpatialRelation.INTERSECTS;
+      }
+      for (;nrMaxLevel < getLevel(); nrMaxLevel++) {
+        if (getValAtLevel(nrMaxLevel + 1) != getNumSubCells(getShapeAtLevel(nrMaxLevel)) - 1)
+          return SpatialRelation.INTERSECTS;
+      }
+      return SpatialRelation.CONTAINS;
+    }
+
+    @Override
+    public UnitNRShape clone() {
+      //no leaf distinction; this is purely based on UnitNRShape
+      NRCell cell = (NRCell) readCell(getTokenBytesNoLeaf(null), null);
+      cell.ensureOwnTermBytes();
+      return cell.getShape();
+    }
+
+    @Override
+    public int compareTo(UnitNRShape o) {
+      assertDecoded();
+      //no leaf distinction; this is purely based on UnitNRShape
+      int cmp = comparePrefix(this, o);
+      if (cmp != 0) {
+        return cmp;
+      } else {
+        return getLevel() - o.getLevel();
+      }
+    }
+
+    @Override
+    public Rectangle getBoundingBox() {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean hasArea() {
+      return true;
+    }
+
+    @Override
+    public double getArea(SpatialContext ctx) {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Point getCenter() {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Shape getBuffered(double distance, SpatialContext ctx) { throw new UnsupportedOperationException(); }
+
+    @Override
+    public boolean isEmpty() {
+      return false;
+    }
+
+    //------- Object
+
+    @Override
+    public boolean equals(Object obj) {
+      if (!(obj instanceof NRCell)) {
+        return false;
+      }
+      if (this == obj)
+        return true;
+      NRCell nrCell = (NRCell) obj;
+      assert term != nrCell.term;
+      if (getLevel() != nrCell.getLevel())
+        return false;
+      //trick to re-use bytesref; provided that we re-instate it
+      int myLastLen = term.length;
+      int otherLastLen = nrCell.term.length;
+      boolean answer = getTokenBytesNoLeaf(term).equals(nrCell.getTokenBytesNoLeaf(nrCell.term));
+      term.length = myLastLen;
+      nrCell.term.length = otherLastLen;
+      return answer;
+    }
+
+    @Override
+    public SpatialContext getContext() {
+      return DUMMY_CTX;
+    }
+
+    @Override
+    public int hashCode() {
+      //trick to re-use bytesref; provided that we re-instate it
+      int myLastLen = term.length;
+      int result = getTokenBytesNoLeaf(term).hashCode();
+      term.length = myLastLen;
+      return result;
+    }
+
+    @Override
+    public String toString() {
+      return NumberRangePrefixTree.this.toString(getShape());
+    }
+
+    /** Configure your IDE to use this. */
+    public String toStringDebug() {
+      String pretty = toString();
+      if (getLevel() == 0)
+        return pretty;
+      return toStringUnitRaw(this) + (isLeaf() ? "•" : "") + " " + pretty;
+    }
+
+  } // END OF NRCell
+
+}


[31/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/ContainsPrefixTreeQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/ContainsPrefixTreeQuery.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/ContainsPrefixTreeQuery.java
new file mode 100644
index 0000000..0046378
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/ContainsPrefixTreeQuery.java
@@ -0,0 +1,362 @@
+/*
+ * 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.prefix;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.SpatialRelation;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.PostingsEnum;
+import org.apache.lucene.index.TermsEnum;
+import org.apache.lucene.search.DocIdSet;
+import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.spatial.prefix.tree.Cell;
+import org.apache.lucene.spatial.prefix.tree.CellIterator;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.util.Bits;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.RamUsageEstimator;
+import org.apache.lucene.util.SentinelIntSet;
+
+/**
+ * Finds docs where its indexed shape {@link org.apache.lucene.spatial.query.SpatialOperation#Contains
+ * CONTAINS} the query shape. For use on {@link RecursivePrefixTreeStrategy}.
+ *
+ * @lucene.experimental
+ */
+public class ContainsPrefixTreeQuery extends AbstractPrefixTreeQuery {
+
+  /**
+   * If the spatial data for a document is comprised of multiple overlapping or adjacent parts,
+   * it might fail to match a query shape when doing the CONTAINS predicate when the sum of
+   * those shapes contain the query shape but none do individually.  Set this to false to
+   * increase performance if you don't care about that circumstance (such as if your indexed
+   * data doesn't even have such conditions).  See LUCENE-5062.
+   */
+  protected final boolean multiOverlappingIndexedShapes;
+
+  public ContainsPrefixTreeQuery(Shape queryShape, String fieldName, SpatialPrefixTree grid, int detailLevel, boolean multiOverlappingIndexedShapes) {
+    super(queryShape, fieldName, grid, detailLevel);
+    this.multiOverlappingIndexedShapes = multiOverlappingIndexedShapes;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (!super.equals(o))
+      return false;
+    return multiOverlappingIndexedShapes == ((ContainsPrefixTreeQuery)o).multiOverlappingIndexedShapes;
+  }
+
+  @Override
+  public int hashCode() {
+    return super.hashCode() + (multiOverlappingIndexedShapes ? 1 : 0);
+  }
+
+  @Override
+  public String toString(String field) {
+    return getClass().getSimpleName() + "(" +
+        "fieldName=" + fieldName + "," +
+        "queryShape=" + queryShape + "," +
+        "detailLevel=" + detailLevel + "," +
+        "multiOverlappingIndexedShapes=" + multiOverlappingIndexedShapes +
+        ")";
+  }
+
+  @Override
+  protected DocIdSet getDocIdSet(LeafReaderContext context) throws IOException {
+    return new ContainsVisitor(context).visit(grid.getWorldCell(), null);
+  }
+
+  private class ContainsVisitor extends BaseTermsEnumTraverser {
+
+    public ContainsVisitor(LeafReaderContext context) throws IOException {
+      super(context);
+      if (termsEnum != null) {
+        nextTerm();//advance to first
+      }
+    }
+
+    BytesRef seekTerm = new BytesRef();//temp; see seek()
+    BytesRef thisTerm;//current term in termsEnum
+    Cell indexedCell;//the cell wrapper around thisTerm
+
+    /** This is the primary algorithm; recursive.  Returns null if finds none. */
+    private SmallDocSet visit(Cell cell, Bits acceptContains) throws IOException {
+
+      if (thisTerm == null)//signals all done
+        return null;
+
+      // Get the AND of all child results (into combinedSubResults)
+      SmallDocSet combinedSubResults = null;
+      //   Optimization: use null subCellsFilter when we know cell is within the query shape.
+      Shape subCellsFilter = queryShape;
+      if (cell.getLevel() != 0 && ((cell.getShapeRel() == null || cell.getShapeRel() == SpatialRelation.WITHIN))) {
+        subCellsFilter = null;
+        assert cell.getShape().relate(queryShape) == SpatialRelation.WITHIN;
+      }
+      CellIterator subCells = cell.getNextLevelCells(subCellsFilter);
+      while (subCells.hasNext()) {
+        Cell subCell = subCells.next();
+        if (!seek(subCell)) {
+          combinedSubResults = null;
+        } else if (subCell.getLevel() == detailLevel) {
+          combinedSubResults = getDocs(subCell, acceptContains);
+        } else if (!multiOverlappingIndexedShapes &&
+            subCell.getShapeRel() == SpatialRelation.WITHIN) {
+          combinedSubResults = getLeafDocs(subCell, acceptContains);
+        } else {
+          //OR the leaf docs with all child results
+          SmallDocSet leafDocs = getLeafDocs(subCell, acceptContains);
+          SmallDocSet subDocs = visit(subCell, acceptContains); //recursion
+          combinedSubResults = union(leafDocs, subDocs);
+        }
+
+        if (combinedSubResults == null)
+          break;
+        acceptContains = combinedSubResults;//has the 'AND' effect on next iteration
+      }
+
+      return combinedSubResults;
+    }
+
+    private boolean seek(Cell cell) throws IOException {
+      if (thisTerm == null)
+        return false;
+      final int compare = indexedCell.compareToNoLeaf(cell);
+      if (compare > 0) {
+        return false;//leap-frog effect
+      } else if (compare == 0) {
+        return true; // already there!
+      } else {//compare > 0
+        //seek!
+        seekTerm = cell.getTokenBytesNoLeaf(seekTerm);
+        final TermsEnum.SeekStatus seekStatus = termsEnum.seekCeil(seekTerm);
+        if (seekStatus == TermsEnum.SeekStatus.END) {
+          thisTerm = null;//all done
+          return false;
+        }
+        thisTerm = termsEnum.term();
+        indexedCell = grid.readCell(thisTerm, indexedCell);
+        if (seekStatus == TermsEnum.SeekStatus.FOUND) {
+          return true;
+        }
+        return indexedCell.isLeaf() && indexedCell.compareToNoLeaf(cell) == 0;
+      }
+    }
+
+    /** Get prefix & leaf docs at this cell. */
+    private SmallDocSet getDocs(Cell cell, Bits acceptContains) throws IOException {
+      assert indexedCell.compareToNoLeaf(cell) == 0;
+      //called when we've reached detailLevel.
+      if (indexedCell.isLeaf()) {//only a leaf
+        SmallDocSet result = collectDocs(acceptContains);
+        nextTerm();
+        return result;
+      } else {
+        SmallDocSet docsAtPrefix = collectDocs(acceptContains);
+        if (!nextTerm()) {
+          return docsAtPrefix;
+        }
+        //collect leaf too
+        if (indexedCell.isLeaf() && indexedCell.compareToNoLeaf(cell) == 0) {
+          SmallDocSet docsAtLeaf = collectDocs(acceptContains);
+          nextTerm();
+          return union(docsAtPrefix, docsAtLeaf);
+        } else {
+          return docsAtPrefix;
+        }
+      }
+    }
+
+    /** Gets docs on the leaf of the given cell, _if_ there is a leaf cell, otherwise null. */
+    private SmallDocSet getLeafDocs(Cell cell, Bits acceptContains) throws IOException {
+      assert indexedCell.compareToNoLeaf(cell) == 0;
+      //Advance past prefix if we're at a prefix; return null if no leaf
+      if (!indexedCell.isLeaf()) {
+        if (!nextTerm() || !indexedCell.isLeaf() || indexedCell.getLevel() != cell.getLevel()) {
+          return null;
+        }
+      }
+      SmallDocSet result = collectDocs(acceptContains);
+      nextTerm();
+      return result;
+    }
+
+    private boolean nextTerm() throws IOException {
+      if ((thisTerm = termsEnum.next()) == null)
+        return false;
+      indexedCell = grid.readCell(thisTerm, indexedCell);
+      return true;
+    }
+
+    private SmallDocSet union(SmallDocSet aSet, SmallDocSet bSet) {
+      if (bSet != null) {
+        if (aSet == null)
+          return bSet;
+        return aSet.union(bSet);//union is 'or'
+      }
+      return aSet;
+    }
+
+    private SmallDocSet collectDocs(Bits acceptContains) throws IOException {
+      SmallDocSet set = null;
+
+      postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.NONE);
+      int docid;
+      while ((docid = postingsEnum.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
+        if (acceptContains != null && acceptContains.get(docid) == false) {
+          continue;
+        }
+        if (set == null) {
+          int size = termsEnum.docFreq();
+          if (size <= 0)
+            size = 16;
+          set = new SmallDocSet(size);
+        }
+        set.set(docid);
+      }
+      return set;
+    }
+
+  }//class ContainsVisitor
+
+  /** A hash based mutable set of docIds. If this were Solr code then we might
+   * use a combination of HashDocSet and SortedIntDocSet instead. */
+  // TODO use DocIdSetBuilder?
+  private static class SmallDocSet extends DocIdSet implements Bits {
+
+    private final SentinelIntSet intSet;
+    private int maxInt = 0;
+
+    public SmallDocSet(int size) {
+      intSet = new SentinelIntSet(size, -1);
+    }
+
+    @Override
+    public boolean get(int index) {
+      return intSet.exists(index);
+    }
+
+    public void set(int index) {
+      intSet.put(index);
+      if (index > maxInt)
+        maxInt = index;
+    }
+
+    /** Largest docid. */
+    @Override
+    public int length() {
+      return maxInt;
+    }
+
+    /** Number of docids. */
+    public int size() {
+      return intSet.size();
+    }
+
+    /** NOTE: modifies and returns either "this" or "other" */
+    public SmallDocSet union(SmallDocSet other) {
+      SmallDocSet bigger;
+      SmallDocSet smaller;
+      if (other.intSet.size() > this.intSet.size()) {
+        bigger = other;
+        smaller = this;
+      } else {
+        bigger = this;
+        smaller = other;
+      }
+      //modify bigger
+      for (int v : smaller.intSet.keys) {
+        if (v == smaller.intSet.emptyVal)
+          continue;
+        bigger.set(v);
+      }
+      return bigger;
+    }
+
+    @Override
+    public Bits bits() throws IOException {
+      //if the # of docids is super small, return null since iteration is going
+      // to be faster
+      return size() > 4 ? this : null;
+    }
+
+    @Override
+    public DocIdSetIterator iterator() throws IOException {
+      if (size() == 0)
+        return null;
+      //copy the unsorted values to a new array then sort them
+      int d = 0;
+      final int[] docs = new int[intSet.size()];
+      for (int v : intSet.keys) {
+        if (v == intSet.emptyVal)
+          continue;
+        docs[d++] = v;
+      }
+      assert d == intSet.size();
+      final int size = d;
+
+      //sort them
+      Arrays.sort(docs, 0, size);
+
+      return new DocIdSetIterator() {
+        int idx = -1;
+        @Override
+        public int docID() {
+          if (idx < 0) {
+            return -1;
+          } else if (idx < size) {
+            return docs[idx];
+          } else {
+            return NO_MORE_DOCS;
+          }
+        }
+
+        @Override
+        public int nextDoc() throws IOException {
+          if (++idx < size)
+            return docs[idx];
+          return NO_MORE_DOCS;
+        }
+
+        @Override
+        public int advance(int target) throws IOException {
+          //for this small set this is likely faster vs. a binary search
+          // into the sorted array
+          return slowAdvance(target);
+        }
+
+        @Override
+        public long cost() {
+          return size;
+        }
+      };
+    }
+
+    @Override
+    public long ramBytesUsed() {
+      return RamUsageEstimator.alignObjectSize(
+            RamUsageEstimator.NUM_BYTES_OBJECT_REF
+          + Integer.BYTES)
+          + intSet.ramBytesUsed();
+    }
+
+  }//class SmallDocSet
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java
new file mode 100644
index 0000000..c6700cd
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java
@@ -0,0 +1,310 @@
+/*
+ * 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.prefix;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.SpatialRelation;
+import org.apache.lucene.index.IndexReaderContext;
+import org.apache.lucene.spatial.prefix.tree.Cell;
+import org.apache.lucene.spatial.prefix.tree.CellIterator;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.util.ArrayUtil;
+import org.apache.lucene.util.Bits;
+
+/**
+ * Computes spatial facets in two dimensions as a grid of numbers.  The data is often visualized as a so-called
+ * "heatmap", hence the name.
+ *
+ * @lucene.experimental
+ */
+public class HeatmapFacetCounter {
+  //TODO where should this code live? It could go to PrefixTreeFacetCounter, or maybe here in its own class is fine.
+
+  /** Maximum number of supported rows (or columns). */
+  public static final int MAX_ROWS_OR_COLUMNS = (int) Math.sqrt(ArrayUtil.MAX_ARRAY_LENGTH);
+  static {
+    Math.multiplyExact(MAX_ROWS_OR_COLUMNS, MAX_ROWS_OR_COLUMNS);//will throw if doesn't stay within integer
+  }
+
+  /** Response structure */
+  public static class Heatmap {
+    public final int columns;
+    public final int rows;
+    public final int[] counts;//in order of 1st column (all rows) then 2nd column (all rows) etc.
+    public final Rectangle region;
+
+    public Heatmap(int columns, int rows, Rectangle region) {
+      this.columns = columns;
+      this.rows = rows;
+      this.counts = new int[columns * rows];
+      this.region = region;
+    }
+
+    public int getCount(int x, int y) {
+      return counts[x * rows + y];
+    }
+
+    @Override
+    public String toString() {
+      return "Heatmap{" + columns + "x" + rows + " " + region + '}';
+    }
+  }
+
+  /**
+   * Calculates spatial 2D facets (aggregated counts) in a grid, sometimes called a heatmap.
+   * Facet computation is implemented by navigating the underlying indexed terms efficiently. If you don't know exactly
+   * what facetLevel to go to for a given input box but you have some sense of how many cells there should be relative
+   * to the size of the shape, then consider using the logic that {@link org.apache.lucene.spatial.prefix.PrefixTreeStrategy}
+   * uses when approximating what level to go to when indexing a shape given a distErrPct.
+   *
+   * @param context the IndexReader's context
+   * @param topAcceptDocs a Bits to limit counted docs.  If null, live docs are counted.
+   * @param inputShape the shape to gather grid squares for; typically a {@link Rectangle}.
+   *                   The <em>actual</em> heatmap area will usually be larger since the cells on the edge that overlap
+   *                   are returned. We always return a rectangle of integers even if the inputShape isn't a rectangle
+   *                   -- the non-intersecting cells will all be 0.
+   *                   If null is given, the entire world is assumed.
+   * @param facetLevel the target depth (detail) of cells.
+   * @param maxCells the maximum number of cells to return. If the cells exceed this count, an
+   */
+  public static Heatmap calcFacets(PrefixTreeStrategy strategy, IndexReaderContext context, Bits topAcceptDocs,
+                                   Shape inputShape, final int facetLevel, int maxCells) throws IOException {
+    if (maxCells > (MAX_ROWS_OR_COLUMNS * MAX_ROWS_OR_COLUMNS)) {
+      throw new IllegalArgumentException("maxCells (" + maxCells + ") should be <= " + MAX_ROWS_OR_COLUMNS);
+    }
+    if (inputShape == null) {
+      inputShape = strategy.getSpatialContext().getWorldBounds();
+    }
+    final Rectangle inputRect = inputShape.getBoundingBox();
+    //First get the rect of the cell at the bottom-left at depth facetLevel
+    final SpatialPrefixTree grid = strategy.getGrid();
+    final SpatialContext ctx = grid.getSpatialContext();
+    final Point cornerPt = ctx.makePoint(inputRect.getMinX(), inputRect.getMinY());
+    final CellIterator cellIterator = grid.getTreeCellIterator(cornerPt, facetLevel);
+    Cell cornerCell = null;
+    while (cellIterator.hasNext()) {
+      cornerCell = cellIterator.next();
+    }
+    assert cornerCell != null && cornerCell.getLevel() == facetLevel : "Cell not at target level: " + cornerCell;
+    final Rectangle cornerRect = (Rectangle) cornerCell.getShape();
+    assert cornerRect.hasArea();
+    //Now calculate the number of columns and rows necessary to cover the inputRect
+    double heatMinX = cornerRect.getMinX();//note: we might change this below...
+    final double cellWidth = cornerRect.getWidth();
+    final Rectangle worldRect = ctx.getWorldBounds();
+    final int columns = calcRowsOrCols(cellWidth, heatMinX, inputRect.getWidth(), inputRect.getMinX(), worldRect.getWidth());
+    final double heatMinY = cornerRect.getMinY();
+    final double cellHeight = cornerRect.getHeight();
+    final int rows = calcRowsOrCols(cellHeight, heatMinY, inputRect.getHeight(), inputRect.getMinY(), worldRect.getHeight());
+    assert rows > 0 && columns > 0;
+    if (columns > MAX_ROWS_OR_COLUMNS || rows > MAX_ROWS_OR_COLUMNS || columns * rows > maxCells) {
+      throw new IllegalArgumentException(
+          "Too many cells (" + columns + " x " + rows + ") for level " + facetLevel + " shape " + inputRect);
+    }
+
+    //Create resulting heatmap bounding rectangle & Heatmap object.
+    final double halfCellWidth = cellWidth / 2.0;
+    // if X world-wraps, use world bounds' range
+    if (columns * cellWidth + halfCellWidth > worldRect.getWidth()) {
+      heatMinX = worldRect.getMinX();
+    }
+    double heatMaxX = heatMinX + columns * cellWidth;
+    if (Math.abs(heatMaxX - worldRect.getMaxX()) < halfCellWidth) {//numeric conditioning issue
+      heatMaxX = worldRect.getMaxX();
+    } else if (heatMaxX > worldRect.getMaxX()) {//wraps dateline (won't happen if !geo)
+      heatMaxX = heatMaxX - worldRect.getMaxX() +  worldRect.getMinX();
+    }
+    final double halfCellHeight = cellHeight / 2.0;
+    double heatMaxY = heatMinY + rows * cellHeight;
+    if (Math.abs(heatMaxY - worldRect.getMaxY()) < halfCellHeight) {//numeric conditioning issue
+      heatMaxY = worldRect.getMaxY();
+    }
+
+    final Heatmap heatmap = new Heatmap(columns, rows, ctx.makeRectangle(heatMinX, heatMaxX, heatMinY, heatMaxY));
+
+    //All ancestor cell counts (of facetLevel) will be captured during facet visiting and applied later. If the data is
+    // just points then there won't be any ancestors.
+    //Facet count of ancestors covering all of the heatmap:
+    int[] allCellsAncestorCount = new int[1]; // single-element array so it can be accumulated in the inner class
+    //All other ancestors:
+    Map<Rectangle,Integer> ancestors = new HashMap<>();
+
+    //Now lets count some facets!
+    PrefixTreeFacetCounter.compute(strategy, context, topAcceptDocs, inputShape, facetLevel,
+        new PrefixTreeFacetCounter.FacetVisitor() {
+      @Override
+      public void visit(Cell cell, int count) {
+        final double heatMinX = heatmap.region.getMinX();
+        final Rectangle rect = (Rectangle) cell.getShape();
+        if (cell.getLevel() == facetLevel) {//heatmap level; count it directly
+          //convert to col & row
+          int column;
+          if (rect.getMinX() >= heatMinX) {
+            column = (int) Math.round((rect.getMinX() - heatMinX) / cellWidth);
+          } else { // due to dateline wrap
+            column = (int) Math.round((rect.getMinX() + 360 - heatMinX) / cellWidth);
+          }
+          int row = (int) Math.round((rect.getMinY() - heatMinY) / cellHeight);
+          //note: unfortunately, it's possible for us to visit adjacent cells to the heatmap (if the SpatialPrefixTree
+          // allows adjacent cells to overlap on the seam), so we need to skip them
+          if (column < 0 || column >= heatmap.columns || row < 0 || row >= heatmap.rows) {
+            return;
+          }
+          // increment
+          heatmap.counts[column * heatmap.rows + row] += count;
+
+        } else if (rect.relate(heatmap.region) == SpatialRelation.CONTAINS) {//containing ancestor
+          allCellsAncestorCount[0] += count;
+
+        } else { // ancestor
+          // note: not particularly efficient (possible put twice, and Integer wrapper); oh well
+          Integer existingCount = ancestors.put(rect, count);
+          if (existingCount != null) {
+            ancestors.put(rect, count + existingCount);
+          }
+        }
+      }
+    });
+
+    //Update the heatmap counts with ancestor counts
+
+    // Apply allCellsAncestorCount
+    if (allCellsAncestorCount[0] > 0) {
+      for (int i = 0; i < heatmap.counts.length; i++) {
+        heatmap.counts[i] += allCellsAncestorCount[0];
+      }
+    }
+
+    // Apply ancestors
+    //  note: This approach isn't optimized for a ton of ancestor cells. We'll potentially increment the same cells
+    //    multiple times in separate passes if any ancestors overlap. IF this poses a problem, we could optimize it
+    //    with additional complication by keeping track of intervals in a sorted tree structure (possible TreeMap/Set)
+    //    and iterate them cleverly such that we just make one pass at this stage.
+
+    int[] pair = new int[2];//output of intersectInterval
+    for (Map.Entry<Rectangle, Integer> entry : ancestors.entrySet()) {
+      Rectangle rect = entry.getKey();
+      final int count = entry.getValue();
+      //note: we approach this in a way that eliminates int overflow/underflow (think huge cell, tiny heatmap)
+      intersectInterval(heatMinY, heatMaxY, cellHeight, rows, rect.getMinY(), rect.getMaxY(), pair);
+      final int startRow = pair[0];
+      final int endRow = pair[1];
+
+      if (!heatmap.region.getCrossesDateLine()) {
+        intersectInterval(heatMinX, heatMaxX, cellWidth, columns, rect.getMinX(), rect.getMaxX(), pair);
+        final int startCol = pair[0];
+        final int endCol = pair[1];
+        incrementRange(heatmap, startCol, endCol, startRow, endRow, count);
+
+      } else {
+        //left half of dateline:
+        if (rect.getMaxX() >= heatMinX) {
+          final int leftColumns = (int) Math.round((180 - heatMinX) / cellWidth) + 1;
+          intersectInterval(heatMinX, 180, cellWidth, leftColumns, rect.getMinX(), rect.getMaxX(), pair);
+          final int startCol = pair[0];
+          final int endCol = pair[1];
+          incrementRange(heatmap, startCol, endCol, startRow, endRow, count);
+        }
+        //right half of dateline
+        if (rect.getMinY() <= heatMaxX) {
+          final int rightColumns = (int) Math.round(heatMaxX / cellWidth) + 1;
+          intersectInterval(0, heatMaxX, cellWidth, rightColumns, rect.getMinX(), rect.getMaxX(), pair);
+          final int startCol = pair[0];
+          final int endCol = pair[1];
+          incrementRange(heatmap, startCol, endCol, startRow, endRow, count);
+        }
+      }
+
+    }
+
+    return heatmap;
+  }
+
+  private static void intersectInterval(double heatMin, double heatMax, double heatCellLen, int heatLen,
+                                        double cellMin, double cellMax,
+                                        int[] out) {
+    //precondition: we know there's an intersection
+    if (heatMin >= cellMin) {
+      out[0] = 0;
+    } else {
+      out[0] = (int) Math.round((cellMin - heatMin) / heatCellLen);
+    }
+    if (heatMax <= cellMax) {
+      out[1] = heatLen - 1;
+    } else {
+      out[1] = (int) Math.round((cellMax - heatMin) / heatCellLen) - 1;
+    }
+  }
+
+  private static void incrementRange(Heatmap heatmap, int startColumn, int endColumn, int startRow, int endRow,
+                                     int count) {
+    //startColumn & startRow are not necessarily within the heatmap range; likewise numRows/columns may overlap.
+    if (startColumn < 0) {
+      endColumn += startColumn;
+      startColumn = 0;
+    }
+    endColumn = Math.min(heatmap.columns-1, endColumn);
+
+    if (startRow < 0) {
+      endRow += startRow;
+      startRow = 0;
+    }
+    endRow = Math.min(heatmap.rows-1, endRow);
+
+    if (startRow > endRow) {
+      return;//short-circuit
+    }
+    for (int c = startColumn; c <= endColumn; c++) {
+      int cBase = c * heatmap.rows;
+      for (int r = startRow; r <= endRow; r++) {
+        heatmap.counts[cBase + r] += count;
+      }
+    }
+  }
+
+  /** Computes the number of intervals (rows or columns) to cover a range given the sizes. */
+  private static int calcRowsOrCols(double cellRange, double cellMin, double requestRange, double requestMin,
+                                    double worldRange) {
+    assert requestMin >= cellMin;
+    //Idealistically this wouldn't be so complicated but we concern ourselves with overflow and edge cases
+    double range = (requestRange + (requestMin - cellMin));
+    if (range == 0) {
+      return 1;
+    }
+    final double intervals = Math.ceil(range / cellRange);
+    if (intervals > Integer.MAX_VALUE) {
+      return Integer.MAX_VALUE;//should result in an error soon (exceed thresholds)
+    }
+    // ensures we don't have more intervals than world bounds (possibly due to rounding/edge issue)
+    final long intervalsMax = Math.round(worldRange / cellRange);
+    if (intervalsMax > Integer.MAX_VALUE) {
+      //just return intervals
+      return (int) intervals;
+    }
+    return Math.min((int)intervalsMax, (int)intervals);
+  }
+
+  private HeatmapFacetCounter() {
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/IntersectsPrefixTreeQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/IntersectsPrefixTreeQuery.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/IntersectsPrefixTreeQuery.java
new file mode 100644
index 0000000..ccb0f89
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/IntersectsPrefixTreeQuery.java
@@ -0,0 +1,95 @@
+/*
+ * 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.prefix;
+
+import java.io.IOException;
+
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.SpatialRelation;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.search.DocIdSet;
+import org.apache.lucene.spatial.prefix.tree.Cell;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.util.BitDocIdSet;
+import org.apache.lucene.util.FixedBitSet;
+
+/**
+ * A Query matching documents that have an {@link SpatialRelation#INTERSECTS}
+ * (i.e. not DISTINCT) relationship with a provided query shape.
+ *
+ * @lucene.internal
+ */
+public class IntersectsPrefixTreeQuery extends AbstractVisitingPrefixTreeQuery {
+
+  public IntersectsPrefixTreeQuery(Shape queryShape, String fieldName,
+                                   SpatialPrefixTree grid, int detailLevel,
+                                   int prefixGridScanLevel) {
+    super(queryShape, fieldName, grid, detailLevel, prefixGridScanLevel);
+  }
+
+  @Override
+  protected DocIdSet getDocIdSet(LeafReaderContext context) throws IOException {
+    /* Possible optimizations (in IN ADDITION TO THOSE LISTED IN VISITORTEMPLATE):
+
+    * If docFreq is 1 (or < than some small threshold), then check to see if we've already
+      collected it; if so short-circuit. Don't do this just for point data, as there is
+      no benefit, or only marginal benefit when multi-valued.
+
+    * Point query shape optimization when the only indexed data is a point (no leaves).  Result is a term query.
+
+     */
+    return new VisitorTemplate(context) {
+      private FixedBitSet results;
+
+      @Override
+      protected void start() {
+        results = new FixedBitSet(maxDoc);
+      }
+
+      @Override
+      protected DocIdSet finish() {
+        return new BitDocIdSet(results);
+      }
+
+      @Override
+      protected boolean visitPrefix(Cell cell) throws IOException {
+        if (cell.getShapeRel() == SpatialRelation.WITHIN || cell.getLevel() == detailLevel) {
+          collectDocs(results);
+          return false;
+        }
+        return true;
+      }
+
+      @Override
+      protected void visitLeaf(Cell cell) throws IOException {
+        collectDocs(results);
+      }
+
+    }.getDocIdSet();
+  }
+
+  @Override
+  public String toString(String field) {
+    return getClass().getSimpleName() + "(" +
+        "fieldName=" + fieldName + "," +
+        "queryShape=" + queryShape + "," +
+        "detailLevel=" + detailLevel + "," +
+        "prefixGridScanLevel=" + prefixGridScanLevel +
+        ")";
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/NumberRangePrefixTreeStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/NumberRangePrefixTreeStrategy.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/NumberRangePrefixTreeStrategy.java
new file mode 100644
index 0000000..8001c82
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/NumberRangePrefixTreeStrategy.java
@@ -0,0 +1,199 @@
+/*
+ * 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.prefix;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.index.IndexReaderContext;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.spatial.prefix.tree.Cell;
+import org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree;
+import org.apache.lucene.util.Bits;
+
+import static org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape;
+
+/** A PrefixTree based on Number/Date ranges. This isn't very "spatial" on the surface (to the user) but
+ * it's implemented using spatial so that's why it's here extending a SpatialStrategy. When using this class, you will
+ * use various utility methods on the prefix tree implementation to convert objects/strings to/from shapes.
+ *
+ * To use with dates, pass in {@link org.apache.lucene.spatial.prefix.tree.DateRangePrefixTree}.
+ *
+ * @lucene.experimental
+ */
+public class NumberRangePrefixTreeStrategy extends RecursivePrefixTreeStrategy {
+
+  public NumberRangePrefixTreeStrategy(NumberRangePrefixTree prefixTree, String fieldName) {
+    super(prefixTree, fieldName);
+    setPruneLeafyBranches(false);
+    setPrefixGridScanLevel(prefixTree.getMaxLevels()-2);//user might want to change, however
+    setPointsOnly(false);
+    setDistErrPct(0);
+  }
+
+  @Override
+  public NumberRangePrefixTree getGrid() {
+    return (NumberRangePrefixTree) super.getGrid();
+  }
+
+  @Override
+  protected Iterator<Cell> createCellIteratorToIndex(Shape shape, int detailLevel, Iterator<Cell> reuse) {
+    //levels doesn't actually matter; NumberRange based Shapes have their own "level".
+    return super.createCellIteratorToIndex(shape, grid.getMaxLevels(), reuse);
+  }
+
+  /** Unsupported. */
+  @Override
+  public ValueSource makeDistanceValueSource(Point queryPoint, double multiplier) {
+    throw new UnsupportedOperationException();
+  }
+
+  /** Calculates facets between {@code start} and {@code end} to a detail level one greater than that provided by the
+   * arguments. For example providing March to October of 2014 would return facets to the day level of those months.
+   * This is just a convenience method.
+   * @see #calcFacets(IndexReaderContext, Bits, Shape, int)
+   */
+  public Facets calcFacets(IndexReaderContext context, Bits topAcceptDocs, UnitNRShape start, UnitNRShape end)
+      throws IOException {
+    Shape facetRange = getGrid().toRangeShape(start, end);
+    int detailLevel = Math.max(start.getLevel(), end.getLevel()) + 1;
+    return calcFacets(context, topAcceptDocs, facetRange, detailLevel);
+  }
+
+  /**
+   * Calculates facets (aggregated counts) given a range shape (start-end span) and a level, which specifies the detail.
+   * To get the level of an existing shape, say a Calendar, call
+   * {@link org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree#toUnitShape(Object)} then call
+   * {@link org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape#getLevel()}.
+   * Facet computation is implemented by navigating the underlying indexed terms efficiently.
+   */
+  public Facets calcFacets(IndexReaderContext context, Bits topAcceptDocs, Shape facetRange, final int level)
+      throws IOException {
+    final Facets facets = new Facets(level);
+    PrefixTreeFacetCounter.compute(this, context, topAcceptDocs, facetRange, level,
+        new PrefixTreeFacetCounter.FacetVisitor() {
+          Facets.FacetParentVal parentFacet;
+          UnitNRShape parentShape;
+
+          @Override
+          public void visit(Cell cell, int count) {
+            if (cell.getLevel() < level - 1) {//some ancestor of parent facet level, direct or distant
+              parentFacet = null;//reset
+              parentShape = null;//reset
+              facets.topLeaves += count;
+            } else if (cell.getLevel() == level - 1) {//parent
+              //set up FacetParentVal
+              setupParent((UnitNRShape) cell.getShape());
+              parentFacet.parentLeaves += count;
+            } else {//at facet level
+              UnitNRShape unitShape = (UnitNRShape) cell.getShape();
+              UnitNRShape unitShapeParent = unitShape.getShapeAtLevel(unitShape.getLevel() - 1);
+              if (parentFacet == null || !parentShape.equals(unitShapeParent)) {
+                setupParent(unitShapeParent);
+              }
+              //lazy init childCounts
+              if (parentFacet.childCounts == null) {
+                parentFacet.childCounts = new int[parentFacet.childCountsLen];
+              }
+              parentFacet.childCounts[unitShape.getValAtLevel(cell.getLevel())] += count;
+            }
+          }
+
+          private void setupParent(UnitNRShape unitShape) {
+            parentShape = unitShape.clone();
+            //Look for existing parentFacet (from previous segment), or create anew if needed
+            parentFacet = facets.parents.get(parentShape);
+            if (parentFacet == null) {//didn't find one; make a new one
+              parentFacet = new Facets.FacetParentVal();
+              parentFacet.childCountsLen = getGrid().getNumSubCells(parentShape);
+              facets.parents.put(parentShape, parentFacet);
+            }
+          }
+        });
+    return facets;
+  }
+
+  /** Facet response information */
+  public static class Facets {
+    //TODO consider a variable-level structure -- more general purpose.
+
+    public Facets(int detailLevel) {
+      this.detailLevel = detailLevel;
+    }
+
+    /** The bottom-most detail-level counted, as requested. */
+    public final int detailLevel;
+
+    /**
+     * The count of documents with ranges that completely spanned the parents of the detail level. In more technical
+     * terms, this is the count of leaf cells 2 up and higher from the bottom. Usually you only care about counts at
+     * detailLevel, and so you will add this number to all other counts below, including to omitted/implied children
+     * counts of 0. If there are no indexed ranges (just instances, i.e. fully specified dates) then this value will
+     * always be 0.
+     */
+    public int topLeaves;
+
+    /** Holds all the {@link FacetParentVal} instances in order of the key. This is sparse; there won't be an
+     * instance if it's count and children are all 0. The keys are {@link org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape} shapes, which can be
+     * converted back to the original Object (i.e. a Calendar) via
+     * {@link NumberRangePrefixTree#toObject(org.apache.lucene.spatial.prefix.tree.NumberRangePrefixTree.UnitNRShape)}. */
+    public final SortedMap<UnitNRShape,FacetParentVal> parents = new TreeMap<>();
+
+    /** Holds a block of detailLevel counts aggregated to their parent level. */
+    public static class FacetParentVal {
+
+      /** The count of ranges that span all of the childCounts.  In more technical terms, this is the number of leaf
+       * cells found at this parent.  Treat this like {@link Facets#topLeaves}. */
+      public int parentLeaves;
+
+      /** The length of {@link #childCounts}. If childCounts is not null then this is childCounts.length, otherwise it
+       * says how long it would have been if it weren't null. */
+      public int childCountsLen;
+
+      /** The detail level counts. It will be null if there are none, and thus they are assumed 0. Most apps, when
+       * presenting the information, will add {@link #topLeaves} and {@link #parentLeaves} to each count. */
+      public int[] childCounts;
+      //assert childCountsLen == childCounts.length
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder buf = new StringBuilder(2048);
+      buf.append("Facets: level=" + detailLevel + " topLeaves=" + topLeaves + " parentCount=" + parents.size());
+      for (Map.Entry<UnitNRShape, FacetParentVal> entry : parents.entrySet()) {
+        buf.append('\n');
+        if (buf.length() > 1000) {
+          buf.append("...");
+          break;
+        }
+        final FacetParentVal pVal = entry.getValue();
+        buf.append(' ').append(entry.getKey()+" leafCount=" + pVal.parentLeaves);
+        if (pVal.childCounts != null) {
+          buf.append(' ').append(Arrays.toString(pVal.childCounts));
+        }
+      }
+      return buf.toString();
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/PointPrefixTreeFieldCacheProvider.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/PointPrefixTreeFieldCacheProvider.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/PointPrefixTreeFieldCacheProvider.java
new file mode 100644
index 0000000..165c418
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/PointPrefixTreeFieldCacheProvider.java
@@ -0,0 +1,48 @@
+/*
+ * 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.prefix;
+
+import com.spatial4j.core.shape.Point;
+import org.apache.lucene.spatial.prefix.tree.Cell;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.spatial.util.ShapeFieldCacheProvider;
+import org.apache.lucene.util.BytesRef;
+
+/**
+ * Implementation of {@link ShapeFieldCacheProvider} designed for {@link PrefixTreeStrategy}s that index points
+ * (AND ONLY POINTS!).
+ *
+ * @lucene.internal
+ */
+public class PointPrefixTreeFieldCacheProvider extends ShapeFieldCacheProvider<Point> {
+
+  private final SpatialPrefixTree grid;
+  private Cell scanCell;//re-used in readShape to save GC
+
+  public PointPrefixTreeFieldCacheProvider(SpatialPrefixTree grid, String shapeField, int defaultSize) {
+    super( shapeField, defaultSize );
+    this.grid = grid;
+  }
+
+  @Override
+  protected Point readShape(BytesRef term) {
+    scanCell = grid.readCell(term, scanCell);
+    if (scanCell.getLevel() == grid.getMaxLevels())
+      return scanCell.getShape().getCenter();
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/PrefixTreeFacetCounter.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/PrefixTreeFacetCounter.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/PrefixTreeFacetCounter.java
new file mode 100644
index 0000000..173c30e
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/PrefixTreeFacetCounter.java
@@ -0,0 +1,201 @@
+/*
+ * 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.prefix;
+
+import java.io.IOException;
+
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.index.IndexReaderContext;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.PostingsEnum;
+import org.apache.lucene.search.DocIdSet;
+import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.spatial.prefix.tree.Cell;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.util.Bits;
+
+/**
+ * Computes facets on cells for {@link org.apache.lucene.spatial.prefix.PrefixTreeStrategy}.
+ * <p>
+ * <em>NOTE:</em> If for a given document and a given field using
+ * {@link org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy}
+ * multiple values are indexed (i.e. multi-valued) and at least one of them is a non-point, then there is a possibility
+ * of double-counting the document in the facet results.  Since each shape is independently turned into grid cells at
+ * a resolution chosen by the shape's size, it's possible they will be indexed at different resolutions.  This means
+ * the document could be present in BOTH the postings for a cell in both its prefix and leaf variants.  To avoid this,
+ * use a single valued field with a {@link com.spatial4j.core.shape.ShapeCollection} (or WKT equivalent).  Or
+ * calculate a suitable level/distErr to index both and call
+ * {@link org.apache.lucene.spatial.prefix.PrefixTreeStrategy#createIndexableFields(com.spatial4j.core.shape.Shape, int)}
+ * with the same value for all shapes for a given document/field.
+ *
+ * @lucene.experimental
+ */
+public class PrefixTreeFacetCounter {
+
+  /** A callback/visitor of facet counts. */
+  public static abstract class FacetVisitor {
+    /** Called at the start of the segment, if there is indexed data. */
+    public void startOfSegment() {}
+
+    /** Called for cells with a leaf, or cells at the target facet level.  {@code count} is greater than zero.
+     * When an ancestor cell is given with non-zero count, the count can be considered to be added to all cells
+     * below. You won't necessarily get a cell at level {@code facetLevel} if the indexed data is courser (bigger).
+     */
+    public abstract void visit(Cell cell, int count);
+  }
+
+  private PrefixTreeFacetCounter() {
+  }
+
+  /**
+   * Computes facets using a callback/visitor style design, allowing flexibility for the caller to determine what to do
+   * with each underlying count.
+   * @param strategy the prefix tree strategy (contains the field reference, grid, max levels)
+   * @param context the IndexReader's context
+   * @param topAcceptDocs a Bits to limit counted docs. If null, live docs are counted.
+   * @param queryShape the shape to limit the range of facet counts to
+   * @param facetLevel the maximum depth (detail) of faceted cells
+   * @param facetVisitor the visitor/callback to receive the counts
+   */
+  public static void compute(PrefixTreeStrategy strategy, IndexReaderContext context, Bits topAcceptDocs,
+                             Shape queryShape, int facetLevel, FacetVisitor facetVisitor)
+      throws IOException {
+    //We collect per-leaf
+    for (final LeafReaderContext leafCtx : context.leaves()) {
+      //determine leaf acceptDocs Bits
+      Bits leafAcceptDocs;
+      if (topAcceptDocs == null) {
+        leafAcceptDocs = leafCtx.reader().getLiveDocs();//filter deleted
+      } else {
+        leafAcceptDocs = new Bits() {
+          @Override
+          public boolean get(int index) {
+            return topAcceptDocs.get(leafCtx.docBase + index);
+          }
+
+          @Override
+          public int length() {
+            return leafCtx.reader().maxDoc();
+          }
+        };
+      }
+
+      compute(strategy, leafCtx, leafAcceptDocs, queryShape, facetLevel, facetVisitor);
+    }
+  }
+
+  /** Lower-level per-leaf segment method. */
+  public static void compute(final PrefixTreeStrategy strategy, final LeafReaderContext context, final Bits acceptDocs,
+                             final Shape queryShape, final int facetLevel, final FacetVisitor facetVisitor)
+      throws IOException {
+    if (acceptDocs != null && acceptDocs.length() != context.reader().maxDoc()) {
+      throw new IllegalArgumentException(
+          "acceptDocs bits length " + acceptDocs.length() +" != leaf maxdoc " + context.reader().maxDoc());
+    }
+    final SpatialPrefixTree tree = strategy.getGrid();
+
+    //scanLevel is an optimization knob of AbstractVisitingPrefixTreeFilter. It's unlikely
+    // another scanLevel would be much faster and it tends to be a risky knob (can help a little, can hurt a ton).
+    // TODO use RPT's configured scan level?  Do we know better here?  Hard to say.
+    final int scanLevel = tree.getMaxLevels();
+    //AbstractVisitingPrefixTreeFilter is a Lucene Filter.  We don't need a filter; we use it for its great prefix-tree
+    // traversal code.  TODO consider refactoring if/when it makes sense (more use cases than this)
+    new AbstractVisitingPrefixTreeQuery(queryShape, strategy.getFieldName(), tree, facetLevel, scanLevel) {
+
+      @Override
+      public String toString(String field) {
+        return "anonPrefixTreeQuery";//un-used
+      }
+
+      @Override
+      public DocIdSet getDocIdSet(LeafReaderContext contexts) throws IOException {
+        assert facetLevel == super.detailLevel;//same thing, FYI. (constant)
+
+        return new VisitorTemplate(context) {
+
+          @Override
+          protected void start() throws IOException {
+            facetVisitor.startOfSegment();
+          }
+
+          @Override
+          protected DocIdSet finish() throws IOException {
+            return null;//unused;
+          }
+
+          @Override
+          protected boolean visitPrefix(Cell cell) throws IOException {
+            // At facetLevel...
+            if (cell.getLevel() == facetLevel) {
+              // Count docs
+              visitLeaf(cell);//we're not a leaf but we treat it as such at facet level
+              return false;//don't descend further; this is enough detail
+            }
+
+            // We optimize for discriminating filters (reflected in acceptDocs) and short-circuit if no
+            // matching docs. We could do this at all levels or never but the closer we get to the facet level, the
+            // higher the probability this is worthwhile. We do when docFreq == 1 because it's a cheap check, especially
+            // due to "pulsing" in the codec.
+            //TODO this opt should move to VisitorTemplate (which contains an optimization TODO to this effect)
+            if (cell.getLevel() == facetLevel - 1 || termsEnum.docFreq() == 1) {
+              if (!hasDocsAtThisTerm()) {
+                return false;
+              }
+            }
+            return true;
+          }
+
+          @Override
+          protected void visitLeaf(Cell cell) throws IOException {
+            final int count = countDocsAtThisTerm();
+            if (count > 0) {
+              facetVisitor.visit(cell, count);
+            }
+          }
+
+          private int countDocsAtThisTerm() throws IOException {
+            if (acceptDocs == null) {
+              return termsEnum.docFreq();
+            }
+            int count = 0;
+            postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.NONE);
+            while (postingsEnum.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
+              if (acceptDocs.get(postingsEnum.docID()) == false) {
+                continue;
+              }
+              count++;
+            }
+            return count;
+          }
+
+          private boolean hasDocsAtThisTerm() throws IOException {
+            if (acceptDocs == null) {
+              return true;
+            }
+            postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.NONE);
+            int nextDoc = postingsEnum.nextDoc();
+            while (nextDoc != DocIdSetIterator.NO_MORE_DOCS && acceptDocs.get(nextDoc) == false) {
+              nextDoc = postingsEnum.nextDoc();
+            }
+            return nextDoc != DocIdSetIterator.NO_MORE_DOCS;
+          }
+
+        }.getDocIdSet();
+      }
+    }.getDocIdSet(context);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java
new file mode 100644
index 0000000..608879b
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java
@@ -0,0 +1,208 @@
+/*
+ * 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.prefix;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.FieldType;
+import org.apache.lucene.index.IndexOptions;
+import org.apache.lucene.index.IndexReaderContext;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.spatial.SpatialStrategy;
+import org.apache.lucene.spatial.prefix.tree.Cell;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.util.ShapeFieldCacheDistanceValueSource;
+import org.apache.lucene.util.Bits;
+
+/**
+ * An abstract SpatialStrategy based on {@link SpatialPrefixTree}. The two
+ * subclasses are {@link RecursivePrefixTreeStrategy} and {@link
+ * TermQueryPrefixTreeStrategy}.  This strategy is most effective as a fast
+ * approximate spatial search filter.
+ * <p>
+ * <b>Characteristics:</b>
+ * <br>
+ * <ul>
+ * <li>Can index any shape; however only {@link RecursivePrefixTreeStrategy}
+ * can effectively search non-point shapes.</li>
+ * <li>Can index a variable number of shapes per field value. This strategy
+ * can do it via multiple calls to {@link #createIndexableFields(com.spatial4j.core.shape.Shape)}
+ * for a document or by giving it some sort of Shape aggregate (e.g. JTS
+ * WKT MultiPoint).  The shape's boundary is approximated to a grid precision.
+ * </li>
+ * <li>Can query with any shape.  The shape's boundary is approximated to a grid
+ * precision.</li>
+ * <li>Only {@link org.apache.lucene.spatial.query.SpatialOperation#Intersects}
+ * is supported.  If only points are indexed then this is effectively equivalent
+ * to IsWithin.</li>
+ * <li>The strategy supports {@link #makeDistanceValueSource(com.spatial4j.core.shape.Point,double)}
+ * even for multi-valued data, so long as the indexed data is all points; the
+ * behavior is undefined otherwise.  However, <em>it will likely be removed in
+ * the future</em> in lieu of using another strategy with a more scalable
+ * implementation.  Use of this call is the only
+ * circumstance in which a cache is used.  The cache is simple but as such
+ * it doesn't scale to large numbers of points nor is it real-time-search
+ * friendly.</li>
+ * </ul>
+ * <p>
+ * <b>Implementation:</b>
+ * <p>
+ * The {@link SpatialPrefixTree} does most of the work, for example returning
+ * a list of terms representing grids of various sizes for a supplied shape.
+ * An important
+ * configuration item is {@link #setDistErrPct(double)} which balances
+ * shape precision against scalability.  See those javadocs.
+ *
+ * @lucene.experimental
+ */
+public abstract class PrefixTreeStrategy extends SpatialStrategy {
+  protected final SpatialPrefixTree grid;
+  private final Map<String, PointPrefixTreeFieldCacheProvider> provider = new ConcurrentHashMap<>();
+  protected int defaultFieldValuesArrayLen = 2;
+  protected double distErrPct = SpatialArgs.DEFAULT_DISTERRPCT;// [ 0 TO 0.5 ]
+  protected boolean pointsOnly = false;//if true, there are no leaves
+
+  public PrefixTreeStrategy(SpatialPrefixTree grid, String fieldName) {
+    super(grid.getSpatialContext(), fieldName);
+    this.grid = grid;
+  }
+
+  public SpatialPrefixTree getGrid() {
+    return grid;
+  }
+
+  /**
+   * A memory hint used by {@link #makeDistanceValueSource(com.spatial4j.core.shape.Point)}
+   * for how big the initial size of each Document's array should be. The
+   * default is 2.  Set this to slightly more than the default expected number
+   * of points per document.
+   */
+  public void setDefaultFieldValuesArrayLen(int defaultFieldValuesArrayLen) {
+    this.defaultFieldValuesArrayLen = defaultFieldValuesArrayLen;
+  }
+
+  public double getDistErrPct() {
+    return distErrPct;
+  }
+
+  /**
+   * The default measure of shape precision affecting shapes at index and query
+   * times. Points don't use this as they are always indexed at the configured
+   * maximum precision ({@link org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree#getMaxLevels()});
+   * this applies to all other shapes. Specific shapes at index and query time
+   * can use something different than this default value.  If you don't set a
+   * default then the default is {@link SpatialArgs#DEFAULT_DISTERRPCT} --
+   * 2.5%.
+   *
+   * @see org.apache.lucene.spatial.query.SpatialArgs#getDistErrPct()
+   */
+  public void setDistErrPct(double distErrPct) {
+    this.distErrPct = distErrPct;
+  }
+
+  public boolean isPointsOnly() {
+    return pointsOnly;
+  }
+
+  /** True if only indexed points shall be supported. There are no "leafs" in such a case, except those
+   * at maximum precision. */
+  public void setPointsOnly(boolean pointsOnly) {
+    this.pointsOnly = pointsOnly;
+  }
+
+  @Override
+  public Field[] createIndexableFields(Shape shape) {
+    double distErr = SpatialArgs.calcDistanceFromErrPct(shape, distErrPct, ctx);
+    return createIndexableFields(shape, distErr);
+  }
+
+  /**
+   * Turns {@link SpatialPrefixTree#getTreeCellIterator(Shape, int)} into a
+   * {@link org.apache.lucene.analysis.TokenStream}.
+   */
+  public Field[] createIndexableFields(Shape shape, double distErr) {
+    int detailLevel = grid.getLevelForDistance(distErr);
+    return createIndexableFields(shape, detailLevel);
+  }
+
+  public Field[] createIndexableFields(Shape shape, int detailLevel) {
+    //TODO re-use TokenStream LUCENE-5776: Subclass Field, put cell iterator there, override tokenStream()
+    Iterator<Cell> cells = createCellIteratorToIndex(shape, detailLevel, null);
+    CellToBytesRefIterator cellToBytesRefIterator = newCellToBytesRefIterator();
+    cellToBytesRefIterator.reset(cells);
+    BytesRefIteratorTokenStream tokenStream = new BytesRefIteratorTokenStream();
+    tokenStream.setBytesRefIterator(cellToBytesRefIterator);
+    Field field = new Field(getFieldName(), tokenStream, FIELD_TYPE);
+    return new Field[]{field};
+  }
+
+  protected CellToBytesRefIterator newCellToBytesRefIterator() {
+    //subclasses could return one that never emits leaves, or does both, or who knows.
+    return new CellToBytesRefIterator();
+  }
+
+  protected Iterator<Cell> createCellIteratorToIndex(Shape shape, int detailLevel, Iterator<Cell> reuse) {
+    if (pointsOnly && !(shape instanceof Point)) {
+      throw new IllegalArgumentException("pointsOnly is true yet a " + shape.getClass() + " is given for indexing");
+    }
+    return grid.getTreeCellIterator(shape, detailLevel);//TODO should take a re-use iterator
+  }
+
+  /* Indexed, tokenized, not stored. */
+  public static final FieldType FIELD_TYPE = new FieldType();
+
+  static {
+    FIELD_TYPE.setTokenized(true);
+    FIELD_TYPE.setOmitNorms(true);
+    FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
+    FIELD_TYPE.freeze();
+  }
+
+  @Override
+  public ValueSource makeDistanceValueSource(Point queryPoint, double multiplier) {
+    PointPrefixTreeFieldCacheProvider p = provider.get( getFieldName() );
+    if( p == null ) {
+      synchronized (this) {//double checked locking idiom is okay since provider is threadsafe
+        p = provider.get( getFieldName() );
+        if (p == null) {
+          p = new PointPrefixTreeFieldCacheProvider(grid, getFieldName(), defaultFieldValuesArrayLen);
+          provider.put(getFieldName(),p);
+        }
+      }
+    }
+
+    return new ShapeFieldCacheDistanceValueSource(ctx, p, queryPoint, multiplier);
+  }
+
+  /**
+   * Computes spatial facets in two dimensions as a grid of numbers.  The data is often visualized as a so-called
+   * "heatmap".
+   *
+   * @see HeatmapFacetCounter#calcFacets(PrefixTreeStrategy, IndexReaderContext, Bits, Shape, int, int)
+   */
+  public HeatmapFacetCounter.Heatmap calcFacets(IndexReaderContext context, Bits topAcceptDocs,
+                                   Shape inputShape, final int facetLevel, int maxCells) throws IOException {
+    return HeatmapFacetCounter.calcFacets(this, context, topAcceptDocs, inputShape, facetLevel, maxCells);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeStrategy.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeStrategy.java
new file mode 100644
index 0000000..68b0449
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeStrategy.java
@@ -0,0 +1,192 @@
+/*
+ * 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.prefix;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.spatial.prefix.tree.Cell;
+import org.apache.lucene.spatial.prefix.tree.CellIterator;
+import org.apache.lucene.spatial.prefix.tree.LegacyCell;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.apache.lucene.spatial.query.UnsupportedSpatialOperation;
+
+/**
+ * A {@link PrefixTreeStrategy} which uses {@link AbstractVisitingPrefixTreeQuery}.
+ * This strategy has support for searching non-point shapes (note: not tested).
+ * Even a query shape with distErrPct=0 (fully precise to the grid) should have
+ * good performance for typical data, unless there is a lot of indexed data
+ * coincident with the shape's edge.
+ *
+ * @lucene.experimental
+ */
+public class RecursivePrefixTreeStrategy extends PrefixTreeStrategy {
+  /* Future potential optimizations:
+
+    Each shape.relate(otherShape) result could be cached since much of the same relations will be invoked when
+    multiple segments are involved. Do this for "complex" shapes, not cheap ones, and don't cache when disjoint to
+    bbox because it's a cheap calc. This is one advantage TermQueryPrefixTreeStrategy has over RPT.
+
+   */
+
+  protected int prefixGridScanLevel;
+
+  //Formerly known as simplifyIndexedCells. Eventually will be removed. Only compatible with RPT
+  // and a LegacyPrefixTree.
+  protected boolean pruneLeafyBranches = true;
+
+  protected boolean multiOverlappingIndexedShapes = true;
+
+  public RecursivePrefixTreeStrategy(SpatialPrefixTree grid, String fieldName) {
+    super(grid, fieldName);
+    prefixGridScanLevel = grid.getMaxLevels() - 4;//TODO this default constant is dependent on the prefix grid size
+  }
+
+  public int getPrefixGridScanLevel() {
+    return prefixGridScanLevel;
+  }
+
+  /**
+   * Sets the grid level [1-maxLevels] at which indexed terms are scanned brute-force
+   * instead of by grid decomposition.  By default this is maxLevels - 4.  The
+   * final level, maxLevels, is always scanned.
+   *
+   * @param prefixGridScanLevel 1 to maxLevels
+   */
+  public void setPrefixGridScanLevel(int prefixGridScanLevel) {
+    //TODO if negative then subtract from maxlevels
+    this.prefixGridScanLevel = prefixGridScanLevel;
+  }
+
+  public boolean isMultiOverlappingIndexedShapes() {
+    return multiOverlappingIndexedShapes;
+  }
+
+  /** See {@link ContainsPrefixTreeQuery#multiOverlappingIndexedShapes}. */
+  public void setMultiOverlappingIndexedShapes(boolean multiOverlappingIndexedShapes) {
+    this.multiOverlappingIndexedShapes = multiOverlappingIndexedShapes;
+  }
+
+  public boolean isPruneLeafyBranches() {
+    return pruneLeafyBranches;
+  }
+
+  /**
+   * An optional hint affecting non-point shapes: it will
+   * prune away a complete set sibling leaves to their parent (recursively), resulting in ~20-50%
+   * fewer indexed cells, and consequently that much less disk and that much faster indexing.
+   * So if it's a quad tree and all 4 sub-cells are there marked as a leaf, then they will be
+   * removed (pruned) and the parent is marked as a leaf instead.  This occurs recursively on up.  Unfortunately, the
+   * current implementation will buffer all cells to do this, so consider disabling for high precision (low distErrPct)
+   * shapes. (default=true)
+   */
+  public void setPruneLeafyBranches(boolean pruneLeafyBranches) {
+    this.pruneLeafyBranches = pruneLeafyBranches;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder str = new StringBuilder(getClass().getSimpleName()).append('(');
+    str.append("SPG:(").append(grid.toString()).append(')');
+    if (pointsOnly)
+      str.append(",pointsOnly");
+    if (pruneLeafyBranches)
+      str.append(",pruneLeafyBranches");
+    if (prefixGridScanLevel != grid.getMaxLevels() - 4)
+      str.append(",prefixGridScanLevel:").append(""+prefixGridScanLevel);
+    if (!multiOverlappingIndexedShapes)
+      str.append(",!multiOverlappingIndexedShapes");
+    return str.append(')').toString();
+  }
+
+  @Override
+  protected Iterator<Cell> createCellIteratorToIndex(Shape shape, int detailLevel, Iterator<Cell> reuse) {
+    if (shape instanceof Point || !pruneLeafyBranches)
+      return super.createCellIteratorToIndex(shape, detailLevel, reuse);
+
+    List<Cell> cells = new ArrayList<>(4096);
+    recursiveTraverseAndPrune(grid.getWorldCell(), shape, detailLevel, cells);
+    return cells.iterator();
+  }
+
+  /** Returns true if cell was added as a leaf. If it wasn't it recursively descends. */
+  private boolean recursiveTraverseAndPrune(Cell cell, Shape shape, int detailLevel, List<Cell> result) {
+    // Important: this logic assumes Cells don't share anything with other cells when
+    // calling cell.getNextLevelCells(). This is only true for LegacyCell.
+    if (!(cell instanceof LegacyCell))
+      throw new IllegalStateException("pruneLeafyBranches must be disabled for use with grid "+grid);
+
+    if (cell.getLevel() == detailLevel) {
+      cell.setLeaf();//FYI might already be a leaf
+    }
+    if (cell.isLeaf()) {
+      result.add(cell);
+      return true;
+    }
+    if (cell.getLevel() != 0)
+      result.add(cell);
+
+    int leaves = 0;
+    CellIterator subCells = cell.getNextLevelCells(shape);
+    while (subCells.hasNext()) {
+      Cell subCell = subCells.next();
+      if (recursiveTraverseAndPrune(subCell, shape, detailLevel, result))
+        leaves++;
+    }
+    //can we prune?
+    if (leaves == ((LegacyCell)cell).getSubCellsSize() && cell.getLevel() != 0) {
+      //Optimization: substitute the parent as a leaf instead of adding all
+      // children as leaves
+
+      //remove the leaves
+      do {
+        result.remove(result.size() - 1);//remove last
+      } while (--leaves > 0);
+      //add cell as the leaf
+      cell.setLeaf();
+      return true;
+    }
+    return false;
+  }
+
+  @Override
+  public Query makeQuery(SpatialArgs args) {
+    final SpatialOperation op = args.getOperation();
+
+    Shape shape = args.getShape();
+    int detailLevel = grid.getLevelForDistance(args.resolveDistErr(ctx, distErrPct));
+
+    if (op == SpatialOperation.Intersects) {
+      return new IntersectsPrefixTreeQuery(
+          shape, getFieldName(), grid, detailLevel, prefixGridScanLevel);
+    } else if (op == SpatialOperation.IsWithin) {
+      return new WithinPrefixTreeQuery(
+          shape, getFieldName(), grid, detailLevel, prefixGridScanLevel,
+          -1);//-1 flag is slower but ensures correct results
+    } else if (op == SpatialOperation.Contains) {
+      return new ContainsPrefixTreeQuery(shape, getFieldName(), grid, detailLevel,
+          multiOverlappingIndexedShapes);
+    }
+    throw new UnsupportedSpatialOperation(op);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/TermQueryPrefixTreeStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/TermQueryPrefixTreeStrategy.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/TermQueryPrefixTreeStrategy.java
new file mode 100644
index 0000000..a74786b
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/TermQueryPrefixTreeStrategy.java
@@ -0,0 +1,111 @@
+/*
+ * 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.prefix;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.queries.TermsQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.spatial.prefix.tree.Cell;
+import org.apache.lucene.spatial.prefix.tree.CellIterator;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.apache.lucene.spatial.query.UnsupportedSpatialOperation;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.BytesRefBuilder;
+
+/**
+ * A basic implementation of {@link PrefixTreeStrategy} using a large
+ * {@link TermsQuery} of all the cells from
+ * {@link SpatialPrefixTree#getTreeCellIterator(com.spatial4j.core.shape.Shape, int)}.
+ * It only supports the search of indexed Point shapes.
+ * <p>
+ * The precision of query shapes (distErrPct) is an important factor in using
+ * this Strategy. If the precision is too precise then it will result in many
+ * terms which will amount to a slower query.
+ *
+ * @lucene.experimental
+ */
+public class TermQueryPrefixTreeStrategy extends PrefixTreeStrategy {
+
+  protected boolean simplifyIndexedCells = false;
+
+  public TermQueryPrefixTreeStrategy(SpatialPrefixTree grid, String fieldName) {
+    super(grid, fieldName);
+  }
+
+  @Override
+  protected CellToBytesRefIterator newCellToBytesRefIterator() {
+    //Ensure we don't have leaves, as this strategy doesn't handle them.
+    return new CellToBytesRefIterator() {
+      @Override
+      public BytesRef next() {
+        if (!cellIter.hasNext()) {
+          return null;
+        }
+        return cellIter.next().getTokenBytesNoLeaf(bytesRef);
+      }
+    };
+  }
+
+  @Override
+  public Query makeQuery(SpatialArgs args) {
+    final SpatialOperation op = args.getOperation();
+    if (op != SpatialOperation.Intersects)
+      throw new UnsupportedSpatialOperation(op);
+
+    Shape shape = args.getShape();
+    int detailLevel = grid.getLevelForDistance(args.resolveDistErr(ctx, distErrPct));
+
+    //--get a List of BytesRef for each term we want (no parents, no leaf bytes))
+    final int GUESS_NUM_TERMS;
+    if (shape instanceof Point)
+      GUESS_NUM_TERMS = detailLevel;//perfect guess
+    else
+      GUESS_NUM_TERMS = 4096;//should this be a method on SpatialPrefixTree?
+
+    BytesRefBuilder masterBytes = new BytesRefBuilder();//shared byte array for all terms
+    List<BytesRef> terms = new ArrayList<>(GUESS_NUM_TERMS);
+
+    CellIterator cells = grid.getTreeCellIterator(shape, detailLevel);
+    while (cells.hasNext()) {
+      Cell cell = cells.next();
+      if (!cell.isLeaf())
+        continue;
+      BytesRef term = cell.getTokenBytesNoLeaf(null);//null because we want a new BytesRef
+      //We copy out the bytes because it may be re-used across the iteration. This also gives us the opportunity
+      // to use one contiguous block of memory for the bytes of all terms we need.
+      masterBytes.grow(masterBytes.length() + term.length);
+      masterBytes.append(term);
+      term.bytes = null;//don't need; will reset later
+      term.offset = masterBytes.length() - term.length;
+      terms.add(term);
+    }
+    //doing this now because if we did earlier, it's possible the bytes needed to grow()
+    for (BytesRef byteRef : terms) {
+      byteRef.bytes = masterBytes.bytes();
+    }
+    //unfortunately TermsQuery will needlessly sort & dedupe
+    //TODO an automatonQuery might be faster?
+    return new TermsQuery(getFieldName(), terms);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/WithinPrefixTreeQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/WithinPrefixTreeQuery.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/WithinPrefixTreeQuery.java
new file mode 100644
index 0000000..cf0d11b
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/WithinPrefixTreeQuery.java
@@ -0,0 +1,232 @@
+/*
+ * 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.prefix;
+
+import java.io.IOException;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.distance.DistanceUtils;
+import com.spatial4j.core.shape.Circle;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.SpatialRelation;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.search.DocIdSet;
+import org.apache.lucene.spatial.prefix.tree.Cell;
+import org.apache.lucene.spatial.prefix.tree.CellIterator;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.util.BitDocIdSet;
+import org.apache.lucene.util.FixedBitSet;
+
+/**
+ * Finds docs where its indexed shape is {@link org.apache.lucene.spatial.query.SpatialOperation#IsWithin
+ * WITHIN} the query shape.  It works by looking at cells outside of the query
+ * shape to ensure documents there are excluded. By default, it will
+ * examine all cells, and it's fairly slow.  If you know that the indexed shapes
+ * are never comprised of multiple disjoint parts (which also means it is not multi-valued),
+ * then you can pass {@code SpatialPrefixTree.getDistanceForLevel(maxLevels)} as
+ * the {@code queryBuffer} constructor parameter to minimally look this distance
+ * beyond the query shape's edge.  Even if the indexed shapes are sometimes
+ * comprised of multiple disjoint parts, you might want to use this option with
+ * a large buffer as a faster approximation with minimal false-positives.
+ *
+ * @lucene.experimental
+ */
+public class WithinPrefixTreeQuery extends AbstractVisitingPrefixTreeQuery {
+  //TODO LUCENE-4869: implement faster algorithm based on filtering out false-positives of a
+  //  minimal query buffer by looking in a DocValues cache holding a representative
+  //  point of each disjoint component of a document's shape(s).
+
+  //TODO Could the recursion in allCellsIntersectQuery() be eliminated when non-fuzzy or other
+  //  circumstances?
+
+  private final Shape bufferedQueryShape;//if null then the whole world
+
+  /**
+   * See {@link AbstractVisitingPrefixTreeQuery#AbstractVisitingPrefixTreeQuery(com.spatial4j.core.shape.Shape, String, org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree, int, int)}.
+   * {@code queryBuffer} is the (minimum) distance beyond the query shape edge
+   * where non-matching documents are looked for so they can be excluded. If
+   * -1 is used then the whole world is examined (a good default for correctness).
+   */
+  public WithinPrefixTreeQuery(Shape queryShape, String fieldName, SpatialPrefixTree grid,
+                               int detailLevel, int prefixGridScanLevel,
+                               double queryBuffer) {
+    super(queryShape, fieldName, grid, detailLevel, prefixGridScanLevel);
+    this.bufferedQueryShape = queryBuffer == -1 ? null : bufferShape(queryShape, queryBuffer);
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (!super.equals(o)) return false;//checks getClass == o.getClass & instanceof
+
+    WithinPrefixTreeQuery that = (WithinPrefixTreeQuery) o;
+
+    if (bufferedQueryShape != null ? !bufferedQueryShape.equals(that.bufferedQueryShape) : that.bufferedQueryShape != null)
+      return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = super.hashCode();
+    result = 31 * result + (bufferedQueryShape != null ? bufferedQueryShape.hashCode() : 0);
+    return result;
+  }
+
+  @Override
+  public String toString(String field) {
+    return getClass().getSimpleName() + "(" +
+             "fieldName=" + fieldName + "," +
+             "queryShape=" + queryShape + "," +
+             "detailLevel=" + detailLevel + "," +
+             "prefixGridScanLevel=" + prefixGridScanLevel +
+           ")";
+  }
+
+  /** Returns a new shape that is larger than shape by at distErr.
+   */
+  //TODO move this generic code elsewhere?  Spatial4j?
+  protected Shape bufferShape(Shape shape, double distErr) {
+    if (distErr <= 0)
+      throw new IllegalArgumentException("distErr must be > 0");
+    SpatialContext ctx = grid.getSpatialContext();
+    if (shape instanceof Point) {
+      return ctx.makeCircle((Point)shape, distErr);
+    } else if (shape instanceof Circle) {
+      Circle circle = (Circle) shape;
+      double newDist = circle.getRadius() + distErr;
+      if (ctx.isGeo() && newDist > 180)
+        newDist = 180;
+      return ctx.makeCircle(circle.getCenter(), newDist);
+    } else {
+      Rectangle bbox = shape.getBoundingBox();
+      double newMinX = bbox.getMinX() - distErr;
+      double newMaxX = bbox.getMaxX() + distErr;
+      double newMinY = bbox.getMinY() - distErr;
+      double newMaxY = bbox.getMaxY() + distErr;
+      if (ctx.isGeo()) {
+        if (newMinY < -90)
+          newMinY = -90;
+        if (newMaxY > 90)
+          newMaxY = 90;
+        if (newMinY == -90 || newMaxY == 90 || bbox.getWidth() + 2*distErr > 360) {
+          newMinX = -180;
+          newMaxX = 180;
+        } else {
+          newMinX = DistanceUtils.normLonDEG(newMinX);
+          newMaxX = DistanceUtils.normLonDEG(newMaxX);
+        }
+      } else {
+        //restrict to world bounds
+        newMinX = Math.max(newMinX, ctx.getWorldBounds().getMinX());
+        newMaxX = Math.min(newMaxX, ctx.getWorldBounds().getMaxX());
+        newMinY = Math.max(newMinY, ctx.getWorldBounds().getMinY());
+        newMaxY = Math.min(newMaxY, ctx.getWorldBounds().getMaxY());
+      }
+      return ctx.makeRectangle(newMinX, newMaxX, newMinY, newMaxY);
+    }
+  }
+
+
+  @Override
+  protected DocIdSet getDocIdSet(LeafReaderContext context) throws IOException {
+    return new VisitorTemplate(context) {
+      private FixedBitSet inside;
+      private FixedBitSet outside;
+
+      @Override
+      protected void start() {
+        inside = new FixedBitSet(maxDoc);
+        outside = new FixedBitSet(maxDoc);
+      }
+
+      @Override
+      protected DocIdSet finish() {
+        inside.andNot(outside);
+        return new BitDocIdSet(inside);
+      }
+
+      @Override
+      protected CellIterator findSubCellsToVisit(Cell cell) {
+        //use buffered query shape instead of orig.  Works with null too.
+        return cell.getNextLevelCells(bufferedQueryShape);
+      }
+
+      @Override
+      protected boolean visitPrefix(Cell cell) throws IOException {
+        //cell.relate is based on the bufferedQueryShape; we need to examine what
+        // the relation is against the queryShape
+        SpatialRelation visitRelation = cell.getShape().relate(queryShape);
+        if (cell.getLevel() == detailLevel) {
+          collectDocs(visitRelation.intersects() ? inside : outside);
+          return false;
+        } else if (visitRelation == SpatialRelation.WITHIN) {
+          collectDocs(inside);
+          return false;
+        } else if (visitRelation == SpatialRelation.DISJOINT) {
+          collectDocs(outside);
+          return false;
+        }
+        return true;
+      }
+
+      @Override
+      protected void visitLeaf(Cell cell) throws IOException {
+        if (allCellsIntersectQuery(cell))
+          collectDocs(inside);
+        else
+          collectDocs(outside);
+      }
+
+      /** Returns true if the provided cell, and all its sub-cells down to
+       * detailLevel all intersect the queryShape.
+       */
+      private boolean allCellsIntersectQuery(Cell cell) {
+        SpatialRelation relate = cell.getShape().relate(queryShape);
+        if (cell.getLevel() == detailLevel)
+          return relate.intersects();
+        if (relate == SpatialRelation.WITHIN)
+          return true;
+        if (relate == SpatialRelation.DISJOINT)
+          return false;
+        // Note: Generating all these cells just to determine intersection is not ideal.
+        // The real solution is LUCENE-4869.
+        CellIterator subCells = cell.getNextLevelCells(null);
+        while (subCells.hasNext()) {
+          Cell subCell = subCells.next();
+          if (!allCellsIntersectQuery(subCell))//recursion
+            return false;
+        }
+        return true;
+      }
+
+      @Override
+      protected void visitScanned(Cell cell) throws IOException {
+        visitLeaf(cell);//collects as we want, even if not a leaf
+//        if (cell.isLeaf()) {
+//          visitLeaf(cell);
+//        } else {
+//          visitPrefix(cell);
+//        }
+      }
+
+    }.getDocIdSet();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/package-info.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/package-info.java
new file mode 100644
index 0000000..b35f8ee
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Prefix Tree Strategy.
+ */
+package org.apache.lucene.spatial.prefix;


[23/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test-files/data/states-poly.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test-files/data/states-poly.txt b/lucene/spatial-extras/src/test-files/data/states-poly.txt
new file mode 100644
index 0000000..e210c39
--- /dev/null
+++ b/lucene/spatial-extras/src/test-files/data/states-poly.txt
@@ -0,0 +1,52 @@
+#id	name	shape
+HI	Hawaii	MULTIPOLYGON (((-160.07380334546815 22.00417734795773, -160.0497093454457 21.988164347942817, -160.0898583454831 21.915870347875487, -160.17013734555786 21.867596347830528, -160.20225934558778 21.795308347763203, -160.24240634562517 21.803280347770627, -160.2263363456102 21.891592347852875, -160.121962345513 21.96397834792029, -160.07380334546815 22.00417734795773)), ((-159.33517434478023 21.94834334790573, -159.43954534487744 21.86807134783097, -159.57602134500453 21.88413634784593, -159.64024734506435 21.94836534790575, -159.7365923451541 21.9644203479207, -159.8008143452139 22.036666347987985, -159.71250634513166 22.14905934809266, -159.57601234500453 22.213179348152376, -159.39136734483256 22.229120348167225, -159.34319534478772 22.197016348137325, -159.29502534474284 22.12481234807008, -159.32713034477274 22.044639347995414, -159.33517434478023 21.94834334790573)), ((-157.67333034323252 21.298027347300074, -157.68137134324002 21.273942347277643, -157.7215013432774 21.
 281971347285122, -157.8258713433746 21.249863347255218, -157.89813434344188 21.330144347329988, -157.94630634348675 21.30606134730756, -158.0988333436288 21.290008347292606, -158.13095134365872 21.354232347352422, -158.23531834375592 21.47465234746457, -158.24334234376337 21.538879347524386, -158.26743134378583 21.58704234756924, -158.11489434364375 21.579016347561765, -158.04262634357644 21.675350347651484, -157.98642834352412 21.699433347673914, -157.91417934345682 21.6352083476141, -157.84995934339702 21.506758347494472, -157.80981534335962 21.43450534742718, -157.76164334331477 21.45858734744961, -157.7134723432699 21.386335347382317, -157.67333034323252 21.298027347300074)), ((-156.71787234234267 21.137419347150498, -156.76604834238753 21.065176347083217, -156.88648434249973 21.049134347068275, -157.0711323426717 21.105331347120615, -157.28789734287355 21.081250347098187, -157.3039483428885 21.137448347150524, -157.24774734283616 21.161530347172953, -157.2316943428212 21.233776
 347240237, -157.16747134276142 21.19364034720286, -157.00690334261185 21.18561034719538, -156.9925463425985 21.195420347204514, -156.958733342567 21.209693347217808, -156.94334634255267 21.172778347183428, -156.91424234252557 21.167372347178393, -156.9102143425218 21.158045347169708, -156.71787234234267 21.137419347150498)), ((-157.03905034264181 20.92870734695612, -156.91058634252215 20.92871834695613, -156.80620534242496 20.840418346873893, -156.81422534243242 20.792252346829034, -156.88648734249972 20.736049346776692, -156.9667653425745 20.728020346769213, -156.99086334259692 20.792237346829022, -156.98282634258945 20.832377346866405, -157.05509834265675 20.88053834691126, -157.03905034264181 20.92870734695612)), ((-156.1960453418567 20.631649346679463, -156.27631734193145 20.583484346634606, -156.3967353420436 20.567427346619652, -156.436879342081 20.623621346671985, -156.46097234210342 20.727981346769177, -156.49307434213333 20.792204346828992, -156.52519334216322 20.7761493468
 14037, -156.63758634226792 20.808261346843945, -156.69378234232025 20.91262434694114, -156.65363634228285 21.016985347038336, -156.59743934223053 21.04106434706076, -156.52519134216323 20.984870347008425, -156.47702234211837 20.896565346926185, -156.35660334200622 20.944726346971038, -156.2602633419165 20.928671346956087, -156.0113923416847 20.800225346836463, -155.9873173416623 20.752061346791606, -156.04351134171463 20.655732346701893, -156.13180934179687 20.623623346671987, -156.1960453418567 20.631649346679463)), ((-155.66619234136323 18.92178634508703, -155.7785853414679 19.01009234516927, -155.85886134154265 19.01010134516928, -155.90703134158753 19.130513345281422, -155.87492734155762 19.371358345505726, -155.94717834162492 19.4837503456104, -155.97125834164734 19.628252345744976, -156.04352434171466 19.78078334588703, -155.97930134165483 19.820922345924416, -155.88295834156511 19.933312346029084, -155.82676134151276 20.005563346096373, -155.83478634152024 20.06175734614871, 
 -155.89097834157258 20.174149346253383, -155.85885834154266 20.270479346343098, -155.73844234143053 20.206256346283283, -155.56182634126603 20.134007346216, -155.20055034092957 19.99752834608889, -155.09618534083236 19.877114345976747, -155.07210634080994 19.724585345834694, -154.97576334072022 19.740643345849648, -154.97576234072022 19.652335345767405, -154.79109634054822 19.53996034566275, -154.81518734057067 19.459676345587976, -154.92758134067535 19.41951834555058, -155.01588134075757 19.331211345468336, -155.1523723408847 19.266992345408525, -155.30489934102675 19.23487834537862, -155.52167834122864 19.122484345273943, -155.5377293412436 19.04221034519918, -155.66619234136323 18.92178634508703)))
+WA	Washington	MULTIPOLYGON (((-122.40201531038355 48.22521637237797, -122.4628553104402 48.22836337238091, -122.45441931043234 48.128492372287894, -122.36133331034566 48.06009737222419, -122.51451131048832 48.133973372293, -122.54207431051398 48.21046037236424, -122.5091303104833 48.25379337240459, -122.40440431038577 48.24659437239789, -122.37832031036149 48.28972137243805, -122.56436631053475 48.414246372554025, -122.66703231063036 48.41289537255277, -122.69941331066052 48.4943283726286, -122.60817831057555 48.51882437265142, -122.52322831049644 48.45840337259515, -122.47383331045043 48.46219537259868, -122.50529931047973 48.55944437268925, -122.4295453104092 48.59939737272646, -122.48779831046343 48.63857037276294, -122.52655831049954 48.71172437283107, -122.51685331049049 48.757921372874094, -122.69740431065864 48.80301537291609, -122.75424231071159 48.90998837301572, -122.82242131077507 48.95072537305366, -122.74394031070199 48.95580837305839, -122.76511931072172 48.99974637309
 931, -120.85705930894468 48.99983037309939, -118.84360330706951 48.999898373099455, -118.20035430647044 48.999908373099466, -117.43858030576098 48.999918373099476, -117.03204930538237 48.999931373099486, -117.02911130537964 48.838075372948744, -117.03886830538872 48.04618637221124, -117.03747230538742 47.9710923721413, -117.04179430539145 47.36144137157352, -117.04239230539201 47.25850137147765, -117.04096830539069 47.11931937134803, -117.04192630539157 46.53660137080533, -117.03855830538843 46.42798037070417, -117.04447030539394 46.38857437066747, -117.06418430541231 46.34869837063033, -117.02797330537858 46.33542737061797, -117.00164230535405 46.30244837058726, -116.97272530532712 46.24930937053777, -116.96749030532226 46.19755437048957, -116.9294263052868 46.1654833704597, -116.9616373053168 46.09727437039618, -116.98721130534062 46.0785093703787, -116.95772330531315 46.06568737036676, -116.91913230527722 45.995175370301084, -117.4816633058011 45.99983437030543, -117.602826305913
 95 46.00026837030583, -117.98267730626772 45.99988037030547, -117.99252730627688 46.0016393703071, -118.98213330719852 45.99905837030471, -119.03222130724518 45.96627437027417, -119.14025030734578 45.92570837023639, -119.17874230738164 45.922351370233265, -119.30276330749714 45.932662370242866, -119.37944130756856 45.91761037022885, -119.4388613076239 45.91426837022574, -119.51222030769222 45.8992003702117, -119.58929430776399 45.91331537022485, -119.62211630779456 45.899410370211896, -119.67844530784703 45.852539370168245, -119.83355630799147 45.84160937015807, -119.86973530802518 45.83169837014884, -119.9943203081412 45.81114037012969, -120.06864830821043 45.78020237010088, -120.1559083082917 45.76126137008324, -120.20744530833969 45.71978437004461, -120.28363530841065 45.71658337004163, -120.44338330855942 45.6892793700162, -120.49915630861136 45.695630370022116, -120.57008230867743 45.74091837006429, -120.62375730872742 45.743610370066804, -120.65840330875969 45.73261237005656, 
 -120.69699430879562 45.71050937003597, -120.86141930894875 45.66518636999376, -120.90793730899208 45.6354773699661, -120.94857330902992 45.65031636997991, -120.96847830904846 45.6451543699751, -121.033482309109 45.65284436998227, -121.07353030914629 45.64661036997646, -121.12520430919443 45.60705936993963, -121.17431630924017 45.60051636993353, -121.19205430925669 45.61324236994538, -121.20330830926716 45.657287369986406, -121.21427130927736 45.66564536999419, -121.27639130933522 45.67834037000601, -121.31997730937582 45.696642370023056, -121.36781430942037 45.699686370025894, -121.42202930947087 45.690603370017435, -121.44255230948997 45.6949673700215, -121.52905430957054 45.71956737004441, -121.70641730973571 45.688793370015745, -121.7586943097844 45.68971637001661, -121.81104130983316 45.70068337002682, -121.88828330990509 45.67685637000463, -121.92682030994098 45.642028369972195, -121.97265930998367 45.63577636996637, -122.00001131000914 45.61782436994965, -122.08203731008555 45
 .590504369924204, -122.24492231023724 45.54811236988473, -122.30315031029147 45.54309236988006, -122.35645731034111 45.56617136990155, -122.43715431041628 45.56477936990025, -122.56542931053573 45.59481836992823, -122.65120931061563 45.606830369939416, -122.69632331065765 45.63104536996197, -122.76054131071746 45.649397369979056, -122.77255131072863 45.72768537005197, -122.76428831072094 45.760568370082595, -122.78800931074304 45.800343370119634, -122.78451631073978 45.8504493701663, -122.78407331073936 45.867886370182546, -122.80622331076 45.90407237021624, -122.8077413107614 45.94389037025333, -122.87541731082445 46.0271833703309, -122.89975731084711 46.07932937037946, -122.97416931091641 46.110483370408474, -123.05059631098759 46.155736370450626, -123.11855431105087 46.17931037047258, -123.17619631110456 46.18358637047656, -123.2124373111383 46.17000637046391, -123.24879931117218 46.14402037043971, -123.30471731122425 46.14473737044038, -123.4707733113789 46.27502337056171, -123.
 62007631151795 46.25866537054648, -123.7254593116161 46.28542337057141, -123.88577131176541 46.2404383705295, -123.99332931186558 46.31027437059455, -124.07910731194546 46.267259370554484, -124.0655103119328 46.639745370901394, -124.02304331189325 46.58354137084905, -124.0130023118839 46.383680370662915, -123.84145131172413 46.404343370682156, -123.94069331181655 46.481115370753656, -123.89356731177267 46.51107937078156, -123.95771231183241 46.61722537088042, -123.92647031180331 46.67306037093242, -123.84096631172368 46.71828837097454, -123.8955423117745 46.7449863709994, -124.04315831191198 46.71585537097228, -124.09104931195658 46.72902237098454, -124.10206731196683 46.78946937104083, -124.13882731200107 46.89998537114376, -124.10576031197029 46.908148371151356, -124.10473831196933 46.874145371119695, -124.02880831189862 46.823767371072776, -124.04692931191549 46.887253371131905, -123.81265531169731 46.963965371203344, -123.99586431186793 46.97638537121491, -124.03439431190381 47.
 031033371265806, -124.11236131197643 47.042675371276644, -124.16203631202269 46.92961237117135, -124.19273331205127 47.16698237139242, -124.23142531208731 47.275070371493086, -124.31942731216927 47.34923837156216, -124.34908031219689 47.526910371727624, -124.37360531221972 47.6387633718318, -124.48403531232259 47.80825537198965, -124.60668531243681 47.87373537205063, -124.73276931255424 48.149989372307914, -124.70520931252857 48.23199637238429, -124.71717531253971 48.37755737251986, -124.56354731239662 48.35727837250097, -123.99121531186361 48.15916137231646, -123.39685731131007 48.11103037227163, -123.12322231105523 48.14873337230675, -122.92159431086745 48.09417937225594, -122.92484431087047 48.066796372230435, -122.84111131079248 48.13313637229222, -122.76888231072522 48.14399437230233, -122.80293131075693 48.08532137224769, -122.66156031062528 47.91715737209107, -122.65358531061784 47.86443137204197, -122.7458703107038 47.80898837199034, -122.7898013107447 47.80254837198434, -12
 2.80951731076306 47.85707537203512, -122.85880431080896 47.827328372007415, -122.89936331084674 47.672517371863236, -122.9827443109244 47.605474371800796, -123.11391531104655 47.45627337166184, -123.15406031108395 47.348547371561516, -123.01047131095021 47.35302737156569, -122.83324731078517 47.43846437164525, -123.03620631097418 47.3560513715685, -123.11268531104541 47.37156937158295, -123.026336310965 47.51593637171741, -122.91696931086314 47.6146063718093, -122.75294231071038 47.66068837185222, -122.72306231068254 47.75689937194182, -122.61116231057832 47.85000837202854, -122.61321731058024 47.9361893721088, -122.5318883105045 47.90946137208391, -122.4735883104502 47.754980371940036, -122.62150931058797 47.69696837188601, -122.58646031055532 47.57119137176887, -122.55526231052627 47.58350537178033, -122.54270231051457 47.52273437172374, -122.50446131047896 47.50721637170929, -122.55844631052923 47.398363371607914, -122.5441253105159 47.373927371585154, -122.588254310557 47.333929
 371547896, -122.55315631052432 47.28333237150078, -122.5805303105498 47.251387371471026, -122.61154631057869 47.29339837151015, -122.60691431057438 47.2705713714889, -122.69974431066083 47.29208537150893, -122.62875431059472 47.39855337160809, -122.6374363106028 47.39858037160811, -122.74154931069975 47.341450371554906, -122.76970831072599 47.26615637148478, -122.71980131067951 47.22313137144471, -122.7612383107181 47.162496371388244, -122.82510831077758 47.234826371455604, -122.77333531072937 47.3373603715511, -122.80218431075623 47.360740371572874, -122.88037331082904 47.299233371515584, -123.11543631104797 47.207981371430606, -123.08120031101609 47.09005837132078, -123.03134831096966 47.10077437133076, -122.92315031086889 47.04796337128157, -122.79004831074494 47.125859371354125, -122.72818631068732 47.082441371313685, -122.70007931066114 47.09832537132848, -122.5918063105603 47.18006037140459, -122.53076331050346 47.28745637150462, -122.54658831051819 47.31627637153146, -122.424
 09431040412 47.25947237147855, -122.39284331037501 47.27772237149556, -122.44160431042042 47.301125371517344, -122.42083731040108 47.31884437153385, -122.32537631031218 47.34432337155758, -122.31973831030692 47.39011537160023, -122.3926333103748 47.5102423717121, -122.38222031036511 47.59540937179142, -122.41481531039547 47.664180371855466, -122.39449231037653 47.77417637195791, -122.30292231029125 47.95021437212186, -122.23012131022347 47.96911337213946, -122.21699231021123 48.007439372175156, -122.36833331035217 48.12814137228757, -122.40201531038355 48.22521637237797)), ((-122.96797831091064 48.44379437258154, -123.09523331102915 48.47942237261472, -123.15972031108922 48.521842372654234, -123.1698993110987 48.56256437269215, -123.14105331107183 48.62364737274905, -123.10372131103706 48.60837737273482, -123.01209531095174 48.557477372687416, -123.00869831094857 48.53371937266529, -122.96798031091063 48.526933372658974, -123.0222713109612 48.513359372646335, -123.01888331095805 48.
 48960537262421, -122.96797831091064 48.44379437258154)), ((-122.73318731069197 48.27664737242587, -122.66561231062904 48.396777372537755, -122.60438431057202 48.40478937254522, -122.52575031049878 48.32104337246722, -122.52864831050148 48.28351037243227, -122.62350931058984 48.29635037244422, -122.73203431069089 48.22541437237816, -122.61092531057811 48.20632137236038, -122.54620231051783 48.07685837223981, -122.49621231047126 48.09407137225584, -122.37999431036303 48.03214637219817, -122.35540031034013 47.963886372134596, -122.38696131036953 47.90454937207933, -122.44278831042152 47.91805637209191, -122.47161631044837 47.987509372156595, -122.54496131051667 47.967531372137984, -122.60862831057597 48.0314303721975, -122.69555431065692 48.18118537233697, -122.76877831072511 48.21881837237201, -122.73318731069197 48.27664737242587)))
+MT	Montana	MULTIPOLYGON (((-111.47542530020736 44.702162369096875, -111.48080430021237 44.691416369086866, -111.46069230019364 44.67002336906694, -111.45826530019139 44.652555369050674, -111.47016830020247 44.640710369039645, -111.50769030023741 44.63768836903683, -111.50174730023188 44.615971369016606, -111.51452630024379 44.59319736899539, -111.49290430022364 44.55118936895627, -111.46282730019563 44.549942368955115, -111.45932530019238 44.53792136894391, -111.48257330021403 44.53614336894226, -111.49024130022117 44.528697368935326, -111.56723130029286 44.55286636895784, -111.60524830032827 44.54298936894864, -111.68486230040241 44.55075236895587, -111.71699730043235 44.53376036894004, -111.76691830047884 44.51882536892613, -111.79260830050276 44.518462368925796, -111.80783730051695 44.503982368912304, -111.87250230057717 44.556265368961, -111.9403863006404 44.54972636895491, -111.97781830067525 44.52967636893624, -112.02361330071791 44.53504336894123, -112.02707730072113 44.52284
 336892987, -112.0593673007512 44.528611368935245, -112.09989730078895 44.518231368925576, -112.12419030081158 44.52825336893491, -112.19965830088186 44.531449368937885, -112.21776330089872 44.53849536894445, -112.2303983009105 44.559491368964004, -112.25667530093496 44.55997236896445, -112.28234130095886 44.54170236894744, -112.3425073010149 44.52510036893197, -112.3405773010131 44.49718036890597, -112.36758330103825 44.44927036886135, -112.42075330108777 44.44928436886136, -112.45851930112295 44.46883436887957, -112.50183930116329 44.462997368874134, -112.53932430119819 44.47749736888764, -112.65318930130424 44.48080236889072, -112.71432630136118 44.49693536890574, -112.73371230137924 44.48432036889399, -112.77986330142222 44.47392236888431, -112.79622830143747 44.45801136886949, -112.82669130146583 44.4210843688351, -112.8187103014584 44.394819368810644, -112.81739630145718 44.36420236878213, -112.84427530148221 44.35363936877229, -112.8707813015069 44.36997836878751, -112.8873073
 0152228 44.3928523688088, -112.93828130156976 44.407192368822166, -112.98524930161349 44.435540368848564, -113.01201430163843 44.43771536885059, -113.00665830163344 44.45261536886447, -113.02030930164615 44.48177636889163, -113.00771330163442 44.51061236891848, -113.03782130166246 44.532959368939295, -113.03966030166417 44.55629436896103, -113.08303730170456 44.582681368985604, -113.0542893016778 44.62428936902435, -113.07314430169536 44.67552536907207, -113.0989563017194 44.69591636909106, -113.10170330172195 44.715173369108996, -113.12743130174591 44.73737936912967, -113.13827430175601 44.761439369152086, -113.24033830185107 44.81184136919902, -113.25715430186673 44.81048636919776, -113.31868030192403 44.78022836916958, -113.34063130194447 44.779000369168436, -113.35002430195323 44.80756836919504, -113.42137930201967 44.833699369219374, -113.4455733020422 44.851239369235714, -113.49619130208936 44.930670369309695, -113.48734830208112 44.93957436931798, -113.46341330205883 44.94077
 53693191, -113.44876530204519 44.94952236932725, -113.44102930203798 44.99819436937258, -113.45885330205458 45.02744936939982, -113.4554353020514 45.04334936941463, -113.48630530208014 45.058321369428576, -113.49015930208374 45.071219369440584, -113.52060930211209 45.08206336945069, -113.51022530210243 45.107835369474685, -113.55227230214157 45.10754936947443, -113.57437630216216 45.117711369483885, -113.57158430215956 45.13454536949956, -113.59409930218054 45.14974236951372, -113.6009283021869 45.18099236954282, -113.6455923022285 45.206790369566846, -113.69012030226996 45.26228136961853, -113.68870930226865 45.27778836963297, -113.73908030231556 45.32153036967371, -113.74131030231763 45.38238636973038, -113.77502630234903 45.41017236975626, -113.78566230235894 45.44563336978929, -113.76916830234359 45.47770736981916, -113.7723043023465 45.507054369846486, -113.78093330235454 45.51686536985562, -113.83371530240369 45.514908369853806, -113.8037543023758 45.583729369917904, -113.8224
 8530239323 45.600636369933646, -113.85202730242075 45.609562369941955, -113.90330530246851 45.61349136994562, -113.90219930246748 45.63725336996775, -113.92353230248735 45.65512436998439, -113.9266983024903 45.67121136999937, -113.96414430252517 45.67937837000698, -113.97114930253169 45.69737637002374, -114.00947230256737 45.68633237001346, -114.01987830257707 45.67237837000046, -114.0109903025688 45.65251136998196, -114.01803230257535 45.64077336997103, -114.05651530261119 45.62514436995647, -114.08296730263582 45.58637836992037, -114.11813930266858 45.571127369906165, -114.13204830268154 45.55038236988685, -114.17266730271938 45.54392436988083, -114.19480830273999 45.52791736986592, -114.24199830278394 45.53529036987278, -114.24788030278941 45.502945369842664, -114.26223930280278 45.485859369826755, -114.32643430286257 45.457424369800265, -114.35024630288476 45.46338336980582, -114.3714573029045 45.485740369826644, -114.41905130294883 45.499008369839, -114.43355530296233 45.527633
 369865654, -114.46270830298948 45.54784736988448, -114.49659130302105 45.54664936988337, -114.52739230304974 45.55819336989411, -114.56092430308095 45.54874036988531, -114.54095830306237 45.5963973699297, -114.56467830308446 45.62427136995566, -114.50174130302585 45.65239336998185, -114.5107063030342 45.674057370002025, -114.49756130302194 45.69440137002097, -114.5349763030568 45.7229963700476, -114.5419583030633 45.74599937006903, -114.56354230308341 45.7623983700843, -114.51737530304041 45.81006737012869, -114.49916430302343 45.842683370159065, -114.47380330299983 45.83946837015607, -114.44323130297136 45.85262137016832, -114.4075253029381 45.84645337016258, -114.39283830292442 45.87088637018533, -114.41353030294368 45.91065137022237, -114.42946030295852 45.92147737023245, -114.40529030293601 45.95397937026272, -114.41244730294268 45.97197337027948, -114.48445530300975 45.98980637029609, -114.47452930300051 46.009765370314675, -114.49432130301894 46.02341037032738, -114.4657563029
 9233 46.05081537035291, -114.45602930298327 46.082229370382166, -114.47737030300314 46.107357370405566, -114.50656830303033 46.11614237041375, -114.51894430304186 46.136063370432296, -114.50961330303318 46.15741737045219, -114.4670183029935 46.15526237045018, -114.44087930296917 46.168969370462946, -114.43955330296792 46.22025437051071, -114.47283330299892 46.243783370532626, -114.47379530299982 46.25296137054117, -114.4317953029607 46.28471137057074, -114.40979630294021 46.39291137067151, -114.3970173029283 46.399545370677686, -114.38402530291621 46.428179370704356, -114.41071530294107 46.48737137075948, -114.36046830289428 46.50612537077694, -114.35011530288463 46.51738937078744, -114.3433193028783 46.58788137085309, -114.32471230286097 46.62283937088564, -114.33468530287027 46.65422737091488, -114.3840173029162 46.66159637092174, -114.44153630296978 46.645715370906956, -114.48471830301 46.62357437088633, -114.54039130306184 46.637891370899666, -114.61082630312744 46.6290483708914
 25, -114.64474030315901 46.66082437092102, -114.6450383031593 46.67092137093043, -114.6259263031415 46.6871073709455, -114.67388730318616 46.734721370989845, -114.69843130320902 46.733760370988946, -114.74810530325529 46.695132370952976, -114.78291930328771 46.70304037096034, -114.77783230328296 46.755717371009396, -114.79403030329806 46.76653137101947, -114.8407923033416 46.77553837102786, -114.86660330336565 46.797045371047886, -114.90232530339892 46.799433371050114, -114.94840930344184 46.85244637109949, -114.94056630343454 46.89088837113529, -114.92412530341922 46.90716537115044, -114.96473030345703 46.92521337116725, -115.00157430349134 46.95880937119854, -115.03733430352466 46.963001371202445, -115.0556383035417 46.97335837121209, -115.08133630356564 47.02652437126161, -115.13550730361608 47.06355037129609, -115.14868430362836 47.09174237132235, -115.17249630365053 47.09757037132778, -115.1930733036697 47.124026371352414, -115.29623430376577 47.17955037140412, -115.32522830379
 278 47.245150371465215, -115.34366130380994 47.25502237147441, -115.40820730387006 47.26359337148239, -115.42664130388722 47.274374371492435, -115.50193030395735 47.281644371499205, -115.52306430397702 47.29198237150884, -115.55552030400725 47.33461337154854, -115.59953630404824 47.3700033715815, -115.6387823040848 47.38004437159085, -115.66647730411059 47.399167371608655, -115.75032630418868 47.42247537163037, -115.75010530418848 47.43396637164106, -115.73248130417207 47.445303371651626, -115.65608730410091 47.44918037165523, -115.64318530408889 47.45779337166326, -115.64014230408605 47.4752353716795, -115.69277030413508 47.489540371692826, -115.70152230414323 47.520893371722025, -115.7428293041817 47.533691371733944, -115.69208830413444 47.590721371787055, -115.6982843041402 47.616080371810675, -115.73406730417354 47.63987937183283, -115.73366530417316 47.69555437188469, -115.77572730421232 47.70973237189789, -115.79053730422612 47.744838371930584, -115.83674230426917 47.756281371
 94124, -115.84932430428088 47.80518237198679, -115.86980930429996 47.82745237200753, -115.90392130433173 47.841074372020216, -115.93784230436331 47.86712437204447, -115.99893230442021 47.92514037209851, -116.02531630444479 47.964939372135575, -116.05349230447102 47.976191372146054, -116.0554973044729 48.208483372362394, -116.05669230447401 48.498665372632644, -116.06353130448036 48.9999503730995, -114.7293253032378 48.99997037309952, -114.06346330261766 48.999977373099526, -112.18838730087137 48.999992373099545, -111.28267930002785 49.00001137309956, -110.75079729953251 49.000005373099555, -109.50073729836829 49.000005373099555, -108.25067529720408 49.00000937309956, -107.1881212962145 49.00001737309957, -106.12557929522494 49.00002137309957, -105.06303429423536 49.00002137309957, -104.062991293304 49.00002637309957, -104.05231729329405 48.645824372769695, -104.05211129329386 48.39101937253239, -104.04842529329044 48.0000813721683, -104.04730729328939 47.40001737160945, -104.0459262
 932881 47.333832371547814, -104.04743729328952 46.64294737090437, -104.04670529328884 46.54253937081086, -104.04783629328989 46.28088137056717, -104.04890629329088 45.942993370252495, -104.04951729329144 45.883052370196665, -104.04385129328617 45.212875369572515, -104.04307229328545 44.997805369372216, -104.05984229330106 44.99733636937178, -105.04179629421559 45.00107636937526, -105.08500329425583 44.999817369374085, -106.02115029512768 44.997213369371664, -106.25923129534941 44.99616236937068, -107.89437429687226 44.99977336937405, -108.25923829721206 45.00011536937437, -108.62525629755294 44.99759336937201, -109.79938529864643 44.999522369373814, -109.99552929882911 45.00279336937686, -110.39276029919905 44.998625369372974, -110.42964929923342 44.992285369367075, -111.05342829981436 44.99569536937025, -111.05161629981266 44.664490369061795, -111.0515602998126 44.473323368883754, -111.09463029985272 44.48612436889567, -111.12891829988466 44.500757368909305, -111.13435929988972 44.
 52790236893458, -111.17024229992315 44.54518636895068, -111.17876429993107 44.564851368968995, -111.21950729996902 44.57317036897675, -111.23423329998273 44.60256236900412, -111.2197972999693 44.61798136901848, -111.22397129997319 44.62690836902679, -111.27066530001667 44.64221236904105, -111.27020830001624 44.673802369070465, -111.29566830003995 44.68293836907897, -111.3154753000584 44.7051933690997, -111.31922130006188 44.72786436912081, -111.34997730009053 44.72617736911924, -111.37230930011133 44.745087369136854, -111.38495930012311 44.73769436912997, -111.39508430013254 44.70886936910313, -111.44363230017775 44.71317936910714, -111.47542530020736 44.702162369096875)))
+ME	Maine	MULTIPOLYGON (((-69.77727626137293 44.07414836851199, -69.85992826144991 44.00000136844294, -69.7915282613862 43.75608536821577, -69.8303922614224 43.727986368189605, -69.85178526144233 43.74432836820482, -69.84615526143709 43.84234436829611, -69.88679126147493 43.87671336832811, -69.90313226149014 43.790732368248044, -69.97290326155513 43.768847368227654, -69.9995002615799 43.78620736824382, -69.9873702615686 43.845738368299266, -70.02640326160495 43.84560136829914, -70.15662826172624 43.78981036824718, -70.23579826179997 43.68579636815031, -70.22223926178734 43.57724036804921, -70.34161026189851 43.53490836800978, -70.36592526192116 43.430303367912366, -70.45697726200596 43.349470367837085, -70.53894126208229 43.33571836782427, -70.66567226220032 43.09105036759641, -70.81866826234281 43.12187136762512, -70.83054826235387 43.15917436765986, -70.81320726233773 43.235222367730685, -70.90108626241957 43.28102036777334, -70.90580126242396 43.30206936779294, -70.96969926248347 
 43.36638036785283, -70.97909926249223 43.39618436788059, -70.96148326247581 43.43812636791965, -70.97079126248448 43.47021136794953, -70.95927826247376 43.51638836799253, -70.96426826247841 43.53198936800707, -70.94961926246476 43.548953368022865, -70.95652426247119 43.56414336803701, -70.97387426248736 43.571830368044175, -70.9844422624972 43.79116336824844, -71.00859626251969 44.28214636870571, -71.02872626253844 44.66853836906556, -71.08750926259319 45.301469369655024, -70.95938226247385 45.338865369689856, -70.87644426239662 45.22544536958422, -70.84287526236535 45.2781373696333, -70.81266626233722 45.35467836970458, -70.82913226235256 45.39072636973815, -70.7969672623226 45.42517236977023, -70.63492926217168 45.391967369739305, -70.71991026225083 45.51295436985198, -70.55227026209471 45.66066436998955, -70.39638326194952 45.72204637004671, -70.416214261968 45.79030937011029, -70.25396426181689 45.89900437021152, -70.24746426181083 45.944619370254, -70.31029526186934 45.96878237
 027651, -70.28002226184115 46.05315437035509, -70.30484926186428 46.06665837036766, -70.22932526179395 46.13743437043358, -70.28349626184439 46.19024937048276, -70.1910582617583 46.33483937061742, -70.04660726162378 46.42611537070243, -70.01414426159354 46.57059837083699, -69.98497726156637 46.69136537094947, -69.23029626086353 47.4533343716591, -69.04697626069279 47.42203037162995, -69.03671426068324 47.25736137147659, -68.89487226055114 47.182256371406645, -68.51467326019704 47.296964371513475, -68.3912572600821 47.28509737150242, -68.33481426002953 47.35737437156973, -68.23080725993267 47.352148371564866, -67.79101125952309 47.06100337129372, -67.7802892595131 45.947062370256276, -67.75561525949011 45.91658037022789, -67.79457125952639 45.878475370192405, -67.75936725949362 45.8277983701452, -67.8030532595343 45.7945083701142, -67.80343325953466 45.6781133700058, -67.75295525948763 45.65928936998827, -67.71803425945512 45.68129937000877, -67.6151402593593 45.60519936993789, -67.4
 3930125919553 45.59256136992612, -67.4160842591739 45.50355436984323, -67.50410625925588 45.48581636982671, -67.4185552591762 45.3758523697243, -67.47795025923152 45.28028036963529, -67.43943525919565 45.18958436955082, -67.34560525910827 45.122252369488116, -67.27409525904167 45.18278336954449, -67.16590525894091 45.15626436951979, -67.1506612589267 45.121990369487875, -67.06535825884727 44.959295369336346, -67.14670625892303 44.904581369285395, -66.96927125875777 44.82865536921469, -67.00771925879359 44.780625369169954, -67.200364258973 44.65378136905181, -67.30846825907368 44.653521369051575, -67.38851025914822 44.69140036908685, -67.57099325931817 44.59833336900017, -67.61883825936273 44.540239368946075, -67.8112192595419 44.5540093689589, -67.858560259586 44.5360773689422, -67.90004225962463 44.45239936886426, -67.96834225968823 44.4712283688818, -67.96343625968366 44.505327368913555, -67.98652325970517 44.48481236889445, -68.01639325973298 44.384956368801454, -68.074379259787 
 44.38137436879812, -68.13626425984462 44.47523736888554, -68.24561425994646 44.49064836889988, -68.3637652600565 44.4313863688447, -68.42857126011685 44.465306368876284, -68.55218626023198 44.39904936881458, -68.53007526021139 44.28983636871287, -68.55942726023872 44.25988736868497, -68.74031026040718 44.34633036876548, -68.81285126047474 44.32743236874788, -68.8137682604756 44.41399036882849, -68.74134826040816 44.50728536891538, -68.74527926041182 44.552320368957325, -68.82355226048472 44.60890636901003, -68.82381326048495 44.664089369061415, -68.86060926051923 44.61097036901195, -68.80790326047014 44.56965436897347, -68.81167826047366 44.494593368903566, -68.95917926061102 44.43033136884371, -68.9850282606351 44.27111236869543, -69.02148226066905 44.24409336867026, -69.07445826071839 44.06906636850726, -69.21914026085314 43.94678736839337, -69.29365026092252 43.94219036838909, -69.3464542609717 44.01596936845781, -69.39448826101643 44.02512836846634, -69.48323326109909 43.8871603
 68337845, -69.5893262611979 43.84486236829845, -69.66445326126787 43.85222436830531, -69.65524526125928 43.98025036842454, -69.61293226121988 44.03361236847424, -69.72063526132018 43.93797936838517, -69.74852826134617 43.893375368343634, -69.72467126132395 43.784477368242214, -69.75035926134787 43.761704368221004, -69.77767326137331 43.79127036824854, -69.80001326139411 44.02686636846796, -69.76675526136314 44.04773236848739, -69.77727626137293 44.07414836851199)), ((-68.387921260079 44.377253368794285, -68.35025426004391 44.398951368814494, -68.35544926004876 44.428857368842344, -68.23870925994004 44.43756336885045, -68.16476925987118 44.33449536875446, -68.3047052600015 44.290031368713045, -68.32071126001641 44.22507936865256, -68.40289026009295 44.27080136869514, -68.387921260079 44.377253368794285)))
+ND	North Dakota	MULTIPOLYGON (((-98.73043728833767 45.93827137024809, -99.00683328859509 45.93955537024929, -99.7173452892568 45.94276137025227, -99.87578328940435 45.94354737025301, -100.51440628999912 45.94038837025006, -102.00277529138528 45.942505370252036, -102.9463972922641 45.94166537025126, -102.99482329230919 45.94111537025074, -104.04890629329088 45.942993370252495, -104.04783629328989 46.28088137056717, -104.04670529328884 46.54253937081086, -104.04743729328952 46.64294737090437, -104.0459262932881 47.333832371547814, -104.04730729328939 47.40001737160945, -104.04842529329044 48.0000813721683, -104.05211129329386 48.39101937253239, -104.05231729329405 48.645824372769695, -104.062991293304 49.00002637309957, -102.93795929225622 49.00002637309957, -102.02226429140342 49.000015373099565, -101.50043729091743 49.000020373099574, -100.18790828969505 49.00000237309955, -99.53356628908564 49.00000837309956, -99.0004032885891 49.00000637309955, -97.93786728759953 48.99999237309954
 5, -97.22943628693976 48.999987373099536, -97.21636928692759 48.931830373036064, -97.17572728688974 48.87375737298198, -97.17120428688553 48.83598037294679, -97.1804222868941 48.81553737292775, -97.16471228687948 48.81036837292294, -97.17394428688807 48.801514372914696, -97.14751628686346 48.781170372895744, -97.13924628685575 48.76354237287933, -97.14789828686382 48.75565337287198, -97.13250228684947 48.747218372864126, -97.13480628685163 48.72623837284459, -97.11010128682861 48.708583372828144, -97.1167392868348 48.695243372815725, -97.09716928681657 48.67452937279643, -97.1076302868263 48.629946372754915, -97.12744428684476 48.62979437275477, -97.12295828684059 48.62076837274636, -97.14471828686085 48.61402437274008, -97.14081228685721 48.586905372714824, -97.1581922868734 48.583640372711784, -97.15212728686775 48.572856372701736, -97.16794328688249 48.56226337269187, -97.14661828686262 48.54953737268002, -97.1604352868755 48.545078372675874, -97.15553728687092 48.53839837266965,
  -97.13938528685588 48.534648372666155, -97.14832728686422 48.51795137265061, -97.13459428685142 48.51731437265001, -97.14361328685983 48.43810937257625, -97.1196332868375 48.43710237257531, -97.12260128684025 48.416110372555764, -97.1516472868673 48.41961237255902, -97.14982328686561 48.40999137255006, -97.12912428684633 48.4078853725481, -97.15881928687399 48.38820637252977, -97.135205286852 48.38441037252623, -97.13378628685068 48.3724543725151, -97.15039628686614 48.3632153725065, -97.1311232868482 48.361491372504894, -97.13713628685379 48.32599137247183, -97.11259128683093 48.319926372466185, -97.1326342868496 48.31096937245784, -97.11475128683294 48.303618372451, -97.11372128683199 48.294882372442856, -97.13051328684763 48.29304037244114, -97.11268328683101 48.286147372434726, -97.11171428683012 48.277876372427016, -97.13665528685334 48.264483372414546, -97.12378428684136 48.259173372409606, -97.12755428684487 48.23352337238571, -97.10923528682781 48.22804937238061, -97.139754
 28685623 48.22175537237475, -97.11089928682935 48.20760537236157, -97.13082828684792 48.20374237235798, -97.13727528685392 48.19506337234989, -97.13629128685301 48.17522737233142, -97.13744328685408 48.16776937232447, -97.11606528683417 48.15922337231652, -97.13651328685322 48.14839837230643, -97.12091828683869 48.1427743723012, -97.12187328683957 48.11636937227661, -97.0990302868183 48.10097237226226, -97.09272128681243 48.07034437223374, -97.06707128678855 48.04816437221308, -97.04805328677082 47.95492437212624, -97.01533128674035 47.917890372091755, -97.02056628674522 47.87556937205234, -97.0003402867264 47.87019737204734, -96.97723128670486 47.82802937200807, -96.98389328671108 47.809661371990956, -96.9578302866868 47.79444037197678, -96.93201228666275 47.763506371947976, -96.92365928665498 47.71409437190196, -96.8894252866231 47.67392537186454, -96.87333528660811 47.61525537180991, -96.85221728658844 47.601151371796774, -96.85866428659445 47.56297837176122, -96.84918828658562 4
 7.54456837174408, -96.86068728659633 47.521356371722455, -96.85161528658789 47.50061937170314, -96.86668428660191 47.46153737166674, -96.8558272865918 47.43675337164366, -96.86724828660245 47.41308737162162, -96.85000528658638 47.408936371617756, -96.8398272865769 47.38411737159464, -96.85063128658696 47.36095437157307, -96.83846128657564 47.34224337155564, -96.84674728658335 47.3146023715299, -96.83771428657494 47.2938843715106, -96.84962328658602 47.25684337147611, -96.83706528657433 47.240458371460846, -96.82649128656448 47.17006337139529, -96.83916428657629 47.15188637137836, -96.81915128655764 47.09260437132315, -96.82696428656492 47.07883237131033, -96.82260828656086 47.033932371268506, -96.83529628657269 47.010231371246434, -96.82453128656266 47.003436371240106, -96.81677228655543 46.96977937120876, -96.79342528653369 46.96964137120863, -96.80188728654157 46.95584337119578, -96.78971028653022 46.948202371188664, -96.78792528652856 46.93218437117375, -96.76306828650542 46.9362
 61371177544, -96.75691128649969 46.92278037116499, -96.77806128651937 46.86734937111336, -96.76825028651024 46.84486137109242, -96.7971972865372 46.812033371061844, -96.78038228652154 46.76231237101554, -96.78155628652263 46.70704437096407, -96.79369528653393 46.67880437093777, -96.79024628653073 46.6297733708921, -96.78431728652521 46.624112370886834, -96.77104128651284 46.59998337086436, -96.75122728649438 46.58861937085378, -96.74031628648423 46.4894323707614, -96.71489428646055 46.46871837074211, -96.70968228645569 46.42716837070341, -96.68822828643572 46.41221837068949, -96.65210128640207 46.35943337064033, -96.61486128636739 46.3508123706323, -96.60207428635547 46.33632437061881, -96.59818328635185 46.23868237052787, -96.58645628634093 46.2154133705062, -96.58789028634227 46.191918370484316, -96.57116628632669 46.17717437047059, -96.55193128630877 46.09552937039455, -96.57621528633139 46.0212793703254, -96.56180228631797 45.947683370256854, -96.56692128632274 45.93411037024421
 , -97.23331028694336 45.936502370246444, -97.97872228763758 45.93082237024116, -98.0147092876711 45.93149837024178, -98.73043728833767 45.93827137024809)))
+SD	South Dakota	MULTIPOLYGON (((-102.78838429211693 42.99530336750724, -103.00587529231949 42.99935436751102, -103.50146429278104 42.99861836751033, -104.05619929329767 43.00306236751447, -104.05915729330043 43.47913436795784, -104.05791429329928 43.50371236798073, -104.05947929330073 43.852906368305945, -104.05973129330096 44.14582536857875, -104.06103629330218 44.18182536861227, -104.05946529330072 44.57435236897784, -104.05984229330106 44.99733636937178, -104.04307229328545 44.997805369372216, -104.04385129328617 45.212875369572515, -104.04951729329144 45.883052370196665, -104.04890629329088 45.942993370252495, -102.99482329230919 45.94111537025074, -102.9463972922641 45.94166537025126, -102.00277529138528 45.942505370252036, -100.51440628999912 45.94038837025006, -99.87578328940435 45.94354737025301, -99.7173452892568 45.94276137025227, -99.00683328859509 45.93955537024929, -98.73043728833767 45.93827137024809, -98.0147092876711 45.93149837024178, -97.97872228763758 45.930822370
 24116, -97.23331028694336 45.936502370246444, -96.56692128632274 45.93411037024421, -96.58795528634232 45.81785437013595, -96.60461028635784 45.80826437012701, -96.65739128640699 45.738970370062475, -96.83279628657036 45.65068736998026, -96.85499028659102 45.609122369941545, -96.84308728657994 45.584090369918236, -96.76924628651116 45.5174783698562, -96.7380322864821 45.45819536980099, -96.69316928644032 45.4106383697567, -96.60508428635828 45.39652436974355, -96.53254928629073 45.37513236972363, -96.47759228623954 45.328509369680205, -96.45760228622093 45.298850369652584, -96.45449628621803 45.27519536963055, -96.4560802862195 44.97199436934818, -96.45521728621871 44.801347369189244, -96.45671828622011 44.62880836902856, -96.45510628621861 44.53834336894431, -96.45739728622074 44.19906136862833, -96.45660228621999 43.848741368302065, -96.46045428622358 43.49971836797701, -96.59831528635198 43.499849367977134, -96.58379628633845 43.48192036796044, -96.5891132863434 43.43553936791724
 4, -96.55770828631415 43.40072736788482, -96.52505328628375 43.38422536786945, -96.52289428628174 43.356966367844066, -96.5405632862982 43.307659367798145, -96.5791312863341 43.29007436778177, -96.57072228632627 43.26361236775712, -96.5595672863159 43.25326336774748, -96.5669912863228 43.23963336773479, -96.558605286315 43.22548936772162, -96.48724528624854 43.217909367714554, -96.47311428623537 43.20908236770634, -96.45150528621525 43.12630836762925, -96.46080528622392 43.08787236759345, -96.46209428622511 43.075582367582, -96.47957328624139 43.06188436756925, -96.52001028627905 43.051508367559585, -96.4990202862595 43.01205036752283, -96.51714828627638 42.986458367499, -96.51493528627432 42.952382367467266, -96.54426328630164 42.913866367431396, -96.53751128629536 42.896906367415596, -96.55621128631276 42.846660367368806, -96.57312628632852 42.83434736735734, -96.58764528634204 42.8353813673583, -96.60087528635437 42.799558367324934, -96.63298028638427 42.776835367303775, -96.6407
 0928639146 42.74860336727748, -96.62654028637826 42.70835436724, -96.56303928631912 42.66851336720289, -96.54116528629875 42.66240536719721, -96.51284428627237 42.629755367166794, -96.48849828624971 42.580480367120906, -96.50094228626129 42.57388536711476, -96.48933728625049 42.56402836710558, -96.48024328624201 42.51713036706191, -96.43939428620396 42.48924036703593, -96.49470128625548 42.488459367035205, -96.5472152863044 42.52049936706504, -96.58475328633935 42.51828736706298, -96.60546728635863 42.50723636705269, -96.62929428638083 42.52269336706709, -96.6366722863877 42.5507313670932, -96.71405928645977 42.61230236715054, -96.7152732864609 42.62190736715949, -96.69459628644165 42.64116336717742, -96.6990602864458 42.657715367192836, -96.72265828646778 42.66859236720296, -96.7993442865392 42.67001936720429, -96.81043728654953 42.68134136721484, -96.81014028654926 42.70408436723602, -96.9082342866406 42.73169936726174, -96.97077328669886 42.721147367251916, -96.97786928670547 42.
 72730836725765, -96.97000328669814 42.75206536728071, -96.97959328670707 42.758313367286526, -97.01513928674018 42.759542367287665, -97.13046928684759 42.773923367301066, -97.16142228687642 42.798619367324065, -97.21183128692336 42.81257336733706, -97.2244432869351 42.84120236736372, -97.24318928695256 42.85182636737362, -97.27145728697889 42.85001436737193, -97.3114142870161 42.86177136738288, -97.38930628708864 42.86743336738815, -97.45726328715193 42.85044336737233, -97.48315928717605 42.857157367378576, -97.50613228719745 42.86013636738136, -97.57065428725754 42.847990367370045, -97.63497028731744 42.86128536738242, -97.68575228736474 42.83683736735966, -97.72525028740152 42.85800836737937, -97.77218628744522 42.846164367368345, -97.79702828746836 42.849597367371544, -97.8186432874885 42.86658736738737, -97.88865928755371 42.855807367377324, -97.88994128755489 42.831271367354475, -97.92947728759172 42.7923243673182, -97.96355828762346 42.773690367300844, -97.99514428765288 42.76
 681236729444, -98.03314028768825 42.769192367296654, -98.12182028777084 42.80836036733314, -98.12311728777206 42.820223367344184, -98.14486928779232 42.83579436735869, -98.1678262878137 42.839571367362204, -98.31033928794642 42.881794367401525, -98.39120428802174 42.92013536743723, -98.45744428808342 42.93716036745309, -98.49765128812088 42.991778367503954, -99.25397128882526 42.99238936750453, -99.53279028908491 42.992335367504474, -100.19814228970458 42.99109536750332, -101.23173729066718 42.98684336749936, -102.08670129146344 42.98988736750219, -102.78838429211693 42.99530336750724)))
+WY	Wyoming	MULTIPOLYGON (((-104.05361529329527 41.69821836629923, -104.05550029329702 41.56422236617444, -104.05401229329564 41.3880853660104, -104.0517052932935 41.003211365651964, -104.93449329411565 40.99428936564365, -105.2787972944363 40.99634936564557, -106.20347129529748 41.00008536564905, -106.3291252954145 41.001289365650166, -106.86543829591398 40.99845736564753, -107.30405129632247 41.00013336564909, -107.91867129689489 41.00337536565211, -109.04831429794694 40.998433365647514, -110.00216529883528 40.997599365646735, -110.06318529889211 40.997892365647004, -111.0510222998121 40.99658336564579, -111.05165129981269 41.25842536588965, -111.05106829981216 41.57859236618782, -111.04869729980994 41.99620336657675, -111.04678029980816 42.50325236704899, -111.04921529981043 43.01988336753013, -111.04749829980882 43.28473436777679, -111.04677129980816 43.515528367991735, -111.05040529981153 43.98255336842669, -111.0515602998126 44.473323368883754, -111.05161629981266 44.6644903690
 61795, -111.05342829981436 44.99569536937025, -110.42964929923342 44.992285369367075, -110.39276029919905 44.998625369372974, -109.99552929882911 45.00279336937686, -109.79938529864643 44.999522369373814, -108.62525629755294 44.99759336937201, -108.25923829721206 45.00011536937437, -107.89437429687226 44.99977336937405, -106.25923129534941 44.99616236937068, -106.02115029512768 44.997213369371664, -105.08500329425583 44.999817369374085, -105.04179629421559 45.00107636937526, -104.05984229330106 44.99733636937178, -104.05946529330072 44.57435236897784, -104.06103629330218 44.18182536861227, -104.05973129330096 44.14582536857875, -104.05947929330073 43.852906368305945, -104.05791429329928 43.50371236798073, -104.05915729330043 43.47913436795784, -104.05619929329767 43.00306236751447, -104.05621929329769 42.61466936715274, -104.05351329329517 41.99981536658012, -104.05361529329527 41.69821836629923)))
+WI	Wisconsin	MULTIPOLYGON (((-87.74855527810999 44.961616369338515, -87.83999227819515 44.92732336930658, -87.8310202781868 44.8733463692563, -87.98579127833094 44.72047436911393, -87.98318227832851 44.67726536907369, -88.01328827835654 44.63911836903816, -87.97575827832159 44.595814368997836, -88.0130212783563 44.622234369022436, -88.04041727838181 44.57144936897514, -87.96622827831271 44.53549636894166, -87.92640827827563 44.539139368945044, -87.86878227822197 44.61690636901747, -87.7642262781246 44.64404836904275, -87.72382127808696 44.68928736908488, -87.6144642779851 44.833047369218775, -87.55278727792768 44.851335369235805, -87.55167227792663 44.82302336920944, -87.4337472778168 44.89109636927283, -87.36745927775507 44.81156736919877, -87.31446527770572 44.79471836918307, -87.37307027776029 44.67691836907336, -87.47352827785386 44.533946368940214, -87.53748927791342 44.32785136874827, -87.51732227789465 44.17575436860662, -87.64437027801297 44.09783036853405, -87.7261222780891
 1 43.893904368344124, -87.70273027806732 43.673176368138556, -87.78604527814491 43.54629736802039, -87.80295927816066 43.458714367938825, -87.87533227822807 43.358592367845574, -87.88983427824157 43.19721636769529, -87.86006927821386 43.07587536758228, -87.89198327824357 43.02577436753562, -87.83643827819185 42.96459236747864, -87.81984927817639 42.84156336736406, -87.75680327811767 42.77754636730444, -87.79150927815 42.66664236720115, -87.79738227815547 42.48915236703585, -88.19479027852559 42.489631367036296, -88.2979892786217 42.49198836703849, -88.70662327900227 42.48967136703634, -88.76505827905669 42.4909223670375, -88.93918727921886 42.49087936703746, -89.35955927961037 42.49791736704401, -89.4006132796486 42.49750236704362, -89.8347392800529 42.50346836704918, -89.92369128013574 42.504115367049785, -90.42010328059807 42.50836536705374, -90.63845628080142 42.509363367054675, -90.62570728078956 42.52856236707255, -90.63921928080214 42.55571436709784, -90.66438028082557 42.5713
 9136711244, -90.69479128085389 42.63792836717441, -90.74561028090122 42.65700136719217, -90.89254528103807 42.678240367211956, -90.91940928106308 42.68067736721422, -90.99918228113738 42.70705836723879, -91.06616828119977 42.744913367274044, -91.08203028121454 42.783365367309855, -91.09342828122514 42.871440367391884, -91.1391212812677 42.9258933674426, -91.1522142812799 43.00131636751284, -91.15975228128691 43.08118236758722, -91.16857128129513 43.08288836758881, -91.16135428128841 43.14757636764905, -91.06905228120245 43.2578983677518, -91.0664282812 43.28068336777302, -91.07849828121125 43.31329736780339, -91.17704828130303 43.35394636784125, -91.19824328132277 43.37051336785668, -91.21091628133458 43.42405136790654, -91.23590328135784 43.464684367944386, -91.22356628134635 43.500808367978024, -91.24055828136218 43.54871236802264, -91.23299028135513 43.59889036806938, -91.25838928137878 43.67732236814242, -91.25891628137927 43.722395368184394, -91.251105281372 43.788075368245565,
  -91.29194828141004 43.847190368300616, -91.37335728148585 43.94719136839375, -91.42590228153479 43.98561936842954, -91.52842028163028 44.034215368474804, -91.56916228166821 44.034955368475494, -91.6017862816986 44.04082236848096, -91.65223328174558 44.066895368505236, -91.75321928183963 44.137227368570734, -91.84874428192859 44.191187368620994, -91.8886942819658 44.25749536868275, -91.92234928199714 44.28834136871147, -91.92275428199753 44.31752036873865, -91.93886828201254 44.33911136875876, -91.97238628204374 44.36448736878239, -92.09133328215452 44.415589368829984, -92.20613728226144 44.43839436885122, -92.24910028230146 44.45621636886782, -92.29668728234577 44.49218236890132, -92.32047828236793 44.540491368946306, -92.34087228238693 44.5528353689578, -92.5092152825437 44.575159368978596, -92.60897328263661 44.61029236901132, -92.63036728265654 44.64265236904146, -92.73714528275598 44.713594369107525, -92.80558428281972 44.746160369137854, -92.76102828277823 44.83537136922094, -
 92.76426328278124 44.862234369245954, -92.77187128278833 44.899496369280655, -92.75392628277162 44.915002369295095, -92.74976828276773 44.93565536931433, -92.7671262827839 45.00100536937519, -92.76299128278005 45.02211936939486, -92.7967622828115 45.06561036943536, -92.74542228276368 45.1130043694795, -92.74493528276324 45.15642236951994, -92.76258328277967 45.18661236954806, -92.755419282773 45.21237636957205, -92.74659328276478 45.297603369651426, -92.70738428272827 45.318201369670604, -92.6848692827073 45.3630763697124, -92.64875128267366 45.395466369742564, -92.64497528267015 45.43945236978353, -92.6548172826793 45.45522136979822, -92.68542128270781 45.470053369812035, -92.72815428274761 45.54724236988392, -92.7621752827793 45.56426336989977, -92.83503728284715 45.56340236989897, -92.87683128288607 45.57883636991335, -92.88539728289405 45.64495536997492, -92.86001928287041 45.71056237003602, -92.83363628284584 45.73089037005495, -92.77910728279507 45.763340370085174, -92.7487622
 827668 45.837302370154056, -92.73409728275314 45.84498037016121, -92.7062402827272 45.89095837020403, -92.66620828268992 45.91570337022708, -92.55267228258418 45.9512693702602, -92.52397728255745 45.98258337028936, -92.46234528250005 45.98119737028807, -92.42499928246528 46.02550437032933, -92.36496328240936 46.01624837032071, -92.34622528239191 46.022596370326625, -92.32737228237436 46.056878370358554, -92.28937028233896 46.07323137037378, -92.28894428233856 46.15660037045143, -92.28868528233832 46.415984370692996, -92.287271282337 46.658786370919124, -92.20915428226425 46.64687237090803, -92.09597028215885 46.74262737099721, -92.00415728207334 46.68380037094242, -91.92146128199632 46.680134370939, -91.55577328165575 46.75686037101046, -90.86173028100937 46.95247937119265, -90.77448628092812 46.92023537116262, -90.77744528093086 46.88312237112805, -90.92624428106944 46.58550337085087, -90.73071428088734 46.64569637090693, -90.54087728071055 46.58752637085276, -90.40820028058698 46.
 568610370835145, -90.38552528056586 46.53965737080817, -90.31370828049899 46.55156337081927, -90.30239328048845 46.544296370812496, -90.30018128048638 46.52505137079457, -90.26978528045808 46.52248037079218, -90.25840128044747 46.508789370779425, -90.21152628040382 46.50629537077711, -90.16139128035712 46.44238037071758, -90.14179728033888 46.39389937067243, -90.11517728031409 46.36515537064566, -90.1116592803108 46.34042937062263, -89.9251362801371 46.30402537058873, -89.09980627936845 46.14564237044122, -88.9853012792618 46.10039137039908, -88.92519527920582 46.07360137037413, -88.80439727909332 46.026804370330545, -88.79381527908347 46.036360370339445, -88.77748027906826 46.032614370335956, -88.7730172790641 46.02114737032528, -88.72640927902069 46.02958137033313, -88.70360527899946 46.01892337032321, -88.67738427897504 46.020144370324346, -88.64366927894363 45.99338837029943, -88.6155022789174 45.99412037030011, -88.59753627890068 46.01551637032003, -88.57535727888002 46.0089593
 70313924, -88.54835827885486 46.019300370323556, -88.51561327882438 46.01860937032291, -88.49408327880433 46.01296037031766, -88.48381427879475 45.99915137030479, -88.45431927876729 46.00076037030629, -88.40352227871998 45.98342237029014, -88.3699382786887 45.994587370300536, -88.32132327864343 45.96671237027458, -88.29915227862278 45.96194437027014, -88.25716827858368 45.9670553702749, -88.2149922785444 45.94790137025706, -88.18019427851199 45.95351637026229, -88.15043827848427 45.93629337024625, -88.11139027844791 45.926287370236935, -88.09385027843157 45.920615370231644, -88.09576427843336 45.89180337020481, -88.0654212784051 45.8736423701879, -88.12178627845759 45.8348783701518, -88.12994927846519 45.81940237013738, -88.08873427842681 45.791532370111426, -88.05163927839226 45.78611237010638, -87.99007027833493 45.795046370114704, -87.96917927831547 45.76644837008807, -87.87362927822647 45.750699370073406, -87.84236227819736 45.722418370047066, -87.80155327815935 45.7113913700367
 9, -87.80115627815898 45.70132437002742, -87.77747327813692 45.684101370011376, -87.78094527814017 45.67591537000375, -87.81705427817379 45.66539036999395, -87.81993827817648 45.65445036998376, -87.7760452781356 45.613200369945346, -87.7750752781347 45.600387369933415, -87.78631227814516 45.56851936990373, -87.82860227818455 45.5685913699038, -87.8051412781627 45.544525369881384, -87.78938527814802 45.499067369839054, -87.81361427817059 45.466460369808686, -87.86026727821404 45.44509836978879, -87.84953127820404 45.40611736975249, -87.88361027823578 45.36585436971499, -87.8739742782268 45.36208536971148, -87.86853527822174 45.37207236972078, -87.86209627821574 45.370165369719004, -87.84128227819636 45.34614936969663, -87.82800827818399 45.35832136970797, -87.76003827812069 45.352897369702916, -87.68959827805509 45.39126936973865, -87.64368427801233 45.36185636971126, -87.64536227801389 45.34816936969852, -87.70447127806894 45.27220536962777, -87.70514227806956 45.247086369604375, -8
 7.71966827808309 45.23677136959477, -87.72162827808492 45.211672369571396, -87.7362002780985 45.19907236955966, -87.7296692780924 45.17660436953874, -87.67281427803945 45.14067236950527, -87.66488627803207 45.10905436947583, -87.5812762779542 45.0946403694624, -87.61852127798889 45.05680736942716, -87.62033527799058 44.99199736936681, -87.74855527810999 44.961616369338515)), ((-87.034524277445 45.290405369644716, -86.98625327740005 45.2986573696524, -86.96771227738277 45.24027736959803, -86.99573427740887 45.218411369577666, -87.04511227745486 45.249019369606174, -87.02544827743655 45.149974369513934, -87.07987627748724 45.14730736951145, -87.04490127745467 45.09551336946321, -87.0876782774945 45.09217836946011, -87.08390027749098 45.05328536942389, -87.11255727751768 45.06476336943457, -87.17869227757927 44.982806369358244, -87.16878827757004 44.93332336931216, -87.20565027760438 44.873239369256204, -87.3111232777026 44.79877336918685, -87.37873727776558 44.83774236922314, -87.4054
 1927779043 44.91120036929156, -87.3421612777315 45.01521336938843, -87.28348427767686 45.05261936942327, -87.2309152776279 45.1750633695373, -87.17791327757854 45.154973369518586, -87.06606427747438 45.29646236965036, -87.034524277445 45.290405369644716)))
+ID	Idaho	MULTIPOLYGON (((-117.02629530537702 43.67903136814401, -117.02379430537468 43.753701368213555, -117.0371173053871 43.8001423682568, -117.02762630537825 43.83156736828607, -117.0105053053623 43.83976936829371, -117.01622030536763 43.852972368306006, -116.98577030533927 43.85935136831195, -116.97814830533218 43.8734693683251, -116.97814130533217 43.90444136835394, -116.95971630531501 43.92857736837642, -116.96795730532268 43.96319536840866, -116.93359330529069 44.01420236845617, -116.97681730533094 44.07389436851176, -116.96344330531849 44.09029836852703, -116.94688630530305 44.093025368529574, -116.9022543052615 44.1463133685792, -116.91305130527155 44.17730436860806, -116.98187130533564 44.19784236862719, -116.9761273053303 44.22518236865265, -116.99270730534573 44.24706336867303, -117.0303523053808 44.249336368675145, -117.05202730540098 44.23155636865859, -117.08138730542832 44.243846368670035, -117.10056030544618 44.26707836869167, -117.11269230545747 44.26980536869421, 
 -117.14327930548598 44.25063236867636, -117.17072330551153 44.25333236867887, -117.21357230555142 44.2847193687081, -117.21745530555505 44.30066536872295, -117.20160230554029 44.33943836875906, -117.23692130557318 44.38998236880613, -117.21722130555483 44.427855368841406, -117.22441030556152 44.47298736888344, -117.20396230554249 44.485785368895364, -117.18739130552706 44.511805368919596, -117.14516030548772 44.534655368940875, -117.14394030548658 44.55928736896381, -117.13050430547406 44.572523368976135, -117.07935430542643 44.68933636908493, -117.06651330541447 44.697557369092586, -117.03957230538938 44.749115369140604, -116.95149430530736 44.776035369165676, -116.90962030526836 44.82894036921495, -116.89736730525695 44.84855536923321, -116.86707630522874 44.86860836925189, -116.83539630519923 44.92014436929989, -116.84755630521056 44.954850369332206, -116.83139630519551 44.97263336934877, -116.84815930521111 44.97174136934794, -116.85588730521832 44.9799653693556, -116.8480973052
 1106 45.0000423693743, -116.85451330521704 45.016945369390044, -116.80730730517307 45.049755369420595, -116.78721030515436 45.075752369444814, -116.77809230514586 45.0994803694669, -116.76126830513019 45.10630036947326, -116.73658530510721 45.13730736950214, -116.68881330506271 45.26235036961859, -116.6722653050473 45.335410369686635, -116.56577230494813 45.45986336980254, -116.55450330493763 45.49364736983401, -116.4785513048669 45.56605836990144, -116.47041830485932 45.60625736993888, -116.51491530490075 45.664491369993115, -116.5282753049132 45.71072837003618, -116.56063230494334 45.74742437007035, -116.65439830503067 45.78063037010128, -116.7031803050761 45.819169370137175, -116.77370730514178 45.81976337013772, -116.79126230515813 45.84586737016203, -116.85647230521886 45.9035973702158, -116.89819730525772 45.98051637028743, -116.91913230527722 45.995175370301084, -116.95772330531315 46.06568737036676, -116.98721130534062 46.0785093703787, -116.9616373053168 46.09727437039618, 
 -116.9294263052868 46.1654833704597, -116.96749030532226 46.19755437048957, -116.97272530532712 46.24930937053777, -117.00164230535405 46.30244837058726, -117.02797330537858 46.33542737061797, -117.06418430541231 46.34869837063033, -117.04447030539394 46.38857437066747, -117.03855830538843 46.42798037070417, -117.04192630539157 46.53660137080533, -117.04096830539069 47.11931937134803, -117.04239230539201 47.25850137147765, -117.04179430539145 47.36144137157352, -117.03747230538742 47.9710923721413, -117.03886830538872 48.04618637221124, -117.02911130537964 48.838075372948744, -117.03204930538237 48.999931373099486, -116.06353130448036 48.9999503730995, -116.05669230447401 48.498665372632644, -116.0554973044729 48.208483372362394, -116.05349230447102 47.976191372146054, -116.02531630444479 47.964939372135575, -115.99893230442021 47.92514037209851, -115.93784230436331 47.86712437204447, -115.90392130433173 47.841074372020216, -115.86980930429996 47.82745237200753, -115.84932430428088 
 47.80518237198679, -115.83674230426917 47.75628137194124, -115.79053730422612 47.744838371930584, -115.77572730421232 47.70973237189789, -115.73366530417316 47.69555437188469, -115.73406730417354 47.63987937183283, -115.6982843041402 47.616080371810675, -115.69208830413444 47.590721371787055, -115.7428293041817 47.533691371733944, -115.70152230414323 47.520893371722025, -115.69277030413508 47.489540371692826, -115.64014230408605 47.4752353716795, -115.64318530408889 47.45779337166326, -115.65608730410091 47.44918037165523, -115.73248130417207 47.445303371651626, -115.75010530418848 47.43396637164106, -115.75032630418868 47.42247537163037, -115.66647730411059 47.399167371608655, -115.6387823040848 47.38004437159085, -115.59953630404824 47.3700033715815, -115.55552030400725 47.33461337154854, -115.52306430397702 47.29198237150884, -115.50193030395735 47.281644371499205, -115.42664130388722 47.274374371492435, -115.40820730387006 47.26359337148239, -115.34366130380994 47.25502237147441
 , -115.32522830379278 47.245150371465215, -115.29623430376577 47.17955037140412, -115.1930733036697 47.124026371352414, -115.17249630365053 47.09757037132778, -115.14868430362836 47.09174237132235, -115.13550730361608 47.06355037129609, -115.08133630356564 47.02652437126161, -115.0556383035417 46.97335837121209, -115.03733430352466 46.963001371202445, -115.00157430349134 46.95880937119854, -114.96473030345703 46.92521337116725, -114.92412530341922 46.90716537115044, -114.94056630343454 46.89088837113529, -114.94840930344184 46.85244637109949, -114.90232530339892 46.799433371050114, -114.86660330336565 46.797045371047886, -114.8407923033416 46.77553837102786, -114.79403030329806 46.76653137101947, -114.77783230328296 46.755717371009396, -114.78291930328771 46.70304037096034, -114.74810530325529 46.695132370952976, -114.69843130320902 46.733760370988946, -114.67388730318616 46.734721370989845, -114.6259263031415 46.6871073709455, -114.6450383031593 46.67092137093043, -114.644740303159
 01 46.66082437092102, -114.61082630312744 46.629048370891425, -114.54039130306184 46.637891370899666, -114.48471830301 46.62357437088633, -114.44153630296978 46.645715370906956, -114.3840173029162 46.66159637092174, -114.33468530287027 46.65422737091488, -114.32471230286097 46.62283937088564, -114.3433193028783 46.58788137085309, -114.35011530288463 46.51738937078744, -114.36046830289428 46.50612537077694, -114.41071530294107 46.48737137075948, -114.38402530291621 46.428179370704356, -114.3970173029283 46.399545370677686, -114.40979630294021 46.39291137067151, -114.4317953029607 46.28471137057074, -114.47379530299982 46.25296137054117, -114.47283330299892 46.243783370532626, -114.43955330296792 46.22025437051071, -114.44087930296917 46.168969370462946, -114.4670183029935 46.15526237045018, -114.50961330303318 46.15741737045219, -114.51894430304186 46.136063370432296, -114.50656830303033 46.11614237041375, -114.47737030300314 46.107357370405566, -114.45602930298327 46.082229370382166
 , -114.46575630299233 46.05081537035291, -114.49432130301894 46.02341037032738, -114.47452930300051 46.009765370314675, -114.48445530300975 45.98980637029609, -114.41244730294268 45.97197337027948, -114.40529030293601 45.95397937026272, -114.42946030295852 45.92147737023245, -114.41353030294368 45.91065137022237, -114.39283830292442 45.87088637018533, -114.4075253029381 45.84645337016258, -114.44323130297136 45.85262137016832, -114.47380330299983 45.83946837015607, -114.49916430302343 45.842683370159065, -114.51737530304041 45.81006737012869, -114.56354230308341 45.7623983700843, -114.5419583030633 45.74599937006903, -114.5349763030568 45.7229963700476, -114.49756130302194 45.69440137002097, -114.5107063030342 45.674057370002025, -114.50174130302585 45.65239336998185, -114.56467830308446 45.62427136995566, -114.54095830306237 45.5963973699297, -114.56092430308095 45.54874036988531, -114.52739230304974 45.55819336989411, -114.49659130302105 45.54664936988337, -114.46270830298948 45.5
 4784736988448, -114.43355530296233 45.527633369865654, -114.41905130294883 45.499008369839, -114.3714573029045 45.485740369826644, -114.35024630288476 45.46338336980582, -114.32643430286257 45.457424369800265, -114.26223930280278 45.485859369826755, -114.24788030278941 45.502945369842664, -114.24199830278394 45.53529036987278, -114.19480830273999 45.52791736986592, -114.17266730271938 45.54392436988083, -114.13204830268154 45.55038236988685, -114.11813930266858 45.571127369906165, -114.08296730263582 45.58637836992037, -114.05651530261119 45.62514436995647, -114.01803230257535 45.64077336997103, -114.0109903025688 45.65251136998196, -114.01987830257707 45.67237837000046, -114.00947230256737 45.68633237001346, -113.97114930253169 45.69737637002374, -113.96414430252517 45.67937837000698, -113.9266983024903 45.67121136999937, -113.92353230248735 45.65512436998439, -113.90219930246748 45.63725336996775, -113.90330530246851 45.61349136994562, -113.85202730242075 45.609562369941955, -113.
 82248530239323 45.600636369933646, -113.8037543023758 45.583729369917904, -113.83371530240369 45.514908369853806, -113.78093330235454 45.51686536985562, -113.7723043023465 45.507054369846486, -113.76916830234359 45.47770736981916, -113.78566230235894 45.44563336978929, -113.77502630234903 45.41017236975626, -113.74131030231763 45.38238636973038, -113.73908030231556 45.32153036967371, -113.68870930226865 45.27778836963297, -113.69012030226996 45.26228136961853, -113.6455923022285 45.206790369566846, -113.6009283021869 45.18099236954282, -113.59409930218054 45.14974236951372, -113.57158430215956 45.13454536949956, -113.57437630216216 45.117711369483885, -113.55227230214157 45.10754936947443, -113.51022530210243 45.107835369474685, -113.52060930211209 45.08206336945069, -113.49015930208374 45.071219369440584, -113.48630530208014 45.058321369428576, -113.4554353020514 45.04334936941463, -113.45885330205458 45.02744936939982, -113.44102930203798 44.99819436937258, -113.44876530204519 44.
 94952236932725, -113.46341330205883 44.9407753693191, -113.48734830208112 44.93957436931798, -113.49619130208936 44.930670369309695, -113.4455733020422 44.851239369235714, -113.42137930201967 44.833699369219374, -113.35002430195323 44.80756836919504, -113.34063130194447 44.779000369168436, -113.31868030192403 44.78022836916958, -113.25715430186673 44.81048636919776, -113.24033830185107 44.81184136919902, -113.13827430175601 44.761439369152086, -113.12743130174591 44.73737936912967, -113.10170330172195 44.715173369108996, -113.0989563017194 44.69591636909106, -113.07314430169536 44.67552536907207, -113.0542893016778 44.62428936902435, -113.08303730170456 44.582681368985604, -113.03966030166417 44.55629436896103, -113.03782130166246 44.532959368939295, -113.00771330163442 44.51061236891848, -113.02030930164615 44.48177636889163, -113.00665830163344 44.45261536886447, -113.01201430163843 44.43771536885059, -112.98524930161349 44.435540368848564, -112.93828130156976 44.407192368822166, 
 -112.88730730152228 44.3928523688088, -112.8707813015069 44.36997836878751, -112.84427530148221 44.35363936877229, -112.81739630145718 44.36420236878213, -112.8187103014584 44.394819368810644, -112.82669130146583 44.4210843688351, -112.79622830143747 44.45801136886949, -112.77986330142222 44.47392236888431, -112.73371230137924 44.48432036889399, -112.71432630136118 44.49693536890574, -112.65318930130424 44.48080236889072, -112.53932430119819 44.47749736888764, -112.50183930116329 44.462997368874134, -112.45851930112295 44.46883436887957, -112.42075330108777 44.44928436886136, -112.36758330103825 44.44927036886135, -112.3405773010131 44.49718036890597, -112.3425073010149 44.52510036893197, -112.28234130095886 44.54170236894744, -112.25667530093496 44.55997236896445, -112.2303983009105 44.559491368964004, -112.21776330089872 44.53849536894445, -112.19965830088186 44.531449368937885, -112.12419030081158 44.52825336893491, -112.09989730078895 44.518231368925576, -112.0593673007512 44.52
 8611368935245, -112.02707730072113 44.52284336892987, -112.02361330071791 44.53504336894123, -111.97781830067525 44.52967636893624, -111.9403863006404 44.54972636895491, -111.87250230057717 44.556265368961, -111.80783730051695 44.503982368912304, -111.79260830050276 44.518462368925796, -111.76691830047884 44.51882536892613, -111.71699730043235 44.53376036894004, -111.68486230040241 44.55075236895587, -111.60524830032827 44.54298936894864, -111.56723130029286 44.55286636895784, -111.49024130022117 44.528697368935326, -111.48257330021403 44.53614336894226, -111.45932530019238 44.53792136894391, -111.46282730019563 44.549942368955115, -111.49290430022364 44.55118936895627, -111.51452630024379 44.59319736899539, -111.50174730023188 44.615971369016606, -111.50769030023741 44.63768836903683, -111.47016830020247 44.640710369039645, -111.45826530019139 44.652555369050674, -111.46069230019364 44.67002336906694, -111.48080430021237 44.691416369086866, -111.47542530020736 44.702162369096875, -
 111.44363230017775 44.71317936910714, -111.39508430013254 44.70886936910313, -111.38495930012311 44.73769436912997, -111.37230930011133 44.745087369136854, -111.34997730009053 44.72617736911924, -111.31922130006188 44.72786436912081, -111.3154753000584 44.7051933690997, -111.29566830003995 44.68293836907897, -111.27020830001624 44.673802369070465, -111.27066530001667 44.64221236904105, -111.22397129997319 44.62690836902679, -111.2197972999693 44.61798136901848, -111.23423329998273 44.60256236900412, -111.21950729996902 44.57317036897675, -111.17876429993107 44.564851368968995, -111.17024229992315 44.54518636895068, -111.13435929988972 44.52790236893458, -111.12891829988466 44.500757368909305, -111.09463029985272 44.48612436889567, -111.0515602998126 44.473323368883754, -111.05040529981153 43.98255336842669, -111.04677129980816 43.515528367991735, -111.04749829980882 43.28473436777679, -111.04921529981043 43.01988336753013, -111.04678029980816 42.50325236704899, -111.04869729980994 4
 1.99620336657675, -111.49458630022521 42.000171366580446, -112.10051430078953 42.00230036658243, -112.14711630083293 41.999054366579415, -112.98957530161753 42.00114636658136, -114.03907230259495 41.995391366576, -114.26947130280954 41.995924366576496, -115.02486330351303 41.99650636657704, -115.94754430437234 41.99459936657526, -116.99231330534536 41.99479436657545, -117.0188643053701 41.99479436657545, -117.02629530537702 43.67903136814401)))
+VT	Vermont	MULTIPOLYGON (((-73.25806026461467 42.74605836727511, -73.26927526462511 42.747481367276436, -73.29616926465016 42.80354936732866, -73.27958326463471 42.8371033673599, -73.27600526463138 42.940294367456005, -73.25007126460723 43.31085436780112, -73.23839126459634 43.512832367989226, -73.25998426461646 43.55938236803258, -73.29140226464573 43.57503336804716, -73.28173626463672 43.593187368064065, -73.29410426464824 43.619653368088706, -73.30353426465702 43.62471436809342, -73.36368526471304 43.61499836808437, -73.38811426473579 43.569143368041665, -73.41832026476392 43.582479368054095, -73.42296026476825 43.63211436810032, -73.37098926471984 43.71428136817684, -73.35666926470651 43.75655836821622, -73.35899726470868 43.77842736823658, -73.38474026473266 43.80450836826087, -73.37512126472369 43.88597736833674, -73.40533426475183 43.9148073683636, -73.41740626476307 43.98819736843194, -73.40825126475454 44.0182223684599, -73.43600026478039 44.04567936848548, -73.435215264779
 66 44.063897368502445, -73.40875726475501 44.10661036854222, -73.4078652647542 44.136227368569806, -73.38206226473015 44.17210736860322, -73.37733226472575 44.20124736863036, -73.30532526465869 44.26014236868521, -73.32978826468147 44.367390368785095, -73.29999526465373 44.40553336882061, -73.29331926464751 44.43285336884606, -73.33445226468581 44.54432836894988, -73.34781226469826 44.55397136895886, -73.37129626472013 44.579167368982326, -73.38182526472994 44.61980736902018, -73.37013626471905 44.63434936903372, -73.3730972647218 44.6612763690588, -73.35815126470789 44.680368369076575, -73.37315826472187 44.724236369117435, -73.32678626467867 44.79929336918734, -73.36905426471805 44.819118369205796, -73.38230626473039 44.847933369232635, -73.33641426468765 44.93260436931149, -73.350758264701 44.98197336935747, -73.34472326469538 45.006138369379975, -73.18854626454993 45.00848636938216, -72.54723126395265 45.005370369379264, -71.90186826335162 45.0073403693811, -71.50537226298235 45
 .0133513693867, -71.54092726301546 44.976563369352434, -71.51697726299317 44.94369636932182, -71.50636526298328 44.899671369280824, -71.57510126304729 44.81601936920291, -71.58350126305511 44.77919736916862, -71.63113326309947 44.741710369133706, -71.60767826307763 44.67786236907425, -71.58874926306 44.650599369048855, -71.5680272630407 44.6374463690366, -71.55410226302773 44.59658936899855, -71.53679126301161 44.57893136898211, -71.5922882630633 44.55120336895628, -71.5914412630625 44.5388743689448, -71.57524326304743 44.52580536893263, -71.58661926305801 44.49453736890351, -71.61422326308373 44.47450736888486, -71.63655426310453 44.47673136888693, -71.64770926311492 44.46917436887989, -71.656399263123 44.440137368852845, -71.67688426314209 44.42134236883534, -71.76657026322562 44.39824836881384, -71.79772926325462 44.384172368800726, -71.82119726327649 44.35036036876923, -71.83481626328917 44.3441993687635, -71.92836126337629 44.33611236875596, -71.9389052633861 44.32578636874635,
  -71.99443326343783 44.32754836874799, -72.03549526347607 44.299434368721805, -72.05956626349848 44.26149436868647, -72.04439026348435 44.23437936866122, -72.05928226349822 44.1821763686126, -72.04472426348467 44.15643536858863, -72.03492026347553 44.12074636855539, -72.04951526348913 44.100452368536494, -72.03244726347323 44.096099368532435, -72.03472826347536 44.08337436852058, -72.07691926351464 44.03204036847278, -72.08520426352236 44.00892436845125, -72.10990926354538 43.9892293684329, -72.11280826354808 43.97651536842106, -72.09171126352842 43.95799136840381, -72.11320426354844 43.93916636838628, -72.12164926355631 43.909217368358384, -72.17008926360141 43.878917368330164, -72.18483626361515 43.80169036825825, -72.20609226363494 43.764635368223736, -72.21912326364708 43.75069236821075, -72.2600552636852 43.73530036819642, -72.30404026372616 43.69853036816217, -72.33308526375322 43.59736436806796, -72.37349826379085 43.57237436804468, -72.39499826381088 43.517554367993625, -72.
 38251526379925 43.48462936796296, -72.39624826381204 43.410156367893606, -72.41213926382684 43.37712536786284, -72.39762826381333 43.351006367838515, -72.41023126382507 43.323404367812806, -72.40241926381779 43.307382367797885, -72.43559826384869 43.23225336772792, -72.45239826386434 43.15602236765692, -72.43760526385056 43.1162703676199, -72.44346426385601 43.079039367585224, -72.46175226387305 43.046504367554924, -72.45715926386877 42.99960336751124, -72.47334126388384 42.9761433674894, -72.50426326391263 42.965584367479565, -72.5202172639275 42.9516723674666, -72.52481026393178 42.91261436743023, -72.55342826395842 42.860643367381826, -72.53891726394491 42.80773336733255, -72.51306826392084 42.789259367315346, -72.50726926391545 42.768732367296224, -72.47932226388942 42.761588367289576, -72.46217126387344 42.74684036727584, -72.45577026386748 42.725852367256294, -72.92299726430262 42.73736436726702, -73.01969526439268 42.74039636726984, -73.25806026461467 42.74605836727511)))
+MN	Minnesota	MULTIPOLYGON (((-91.73036628181835 43.49957136797688, -92.07753228214168 43.49915336797649, -92.45316928249152 43.499462367976776, -92.55800828258914 43.50025936797752, -93.02721128302613 43.501278367978465, -93.05438028305143 43.50145736797863, -93.50083028346722 43.50048836797773, -93.65369928360958 43.500762367977984, -93.97395028390784 43.50029836797755, -94.24678728416194 43.4989483679763, -94.45523828435608 43.498102367975505, -94.8598392847329 43.5000303679773, -94.92046428478936 43.49937136797669, -95.39655828523276 43.50033436797759, -95.46477528529628 43.499541367976846, -95.86691228567081 43.49894436797629, -96.0610392858516 43.49853336797591, -96.46045428622358 43.49971836797701, -96.45660228621999 43.848741368302065, -96.45739728622074 44.19906136862833, -96.45510628621861 44.53834336894431, -96.45671828622011 44.62880836902856, -96.45521728621871 44.801347369189244, -96.4560802862195 44.97199436934818, -96.45449628621803 45.27519536963055, -96.457602286220
 93 45.298850369652584, -96.47759228623954 45.328509369680205, -96.53254928629073 45.37513236972363, -96.60508428635828 45.39652436974355, -96.69316928644032 45.4106383697567, -96.7380322864821 45.45819536980099, -96.76924628651116 45.5174783698562, -96.84308728657994 45.584090369918236, -96.85499028659102 45.609122369941545, -96.83279628657036 45.65068736998026, -96.65739128640699 45.738970370062475, -96.60461028635784 45.80826437012701, -96.58795528634232 45.81785437013595, -96.56692128632274 45.93411037024421, -96.56180228631797 45.947683370256854, -96.57621528633139 46.0212793703254, -96.55193128630877 46.09552937039455, -96.57116628632669 46.17717437047059, -96.58789028634227 46.191918370484316, -96.58645628634093 46.2154133705062, -96.59818328635185 46.23868237052787, -96.60207428635547 46.33632437061881, -96.61486128636739 46.3508123706323, -96.65210128640207 46.35943337064033, -96.68822828643572 46.41221837068949, -96.70968228645569 46.42716837070341, -96.71489428646055 46.46
 871837074211, -96.74031628648423 46.4894323707614, -96.75122728649438 46.58861937085378, -96.77104128651284 46.59998337086436, -96.78431728652521 46.624112370886834, -96.79024628653073 46.6297733708921, -96.79369528653393 46.67880437093777, -96.78155628652263 46.70704437096407, -96.78038228652154 46.76231237101554, -96.7971972865372 46.812033371061844, -96.76825028651024 46.84486137109242, -96.77806128651937 46.86734937111336, -96.75691128649969 46.92278037116499, -96.76306828650542 46.936261371177544, -96.78792528652856 46.93218437117375, -96.78971028653022 46.948202371188664, -96.80188728654157 46.95584337119578, -96.79342528653369 46.96964137120863, -96.81677228655543 46.96977937120876, -96.82453128656266 47.003436371240106, -96.83529628657269 47.010231371246434, -96.82260828656086 47.033932371268506, -96.82696428656492 47.07883237131033, -96.81915128655764 47.09260437132315, -96.83916428657629 47.15188637137836, -96.82649128656448 47.17006337139529, -96.83706528657433 47.2404583
 71460846, -96.84962328658602 47.25684337147611, -96.83771428657494 47.2938843715106, -96.84674728658335 47.3146023715299, -96.83846128657564 47.34224337155564, -96.85063128658696 47.36095437157307, -96.8398272865769 47.38411737159464, -96.85000528658638 47.408936371617756, -96.86724828660245 47.41308737162162, -96.8558272865918 47.43675337164366, -96.86668428660191 47.46153737166674, -96.85161528658789 47.50061937170314, -96.86068728659633 47.521356371722455, -96.84918828658562 47.54456837174408, -96.85866428659445 47.56297837176122, -96.85221728658844 47.601151371796774, -96.87333528660811 47.61525537180991, -96.8894252866231 47.67392537186454, -96.92365928665498 47.71409437190196, -96.93201228666275 47.763506371947976, -96.9578302866868 47.79444037197678, -96.98389328671108 47.809661371990956, -96.97723128670486 47.82802937200807, -97.0003402867264 47.87019737204734, -97.02056628674522 47.87556937205234, -97.01533128674035 47.917890372091755, -97.04805328677082 47.95492437212624, 
 -97.06707128678855 48.04816437221308, -97.09272128681243 48.07034437223374, -97.0990302868183 48.10097237226226, -97.12187328683957 48.11636937227661, -97.12091828683869 48.1427743723012, -97.13651328685322 48.14839837230643, -97.11606528683417 48.15922337231652, -97.13744328685408 48.16776937232447, -97.13629128685301 48.17522737233142, -97.13727528685392 48.19506337234989, -97.13082828684792 48.20374237235798, -97.11089928682935 48.20760537236157, -97.13975428685623 48.22175537237475, -97.10923528682781 48.22804937238061, -97.12755428684487 48.23352337238571, -97.12378428684136 48.259173372409606, -97.13665528685334 48.264483372414546, -97.11171428683012 48.277876372427016, -97.11268328683101 48.286147372434726, -97.13051328684763 48.29304037244114, -97.11372128683199 48.294882372442856, -97.11475128683294 48.303618372451, -97.1326342868496 48.31096937245784, -97.11259128683093 48.319926372466185, -97.13713628685379 48.32599137247183, -97.1311232868482 48.361491372504894, -97.1503
 9628686614 48.3632153725065, -97.13378628685068 48.3724543725151, -97.135205286852 48.38441037252623, -97.15881928687399 48.38820637252977, -97.12912428684633 48.4078853725481, -97.14982328686561 48.40999137255006, -97.1516472868673 48.41961237255902, -97.12260128684025 48.416110372555764, -97.1196332868375 48.43710237257531, -97.14361328685983 48.43810937257625, -97.13459428685142 48.51731437265001, -97.14832728686422 48.51795137265061, -97.13938528685588 48.534648372666155, -97.15553728687092 48.53839837266965, -97.1604352868755 48.545078372675874, -97.14661828686262 48.54953737268002, -97.16794328688249 48.56226337269187, -97.15212728686775 48.572856372701736, -97.1581922868734 48.583640372711784, -97.14081228685721 48.586905372714824, -97.14471828686085 48.61402437274008, -97.12295828684059 48.62076837274636, -97.12744428684476 48.62979437275477, -97.1076302868263 48.629946372754915, -97.09716928681657 48.67452937279643, -97.1167392868348 48.695243372815725, -97.11010128682861 4
 8.708583372828144, -97.13480628685163 48.72623837284459, -97.13250228684947 48.747218372864126, -97.14789828686382 48.75565337287198, -97.13924628685575 48.76354237287933, -97.14751628686346 48.781170372895744, -97.17394428688807 48.801514372914696, -97.16471228687948 48.81036837292294, -97.1804222868941 48.81553737292775, -97.17120428688553 48.83598037294679, -97.17572728688974 48.87375737298198, -97.21636928692759 48.931830373036064, -97.22943628693976 48.999987373099536, -96.40691528617373 48.999982373099535, -95.27665728512109 48.99999137309954, -95.15775028501035 48.99999637309955, -95.15186728500487 49.37173037344575, -94.83203928470701 49.33080637340764, -94.68125028456657 48.87716137298514, -94.69443228457885 48.77761537289244, -94.57031228446326 48.71367637283289, -94.43063428433317 48.7107853728302, -94.29233728420436 48.70771137282733, -94.23082728414708 48.65198737277544, -93.84390428378673 48.62473737275006, -93.81268528375766 48.52540837265755, -93.78110628372825 48.51
 159037264468, -93.51413928347961 48.534271372665806, -93.46533928343416 48.54952037268001, -93.45776928342711 48.592710372720234, -93.30423628328413 48.637163372761634, -93.09144228308595 48.62658437275178, -92.94692628295135 48.62835537275343, -92.7290002827484 48.54021137267134, -92.6418202826672 48.54034937267147, -92.62638028265282 48.50282437263652, -92.69882128272029 48.49472137262897, -92.70664328272757 48.460370372596984, -92.49752928253282 48.44007237257807, -92.45634528249447 48.40216937254277, -92.47332228251028 48.357499372501174, -92.37011628241416 48.22077937237384, -92.27691828232736 48.24434037239578, -92.30027228234911 48.29831137244605, -92.27613128232663 48.35231937249635, -92.12596228218678 48.3667563725098, -92.03518328210222 48.355508372499315, -91.9795342820504 48.25039837240143, -91.78881528187279 48.20614537236021, -91.71193828180118 48.19677537235149, -91.70373128179354 48.11483537227518, -91.56877528166785 48.104457372265514, -91.57156228167045 48.04357137
 22088, -91.23944628136114 48.08129837224394, -91.02714828116342 48.19533937235015, -90.86449528101194 48.25419837240497, -90.74336528089913 48.088443372250595, -90.5674552807353 48.12169937228157, -90.55683528072541 48.092750372254606, -90.1452702803421 48.11277037227325, -90.02670028023168 48.08607937224839, -89.98702028019473 48.023556372190164, -89.90038928011404 47.99250537216125, -89.74931027997334 48.0264843721929, -89.53067327976972 48.00165637216977, -89.62564527985818 47.9925613721613, -89.63637327986817 47.95939037213041, -89.99967728020651 47.82456437200484, -90.50963328068146 47.70993837189809, -91.02147528115815 47.4610583716663, -91.46865728157461 47.12493537135326, -91.8009692818841 46.927086371169, -92.08849228215188 46.79189737104309, -92.21462428226934 46.668204370927896, -92.30314828235178 46.66657537092638, -92.287271282337 46.658786370919124, -92.28868528233832 46.415984370692996, -92.28894428233856 46.15660037045143, -92.28937028233896 46.07323137037378, -92.32
 737228237436 46.056878370358554, -92.34622528239191 46.022596370326625, -92.36496328240936 46.01624837032071, -92.42499928246528 46.02550437032933, -92.46234528250005 45.98119737028807, -92.52397728255745 45.98258337028936, -92.55267228258418 45.9512693702602, -92.66620828268992 45.91570337022708, -92.7062402827272 45.89095837020403, -92.73409728275314 45.84498037016121, -92.7487622827668 45.837302370154056, -92.77910728279507 45.763340370085174, -92.83363628284584 45.73089037005495, -92.86001928287041 45.71056237003602, -92.88539728289405 45.64495536997492, -92.87683128288607 45.57883636991335, -92.83503728284715 45.56340236989897, -92.7621752827793 45.56426336989977, -92.72815428274761 45.54724236988392, -92.68542128270781 45.470053369812035, -92.6548172826793 45.45522136979822, -92.64497528267015 45.43945236978353, -92.64875128267366 45.395466369742564, -92.6848692827073 45.3630763697124, -92.70738428272827 45.318201369670604, -92.74659328276478 45.297603369651426, -92.7554192827
 73 45.21237636957205, -92.76258328277967 45.18661236954806, -92.74493528276324 45.15642236951994, -92.74542228276368 45.1130043694795, -92.7967622828115 45.06561036943536, -92.76299128278005 45.02211936939486, -92.7671262827839 45.00100536937519, -92.74976828276773 44.93565536931433, -92.75392628277162 44.915002369295095, -92.77187128278833 44.899496369280655, -92.76426328278124 44.862234369245954, -92.76102828277823 44.83537136922094, -92.80558428281972 44.746160369137854, -92.73714528275598 44.713594369107525, -92.63036728265654 44.64265236904146, -92.60897328263661 44.61029236901132, -92.5092152825437 44.575159368978596, -92.34087228238693 44.5528353689578, -92.32047828236793 44.540491368946306, -92.29668728234577 44.49218236890132, -92.24910028230146 44.45621636886782, -92.20613728226144 44.43839436885122, -92.09133328215452 44.415589368829984, -91.97238628204374 44.36448736878239, -91.93886828201254 44.33911136875876, -91.92275428199753 44.31752036873865, -91.92234928199714 44.
 28834136871147, -91.8886942819658 44.25749536868275, -91.84874428192859 44.191187368620994, -91.75321928183963 44.137227368570734, -91.65223328174558 44.066895368505236, -91.6017862816986 44.04082236848096, -91.56916228166821 44.034955368475494, -91.52842028163028 44.034215368474804, -91.42590228153479 43.98561936842954, -91.37335728148585 43.94719136839375, -91.29194828141004 43.847190368300616, -91.251105281372 43.788075368245565, -91.25891628137927 43.722395368184394, -91.25838928137878 43.67732236814242, -91.23299028135513 43.59889036806938, -91.24055828136218 43.54871236802264, -91.22356628134635 43.500808367978024, -91.61109928170727 43.50062636797786, -91.73036628181835 43.49957136797688)))
+OR	Oregon	MULTIPOLYGON (((-121.441509309489 41.99433436657502, -122.28470531027429 42.000764366581, -123.22210231114731 42.00219136658233, -123.51320431141842 41.99783336657828, -123.81914631170335 41.99294836657373, -124.20644431206405 41.997648366578105, -124.35224631219984 42.09867736667219, -124.41506231225834 42.245894366809296, -124.43781831227955 42.429608366980396, -124.39176331223663 42.55302736709534, -124.40107831224532 42.62269936716022, -124.55961731239297 42.83245736735557, -124.4853463123238 42.955454367470125, -124.386772312232 43.261589367755235, -124.40607631224998 43.3001973677912, -124.27399431212697 43.45910536793919, -124.22600431208227 43.60500436807507, -124.15832531201923 43.85711836830987, -124.11831931198198 44.269515368693945, -124.05440531192245 44.6621393690596, -124.07556831194216 44.81473836920172, -124.00757231187885 45.03610336940788, -123.95660731183138 45.292965369647106, -123.98056031185368 45.485084369826026, -123.93667431181281 45.5079663698473
 4, -123.8921083117713 45.47405036981576, -123.85950731174094 45.499082369839066, -123.9534153118284 45.568528369903746,

<TRUNCATED>

[28/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/CachingDoubleValueSource.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/CachingDoubleValueSource.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/CachingDoubleValueSource.java
new file mode 100644
index 0000000..73d25ca
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/CachingDoubleValueSource.java
@@ -0,0 +1,93 @@
+/*
+ * 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.util;
+
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.queries.function.ValueSource;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Caches the doubleVal of another value source in a HashMap
+ * so that it is computed only once.
+ * @lucene.internal
+ */
+public class CachingDoubleValueSource extends ValueSource {
+
+  final ValueSource source;
+  final Map<Integer, Double> cache;
+
+  public CachingDoubleValueSource( ValueSource source )
+  {
+    this.source = source;
+    cache = new HashMap<>();
+  }
+
+  @Override
+  public String description() {
+    return "Cached["+source.description()+"]";
+  }
+
+  @Override
+  public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
+    final int base = readerContext.docBase;
+    final FunctionValues vals = source.getValues(context,readerContext);
+    return new FunctionValues() {
+
+      @Override
+      public double doubleVal(int doc) {
+        Integer key = Integer.valueOf( base+doc );
+        Double v = cache.get( key );
+        if( v == null ) {
+          v = Double.valueOf( vals.doubleVal(doc) );
+          cache.put( key, v );
+        }
+        return v.doubleValue();
+      }
+
+      @Override
+      public float floatVal(int doc) {
+        return (float)doubleVal(doc);
+      }
+
+      @Override
+      public String toString(int doc) {
+        return doubleVal(doc)+"";
+      }
+    };
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    CachingDoubleValueSource that = (CachingDoubleValueSource) o;
+
+    if (source != null ? !source.equals(that.source) : that.source != null) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    return source != null ? source.hashCode() : 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/DistanceToShapeValueSource.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/DistanceToShapeValueSource.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/DistanceToShapeValueSource.java
new file mode 100644
index 0000000..57cad87
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/DistanceToShapeValueSource.java
@@ -0,0 +1,122 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
+import org.apache.lucene.search.Explanation;
+import org.apache.lucene.search.IndexSearcher;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.distance.DistanceCalculator;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Shape;
+
+/**
+ * The distance from a provided Point to a Point retrieved from a ValueSource via
+ * {@link org.apache.lucene.queries.function.FunctionValues#objectVal(int)}. The distance
+ * is calculated via a {@link com.spatial4j.core.distance.DistanceCalculator}.
+ *
+ * @lucene.experimental
+ */
+public class DistanceToShapeValueSource extends ValueSource {
+  private final ValueSource shapeValueSource;
+  private final Point queryPoint;
+  private final double multiplier;
+  private final DistanceCalculator distCalc;
+
+  //TODO if FunctionValues returns NaN; will things be ok?
+  private final double nullValue;//computed
+
+  public DistanceToShapeValueSource(ValueSource shapeValueSource, Point queryPoint,
+                                    double multiplier, SpatialContext ctx) {
+    this.shapeValueSource = shapeValueSource;
+    this.queryPoint = queryPoint;
+    this.multiplier = multiplier;
+    this.distCalc = ctx.getDistCalc();
+    this.nullValue =
+        (ctx.isGeo() ? 180 * multiplier : Double.MAX_VALUE);
+  }
+
+  @Override
+  public String description() {
+    return "distance(" + queryPoint + " to " + shapeValueSource.description() + ")*" + multiplier + ")";
+  }
+
+  @Override
+  public void createWeight(Map context, IndexSearcher searcher) throws IOException {
+    shapeValueSource.createWeight(context, searcher);
+  }
+
+  @Override
+  public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
+    final FunctionValues shapeValues = shapeValueSource.getValues(context, readerContext);
+
+    return new DoubleDocValues(this) {
+      @Override
+      public double doubleVal(int doc) {
+        Shape shape = (Shape) shapeValues.objectVal(doc);
+        if (shape == null || shape.isEmpty())
+          return nullValue;
+        Point pt = shape.getCenter();
+        return distCalc.distance(queryPoint, pt) * multiplier;
+      }
+
+      @Override
+      public Explanation explain(int doc) {
+        Explanation exp = super.explain(doc);
+        List<Explanation> details = new ArrayList<>(Arrays.asList(exp.getDetails()));
+        details.add(shapeValues.explain(doc));
+        return Explanation.match(exp.getValue(), exp.getDescription(), details);
+      }
+    };
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    DistanceToShapeValueSource that = (DistanceToShapeValueSource) o;
+
+    if (!queryPoint.equals(that.queryPoint)) return false;
+    if (Double.compare(that.multiplier, multiplier) != 0) return false;
+    if (!shapeValueSource.equals(that.shapeValueSource)) return false;
+    if (!distCalc.equals(that.distCalc)) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result;
+    long temp;
+    result = shapeValueSource.hashCode();
+    result = 31 * result + queryPoint.hashCode();
+    temp = Double.doubleToLongBits(multiplier);
+    result = 31 * result + (int) (temp ^ (temp >>> 32));
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapeAreaValueSource.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapeAreaValueSource.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapeAreaValueSource.java
new file mode 100644
index 0000000..dd391d1
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapeAreaValueSource.java
@@ -0,0 +1,116 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Shape;
+
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
+import org.apache.lucene.search.Explanation;
+import org.apache.lucene.search.IndexSearcher;
+
+/**
+ * The area of a Shape retrieved from a ValueSource via
+ * {@link org.apache.lucene.queries.function.FunctionValues#objectVal(int)}.
+ *
+ * @see Shape#getArea(com.spatial4j.core.context.SpatialContext)
+ *
+ * @lucene.experimental
+ */
+public class ShapeAreaValueSource extends ValueSource {
+  private final ValueSource shapeValueSource;
+  private final SpatialContext ctx;//not part of identity; should be associated with shapeValueSource indirectly
+  private final boolean geoArea;
+  private double multiplier;
+
+  public ShapeAreaValueSource(ValueSource shapeValueSource, SpatialContext ctx, boolean geoArea, double multiplier) {
+    this.shapeValueSource = shapeValueSource;
+    this.ctx = ctx;
+    this.geoArea = geoArea;
+    this.multiplier = multiplier;
+  }
+
+  @Override
+  public String description() {
+    return "area(" + shapeValueSource.description() + ",geo=" + geoArea + ")";
+  }
+
+  @Override
+  public void createWeight(Map context, IndexSearcher searcher) throws IOException {
+    shapeValueSource.createWeight(context, searcher);
+  }
+
+  @Override
+  public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
+    final FunctionValues shapeValues = shapeValueSource.getValues(context, readerContext);
+
+    return new DoubleDocValues(this) {
+      @Override
+      public double doubleVal(int doc) {
+        Shape shape = (Shape) shapeValues.objectVal(doc);
+        if (shape == null || shape.isEmpty())
+          return 0;//or NaN?
+        //This part of Spatial4j API is kinda weird. Passing null means 2D area, otherwise geo
+        //   assuming ctx.isGeo()
+        return shape.getArea( geoArea ? ctx : null ) * multiplier;
+      }
+
+      @Override
+      public boolean exists(int doc) {
+        return shapeValues.exists(doc);
+      }
+
+      @Override
+      public Explanation explain(int doc) {
+        Explanation exp = super.explain(doc);
+        List<Explanation> details = new ArrayList<>(Arrays.asList(exp.getDetails()));
+        details.add(shapeValues.explain(doc));
+        return Explanation.match(exp.getValue(), exp.getDescription(), details);
+      }
+    };
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    ShapeAreaValueSource that = (ShapeAreaValueSource) o;
+
+    if (geoArea != that.geoArea) return false;
+    if (!shapeValueSource.equals(that.shapeValueSource)) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = shapeValueSource.hashCode();
+    result = 31 * result + (geoArea ? 1 : 0);
+    return result;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapeFieldCache.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapeFieldCache.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapeFieldCache.java
new file mode 100644
index 0000000..480369b
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapeFieldCache.java
@@ -0,0 +1,54 @@
+/*
+ * 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.util;
+
+import com.spatial4j.core.shape.Shape;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Bounded Cache of Shapes associated with docIds.  Note, multiple Shapes can be
+ * associated with a given docId.
+ * <p>
+ * WARNING: This class holds the data in an extremely inefficient manner as all Points are in memory as objects and they
+ * are stored in many ArrayLists (one per document).  So it works but doesn't scale.  It will be replaced in the future.
+ *
+ * @lucene.internal
+ */
+public class ShapeFieldCache<T extends Shape> {
+  private final List<T>[] cache;
+  public final int defaultLength;
+
+  @SuppressWarnings({"unchecked", "rawtypes"})
+  public ShapeFieldCache( int length, int defaultLength ) {
+    cache = new List[length];
+    this.defaultLength= defaultLength;
+  }
+
+  public void add( int docid, T s ) {
+    List<T> list = cache[docid];
+    if( list == null ) {
+      list = cache[docid] = new ArrayList<>(defaultLength);
+    }
+    list.add( s );
+  }
+
+  public List<T> getShapes( int docid ) {
+    return cache[docid];
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheDistanceValueSource.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheDistanceValueSource.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheDistanceValueSource.java
new file mode 100644
index 0000000..e4cb146
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheDistanceValueSource.java
@@ -0,0 +1,112 @@
+/*
+ * 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.util;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.distance.DistanceCalculator;
+import com.spatial4j.core.shape.Point;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.queries.function.ValueSource;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An implementation of the Lucene ValueSource that returns the spatial distance
+ * between an input point and a document's points in
+ * {@link ShapeFieldCacheProvider}. The shortest distance is returned if a
+ * document has more than one point.
+ *
+ * @lucene.internal
+ */
+public class ShapeFieldCacheDistanceValueSource extends ValueSource {
+
+  private final SpatialContext ctx;
+  private final Point from;
+  private final ShapeFieldCacheProvider<Point> provider;
+  private final double multiplier;
+
+  public ShapeFieldCacheDistanceValueSource(SpatialContext ctx,
+      ShapeFieldCacheProvider<Point> provider, Point from, double multiplier) {
+    this.ctx = ctx;
+    this.from = from;
+    this.provider = provider;
+    this.multiplier = multiplier;
+  }
+
+  @Override
+  public String description() {
+    return getClass().getSimpleName()+"("+provider+", "+from+")";
+  }
+
+  @Override
+  public FunctionValues getValues(Map context, final LeafReaderContext readerContext) throws IOException {
+    return new FunctionValues() {
+      private final ShapeFieldCache<Point> cache =
+          provider.getCache(readerContext.reader());
+      private final Point from = ShapeFieldCacheDistanceValueSource.this.from;
+      private final DistanceCalculator calculator = ctx.getDistCalc();
+      private final double nullValue = (ctx.isGeo() ? 180 * multiplier : Double.MAX_VALUE);
+
+      @Override
+      public float floatVal(int doc) {
+        return (float) doubleVal(doc);
+      }
+
+      @Override
+      public double doubleVal(int doc) {
+
+        List<Point> vals = cache.getShapes( doc );
+        if( vals != null ) {
+          double v = calculator.distance(from, vals.get(0));
+          for( int i=1; i<vals.size(); i++ ) {
+            v = Math.min(v, calculator.distance(from, vals.get(i)));
+          }
+          return v * multiplier;
+        }
+        return nullValue;
+      }
+
+      @Override
+      public String toString(int doc) {
+        return description() + "=" + floatVal(doc);
+      }
+    };
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    ShapeFieldCacheDistanceValueSource that = (ShapeFieldCacheDistanceValueSource) o;
+
+    if (!ctx.equals(that.ctx)) return false;
+    if (!from.equals(that.from)) return false;
+    if (!provider.equals(that.provider)) return false;
+    if (multiplier != that.multiplier) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    return from.hashCode();
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheProvider.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheProvider.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheProvider.java
new file mode 100644
index 0000000..04c52f7
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheProvider.java
@@ -0,0 +1,87 @@
+/*
+ * 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.util;
+
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.index.*;
+import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.util.BytesRef;
+
+import java.io.IOException;
+import java.util.WeakHashMap;
+import java.util.logging.Logger;
+
+/**
+ * Provides access to a {@link ShapeFieldCache} for a given {@link org.apache.lucene.index.LeafReader}.
+ *
+ * If a Cache does not exist for the Reader, then it is built by iterating over
+ * the all terms for a given field, reconstructing the Shape from them, and adding
+ * them to the Cache.
+ *
+ * @lucene.internal
+ */
+public abstract class ShapeFieldCacheProvider<T extends Shape> {
+  private Logger log = Logger.getLogger(getClass().getName());
+
+  // it may be a List<T> or T
+  WeakHashMap<IndexReader, ShapeFieldCache<T>> sidx = new WeakHashMap<>();
+
+  protected final int defaultSize;
+  protected final String shapeField;
+
+  public ShapeFieldCacheProvider(String shapeField, int defaultSize) {
+    this.shapeField = shapeField;
+    this.defaultSize = defaultSize;
+  }
+
+  protected abstract T readShape( BytesRef term );
+
+  public synchronized ShapeFieldCache<T> getCache(LeafReader reader) throws IOException {
+    ShapeFieldCache<T> idx = sidx.get(reader);
+    if (idx != null) {
+      return idx;
+    }
+    long startTime = System.currentTimeMillis();
+
+    log.fine("Building Cache [" + reader.maxDoc() + "]");
+    idx = new ShapeFieldCache<>(reader.maxDoc(),defaultSize);
+    int count = 0;
+    PostingsEnum docs = null;
+    Terms terms = reader.terms(shapeField);
+    if (terms != null) {
+      TermsEnum te = terms.iterator();
+      BytesRef term = te.next();
+      while (term != null) {
+        T shape = readShape(term);
+        if( shape != null ) {
+          docs = te.postings(docs, PostingsEnum.NONE);
+          Integer docid = docs.nextDoc();
+          while (docid != DocIdSetIterator.NO_MORE_DOCS) {
+            idx.add( docid, shape );
+            docid = docs.nextDoc();
+            count++;
+          }
+        }
+        term = te.next();
+      }
+    }
+    sidx.put(reader, idx);
+    long elapsed = System.currentTimeMillis() - startTime;
+    log.fine("Cached: [" + count + " in " + elapsed + "ms] " + idx);
+    return idx;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapePredicateValueSource.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapePredicateValueSource.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapePredicateValueSource.java
new file mode 100644
index 0000000..b1dfaaa
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/ShapePredicateValueSource.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial.util;
+
+import com.spatial4j.core.shape.Shape;
+
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.queries.function.docvalues.BoolDocValues;
+import org.apache.lucene.search.Explanation;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.spatial.query.SpatialOperation;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A boolean ValueSource that compares a shape from a provided ValueSource with a given Shape and sees
+ * if it matches a given {@link SpatialOperation} (the predicate).
+ *
+ * @lucene.experimental
+ */
+public class ShapePredicateValueSource extends ValueSource {
+  private final ValueSource shapeValuesource;//the left hand side
+  private final SpatialOperation op;
+  private final Shape queryShape;//the right hand side (constant)
+
+  /**
+   *
+   * @param shapeValuesource Must yield {@link Shape} instances from its objectVal(doc). If null
+   *                         then the result is false. This is the left-hand (indexed) side.
+   * @param op the predicate
+   * @param queryShape The shape on the right-hand (query) side.
+   */
+  public ShapePredicateValueSource(ValueSource shapeValuesource, SpatialOperation op, Shape queryShape) {
+    this.shapeValuesource = shapeValuesource;
+    this.op = op;
+    this.queryShape = queryShape;
+  }
+
+  @Override
+  public String description() {
+    return shapeValuesource + " " + op + " " + queryShape;
+  }
+
+  @Override
+  public void createWeight(Map context, IndexSearcher searcher) throws IOException {
+    shapeValuesource.createWeight(context, searcher);
+  }
+
+  @Override
+  public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
+    final FunctionValues shapeValues = shapeValuesource.getValues(context, readerContext);
+
+    return new BoolDocValues(this) {
+      @Override
+      public boolean boolVal(int doc) {
+        Shape indexedShape = (Shape) shapeValues.objectVal(doc);
+        if (indexedShape == null)
+          return false;
+        return op.evaluate(indexedShape, queryShape);
+      }
+
+      @Override
+      public Explanation explain(int doc) {
+        Explanation exp = super.explain(doc);
+        List<Explanation> details = new ArrayList<>(Arrays.asList(exp.getDetails()));
+        details.add(shapeValues.explain(doc));
+        return Explanation.match(exp.getValue(), exp.getDescription(), details);
+      }
+    };
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    ShapePredicateValueSource that = (ShapePredicateValueSource) o;
+
+    if (!shapeValuesource.equals(that.shapeValuesource)) return false;
+    if (!op.equals(that.op)) return false;
+    if (!queryShape.equals(that.queryShape)) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = shapeValuesource.hashCode();
+    result = 31 * result + op.hashCode();
+    result = 31 * result + queryShape.hashCode();
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/package-info.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/package-info.java
new file mode 100644
index 0000000..08a872a
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/util/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Advanced spatial utilities.
+ */
+package org.apache.lucene.spatial.util;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/DistanceValueSource.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/DistanceValueSource.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/DistanceValueSource.java
new file mode 100644
index 0000000..d31fd59
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/DistanceValueSource.java
@@ -0,0 +1,120 @@
+/*
+ * 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.vector;
+
+import com.spatial4j.core.distance.DistanceCalculator;
+import com.spatial4j.core.shape.Point;
+import org.apache.lucene.index.LeafReader;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.DocValues;
+import org.apache.lucene.index.NumericDocValues;
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.util.Bits;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * An implementation of the Lucene ValueSource model that returns the distance
+ * for a {@link PointVectorStrategy}.
+ *
+ * @lucene.internal
+ */
+public class DistanceValueSource extends ValueSource {
+
+  private PointVectorStrategy strategy;
+  private final Point from;
+  private final double multiplier;
+
+  /**
+   * Constructor.
+   */
+  public DistanceValueSource(PointVectorStrategy strategy, Point from, double multiplier) {
+    this.strategy = strategy;
+    this.from = from;
+    this.multiplier = multiplier;
+  }
+
+  /**
+   * Returns the ValueSource description.
+   */
+  @Override
+  public String description() {
+    return "DistanceValueSource("+strategy+", "+from+")";
+  }
+
+  /**
+   * Returns the FunctionValues used by the function query.
+   */
+  @Override
+  public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
+    LeafReader reader = readerContext.reader();
+
+    final NumericDocValues ptX = DocValues.getNumeric(reader, strategy.getFieldNameX());
+    final NumericDocValues ptY = DocValues.getNumeric(reader, strategy.getFieldNameY());
+    final Bits validX =  DocValues.getDocsWithField(reader, strategy.getFieldNameX());
+    final Bits validY =  DocValues.getDocsWithField(reader, strategy.getFieldNameY());
+
+    return new FunctionValues() {
+
+      private final Point from = DistanceValueSource.this.from;
+      private final DistanceCalculator calculator = strategy.getSpatialContext().getDistCalc();
+      private final double nullValue =
+          (strategy.getSpatialContext().isGeo() ? 180 * multiplier : Double.MAX_VALUE);
+
+      @Override
+      public float floatVal(int doc) {
+        return (float) doubleVal(doc);
+      }
+
+      @Override
+      public double doubleVal(int doc) {
+        // make sure it has minX and area
+        if (validX.get(doc)) {
+          assert validY.get(doc);
+          return calculator.distance(from, Double.longBitsToDouble(ptX.get(doc)), Double.longBitsToDouble(ptY.get(doc))) * multiplier;
+        }
+        return nullValue;
+      }
+
+      @Override
+      public String toString(int doc) {
+        return description() + "=" + floatVal(doc);
+      }
+    };
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    DistanceValueSource that = (DistanceValueSource) o;
+
+    if (!from.equals(that.from)) return false;
+    if (!strategy.equals(that.strategy)) return false;
+    if (multiplier != that.multiplier) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    return from.hashCode();
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/PointVectorStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/PointVectorStrategy.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/PointVectorStrategy.java
new file mode 100644
index 0000000..f572f82
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/PointVectorStrategy.java
@@ -0,0 +1,178 @@
+/*
+ * 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.vector;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Circle;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.document.LegacyDoubleField;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.FieldType;
+import org.apache.lucene.queries.function.FunctionRangeQuery;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.ConstantScoreQuery;
+import org.apache.lucene.search.LegacyNumericRangeQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.spatial.SpatialStrategy;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.apache.lucene.spatial.query.UnsupportedSpatialOperation;
+
+/**
+ * Simple {@link SpatialStrategy} which represents Points in two numeric {@link
+ * org.apache.lucene.document.LegacyDoubleField}s.  The Strategy's best feature is decent distance sort.
+ *
+ * <p>
+ * <b>Characteristics:</b>
+ * <br>
+ * <ul>
+ * <li>Only indexes points; just one per field value.</li>
+ * <li>Can query by a rectangle or circle.</li>
+ * <li>{@link
+ * org.apache.lucene.spatial.query.SpatialOperation#Intersects} and {@link
+ * SpatialOperation#IsWithin} is supported.</li>
+ * <li>Uses the FieldCache for
+ * {@link #makeDistanceValueSource(com.spatial4j.core.shape.Point)} and for
+ * searching with a Circle.</li>
+ * </ul>
+ *
+ * <p>
+ * <b>Implementation:</b>
+ * <p>
+ * This is a simple Strategy.  Search works with {@link org.apache.lucene.search.LegacyNumericRangeQuery}s on
+ * an x and y pair of fields.  A Circle query does the same bbox query but adds a
+ * ValueSource filter on
+ * {@link #makeDistanceValueSource(com.spatial4j.core.shape.Point)}.
+ * <p>
+ * One performance shortcoming with this strategy is that a scenario involving
+ * both a search using a Circle and sort will result in calculations for the
+ * spatial distance being done twice -- once for the filter and second for the
+ * sort.
+ *
+ * @lucene.experimental
+ */
+public class PointVectorStrategy extends SpatialStrategy {
+
+  public static final String SUFFIX_X = "__x";
+  public static final String SUFFIX_Y = "__y";
+
+  private final String fieldNameX;
+  private final String fieldNameY;
+
+  public int precisionStep = 8; // same as solr default
+
+  public PointVectorStrategy(SpatialContext ctx, String fieldNamePrefix) {
+    super(ctx, fieldNamePrefix);
+    this.fieldNameX = fieldNamePrefix+SUFFIX_X;
+    this.fieldNameY = fieldNamePrefix+SUFFIX_Y;
+  }
+
+  public void setPrecisionStep( int p ) {
+    precisionStep = p;
+    if (precisionStep<=0 || precisionStep>=64)
+      precisionStep=Integer.MAX_VALUE;
+  }
+
+  String getFieldNameX() {
+    return fieldNameX;
+  }
+
+  String getFieldNameY() {
+    return fieldNameY;
+  }
+
+  @Override
+  public Field[] createIndexableFields(Shape shape) {
+    if (shape instanceof Point)
+      return createIndexableFields((Point) shape);
+    throw new UnsupportedOperationException("Can only index Point, not " + shape);
+  }
+
+  /** @see #createIndexableFields(com.spatial4j.core.shape.Shape) */
+  public Field[] createIndexableFields(Point point) {
+    FieldType doubleFieldType = new FieldType(LegacyDoubleField.TYPE_NOT_STORED);
+    doubleFieldType.setNumericPrecisionStep(precisionStep);
+    Field[] f = new Field[2];
+    f[0] = new LegacyDoubleField(fieldNameX, point.getX(), doubleFieldType);
+    f[1] = new LegacyDoubleField(fieldNameY, point.getY(), doubleFieldType);
+    return f;
+  }
+
+  @Override
+  public ValueSource makeDistanceValueSource(Point queryPoint, double multiplier) {
+    return new DistanceValueSource(this, queryPoint, multiplier);
+  }
+
+  @Override
+  public ConstantScoreQuery makeQuery(SpatialArgs args) {
+    if(! SpatialOperation.is( args.getOperation(),
+        SpatialOperation.Intersects,
+        SpatialOperation.IsWithin ))
+      throw new UnsupportedSpatialOperation(args.getOperation());
+    Shape shape = args.getShape();
+    if (shape instanceof Rectangle) {
+      Rectangle bbox = (Rectangle) shape;
+      return new ConstantScoreQuery(makeWithin(bbox));
+    } else if (shape instanceof Circle) {
+      Circle circle = (Circle)shape;
+      Rectangle bbox = circle.getBoundingBox();
+      Query approxQuery = makeWithin(bbox);
+      BooleanQuery.Builder bqBuilder = new BooleanQuery.Builder();
+      FunctionRangeQuery vsRangeQuery =
+          new FunctionRangeQuery(makeDistanceValueSource(circle.getCenter()), 0.0, circle.getRadius(), true, true);
+      bqBuilder.add(approxQuery, BooleanClause.Occur.FILTER);//should have lowest "cost" value; will drive iteration
+      bqBuilder.add(vsRangeQuery, BooleanClause.Occur.FILTER);
+      return new ConstantScoreQuery(bqBuilder.build());
+    } else {
+      throw new UnsupportedOperationException("Only Rectangles and Circles are currently supported, " +
+          "found [" + shape.getClass() + "]");//TODO
+    }
+  }
+
+  /**
+   * Constructs a query to retrieve documents that fully contain the input envelope.
+   */
+  private Query makeWithin(Rectangle bbox) {
+    BooleanQuery.Builder bq = new BooleanQuery.Builder();
+    BooleanClause.Occur MUST = BooleanClause.Occur.MUST;
+    if (bbox.getCrossesDateLine()) {
+      //use null as performance trick since no data will be beyond the world bounds
+      bq.add(rangeQuery(fieldNameX, null/*-180*/, bbox.getMaxX()), BooleanClause.Occur.SHOULD );
+      bq.add(rangeQuery(fieldNameX, bbox.getMinX(), null/*+180*/), BooleanClause.Occur.SHOULD );
+      bq.setMinimumNumberShouldMatch(1);//must match at least one of the SHOULD
+    } else {
+      bq.add(rangeQuery(fieldNameX, bbox.getMinX(), bbox.getMaxX()), MUST);
+    }
+    bq.add(rangeQuery(fieldNameY, bbox.getMinY(), bbox.getMaxY()), MUST);
+    return bq.build();
+  }
+
+  private LegacyNumericRangeQuery<Double> rangeQuery(String fieldName, Double min, Double max) {
+    return LegacyNumericRangeQuery.newDoubleRange(
+        fieldName,
+        precisionStep,
+        min,
+        max,
+        true,
+        true);//inclusive
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/package-info.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/package-info.java
new file mode 100644
index 0000000..f8dffe2
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Spatial strategy that uses two fields.
+ */
+package org.apache.lucene.spatial.vector;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/overview.html
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/overview.html b/lucene/spatial-extras/src/java/overview.html
new file mode 100644
index 0000000..1b7afd1
--- /dev/null
+++ b/lucene/spatial-extras/src/java/overview.html
@@ -0,0 +1,67 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+  <head>
+    <title>Apache Lucene Spatial-Extras Module</title>
+  </head>
+  <body>
+
+  <h1>The Spatial-Extras Module for Apache Lucene</h1>
+
+  <p>
+    The spatial-extras module, new to Lucene 6.5, is the new home for the original
+    lucene <a href="../spatial/overview-summary.html">spatial</a> module.
+    The principle interface to this module is a {@link org.apache.lucene.spatial.SpatialStrategy}
+    which encapsulates an approach to indexing and searching
+    based on shapes.  Different Strategies have different features and
+    performance profiles, which are documented at each Strategy implementation
+    class level.
+  </p>
+  <p>
+    For some sample code showing how to use the API, see
+      SpatialExample.java in the tests.
+  </p>
+<p>
+    The spatial-extras module uses
+    <a href="https://github.com/spatial4j/spatial4j">Spatial4j</a>
+    heavily.  Spatial4j is an ASL licensed library with these capabilities:
+    <ul>
+    <li>Provides shape implementations, namely point, rectangle,
+      and circle.  Both geospatial contexts and plain 2D Euclidean/Cartesian contexts
+      are supported.
+      With an additional dependency, it adds polygon and other geometry shape
+      support via integration with
+      <a href="http://sourceforge.net/projects/jts-topo-suite/">JTS Topology Suite</a>.
+      This includes dateline wrap support.</li>
+    <li>Shape parsing and serialization, including
+      <a href="http://en.wikipedia.org/wiki/Well-known_text">Well-Known Text (WKT)</a>
+      (via JTS).</li>
+    <li>Distance and other spatial related math calculations.</li>
+    </ul>
+  </p>
+  <p>
+    Historical note: The new spatial-extras module was once known as
+    Lucene Spatial Playground (LSP) as an external project.  In ~March 2012, LSP
+    split into the spatial module as part of Lucene and Spatial4j externally. A
+    large chunk of the LSP implementation originated as SOLR-2155 which uses
+    trie/prefix-tree algorithms with a geohash encoding.  That approach is
+    implemented in {@link org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy}
+    today.
+  </p>
+
+  </body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test-files/cities-Intersects-BBox.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test-files/cities-Intersects-BBox.txt b/lucene/spatial-extras/src/test-files/cities-Intersects-BBox.txt
new file mode 100644
index 0000000..e85748c
--- /dev/null
+++ b/lucene/spatial-extras/src/test-files/cities-Intersects-BBox.txt
@@ -0,0 +1,3 @@
+[San Francisco] G5391959 @ Intersects(ENVELOPE(-122.524918, -122.360123, 37.817108, 37.674973))
+[Wellington] G2179537 @ Intersects(ENVELOPE(174.711456, 174.854279, -41.213837, -41.360779))
+[Barcelona] G6544100 G3128760  @  Intersects(ENVELOPE(2.127228, 2.226105, 41.408844, 41.333313))
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test-files/data/LUCENE-4464.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test-files/data/LUCENE-4464.txt b/lucene/spatial-extras/src/test-files/data/LUCENE-4464.txt
new file mode 100644
index 0000000..dfb5a40
--- /dev/null
+++ b/lucene/spatial-extras/src/test-files/data/LUCENE-4464.txt
@@ -0,0 +1,3 @@
+#id	name	shape
+poly1	poly1	POLYGON ((-93.17288720912401 45.280265431486754, -93.17232270645628 45.2802724629027, -93.17229737711205 45.279497574052314, -93.1722224854913 45.277577770983854, -93.17218124644266 45.276747010395624, -93.16722650828461 45.276819421108826, -93.16581262076448 45.27684404529939, -93.16363038333625 45.276882054199596, -93.16249244695301 45.276929493877525, -93.16247370542268 45.27641118002343, -93.16246893668628 45.276279382682894, -93.1624671302382 45.274701063846244, -93.16246679905096 45.273381422360785, -93.16247689122851 45.273189685068424, -93.16249146710186 45.27291249464421, -93.16249868565903 45.272467966062614, -93.16247955957382 45.27177209534391, -93.1624787718002 45.27127651548793, -93.16247840794293 45.27104491547271, -93.16247917486976 45.27087000356473, -93.1624817727418 45.270279315147775, -93.16252487154968 45.26996729342093, -93.16254025661699 45.26976826077157, -93.16247902564132 45.269527941604, -93.16242684845764 45.2692774997531, -93.16242126018722 4
 5.26894470083864, -93.16241263011544 45.26769394309626, -93.16246809168283 45.26571736107859, -93.16247263940593 45.26195548919013, -93.16253090997651 45.258615729449964, -93.16256878834184 45.25650987969364, -93.1626048203569 45.2546538608912, -93.16265873943591 45.251876274357876, -93.16275002007988 45.2510418534315, -93.16282237443883 45.25042383853711, -93.16286421513767 45.249181538840595, -93.16288289220509 45.24862697953288, -93.1629601120395 45.248250613185206, -93.16301002807151 45.24802483983211, -93.16301621932013 45.247670020958665, -93.16301519349018 45.247478630666144, -93.16303001333274 45.24727504082362, -93.16303463142393 45.24713931946277, -93.16302280990728 45.2470107542477, -93.16298327344437 45.24685970499298, -93.16294217154733 45.246633449219054, -93.16294315088282 45.246419514713516, -93.16295754265565 45.24621538933992, -93.16296755618336 45.24580786412655, -93.16296268372803 45.245362220836384, -93.16296319568123 45.245046689033444, -93.16297766811293 45.24
 481357093532, -93.16296370759883 45.2445699039253, -93.16294931051515 45.24231310924752, -93.16294559876471 45.24173111255096, -93.16295568091667 45.240776604513705, -93.1629609359182 45.24053954238007, -93.1629658719288 45.24019639978025, -93.1625355179785 45.24018482062359, -93.15847246037083 45.24007549519542, -93.15641780558727 45.24006372373029, -93.15470331938288 45.24002991133718, -93.1515176880772 45.240038275846665, -93.14892151971884 45.24004508944476, -93.14597353408716 45.240012024375574, -93.14198169289922 45.239944427606616, -93.14246140322608 45.21441838866706, -93.14239730934507 45.20842345035032, -93.14240307538512 45.203669567890245, -93.13209436867183 45.20385828388066, -93.13238731320574 45.19696183064252, -93.13244550539693 45.19559178376392, -93.13255875219626 45.19292582294682, -93.12747185962866 45.19303831675316, -93.12741613255534 45.196689407842044, -93.12341724811418 45.196748516850086, -93.12336451543653 45.19630050937325, -93.12233270487748 45.196311891
 79194, -93.12244695905335 45.18943470505876, -93.12752867296823 45.18931969757398, -93.1275981937757 45.18579899512077, -93.12249095182051 45.18589579364393, -93.12250905286206 45.18230218633591, -93.11745336177542 45.182234528897865, -93.11742994994425 45.17494109686777, -93.11234677240823 45.174914625057596, -93.11232755368056 45.178541858988, -93.09142510557425 45.17830768889981, -93.0878908215621 45.18208021181682, -93.04087986544745 45.182020129318005, -93.02011304608662 45.18206919600553, -92.99725469269949 45.18154883703301, -92.9866455346556 45.18162938363265, -92.98002761377205 45.181741313792635, -92.97460481311676 45.1817232745721, -92.95815138711436 45.18159971137449, -92.95832448011389 45.16710586357575, -92.95821211351648 45.15266682925307, -92.94804883291458 45.152678829402525, -92.94820512323935 45.14582287000843, -92.94821449767262 45.14541149629351, -92.93808126859899 45.145435393255234, -92.938064080176 45.1464755574292, -92.93790172782569 45.15630033200825, -92.9
 3776855788026 45.156299483202375, -92.93416458772786 45.15627656196406, -92.92776593175911 45.156235863288074, -92.92779198321185 45.15260820059608, -92.9228643837518 45.15257871636257, -92.91761510291013 45.15254730117589, -92.91755895303478 45.15978011255037, -92.90742527225278 45.15975884768774, -92.90734951861361 45.16700513027527, -92.90243435593408 45.16697925148226, -92.90226994175299 45.16697838648701, -92.90228225598396 45.16960751885433, -92.90228682505473 45.170583562524534, -92.89838293958822 45.17058359192683, -92.89776337384279 45.17058359923907, -92.89720228241329 45.170636798053465, -92.89720546113311 45.171648743169875, -92.89721045187194 45.17323675651512, -92.89721215942521 45.17377958217219, -92.8972133713998 45.17416655315385, -92.89752994284902 45.17416793500262, -92.90230392627396 45.174188700362095, -92.90230695467396 45.17483317173849, -92.90230939234701 45.175352265892315, -92.90231342163983 45.17620891826606, -92.9023378718661 45.18141217320357, -92.898291
 95794003 45.18137903577816, -92.89197067471983 45.181327269964534, -92.86573042754982 45.18111238484799, -92.86537258386163 45.18110945889712, -92.86579788828743 45.16683341076013, -92.85850341291456 45.166840495697045, -92.85576616527777 45.1668651317465, -92.8455814929548 45.16695680639518, -92.8403672382906 45.167003741522834, -92.84037534438275 45.166359277271084, -92.83914257524022 45.166407761467035, -92.83786182101709 45.16655768366541, -92.83762301824869 45.16658563659705, -92.83700510809494 45.16665797101126, -92.83700330475195 45.1670405349812, -92.83520392476423 45.16704646605868, -92.83519998302931 45.1672093811339, -92.83518241658018 45.17114095264113, -92.8351705215998 45.17380185475555, -92.83516823773242 45.17431412368648, -92.82501384033566 45.174380025018145, -92.82373302900695 45.174963166130034, -92.82127603798283 45.17799740439804, -92.81495695139105 45.17798284134312, -92.81498212776123 45.18394380043827, -92.81496335262872 45.20297631525698, -92.81496300732859
  45.2033351264244, -92.8149190887153 45.20460132029917, -92.81473397710002 45.21, -92.8198460035041 45.21, -92.81985864578533 45.21352006541341, -92.81476009958381 45.21350519453624, -92.81473397710002 45.211, -92.79434616877515 45.20979982288059, -92.79434485197183 45.210003888814526, -92.7942994128934 45.217028016258524, -92.79414754531777 45.217027433538036, -92.75950558164095 45.216895251116746, -92.75791266717471 45.216889175072694, -92.75634408090858 45.21737192056616, -92.75539334998972 45.21781096867505, -92.75544275719047 45.219840930849315, -92.75232263931744 45.219847708152834, -92.75345360864661 45.22241622713623, -92.75393100188802 45.22290500013628, -92.75454911801587 45.22425238152991, -92.75465656863904 45.22441872007679, -92.75478824580995 45.22461252606749, -92.75573200183275 45.22594899943625, -92.7559326169467 45.2263989667922, -92.756173357985 45.22677479396459, -92.75628338889855 45.227185737281864, -92.75651400327136 45.22770300256764, -92.75667800355963 45.22
 8069998932774, -92.75745600158125 45.23052599674398, -92.75737071502948 45.23131853178694, -92.75760683805547 45.23212889115611, -92.7575248338702 45.23249816977935, -92.75760900807862 45.233043995948975, -92.75740715667484 45.23498808590038, -92.75739258433605 45.23515457917446, -92.75736004212973 45.235441823970014, -92.75728900664646 45.2361259970008, -92.75750924881613 45.23833187652166, -92.75783421241928 45.239151014730965, -92.75799784052033 45.2401986059374, -92.75814399470411 45.24075700093086, -92.75910499448543 45.24444199845027, -92.75927217262658 45.246363482652335, -92.759708376526 45.24795052230262, -92.76024900009054 45.24960000150479, -92.76026400206055 45.25171699829065, -92.75984499770836 45.25286799832034, -92.75883599655404 45.25442699925451, -92.75592228367496 45.256779108256175, -92.75559993467031 45.25707105760005, -92.75540261715516 45.25725539605134, -92.75458100472993 45.258140999051975, -92.75362100152239 45.25941899619891, -92.75258800661327 45.261786002
 1943, -92.7523530053651 45.26244399793552, -92.7521330910868 45.26318539548715, -92.75199986320791 45.26381589028983, -92.7519440909167 45.26415703570502, -92.75192391851121 45.26559725594415, -92.75247612752318 45.26746623235666, -92.75254008932185 45.26768063816608, -92.75267394173396 45.268130176728555, -92.75287910082022 45.2688320393691, -92.7530104867237 45.26921012533672, -92.75329204456183 45.26980089141646, -92.75414711285153 45.2712720735891, -92.7552129966957 45.27237299947564, -92.75574299378961 45.27288399662051, -92.75678399520334 45.273891998902435, -92.75750199664172 45.27442999825494, -92.75801999923948 45.274822998224586, -92.75866321741752 45.27578539520815, -92.7589271849383 45.27616491445647, -92.75924599787822 45.27671899844492, -92.75941999802778 45.27718649803985, -92.75960999785612 45.27731999914, -92.75978699565532 45.27743849638546, -92.76004300142414 45.277978995119405, -92.76061199738588 45.27882799808139, -92.76117799722955 45.280582999200305, -92.76136
 19999475 45.28220800042353, -92.76167096088638 45.2836803717185, -92.76198517744629 45.2850267976271, -92.76206945308458 45.2853507773657, -92.76202745146396 45.286658659028, -92.76204199858486 45.28698499388888, -92.76201199644161 45.28793199672008, -92.76200399722086 45.28821299803955, -92.76121399640145 45.28913599914764, -92.7603870028136 45.28991599406784, -92.75871000510011 45.29096499709372, -92.75799200634881 45.291140996050984, -92.75687800551285 45.29148399845183, -92.75507700319366 45.2919269952758, -92.75480030147037 45.291986779669465, -92.74569331443023 45.29606484000191, -92.74555580404507 45.29614422445335, -92.74523588498667 45.29631411941847, -92.76071968429389 45.29617634034589, -92.79448651640953 45.29587194744184, -92.82553071142016 45.29634288822895, -92.82523623967 45.28697641600944, -92.8246113114385 45.27459391718561, -92.82414631698042 45.26733414102221, -92.83443181636859 45.267466042102846, -92.83450366471794 45.265666722695805, -92.8395297613521 45.26570
 782145342, -92.83954651660255 45.2675117790906, -92.85488466565545 45.267633226883305, -92.85446380439222 45.260381978642265, -92.8530801070886 45.256940031152055, -92.8746167542768 45.2569553750289, -92.87517983690772 45.26774272327855, -92.88032459143679 45.26775272915376, -92.88028907325248 45.27498539130476, -92.885429695981 45.27499516876503, -92.88541044770409 45.27862274921294, -92.8854460740016 45.28269595676258, -92.8858306795285 45.28583335680999, -92.89095994168375 45.285838365551086, -92.89147668909354 45.290056047991875, -92.89183494474656 45.292995365557246, -92.89287941280966 45.29621886928581, -92.93574219102997 45.296382695230655, -92.9366855829562 45.29639453639271, -92.93730010601949 45.29640233268984, -92.93773633826109 45.296407862218295, -92.95031707870098 45.29656663627082, -92.95732733387652 45.29663267857854, -92.95723233585932 45.305785498930874, -92.95755812361517 45.31807293816823, -92.9575313307762 45.325662873647204, -92.96200814151011 45.32569410734573
 , -92.96201051236334 45.33056403262943, -92.95763365021791 45.330562956294486, -92.95750484414667 45.34006528297348, -92.95740249422305 45.3523406680097, -92.96272753035339 45.352295608902175, -92.96260253143201 45.363259386181184, -92.95732537061275 45.363286992831206, -92.95715614538045 45.36869421119079, -92.97302216756823 45.36904156334545, -92.9731090974606 45.37554810693529, -92.98760985309234 45.37555619312347, -92.98429494637762 45.38215591061988, -92.9924184629002 45.38233326055907, -93.01850137881846 45.38277378724873, -93.01956464133914 45.41174708503911, -93.03973263863047 45.412106304897264, -93.06569776540464 45.412656360563524, -93.08346874844985 45.41297273973574, -93.09263091377308 45.41335460313747, -93.1012213163472 45.413720365424695, -93.10759754754753 45.41373499082408, -93.14214551761233 45.41373101611429, -93.1421802894172 45.40666589187203, -93.14209155741717 45.38498980813781, -93.14398965535287 45.369981475770224, -93.13861914028635 45.36992203894643, -93.
 13946982733188 45.35540022959687, -93.14362673736643 45.35542059147377, -93.14338145836778 45.34816201728363, -93.14259222919002 45.34815677471413, -93.14123737100095 45.34271091215897, -93.14120170425102 45.34166175650565, -93.14159640367895 45.340845226624126, -93.16430988689314 45.34107128935172, -93.1641229508536 45.33731028186903, -93.163783504365 45.32713863170596, -93.16354815472778 45.31568179036097, -93.1634974864936 45.3115083559682, -93.16335415000293 45.30838048844207, -93.16326942872365 45.30653168298998, -93.16286993093225 45.29781375116957, -93.16292479029 45.297483756012355, -93.16251838572086 45.29748043583636, -93.16242411934059 45.29340169752503, -93.16237192435095 45.291513658346155, -93.16125915756838 45.29101148729498, -93.16224903398384 45.290456018307964, -93.16243543883762 45.29031474509565, -93.16248365754952 45.29016960982244, -93.1625270557542 45.28932067928762, -93.16350507037129 45.28940282906675, -93.16413761242012 45.28944739938537, -93.16430369461645
  45.289411531953206, -93.164472138656 45.28937514511818, -93.16431016328954 45.288334379584406, -93.16422830296436 45.28780835028316, -93.16373011428878 45.287807744950875, -93.16348868413621 45.28778563548775, -93.16304669211718 45.28779811404454, -93.16252493722239 45.28781182501286, -93.1625182014603 45.28601279964026, -93.1625127377889 45.28416325442296, -93.1717122152211 45.28391079701647, -93.17291828928865 45.28387769615237, -93.17292468588315 45.28327561174209, -93.1729215958459 45.28269914269899, -93.17290904354249 45.28216703245599, -93.17290447076888 45.281410092382885, -93.17289432485279 45.28068732375472, -93.17288720912401 45.280265431486754))
+poly2	poly2	POLYGON((-93.26592485308495 45.18931973506328, -93.26373519655886 45.18933815615675, -93.2637828223868 45.18660121752107, -93.26280973893772 45.18656958194617, -93.2603275028686 45.186488876325654, -93.25976682936536 45.18646929139094, -93.25877703935303 45.18686109057519, -93.25788401039608 45.18633824889261, -93.25713811973642 45.186864792015704, -93.25660115549654 45.18628640445176, -93.24081325108644 45.18609354693712, -93.2356823133177 45.1860308697061, -93.23474944979115 45.186019474019865, -93.23478565684188 45.18266103967549, -93.23072066106351 45.18267669158043, -93.22480340476464 45.18267437402639, -93.21952101307244 45.18267371221728, -93.21950131879755 45.184689058075534, -93.21950381582634 45.18590104693386, -93.21950547892035 45.186708829298695, -93.21948324866376 45.18808573281868, -93.21947477056304 45.188619717930756, -93.2194751507154 45.1899146284615, -93.22390334137022 45.18991091026497, -93.2245904557543 45.18993775453468, -93.2245784309098 45.190287
 02856576, -93.2245932424241 45.19081834295508, -93.22460314163764 45.19137779927979, -93.22459067695124 45.19162607300785, -93.22458367100289 45.19176562022696, -93.22354968949122 45.191760188521705, -93.22131530006368 45.19175468785821, -93.22018302807493 45.19175762419069, -93.21965635944291 45.19175898704962, -93.21824735047468 45.191762639857636, -93.21840068968908 45.191840907619024, -93.21858279007587 45.191950538176606, -93.21874378970492 45.19205449060312, -93.21893581214327 45.192204972059955, -93.21911499957261 45.19238205879934, -93.21934767139433 45.192628269473076, -93.21954522989743 45.1928508489684, -93.21972003978802 45.19304459976245, -93.21997538064213 45.19332124206717, -93.22011354045264 45.193470928079385, -93.22046875034326 45.19384479955501, -93.2206469058326 45.19404172922978, -93.22079845082156 45.194244494502364, -93.2209416400795 45.19447508772328, -93.22107397875365 45.19474417974581, -93.2211368505518 45.19490985928749, -93.22118231976518 45.195047277731
 625, -93.22124659963487 45.19525315038074, -93.22128314962913 45.195396480693944, -93.22130715028514 45.195564823375, -93.22131862069979 45.195757013030224, -93.22130704484326 45.19599065847414, -93.22127083850016 45.19622942989826, -93.22124456959293 45.19636257994296, -93.22120917947201 45.19651471803614, -93.22115328972328 45.196774039833144, -93.22110053150747 45.19700410181286, -93.22105123806169 45.19721904984113, -93.21939747849284 45.19720754776318, -93.21658707902952 45.19719901749774, -93.21405492494755 45.19718389708806, -93.21060961905127 45.19716332241369, -93.20846870851273 45.19715738191871, -93.20635420918421 45.19714993030806, -93.20384995444252 45.19713947337882, -93.20382099935851 45.195915480832355, -93.20379040854755 45.195493880093856, -93.20373937951182 45.19525460196455, -93.20366799901262 45.194730001052676, -93.20359944927 45.194273469702246, -93.20351980946141 45.19386975065817, -93.20336890147132 45.1933312322322, -93.20348773988103 45.19317805926476, -93
 .20364964522179 45.19294381603321, -93.20373782170354 45.192758795441485, -93.20378634041538 45.1925589245846, -93.20378780054193 45.1924118820702, -93.20373224993294 45.192246366644895, -93.20366678053941 45.192063182244134, -93.20349712021084 45.19164111034226, -93.20336402335359 45.191262445660406, -93.20333661484061 45.19107258136713, -93.20334012614478 45.19082850506992, -93.20338500114326 45.190584969374704, -93.20346313590359 45.19035226093307, -93.20353125074365 45.19015096025676, -93.20337886118753 45.19012069933683, -93.20280004152556 45.18999823901699, -93.20236430223584 45.1898748712581, -93.20223796285948 45.18983446401002, -93.20171338128353 45.189666689690526, -93.20105175026708 45.18940210042135, -93.20059509118217 45.18937347081525, -93.20014399997638 45.18935951962055, -93.1999096512546 45.18934032171285, -93.19969162075753 45.18934030912719, -93.19953079227915 45.18938062079311, -93.19930724128803 45.189471810355066, -93.19836742091539 45.18954495845859, -93.19790
 904174889 45.189755310346555, -93.19770094626355 45.18978905045578, -93.19728573057267 45.1898563687543, -93.19706717806918 45.18978234280038, -93.1961191012612 45.18980511056629, -93.19583707702907 45.18977039110604, -93.19495714548943 45.18966207098092, -93.19409949054268 45.18955648989894, -93.19361391124465 45.18954758129998, -93.19142135137997 45.189507349701145, -93.18867729058191 45.18943758222878, -93.18766468614145 45.18941183701645, -93.1869063815807 45.18939255950494, -93.18676117212036 45.18939312363656, -93.18583601993124 45.18939673056086, -93.18362870083628 45.18940533739182, -93.18015920861117 45.189432919714875, -93.17748344774633 45.18940274982507, -93.17100678798263 45.18934067185518, -93.1680509570817 45.18931686702863, -93.16712265967519 45.189309389152754, -93.1632729184803 45.189289560128074, -93.1524420382428 45.189137301470666, -93.1488330300988 45.189087681208825, -93.14258337454692 45.18900953614207, -93.1425728385595 45.18964797148711, -93.14257129908563 
 45.19044710129245, -93.14256839076815 45.191380659844974, -93.14257549009486 45.192639988690985, -93.14256591028126 45.193624481846925, -93.1425562203409 45.19475816134898, -93.14254671019609 45.19564806883362, -93.14253591314012 45.19592629600891, -93.1425191002932 45.19635953895129, -93.14240307328147 45.20366956427245, -93.14239731024965 45.20842345007226, -93.14246141142196 45.2144183909345, -93.14198170032972 45.23994442974387, -93.14597353942523 45.240012030562795, -93.14892151981124 45.24004509174428, -93.15151768504401 45.24003827478177, -93.15470331907811 45.2400299112851, -93.15641781022819 45.240063720104146, -93.15847245794774 45.24007548756677, -93.16253551804624 45.24018481776239, -93.16296586932476 45.24019639699945, -93.16296093749654 45.240539543608094, -93.16295567833508 45.24077659970959, -93.16294559992268 45.24173110984731, -93.16294931429802 45.242313107885224, -93.16296371061823 45.24456989801016, -93.16297766989932 45.24481356907269, -93.16296319587042 45.245
 04668430867, -93.16296267909655 45.24536222031531, -93.16296756070733 45.24580785775435, -93.16295754084666 45.24621538734816, -93.16294315030365 45.24641950970948, -93.1629421699368 45.246633444731216, -93.16298326866249 45.24685970478054, -93.16302280494743 45.24701074802872, -93.1630346343297 45.247139320093076, -93.16303000914128 45.24727503858908, -93.16301519072017 45.24747862874394, -93.16301622062082 45.247670019373224, -93.16301002844395 45.24802483903903, -93.16296010836595 45.248250609285236, -93.16288288941641 45.248626979189, -93.16286421036493 45.24918153632857, -93.16282236866641 45.25042383853131, -93.16275001793326 45.25104184745623, -93.16265874011768 45.251876269431015, -93.1626048141941 45.25465385517585, -93.162568780952 45.25650987775294, -93.16253090903855 45.25861572819838, -93.16247264162719 45.261955487720506, -93.16246809047925 45.26571735738526, -93.16241263022145 45.267693939529536, -93.16242125944353 45.26894469986081, -93.16242684956876 45.269277499432
 015, -93.16247902269161 45.26952793567272, -93.16254025984375 45.269768259020054, -93.1625248689828 45.26996728874923, -93.16248176954191 45.27027930739088, -93.16247917649272 45.270869996810376, -93.16247840915516 45.27104490906511, -93.16247877426206 45.27127651283899, -93.162479560911 45.27177208702322, -93.16249869026827 45.272467959171365, -93.16249147172434 45.27291248854739, -93.16247688682598 45.27318968296259, -93.16246680083795 45.27338141702519, -93.1624671298516 45.27470105775956, -93.16246893968787 45.276279379505084, -93.1624737063593 45.2764111771935, -93.16249244905424 45.276929488819604, -93.16363037995181 45.27688204948932, -93.16581262202895 45.276844043452684, -93.16722651010657 45.27681941864911, -93.17218124072862 45.27674700948904, -93.1722224784459 45.27757776899891, -93.17229737034532 45.279497570305445, -93.17232269933695 45.28027246109518, -93.17288721010608 45.28026543129147, -93.1728943187817 45.2806873180744, -93.17290447218495 45.28141008817547, -93.17
 290904002667 45.28216703008146, -93.17292159084371 45.28269913830247, -93.17292468118433 45.283275608616165, -93.17291828224536 45.28387769767021, -93.1717122127579 45.283910797244246, -93.16251273143365 45.28416325629099, -93.16251820094257 45.28601279797615, -93.16252493935717 45.287811833132764, -93.16304669905364 45.28779811692505, -93.16348868871324 45.28778563925035, -93.16373011962693 45.28780774767522, -93.16422830587629 45.28780835110865, -93.1643101699488 45.28833437868018, -93.16447213914093 45.289375147768524, -93.16430369361024 45.28941153310711, -93.16413761723706 45.28944740219967, -93.16350507286433 45.289402832527344, -93.16252705964098 45.289320683284735, -93.16248365939401 45.29016961156254, -93.16243543831087 45.29031475002342, -93.16224903970826 45.2904560215217, -93.16125915934788 45.29101149209126, -93.16237192796683 45.291513661220456, -93.16242412151107 45.29340170072084, -93.16251838980172 45.29748044313293, -93.16292479370829 45.29748376064082, -93.1863909
 4534673 45.29767533425263, -93.18833342032521 45.29769119188229, -93.1925428426471 45.29770437859642, -93.19474753040078 45.29771128804242, -93.19765740975974 45.29769541872667, -93.20297591868295 45.29776263827187, -93.20683144906876 45.29774197003572, -93.20883497923562 45.297766559466794, -93.21546742887979 45.297768422222155, -93.22617724980643 45.29791971794424, -93.23408017640227 45.298023690859175, -93.2343080073169 45.288444186545625, -93.23432525195352 45.287995322205425, -93.23469515647318 45.269279712377234, -93.23475627635968 45.266203358381446, -93.23560542207227 45.26619551047824, -93.23899176558338 45.26613779367068, -93.24250527367546 45.26608234822973, -93.243445378056 45.26606503829342, -93.24512861083372 45.2660344570852, -93.24588057830995 45.26602026067889, -93.24713274287363 45.26599455787498, -93.25036838013868 45.26592734514467, -93.25172461510564 45.265900698298395, -93.25236738024864 45.265888260809106, -93.25481754173921 45.26583307838667, -93.255713579529
 06 45.265819559899164, -93.2594981489083 45.26575415212897, -93.26098138766197 45.265754375486374, -93.26155216698102 45.26565612540643, -93.26170097145753 45.26562288963898, -93.26208574477789 45.26553876835043, -93.26245875524685 45.265434673708015, -93.26277275191426 45.265316250819595, -93.26311663127117 45.26517251314189, -93.26346212923646 45.26500240317637, -93.26393572774133 45.26477558787491, -93.2651820516718 45.26406759657772, -93.26518110226205 45.26337226279194, -93.26515218908767 45.26311636791454, -93.26518703008779 45.262871689663605, -93.2652064900752 45.26265582104258, -93.2652110298225 45.26215614194132, -93.26522443086994 45.26112430402238, -93.26522989950563 45.260703199933474, -93.26524872191168 45.25930812973533, -93.26525187087448 45.258897852775995, -93.26525857049303 45.258025812056765, -93.26527734826267 45.256675072153314, -93.26528081766433 45.25612813038996, -93.265287399575 45.25512698071874, -93.26530031054412 45.253711671615115, -93.26531490547187 45
 .25273002640574, -93.26532214123614 45.252243491267, -93.26533817105908 45.25062180123498, -93.26535413994274 45.24906421173263, -93.26536141910549 45.24841165046578, -93.26536638602661 45.24796649509243, -93.26537318826473 45.24735637067748, -93.26539798003012 45.24589779189643, -93.265404909549 45.24454674190931, -93.2654060939449 45.24296904311022, -93.26540624905046 45.24276127146885, -93.26540843815205 45.2420263885843, -93.26541275006169 45.240577352345994, -93.2654375717671 45.238843301612725, -93.26544518264211 45.237906888690105, -93.26544940933664 45.23738688110566, -93.26546966016808 45.236093591927926, -93.2654781584622 45.235359229961944, -93.26548338867605 45.23490715107922, -93.26553582901259 45.23354268990693, -93.26554071996831 45.23330119833777, -93.26555987026248 45.2323552839169, -93.26557251955711 45.23173040973764, -93.26556626032777 45.22975235185782, -93.26556606661761 45.229367333607186, -93.26556579189545 45.228823722705066, -93.26562882232702 45.2268722061
 76665, -93.26571073971922 45.224335971082276, -93.26574560622672 45.22192222321787, -93.26574836877063 45.22173093256304, -93.26577033227747 45.22021043432355, -93.26578588443306 45.21913391123174, -93.26580662128347 45.21769799745153, -93.26580983179628 45.217475736026664, -93.26581322607608 45.217240685631346, -93.26590715360736 45.210737684073244, -93.26591966090616 45.209871711997586, -93.2659016992406 45.20722015227932, -93.26587484243684 45.203254836571126, -93.26585637174348 45.20052765082941, -93.26585684827346 45.19841676076085, -93.26587786763154 45.19732741144391, -93.2658624676632 45.1970879109074, -93.2659274100303 45.194004979577755, -93.26595017983325 45.191531890895845, -93.26595423366354 45.19092534610275, -93.26593099287571 45.190637988686554, -93.2659274057232 45.18986823069059, -93.26592485308495 45.18931973506328))
\ No newline at end of file


[15/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/PackedQuadPrefixTree.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/PackedQuadPrefixTree.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/PackedQuadPrefixTree.java
deleted file mode 100644
index 6fe2bff..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/PackedQuadPrefixTree.java
+++ /dev/null
@@ -1,459 +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.prefix.tree;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.SpatialRelation;
-import com.spatial4j.core.shape.impl.RectangleImpl;
-import org.apache.lucene.util.BytesRef;
-
-/**
- * Uses a compact binary representation of 8 bytes to encode a spatial quad trie.
- *
- * The binary representation is as follows:
- * <pre>
- * CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDL
- *
- * Where C = Cell bits (2 per quad)
- *       D = Depth bits (5 with max of 29 levels)
- *       L = isLeaf bit
- * </pre>
- *
- * It includes a built-in "pruneLeafyBranches" setting (true by default) similar to
- * {@link org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy#setPruneLeafyBranches(boolean)} although
- * this one only prunes at the target detail level (where it has the most effect).  Usually you should disable RPT's
- * prune, since it is very memory in-efficient.
- *
- * @lucene.experimental
- */
-public class PackedQuadPrefixTree extends QuadPrefixTree {
-  public static final int MAX_LEVELS_POSSIBLE = 29;
-  protected static final byte[] QUAD = new byte[] {0x00, 0x01, 0x02, 0x03};
-
-  protected boolean leafyPrune = true;
-
-  /**
-   * Factory for creating {@link PackedQuadPrefixTree} instances with useful defaults.
-   */
-  public static class Factory extends QuadPrefixTree.Factory {
-    @Override
-    protected SpatialPrefixTree newSPT() {
-      return new PackedQuadPrefixTree(ctx, maxLevels != null ? maxLevels : MAX_LEVELS_POSSIBLE);
-    }
-  }
-
-  public PackedQuadPrefixTree(SpatialContext ctx, int maxLevels) {
-    super(ctx, maxLevels);
-    if (maxLevels > MAX_LEVELS_POSSIBLE) {
-      throw new IllegalArgumentException("maxLevels of " + maxLevels + " exceeds limit of " + MAX_LEVELS_POSSIBLE);
-    }
-  }
-
-  @Override
-  public String toString() {
-    return getClass().getSimpleName() + "(maxLevels:" + maxLevels + ",ctx:" + ctx + ",prune:" + leafyPrune + ")";
-  }
-
-  @Override
-  public Cell getWorldCell() {
-    return new PackedQuadCell(0x0L);
-  }
-
-  @Override
-  public Cell getCell(Point p, int level) {
-    List<Cell> cells = new ArrayList<>(1);
-    build(xmid, ymid, 0, cells, 0x0L, ctx.makePoint(p.getX(), p.getY()), level);
-    return cells.get(0);//note cells could be longer if p on edge
-  }
-
-  protected void build(double x, double y, int level, List<Cell> matches, long term, Shape shape, int maxLevel) {
-    double w = levelW[level] / 2;
-    double h = levelH[level] / 2;
-
-    // Z-Order
-    // http://en.wikipedia.org/wiki/Z-order_%28curve%29
-    checkBattenberg(QUAD[0], x - w, y + h, level, matches, term, shape, maxLevel);
-    checkBattenberg(QUAD[1], x + w, y + h, level, matches, term, shape, maxLevel);
-    checkBattenberg(QUAD[2], x - w, y - h, level, matches, term, shape, maxLevel);
-    checkBattenberg(QUAD[3], x + w, y - h, level, matches, term, shape, maxLevel);
-  }
-
-  protected void checkBattenberg(byte quad, double cx, double cy, int level, List<Cell> matches,
-                               long term, Shape shape, int maxLevel) {
-    // short-circuit if we find a match for the point (no need to continue recursion)
-    if (shape instanceof Point && !matches.isEmpty())
-      return;
-    double w = levelW[level] / 2;
-    double h = levelH[level] / 2;
-
-    SpatialRelation v = shape.relate(ctx.makeRectangle(cx - w, cx + w, cy - h, cy + h));
-
-    if (SpatialRelation.DISJOINT == v) {
-      return;
-    }
-
-    // set bits for next level
-    term |= (((long)(quad))<<(64-(++level<<1)));
-    // increment level
-    term = ((term>>>1)+1)<<1;
-
-    if (SpatialRelation.CONTAINS == v || (level >= maxLevel)) {
-      matches.add(new PackedQuadCell(term, v.transpose()));
-    } else {// SpatialRelation.WITHIN, SpatialRelation.INTERSECTS
-      build(cx, cy, level, matches, term, shape, maxLevel);
-    }
-  }
-
-  @Override
-  public Cell readCell(BytesRef term, Cell scratch) {
-    PackedQuadCell cell = (PackedQuadCell) scratch;
-    if (cell == null)
-      cell = (PackedQuadCell) getWorldCell();
-    cell.readCell(term);
-    return cell;
-  }
-
-  @Override
-  public CellIterator getTreeCellIterator(Shape shape, int detailLevel) {
-    if (detailLevel > maxLevels) {
-      throw new IllegalArgumentException("detailLevel:" + detailLevel +" exceed max: " + maxLevels);
-    }
-    return new PrefixTreeIterator(shape, (short) detailLevel);
-  }
-
-  public boolean isPruneLeafyBranches() {
-    return leafyPrune;
-  }
-
-  /** Like {@link org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy#setPruneLeafyBranches(boolean)}
-   * but more memory efficient and only applies to the detailLevel, where it has the most effect. */
-  public void setPruneLeafyBranches( boolean pruneLeafyBranches ) {
-    this.leafyPrune = pruneLeafyBranches;
-  }
-
-  /** See binary representation in the javadocs of {@link PackedQuadPrefixTree}. */
-  protected class PackedQuadCell extends QuadCell {
-    private long term;
-
-    PackedQuadCell(long term) {
-      super(null, 0, 0);
-      this.term = term;
-      this.b_off = 0;
-      this.bytes = longToByteArray(this.term);
-      this.b_len = 8;
-      readLeafAdjust();
-    }
-
-    PackedQuadCell(long term, SpatialRelation shapeRel) {
-      this(term);
-      this.shapeRel = shapeRel;
-    }
-
-    @Override
-    protected void readCell(BytesRef bytes) {
-      shapeRel = null;
-      shape = null;
-      this.bytes = bytes.bytes;
-      this.b_off = bytes.offset;
-      this.b_len = (short) bytes.length;
-      this.term = longFromByteArray(this.bytes, bytes.offset);
-      readLeafAdjust();
-    }
-
-    private final int getShiftForLevel(final int level) {
-      return 64 - (level<<1);
-    }
-
-    public boolean isEnd(final int level, final int shift) {
-      return (term != 0x0L && ((((0x1L<<(level<<1))-1)-(term>>>shift)) == 0x0L));
-    }
-
-    /**
-     * Get the next cell in the tree without using recursion. descend parameter requests traversal to the child nodes,
-     * setting this to false will step to the next sibling.
-     * Note: This complies with lexicographical ordering, once you've moved to the next sibling there is no backtracking.
-     */
-    public PackedQuadCell nextCell(boolean descend) {
-      final int level = getLevel();
-      final int shift = getShiftForLevel(level);
-      // base case: can't go further
-      if ( (!descend && isEnd(level, shift)) || isEnd(maxLevels, getShiftForLevel(maxLevels))) {
-        return null;
-      }
-      long newTerm;
-      final boolean isLeaf = (term&0x1L)==0x1L;
-      // if descend requested && we're not at the maxLevel
-      if ((descend && !isLeaf && (level != maxLevels)) || level == 0) {
-        // simple case: increment level bits (next level)
-        newTerm = ((term>>>1)+0x1L)<<1;
-      } else {  // we're not descending or we can't descend
-        newTerm = term + (0x1L<<shift);
-        // we're at the last sibling...force descend
-        if (((term>>>shift)&0x3L) == 0x3L) {
-          // adjust level for number popping up
-          newTerm = ((newTerm>>>1) - (Long.numberOfTrailingZeros(newTerm>>>shift)>>>1))<<1;
-        }
-      }
-      return new PackedQuadCell(newTerm);
-    }
-
-    @Override
-    protected void readLeafAdjust() {
-      isLeaf = ((0x1L)&term) == 0x1L;
-      if (getLevel() == getMaxLevels()) {
-        isLeaf = true;
-      }
-    }
-
-    @Override
-    public BytesRef getTokenBytesWithLeaf(BytesRef result) {
-      if (isLeaf) {
-        term |= 0x1L;
-      }
-      return getTokenBytesNoLeaf(result);
-    }
-
-    @Override
-    public BytesRef getTokenBytesNoLeaf(BytesRef result) {
-      if (result == null)
-        return new BytesRef(bytes, b_off, b_len);
-      result.bytes = longToByteArray(this.term);
-      result.offset = 0;
-      result.length = result.bytes.length;
-      return result;
-    }
-
-    @Override
-    public int compareToNoLeaf(Cell fromCell) {
-      PackedQuadCell b = (PackedQuadCell) fromCell;
-      final long thisTerm = (((0x1L)&term) == 0x1L) ? term-1 : term;
-      final long fromTerm = (((0x1L)&b.term) == 0x1L) ? b.term-1 : b.term;
-      final int result = Long.compareUnsigned(thisTerm, fromTerm);
-      assert Math.signum(result)
-          == Math.signum(compare(longToByteArray(thisTerm), 0, 8, longToByteArray(fromTerm), 0, 8)); // TODO remove
-      return result;
-    }
-
-    @Override
-    public int getLevel() {
-      int l = (int)((term >>> 1)&0x1FL);
-      return l;
-    }
-
-    @Override
-    protected Collection<Cell> getSubCells() {
-      List<Cell> cells = new ArrayList<>(4);
-      PackedQuadCell pqc = (new PackedQuadCell(((term&0x1)==0x1) ? this.term-1 : this.term))
-          .nextCell(true);
-      cells.add(pqc);
-      cells.add((pqc = pqc.nextCell(false)));
-      cells.add((pqc = pqc.nextCell(false)));
-      cells.add(pqc.nextCell(false));
-      return cells;
-    }
-
-    @Override
-    protected QuadCell getSubCell(Point p) {
-      return (PackedQuadCell) PackedQuadPrefixTree.this.getCell(p, getLevel() + 1);//not performant!
-    }
-
-    @Override
-    public boolean isPrefixOf(Cell c) {
-      PackedQuadCell cell = (PackedQuadCell)c;
-      return (this.term == 0x0L) || isInternalPrefix(cell);
-    }
-
-    protected boolean isInternalPrefix(PackedQuadCell c) {
-      final int shift = 64 - (getLevel()<<1);
-      return ((term>>>shift)-(c.term>>>shift)) == 0x0L;
-    }
-
-    protected long concat(byte postfix) {
-      // extra leaf bit
-      return this.term | (((long)(postfix))<<((getMaxLevels()-getLevel()<<1)+6));
-    }
-
-    /**
-     * Constructs a bounding box shape out of the encoded cell
-     */
-    @Override
-    protected Rectangle makeShape() {
-      double xmin = PackedQuadPrefixTree.this.xmin;
-      double ymin = PackedQuadPrefixTree.this.ymin;
-      int level = getLevel();
-
-      byte b;
-      for (short l=0, i=1; l<level; ++l, ++i) {
-        b = (byte) ((term>>>(64-(i<<1))) & 0x3L);
-
-        switch (b) {
-          case 0x00:
-            ymin += levelH[l];
-            break;
-          case 0x01:
-            xmin += levelW[l];
-            ymin += levelH[l];
-            break;
-          case 0x02:
-            break;//nothing really
-          case 0x03:
-            xmin += levelW[l];
-            break;
-          default:
-            throw new RuntimeException("unexpected quadrant");
-        }
-      }
-
-      double width, height;
-      if (level > 0) {
-        width = levelW[level - 1];
-        height = levelH[level - 1];
-      } else {
-        width = gridW;
-        height = gridH;
-      }
-      return new RectangleImpl(xmin, xmin + width, ymin, ymin + height, ctx);
-    }
-
-    private long fromBytes(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8) {
-      return ((long)b1 & 255L) << 56 | ((long)b2 & 255L) << 48 | ((long)b3 & 255L) << 40
-          | ((long)b4 & 255L) << 32 | ((long)b5 & 255L) << 24 | ((long)b6 & 255L) << 16
-          | ((long)b7 & 255L) << 8 | (long)b8 & 255L;
-    }
-
-    private byte[] longToByteArray(long value) {
-      byte[] result = new byte[8];
-      for(int i = 7; i >= 0; --i) {
-        result[i] = (byte)((int)(value & 255L));
-        value >>= 8;
-      }
-      return result;
-    }
-
-    private long longFromByteArray(byte[] bytes, int ofs) {
-      assert bytes.length >= 8;
-      return fromBytes(bytes[0+ofs], bytes[1+ofs], bytes[2+ofs], bytes[3+ofs],
-          bytes[4+ofs], bytes[5+ofs], bytes[6+ofs], bytes[7+ofs]);
-    }
-
-    /**
-     * Used for debugging, this will print the bits of the cell
-     */
-    @Override
-    public String toString() {
-      StringBuilder s = new StringBuilder(64);
-      final int numberOfLeadingZeros = Long.numberOfLeadingZeros(term);
-      for (int i = 0; i < numberOfLeadingZeros; i++) {
-        s.append('0');
-      }
-      if (term != 0)
-        s.append(Long.toBinaryString(term));
-      return s.toString();
-    }
-  } // PackedQuadCell
-
-  /** This is a streamlined version of TreeCellIterator, with built-in support to prune at detailLevel
-   * (but not recursively upwards). */
-  protected class PrefixTreeIterator extends CellIterator {
-    private Shape shape;
-    private PackedQuadCell thisCell;
-    private PackedQuadCell nextCell;
-
-    private short level;
-    private final short detailLevel;
-    private CellIterator pruneIter;
-
-    PrefixTreeIterator(Shape shape, short detailLevel) {
-      this.shape = shape;
-      this.thisCell = ((PackedQuadCell)(getWorldCell())).nextCell(true);
-      this.detailLevel = detailLevel;
-      this.nextCell = null;
-    }
-
-    @Override
-    public boolean hasNext() {
-      if (nextCell != null) {
-        return true;
-      }
-      SpatialRelation rel;
-      // loop until we're at the end of the quad tree or we hit a relation
-      while (thisCell != null) {
-        rel = thisCell.getShape().relate(shape);
-        if (rel == SpatialRelation.DISJOINT) {
-          thisCell = thisCell.nextCell(false);
-        } else { // within || intersects || contains
-          thisCell.setShapeRel(rel);
-          nextCell = thisCell;
-          if (rel == SpatialRelation.WITHIN) {
-            thisCell.setLeaf();
-            thisCell = thisCell.nextCell(false);
-          } else {  // intersects || contains
-            level = (short) (thisCell.getLevel());
-            if (level == detailLevel || pruned(rel)) {
-              thisCell.setLeaf();
-              if (shape instanceof Point) {
-                thisCell.setShapeRel(SpatialRelation.WITHIN);
-                thisCell = null;
-              } else {
-                thisCell = thisCell.nextCell(false);
-              }
-              break;
-            }
-            thisCell = thisCell.nextCell(true);
-          }
-          break;
-        }
-      }
-      return nextCell != null;
-    }
-
-    private boolean pruned(SpatialRelation rel) {
-      int leaves;
-      if (rel == SpatialRelation.INTERSECTS && leafyPrune && level == detailLevel - 1) {
-        for (leaves=0, pruneIter=thisCell.getNextLevelCells(shape); pruneIter.hasNext(); pruneIter.next(), ++leaves);
-        return leaves == 4;
-      }
-      return false;
-    }
-
-    @Override
-    public Cell next() {
-      if (nextCell == null) {
-        if (!hasNext()) {
-          throw new NoSuchElementException();
-        }
-      }
-      // overriding since this implementation sets thisCell in hasNext
-      Cell temp = nextCell;
-      nextCell = null;
-      return temp;
-    }
-
-    @Override
-    public void remove() {
-      //no-op
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java
deleted file mode 100644
index 48dac87..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java
+++ /dev/null
@@ -1,308 +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.prefix.tree;
-
-import java.io.PrintStream;
-import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Locale;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.SpatialRelation;
-import org.apache.lucene.util.BytesRef;
-
-/**
- * A {@link SpatialPrefixTree} which uses a
- * <a href="http://en.wikipedia.org/wiki/Quadtree">quad tree</a> in which an
- * indexed term will be generated for each cell, 'A', 'B', 'C', 'D'.
- *
- * @lucene.experimental
- */
-public class QuadPrefixTree extends LegacyPrefixTree {
-
-  /**
-   * Factory for creating {@link QuadPrefixTree} instances with useful defaults
-   */
-  public static class Factory extends SpatialPrefixTreeFactory {
-
-    @Override
-    protected int getLevelForDistance(double degrees) {
-      QuadPrefixTree grid = new QuadPrefixTree(ctx, MAX_LEVELS_POSSIBLE);
-      return grid.getLevelForDistance(degrees);
-    }
-
-    @Override
-    protected SpatialPrefixTree newSPT() {
-      return new QuadPrefixTree(ctx,
-          maxLevels != null ? maxLevels : MAX_LEVELS_POSSIBLE);
-    }
-  }
-
-  public static final int MAX_LEVELS_POSSIBLE = 50;//not really sure how big this should be
-
-  public static final int DEFAULT_MAX_LEVELS = 12;
-  protected final double xmin;
-  protected final double xmax;
-  protected final double ymin;
-  protected final double ymax;
-  protected final double xmid;
-  protected final double ymid;
-
-  protected final double gridW;
-  public final double gridH;
-
-  final double[] levelW;
-  final double[] levelH;
-  final int[]    levelS; // side
-  final int[]    levelN; // number
-
-  public QuadPrefixTree(
-      SpatialContext ctx, Rectangle bounds, int maxLevels) {
-    super(ctx, maxLevels);
-    this.xmin = bounds.getMinX();
-    this.xmax = bounds.getMaxX();
-    this.ymin = bounds.getMinY();
-    this.ymax = bounds.getMaxY();
-
-    levelW = new double[maxLevels];
-    levelH = new double[maxLevels];
-    levelS = new int[maxLevels];
-    levelN = new int[maxLevels];
-
-    gridW = xmax - xmin;
-    gridH = ymax - ymin;
-    this.xmid = xmin + gridW/2.0;
-    this.ymid = ymin + gridH/2.0;
-    levelW[0] = gridW/2.0;
-    levelH[0] = gridH/2.0;
-    levelS[0] = 2;
-    levelN[0] = 4;
-
-    for (int i = 1; i < levelW.length; i++) {
-      levelW[i] = levelW[i - 1] / 2.0;
-      levelH[i] = levelH[i - 1] / 2.0;
-      levelS[i] = levelS[i - 1] * 2;
-      levelN[i] = levelN[i - 1] * 4;
-    }
-  }
-
-  public QuadPrefixTree(SpatialContext ctx) {
-    this(ctx, DEFAULT_MAX_LEVELS);
-  }
-
-  public QuadPrefixTree(
-      SpatialContext ctx, int maxLevels) {
-    this(ctx, ctx.getWorldBounds(), maxLevels);
-  }
-
-  @Override
-  public Cell getWorldCell() {
-    return new QuadCell(BytesRef.EMPTY_BYTES, 0, 0);
-  }
-
-  public void printInfo(PrintStream out) {
-    NumberFormat nf = NumberFormat.getNumberInstance(Locale.ROOT);
-    nf.setMaximumFractionDigits(5);
-    nf.setMinimumFractionDigits(5);
-    nf.setMinimumIntegerDigits(3);
-
-    for (int i = 0; i < maxLevels; i++) {
-      out.println(i + "]\t" + nf.format(levelW[i]) + "\t" + nf.format(levelH[i]) + "\t" +
-          levelS[i] + "\t" + (levelS[i] * levelS[i]));
-    }
-  }
-
-  @Override
-  public int getLevelForDistance(double dist) {
-    if (dist == 0)//short circuit
-      return maxLevels;
-    for (int i = 0; i < maxLevels-1; i++) {
-      //note: level[i] is actually a lookup for level i+1
-      if(dist > levelW[i] && dist > levelH[i]) {
-        return i+1;
-      }
-    }
-    return maxLevels;
-  }
-
-  @Override
-  public Cell getCell(Point p, int level) {
-    List<Cell> cells = new ArrayList<>(1);
-    build(xmid, ymid, 0, cells, new BytesRef(maxLevels+1), ctx.makePoint(p.getX(),p.getY()), level);
-    return cells.get(0);//note cells could be longer if p on edge
-  }
-
-  private void build(
-      double x,
-      double y,
-      int level,
-      List<Cell> matches,
-      BytesRef str,
-      Shape shape,
-      int maxLevel) {
-    assert str.length == level;
-    double w = levelW[level] / 2;
-    double h = levelH[level] / 2;
-
-    // Z-Order
-    // http://en.wikipedia.org/wiki/Z-order_%28curve%29
-    checkBattenberg('A', x - w, y + h, level, matches, str, shape, maxLevel);
-    checkBattenberg('B', x + w, y + h, level, matches, str, shape, maxLevel);
-    checkBattenberg('C', x - w, y - h, level, matches, str, shape, maxLevel);
-    checkBattenberg('D', x + w, y - h, level, matches, str, shape, maxLevel);
-
-    // possibly consider hilbert curve
-    // http://en.wikipedia.org/wiki/Hilbert_curve
-    // http://blog.notdot.net/2009/11/Damn-Cool-Algorithms-Spatial-indexing-with-Quadtrees-and-Hilbert-Curves
-    // if we actually use the range property in the query, this could be useful
-  }
-
-  protected void checkBattenberg(
-      char c,
-      double cx,
-      double cy,
-      int level,
-      List<Cell> matches,
-      BytesRef str,
-      Shape shape,
-      int maxLevel) {
-    assert str.length == level;
-    assert str.offset == 0;
-    double w = levelW[level] / 2;
-    double h = levelH[level] / 2;
-
-    int strlen = str.length;
-    Rectangle rectangle = ctx.makeRectangle(cx - w, cx + w, cy - h, cy + h);
-    SpatialRelation v = shape.relate(rectangle);
-    if (SpatialRelation.CONTAINS == v) {
-      str.bytes[str.length++] = (byte)c;//append
-      //str.append(SpatialPrefixGrid.COVER);
-      matches.add(new QuadCell(BytesRef.deepCopyOf(str), v.transpose()));
-    } else if (SpatialRelation.DISJOINT == v) {
-      // nothing
-    } else { // SpatialRelation.WITHIN, SpatialRelation.INTERSECTS
-      str.bytes[str.length++] = (byte)c;//append
-
-      int nextLevel = level+1;
-      if (nextLevel >= maxLevel) {
-        //str.append(SpatialPrefixGrid.INTERSECTS);
-        matches.add(new QuadCell(BytesRef.deepCopyOf(str), v.transpose()));
-      } else {
-        build(cx, cy, nextLevel, matches, str, shape, maxLevel);
-      }
-    }
-    str.length = strlen;
-  }
-
-  protected class QuadCell extends LegacyCell {
-
-    QuadCell(byte[] bytes, int off, int len) {
-      super(bytes, off, len);
-    }
-
-    QuadCell(BytesRef str, SpatialRelation shapeRel) {
-      this(str.bytes, str.offset, str.length);
-      this.shapeRel = shapeRel;
-    }
-
-    @Override
-    protected QuadPrefixTree getGrid() { return QuadPrefixTree.this; }
-
-    @Override
-    protected int getMaxLevels() { return maxLevels; }
-
-    @Override
-    protected Collection<Cell> getSubCells() {
-      BytesRef source = getTokenBytesNoLeaf(null);
-
-      List<Cell> cells = new ArrayList<>(4);
-      cells.add(new QuadCell(concat(source, (byte)'A'), null));
-      cells.add(new QuadCell(concat(source, (byte)'B'), null));
-      cells.add(new QuadCell(concat(source, (byte)'C'), null));
-      cells.add(new QuadCell(concat(source, (byte)'D'), null));
-      return cells;
-    }
-
-    protected BytesRef concat(BytesRef source, byte b) {
-      //+2 for new char + potential leaf
-      final byte[] buffer = Arrays.copyOfRange(source.bytes, source.offset, source.offset + source.length + 2);
-      BytesRef target = new BytesRef(buffer);
-      target.length = source.length;
-      target.bytes[target.length++] = b;
-      return target;
-    }
-
-    @Override
-    public int getSubCellsSize() {
-      return 4;
-    }
-
-    @Override
-    protected QuadCell getSubCell(Point p) {
-      return (QuadCell) QuadPrefixTree.this.getCell(p, getLevel() + 1);//not performant!
-    }
-
-    @Override
-    public Shape getShape() {
-      if (shape == null)
-        shape = makeShape();
-      return shape;
-    }
-
-    protected Rectangle makeShape() {
-      BytesRef token = getTokenBytesNoLeaf(null);
-      double xmin = QuadPrefixTree.this.xmin;
-      double ymin = QuadPrefixTree.this.ymin;
-
-      for (int i = 0; i < token.length; i++) {
-        byte c = token.bytes[token.offset + i];
-        switch (c) {
-          case 'A':
-            ymin += levelH[i];
-            break;
-          case 'B':
-            xmin += levelW[i];
-            ymin += levelH[i];
-            break;
-          case 'C':
-            break;//nothing really
-          case 'D':
-            xmin += levelW[i];
-            break;
-          default:
-            throw new RuntimeException("unexpected char: " + c);
-        }
-      }
-      int len = token.length;
-      double width, height;
-      if (len > 0) {
-        width = levelW[len-1];
-        height = levelH[len-1];
-      } else {
-        width = gridW;
-        height = gridH;
-      }
-      return ctx.makeRectangle(xmin, xmin + width, ymin, ymin + height);
-    }
-  }//QuadCell
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SingletonCellIterator.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SingletonCellIterator.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SingletonCellIterator.java
deleted file mode 100644
index 177b431..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SingletonCellIterator.java
+++ /dev/null
@@ -1,36 +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.prefix.tree;
-
-/**
- * A singleton (one Cell) instance of CellIterator.
- *
- * @lucene.internal
- */
-class SingletonCellIterator extends CellIterator {
-
-  SingletonCellIterator(Cell cell) {
-    this.nextCell = cell;//preload nextCell
-  }
-
-  @Override
-  public boolean hasNext() {
-    thisCell = null;
-    return nextCell != null;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTree.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTree.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTree.java
deleted file mode 100644
index 8ead954..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTree.java
+++ /dev/null
@@ -1,117 +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.prefix.tree;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.util.BytesRef;
-
-/**
- * A spatial Prefix Tree, or Trie, which decomposes shapes into prefixed strings
- * at variable lengths corresponding to variable precision.  Each string
- * corresponds to a rectangular spatial region.  This approach is
- * also referred to "Grids", "Tiles", and "Spatial Tiers".
- * <p>
- * Implementations of this class should be thread-safe and immutable once
- * initialized.
- *
- * @lucene.experimental
- */
-public abstract class SpatialPrefixTree {
-
-  protected final int maxLevels;
-
-  protected final SpatialContext ctx;
-
-  public SpatialPrefixTree(SpatialContext ctx, int maxLevels) {
-    assert maxLevels > 0;
-    this.ctx = ctx;
-    this.maxLevels = maxLevels;
-  }
-
-  public SpatialContext getSpatialContext() {
-    return ctx;
-  }
-
-  public int getMaxLevels() {
-    return maxLevels;
-  }
-
-  @Override
-  public String toString() {
-    return getClass().getSimpleName() + "(maxLevels:" + maxLevels + ",ctx:" + ctx + ")";
-  }
-
-  /**
-   * Returns the level of the largest grid in which its longest side is less
-   * than or equal to the provided distance (in degrees). Consequently {@code
-   * dist} acts as an error epsilon declaring the amount of detail needed in the
-   * grid, such that you can get a grid with just the right amount of
-   * precision.
-   *
-   * @param dist {@code >= 0}
-   * @return level [1 to maxLevels]
-   */
-  public abstract int getLevelForDistance(double dist);
-
-  /**
-   * Given a cell having the specified level, returns the distance from opposite
-   * corners. Since this might vary depending on where the cell is, this method
-   * may over-estimate.
-   *
-   * @param level [1 to maxLevels]
-   * @return {@code > 0}
-   */
-  public abstract double getDistanceForLevel(int level);
-
-  /**
-   * Returns the level 0 cell which encompasses all spatial data. Equivalent to {@link #readCell(BytesRef,Cell)}
-   * with no bytes.
-   */
-  public abstract Cell getWorldCell(); //another possible name: getTopCell
-
-  /**
-   * This creates a new Cell (or re-using {@code scratch} if provided), initialized to the state as read
-   * by the bytes.
-   * Warning: An implementation may refer to the same byte array (no copy). If {@link Cell#setLeaf()} is
-   * subsequently called, it would then modify these bytes.
-   */
-  public abstract Cell readCell(BytesRef term, Cell scratch);
-
-  /**
-   * Gets the intersecting cells for the specified shape, without exceeding
-   * detail level. If a cell is within the query shape then it's marked as a
-   * leaf and none of its children are added. For cells at detailLevel, they are marked as
-   * leaves too, unless it's a point.
-   * <p>
-   * IMPORTANT: Cells returned from the iterator can be re-used for cells at the same level. So you can't simply
-   * iterate to subsequent cells and still refer to the former cell nor the bytes returned from the former cell, unless
-   * you know the former cell is a parent.
-   *
-   * @param shape       the shape; possibly null but the caller should liberally call
-   *  {@code remove()} if so.
-   * @param detailLevel the maximum detail level to get cells for
-   * @return the matching cells
-   */
-  public CellIterator getTreeCellIterator(Shape shape, int detailLevel) {
-    if (detailLevel > maxLevels) {
-      throw new IllegalArgumentException("detailLevel > maxLevels");
-    }
-    return new TreeCellIterator(shape, detailLevel, getWorldCell());
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeFactory.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeFactory.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeFactory.java
deleted file mode 100644
index b74dc93..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeFactory.java
+++ /dev/null
@@ -1,99 +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.prefix.tree;
-
-import java.util.Map;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.distance.DistanceUtils;
-
-/**
- * Abstract Factory for creating {@link SpatialPrefixTree} instances with useful
- * defaults and passed on configurations defined in a Map.
- *
- * @lucene.experimental
- */
-public abstract class SpatialPrefixTreeFactory {
-
-  private static final double DEFAULT_GEO_MAX_DETAIL_KM = 0.001;//1m
-  public static final String PREFIX_TREE = "prefixTree";
-  public static final String MAX_LEVELS = "maxLevels";
-  public static final String MAX_DIST_ERR = "maxDistErr";
-
-  protected Map<String, String> args;
-  protected SpatialContext ctx;
-  protected Integer maxLevels;
-
-  /**
-   * The factory  is looked up via "prefixTree" in args, expecting "geohash" or "quad".
-   * If it's neither of these, then "geohash" is chosen for a geo context, otherwise "quad" is chosen.
-   */
-  public static SpatialPrefixTree makeSPT(Map<String,String> args, ClassLoader classLoader, SpatialContext ctx) {
-    SpatialPrefixTreeFactory instance;
-    String cname = args.get(PREFIX_TREE);
-    if (cname == null)
-      cname = ctx.isGeo() ? "geohash" : "quad";
-    if ("geohash".equalsIgnoreCase(cname))
-      instance = new GeohashPrefixTree.Factory();
-    else if ("quad".equalsIgnoreCase(cname))
-      instance = new QuadPrefixTree.Factory();
-    else if ("packedQuad".equalsIgnoreCase(cname))
-      instance = new PackedQuadPrefixTree.Factory();
-    else {
-      try {
-        Class<?> c = classLoader.loadClass(cname);
-        instance = (SpatialPrefixTreeFactory) c.newInstance();
-      } catch (Exception e) {
-        throw new RuntimeException(e);
-      }
-    }
-    instance.init(args,ctx);
-    return instance.newSPT();
-  }
-
-  protected void init(Map<String, String> args, SpatialContext ctx) {
-    this.args = args;
-    this.ctx = ctx;
-    initMaxLevels();
-  }
-
-  protected void initMaxLevels() {
-    String mlStr = args.get(MAX_LEVELS);
-    if (mlStr != null) {
-      maxLevels = Integer.valueOf(mlStr);
-      return;
-    }
-
-    double degrees;
-    String maxDetailDistStr = args.get(MAX_DIST_ERR);
-    if (maxDetailDistStr == null) {
-      if (!ctx.isGeo()) {
-        return;//let default to max
-      }
-      degrees = DistanceUtils.dist2Degrees(DEFAULT_GEO_MAX_DETAIL_KM, DistanceUtils.EARTH_MEAN_RADIUS_KM);
-    } else {
-      degrees = Double.parseDouble(maxDetailDistStr);
-    }
-    maxLevels = getLevelForDistance(degrees);
-  }
-
-  /** Calls {@link SpatialPrefixTree#getLevelForDistance(double)}. */
-  protected abstract int getLevelForDistance(double degrees);
-
-  protected abstract SpatialPrefixTree newSPT();
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/TreeCellIterator.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/TreeCellIterator.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/TreeCellIterator.java
deleted file mode 100644
index 3ec56ac..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/TreeCellIterator.java
+++ /dev/null
@@ -1,87 +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.prefix.tree;
-
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Shape;
-
-/**
- * Navigates a {@link org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree} from a given cell (typically the world
- * cell) down to a maximum number of configured levels, filtered by a given shape. Intermediate non-leaf cells are
- * returned. It supports {@link #remove()} for skipping traversal of subcells of the current cell.
- *
- * @lucene.internal
- */
-class TreeCellIterator extends CellIterator {
-  //This class uses a stack approach, which is more efficient than creating linked nodes. And it might more easily
-  // pave the way for re-using Cell & CellIterator at a given level in the future.
-
-  private final Shape shapeFilter;//possibly null
-  private final CellIterator[] iterStack;//starts at level 1
-  private int stackIdx;//-1 when done
-  private boolean descend;
-
-  public TreeCellIterator(Shape shapeFilter, int detailLevel, Cell parentCell) {
-    this.shapeFilter = shapeFilter;
-    assert parentCell.getLevel() == 0;
-    iterStack = new CellIterator[detailLevel];
-    iterStack[0] = parentCell.getNextLevelCells(shapeFilter);
-    stackIdx = 0;//always points to an iter (non-null)
-    //note: not obvious but needed to visit the first cell before trying to descend
-    descend = false;
-  }
-
-  @Override
-  public boolean hasNext() {
-    if (nextCell != null)
-      return true;
-    while (true) {
-      if (stackIdx == -1)//the only condition in which we return false
-        return false;
-      //If we can descend...
-      if (descend && !(stackIdx == iterStack.length - 1 || iterStack[stackIdx].thisCell().isLeaf())) {
-        CellIterator nextIter = iterStack[stackIdx].thisCell().getNextLevelCells(shapeFilter);
-        //push stack
-        iterStack[++stackIdx] = nextIter;
-      }
-      //Get sibling...
-      if (iterStack[stackIdx].hasNext()) {
-        nextCell = iterStack[stackIdx].next();
-        //at detailLevel
-        if (stackIdx == iterStack.length - 1 && !(shapeFilter instanceof Point)) //point check is a kludge
-          nextCell.setLeaf();//because at bottom
-        break;
-      }
-      //Couldn't get next; go up...
-      //pop stack
-      iterStack[stackIdx--] = null;
-      descend = false;//so that we don't re-descend where we just were
-    }
-    assert nextCell != null;
-    descend = true;//reset
-    return true;
-  }
-
-  @Override
-  public void remove() {
-    assert thisCell() != null && nextCell == null;
-    descend = false;
-  }
-
-  //TODO implement a smart nextFrom() that looks at the parent's bytes first
-
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/package-info.java b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/package-info.java
deleted file mode 100644
index 4dd85b1..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/package-info.java
+++ /dev/null
@@ -1,30 +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.
- */
- 
-/** 
- * This package is about SpatialPrefixTree and any supporting classes.
- * A SpatialPrefixTree supports spatial indexing by index-time tokens
- * where adding characters to a string gives greater resolution.
- * <p>
- * Potential Implementations include:
- * <ul>
- * <li>http://en.wikipedia.org/wiki/Quadtree
- * <li>http://en.wikipedia.org/wiki/Geohash
- * <li>http://healpix.jpl.nasa.gov/
- * </ul>
- */
-package org.apache.lucene.spatial.prefix.tree;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialArgs.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialArgs.java b/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialArgs.java
deleted file mode 100644
index 0503072..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialArgs.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.query;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-
-/**
- * Principally holds the query {@link Shape} and the {@link SpatialOperation}.
- * It's used as an argument to some methods on {@link org.apache.lucene.spatial.SpatialStrategy}.
- *
- * @lucene.experimental
- */
-public class SpatialArgs {
-
-  public static final double DEFAULT_DISTERRPCT = 0.025d;
-
-  private SpatialOperation operation;
-  private Shape shape;
-  private Double distErrPct;
-  private Double distErr;
-
-  public SpatialArgs(SpatialOperation operation, Shape shape) {
-    if (operation == null || shape == null)
-      throw new NullPointerException("operation and shape are required");
-    this.operation = operation;
-    this.shape = shape;
-  }
-
-  /**
-   * Computes the distance given a shape and the {@code distErrPct}.  The
-   * algorithm is the fraction of the distance from the center of the query
-   * shape to its closest bounding box corner.
-   *
-   * @param shape Mandatory.
-   * @param distErrPct 0 to 0.5
-   * @param ctx Mandatory
-   * @return A distance (in degrees).
-   */
-  public static double calcDistanceFromErrPct(Shape shape, double distErrPct, SpatialContext ctx) {
-    if (distErrPct < 0 || distErrPct > 0.5) {
-      throw new IllegalArgumentException("distErrPct " + distErrPct + " must be between [0 to 0.5]");
-    }
-    if (distErrPct == 0 || shape instanceof Point) {
-      return 0;
-    }
-    Rectangle bbox = shape.getBoundingBox();
-    //Compute the distance from the center to a corner.  Because the distance
-    // to a bottom corner vs a top corner can vary in a geospatial scenario,
-    // take the closest one (greater precision).
-    Point ctr = bbox.getCenter();
-    double y = (ctr.getY() >= 0 ? bbox.getMaxY() : bbox.getMinY());
-    double diagonalDist = ctx.getDistCalc().distance(ctr, bbox.getMaxX(), y);
-    return diagonalDist * distErrPct;
-  }
-
-  /**
-   * Gets the error distance that specifies how precise the query shape is. This
-   * looks at {@link #getDistErr()}, {@link #getDistErrPct()}, and {@code
-   * defaultDistErrPct}.
-   * @param defaultDistErrPct 0 to 0.5
-   * @return {@code >= 0}
-   */
-  public double resolveDistErr(SpatialContext ctx, double defaultDistErrPct) {
-    if (distErr != null)
-      return distErr;
-    double distErrPct = (this.distErrPct != null ? this.distErrPct : defaultDistErrPct);
-    return calcDistanceFromErrPct(shape, distErrPct, ctx);
-  }
-
-  /** Check if the arguments make sense -- throw an exception if not */
-  public void validate() throws IllegalArgumentException {
-    if (distErr != null && distErrPct != null)
-      throw new IllegalArgumentException("Only distErr or distErrPct can be specified.");
-  }
-
-  @Override
-  public String toString() {
-    return SpatialArgsParser.writeSpatialArgs(this);
-  }
-
-  //------------------------------------------------
-  // Getters & Setters
-  //------------------------------------------------
-
-  public SpatialOperation getOperation() {
-    return operation;
-  }
-
-  public void setOperation(SpatialOperation operation) {
-    this.operation = operation;
-  }
-
-  public Shape getShape() {
-    return shape;
-  }
-
-  public void setShape(Shape shape) {
-    this.shape = shape;
-  }
-
-  /**
-   * A measure of acceptable error of the shape as a fraction.  This effectively
-   * inflates the size of the shape but should not shrink it.
-   *
-   * @return 0 to 0.5
-   * @see #calcDistanceFromErrPct(com.spatial4j.core.shape.Shape, double,
-   *      com.spatial4j.core.context.SpatialContext)
-   */
-  public Double getDistErrPct() {
-    return distErrPct;
-  }
-
-  public void setDistErrPct(Double distErrPct) {
-    if (distErrPct != null)
-      this.distErrPct = distErrPct;
-  }
-
-  /**
-   * The acceptable error of the shape.  This effectively inflates the
-   * size of the shape but should not shrink it.
-   *
-   * @return {@code >= 0}
-   */
-  public Double getDistErr() {
-    return distErr;
-  }
-
-  public void setDistErr(Double distErr) {
-    this.distErr = distErr;
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialArgsParser.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialArgsParser.java b/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialArgsParser.java
deleted file mode 100644
index 81612ff..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialArgsParser.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.spatial.query;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.exception.InvalidShapeException;
-import com.spatial4j.core.shape.Shape;
-
-import java.text.ParseException;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-/**
- * Parses a string that usually looks like "OPERATION(SHAPE)" into a {@link SpatialArgs}
- * object. The set of operations supported are defined in {@link SpatialOperation}, such
- * as "Intersects" being a common one. The shape portion is defined by WKT {@link com.spatial4j.core.io.WktShapeParser},
- * but it can be overridden/customized via {@link #parseShape(String, com.spatial4j.core.context.SpatialContext)}.
- * There are some optional name-value pair parameters that follow the closing parenthesis.  Example:
- * <pre>
- *   Intersects(ENVELOPE(-10,-8,22,20)) distErrPct=0.025
- * </pre>
- * <p>
- * In the future it would be good to support something at least semi-standardized like a
- * variant of <a href="http://docs.geoserver.org/latest/en/user/filter/ecql_reference.html#spatial-predicate">
- *   [E]CQL</a>.
- *
- * @lucene.experimental
- */
-public class SpatialArgsParser {
-
-  public static final String DIST_ERR_PCT = "distErrPct";
-  public static final String DIST_ERR = "distErr";
-
-  /** Writes a close approximation to the parsed input format. */
-  static String writeSpatialArgs(SpatialArgs args) {
-    StringBuilder str = new StringBuilder();
-    str.append(args.getOperation().getName());
-    str.append('(');
-    str.append(args.getShape().toString());
-    if (args.getDistErrPct() != null)
-      str.append(" distErrPct=").append(String.format(Locale.ROOT, "%.2f%%", args.getDistErrPct() * 100d));
-    if (args.getDistErr() != null)
-      str.append(" distErr=").append(args.getDistErr());
-    str.append(')');
-    return str.toString();
-  }
-
-  /**
-   * Parses a string such as "Intersects(ENVELOPE(-10,-8,22,20)) distErrPct=0.025".
-   *
-   * @param v   The string to parse. Mandatory.
-   * @param ctx The spatial context. Mandatory.
-   * @return Not null.
-   * @throws IllegalArgumentException if the parameters don't make sense or an add-on parameter is unknown
-   * @throws ParseException If there is a problem parsing the string
-   * @throws InvalidShapeException When the coordinates are invalid for the shape
-   */
-  public SpatialArgs parse(String v, SpatialContext ctx) throws ParseException, InvalidShapeException {
-    int idx = v.indexOf('(');
-    int edx = v.lastIndexOf(')');
-
-    if (idx < 0 || idx > edx) {
-      throw new ParseException("missing parens: " + v, -1);
-    }
-
-    SpatialOperation op = SpatialOperation.get(v.substring(0, idx).trim());
-
-    String body = v.substring(idx + 1, edx).trim();
-    if (body.length() < 1) {
-      throw new ParseException("missing body : " + v, idx + 1);
-    }
-
-    Shape shape = parseShape(body, ctx);
-    SpatialArgs args = newSpatialArgs(op, shape);
-
-    if (v.length() > (edx + 1)) {
-      body = v.substring(edx + 1).trim();
-      if (body.length() > 0) {
-        Map<String, String> aa = parseMap(body);
-        readNameValuePairs(args, aa);
-        if (!aa.isEmpty()) {
-          throw new IllegalArgumentException("unused parameters: " + aa);
-        }
-      }
-    }
-    args.validate();
-    return args;
-  }
-
-  protected SpatialArgs newSpatialArgs(SpatialOperation op, Shape shape) {
-    return new SpatialArgs(op, shape);
-  }
-
-  protected void readNameValuePairs(SpatialArgs args, Map<String, String> nameValPairs) {
-    args.setDistErrPct(readDouble(nameValPairs.remove(DIST_ERR_PCT)));
-    args.setDistErr(readDouble(nameValPairs.remove(DIST_ERR)));
-  }
-
-  protected Shape parseShape(String str, SpatialContext ctx) throws ParseException {
-    //return ctx.readShape(str);//still in Spatial4j 0.4 but will be deleted
-    return ctx.readShapeFromWkt(str);
-  }
-
-  protected static Double readDouble(String v) {
-    return v == null ? null : Double.valueOf(v);
-  }
-
-  protected static boolean readBool(String v, boolean defaultValue) {
-    return v == null ? defaultValue : Boolean.parseBoolean(v);
-  }
-
-  /** Parses "a=b c=d f" (whitespace separated) into name-value pairs. If there
-   * is no '=' as in 'f' above then it's short for f=f. */
-  protected static Map<String, String> parseMap(String body) {
-    Map<String, String> map = new HashMap<>();
-    StringTokenizer st = new StringTokenizer(body, " \n\t");
-    while (st.hasMoreTokens()) {
-      String a = st.nextToken();
-      int idx = a.indexOf('=');
-      if (idx > 0) {
-        String k = a.substring(0, idx);
-        String v = a.substring(idx + 1);
-        map.put(k, v);
-      } else {
-        map.put(a, a);
-      }
-    }
-    return map;
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialOperation.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialOperation.java b/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialOperation.java
deleted file mode 100644
index 7d750ac..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialOperation.java
+++ /dev/null
@@ -1,179 +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.query;
-
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.SpatialRelation;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-/**
- * A predicate that compares a stored geometry to a supplied geometry. It's enum-like. For more
- * explanation of each predicate, consider looking at the source implementation
- * of {@link #evaluate(com.spatial4j.core.shape.Shape, com.spatial4j.core.shape.Shape)}. It's important
- * to be aware that Lucene-spatial makes no distinction of shape boundaries, unlike many standardized
- * definitions. Nor does it make dimensional distinctions (e.g. line vs polygon).
- * You can lookup a predicate by "Covers" or "Contains", for example, and you will get the
- * same underlying predicate implementation.
- *
- * @see <a href="http://en.wikipedia.org/wiki/DE-9IM">DE-9IM at Wikipedia, based on OGC specs</a>
- * @see <a href="http://edndoc.esri.com/arcsde/9.1/general_topics/understand_spatial_relations.htm">
- *   ESRIs docs on spatial relations</a>
- *
- * @lucene.experimental
- */
-public abstract class SpatialOperation implements Serializable {
-  //TODO rename to SpatialPredicate. Use enum?  LUCENE-5771
-
-  // Private registry
-  private static final Map<String, SpatialOperation> registry = new HashMap<>();//has aliases
-  private static final List<SpatialOperation> list = new ArrayList<>();
-
-  // Geometry Operations
-
-  /** Bounding box of the *indexed* shape, then {@link #Intersects}. */
-  public static final SpatialOperation BBoxIntersects = new SpatialOperation("BBoxIntersects") {
-    @Override
-    public boolean evaluate(Shape indexedShape, Shape queryShape) {
-      return indexedShape.getBoundingBox().relate(queryShape).intersects();
-    }
-  };
-  /** Bounding box of the *indexed* shape, then {@link #IsWithin}. */
-  public static final SpatialOperation BBoxWithin     = new SpatialOperation("BBoxWithin") {
-    {
-      register("BBoxCoveredBy");//alias -- the better name
-    }
-    @Override
-    public boolean evaluate(Shape indexedShape, Shape queryShape) {
-      Rectangle bbox = indexedShape.getBoundingBox();
-      return bbox.relate(queryShape) == SpatialRelation.WITHIN || bbox.equals(queryShape);
-    }
-  };
-  /** Meets the "Covers" OGC definition (boundary-neutral). */
-  public static final SpatialOperation Contains       = new SpatialOperation("Contains") {
-    {
-      register("Covers");//alias -- the better name
-    }
-    @Override
-    public boolean evaluate(Shape indexedShape, Shape queryShape) {
-      return indexedShape.relate(queryShape) == SpatialRelation.CONTAINS || indexedShape.equals(queryShape);
-    }
-  };
-  /** Meets the "Intersects" OGC definition. */
-  public static final SpatialOperation Intersects     = new SpatialOperation("Intersects") {
-    @Override
-    public boolean evaluate(Shape indexedShape, Shape queryShape) {
-      return indexedShape.relate(queryShape).intersects();
-    }
-  };
-  /** Meets the "Equals" OGC definition. */
-  public static final SpatialOperation IsEqualTo      = new SpatialOperation("Equals") {
-    {
-      register("IsEqualTo");//alias (deprecated)
-    }
-    @Override
-    public boolean evaluate(Shape indexedShape, Shape queryShape) {
-      return indexedShape.equals(queryShape);
-    }
-  };
-  /** Meets the "Disjoint" OGC definition. */
-  public static final SpatialOperation IsDisjointTo   = new SpatialOperation("Disjoint") {
-    {
-      register("IsDisjointTo");//alias (deprecated)
-    }
-    @Override
-    public boolean evaluate(Shape indexedShape, Shape queryShape) {
-      return ! indexedShape.relate(queryShape).intersects();
-    }
-  };
-  /** Meets the "CoveredBy" OGC definition (boundary-neutral). */
-  public static final SpatialOperation IsWithin       = new SpatialOperation("Within") {
-    {
-      register("IsWithin");//alias (deprecated)
-      register("CoveredBy");//alias -- the more appropriate name.
-    }
-    @Override
-    public boolean evaluate(Shape indexedShape, Shape queryShape) {
-      return indexedShape.relate(queryShape) == SpatialRelation.WITHIN || indexedShape.equals(queryShape);
-    }
-  };
-  /** Almost meets the "Overlaps" OGC definition, but boundary-neutral (boundary==interior). */
-  public static final SpatialOperation Overlaps       = new SpatialOperation("Overlaps") {
-    @Override
-    public boolean evaluate(Shape indexedShape, Shape queryShape) {
-      return indexedShape.relate(queryShape) == SpatialRelation.INTERSECTS;//not Contains or Within or Disjoint
-    }
-  };
-
-  private final String name;
-
-  protected SpatialOperation(String name) {
-    this.name = name;
-    register(name);
-    list.add( this );
-  }
-
-  protected void register(String name) {
-    registry.put(name, this);
-    registry.put(name.toUpperCase(Locale.ROOT), this);
-  }
-
-  public static SpatialOperation get( String v ) {
-    SpatialOperation op = registry.get( v );
-    if( op == null ) {
-      op = registry.get(v.toUpperCase(Locale.ROOT));
-    }
-    if( op == null ) {
-      throw new IllegalArgumentException("Unknown Operation: " + v );
-    }
-    return op;
-  }
-
-  public static List<SpatialOperation> values() {
-    return list;
-  }
-
-  public static boolean is( SpatialOperation op, SpatialOperation ... tst ) {
-    for( SpatialOperation t : tst ) {
-      if( op == t ) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Returns whether the relationship between indexedShape and queryShape is
-   * satisfied by this operation.
-   */
-  public abstract boolean evaluate(Shape indexedShape, Shape queryShape);
-
-  public String getName() {
-    return name;
-  }
-
-  @Override
-  public String toString() {
-    return name;
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/query/UnsupportedSpatialOperation.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/query/UnsupportedSpatialOperation.java b/lucene/spatial/src/java/org/apache/lucene/spatial/query/UnsupportedSpatialOperation.java
deleted file mode 100644
index d6cb152..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/query/UnsupportedSpatialOperation.java
+++ /dev/null
@@ -1,28 +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.query;
-
-/**
- * Exception thrown when the {@link org.apache.lucene.spatial.SpatialStrategy} cannot implement the requested operation.
- * @lucene.experimental
- */
-public class UnsupportedSpatialOperation extends UnsupportedOperationException {
-
-  public UnsupportedSpatialOperation(SpatialOperation op) {
-    super(op.getName());
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/query/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/query/package-info.java b/lucene/spatial/src/java/org/apache/lucene/spatial/query/package-info.java
deleted file mode 100644
index 42a5036..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/query/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.
- */
- 
-/** 
- * Spatial Query options useful for client side requests
- */
-package org.apache.lucene.spatial.query;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java b/lucene/spatial/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java
deleted file mode 100644
index c54cf75..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java
+++ /dev/null
@@ -1,278 +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.serialized;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.util.Map;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.io.BinaryCodec;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Shape;
-import org.apache.lucene.document.BinaryDocValuesField;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.index.BinaryDocValues;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.queries.function.FunctionValues;
-import org.apache.lucene.queries.function.ValueSource;
-import org.apache.lucene.search.Explanation;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.RandomAccessWeight;
-import org.apache.lucene.search.TwoPhaseIterator;
-import org.apache.lucene.search.Weight;
-import org.apache.lucene.spatial.SpatialStrategy;
-import org.apache.lucene.spatial.query.SpatialArgs;
-import org.apache.lucene.spatial.util.DistanceToShapeValueSource;
-import org.apache.lucene.spatial.util.ShapePredicateValueSource;
-import org.apache.lucene.util.Bits;
-import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.BytesRefBuilder;
-
-
-/**
- * A SpatialStrategy based on serializing a Shape stored into BinaryDocValues.
- * This is not at all fast; it's designed to be used in conjunction with another index based
- * SpatialStrategy that is approximated (like {@link org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy})
- * to add precision or eventually make more specific / advanced calculations on the per-document
- * geometry.
- * The serialization uses Spatial4j's {@link com.spatial4j.core.io.BinaryCodec}.
- *
- * @lucene.experimental
- */
-public class SerializedDVStrategy extends SpatialStrategy {
-
-  /**
-   * A cache heuristic for the buf size based on the last shape size.
-   */
-  //TODO do we make this non-volatile since it's merely a heuristic?
-  private volatile int indexLastBufSize = 8 * 1024;//8KB default on first run
-
-  /**
-   * Constructs the spatial strategy with its mandatory arguments.
-   */
-  public SerializedDVStrategy(SpatialContext ctx, String fieldName) {
-    super(ctx, fieldName);
-  }
-
-  @Override
-  public Field[] createIndexableFields(Shape shape) {
-    int bufSize = Math.max(128, (int) (this.indexLastBufSize * 1.5));//50% headroom over last
-    ByteArrayOutputStream byteStream = new ByteArrayOutputStream(bufSize);
-    final BytesRef bytesRef = new BytesRef();//receiver of byteStream's bytes
-    try {
-      ctx.getBinaryCodec().writeShape(new DataOutputStream(byteStream), shape);
-      //this is a hack to avoid redundant byte array copying by byteStream.toByteArray()
-      byteStream.writeTo(new FilterOutputStream(null/*not used*/) {
-        @Override
-        public void write(byte[] b, int off, int len) throws IOException {
-          bytesRef.bytes = b;
-          bytesRef.offset = off;
-          bytesRef.length = len;
-        }
-      });
-    } catch (IOException e) {
-      throw new RuntimeException(e);
-    }
-    this.indexLastBufSize = bytesRef.length;//cache heuristic
-    return new Field[]{new BinaryDocValuesField(getFieldName(), bytesRef)};
-  }
-
-  @Override
-  public ValueSource makeDistanceValueSource(Point queryPoint, double multiplier) {
-    //TODO if makeShapeValueSource gets lifted to the top; this could become a generic impl.
-    return new DistanceToShapeValueSource(makeShapeValueSource(), queryPoint, multiplier, ctx);
-  }
-
-  /**
-   * Returns a Query that should be used in a random-access fashion.
-   * Use in another manner will be SLOW.
-   */
-  @Override
-  public Query makeQuery(SpatialArgs args) {
-    ValueSource shapeValueSource = makeShapeValueSource();
-    ShapePredicateValueSource predicateValueSource = new ShapePredicateValueSource(
-        shapeValueSource, args.getOperation(), args.getShape());
-    return new PredicateValueSourceQuery(predicateValueSource);
-  }
-
-  /**
-   * Provides access to each shape per document as a ValueSource in which
-   * {@link org.apache.lucene.queries.function.FunctionValues#objectVal(int)} returns a {@link
-   * Shape}.
-   */ //TODO raise to SpatialStrategy
-  public ValueSource makeShapeValueSource() {
-    return new ShapeDocValueSource(getFieldName(), ctx.getBinaryCodec());
-  }
-
-  /** Warning: don't iterate over the results of this query; it's designed for use in a random-access fashion
-   * by {@link TwoPhaseIterator}.
-   */
-  static class PredicateValueSourceQuery extends Query {
-    private final ValueSource predicateValueSource;//we call boolVal(doc)
-
-    public PredicateValueSourceQuery(ValueSource predicateValueSource) {
-      this.predicateValueSource = predicateValueSource;
-    }
-
-    @Override
-    public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
-      return new RandomAccessWeight(this) {
-        @Override
-        protected Bits getMatchingDocs(LeafReaderContext context) throws IOException {
-          final FunctionValues predFuncValues = predicateValueSource.getValues(null, context);
-          return new Bits() {
-            @Override
-            public boolean get(int index) {
-              return predFuncValues.boolVal(index);
-            }
-
-            @Override
-            public int length() {
-              return context.reader().maxDoc();
-            }
-          };
-        }
-      };
-    }
-
-    @Override
-    public boolean equals(Object o) {
-      if (this == o) return true;
-      if (super.equals(o) == false) return false;
-
-      PredicateValueSourceQuery that = (PredicateValueSourceQuery) o;
-
-      if (!predicateValueSource.equals(that.predicateValueSource)) return false;
-
-      return true;
-    }
-
-    @Override
-    public int hashCode() {
-      return super.hashCode() + 31 * predicateValueSource.hashCode();
-    }
-    
-    @Override
-    public String toString(String field) {
-      return "PredicateValueSourceQuery(" +
-               predicateValueSource.toString() +
-             ")";
-    }
-  }//PredicateValueSourceQuery
-
-  /**
-   * Implements a ValueSource by deserializing a Shape in from BinaryDocValues using BinaryCodec.
-   * @see #makeShapeValueSource()
-   */
-  static class ShapeDocValueSource extends ValueSource {
-
-    private final String fieldName;
-    private final BinaryCodec binaryCodec;//spatial4j
-
-    private ShapeDocValueSource(String fieldName, BinaryCodec binaryCodec) {
-      this.fieldName = fieldName;
-      this.binaryCodec = binaryCodec;
-    }
-
-    @Override
-    public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
-      final BinaryDocValues docValues = readerContext.reader().getBinaryDocValues(fieldName);
-
-      return new FunctionValues() {
-        int bytesRefDoc = -1;
-        BytesRefBuilder bytesRef = new BytesRefBuilder();
-
-        boolean fillBytes(int doc) {
-          if (bytesRefDoc != doc) {
-            bytesRef.copyBytes(docValues.get(doc));
-            bytesRefDoc = doc;
-          }
-          return bytesRef.length() != 0;
-        }
-
-        @Override
-        public boolean exists(int doc) {
-          return fillBytes(doc);
-        }
-
-        @Override
-        public boolean bytesVal(int doc, BytesRefBuilder target) {
-          target.clear();
-          if (fillBytes(doc)) {
-            target.copyBytes(bytesRef);
-            return true;
-          } else {
-            return false;
-          }
-        }
-
-        @Override
-        public Object objectVal(int docId) {
-          if (!fillBytes(docId))
-            return null;
-          DataInputStream dataInput = new DataInputStream(
-              new ByteArrayInputStream(bytesRef.bytes(), 0, bytesRef.length()));
-          try {
-            return binaryCodec.readShape(dataInput);
-          } catch (IOException e) {
-            throw new RuntimeException(e);
-          }
-        }
-
-        @Override
-        public Explanation explain(int doc) {
-          return Explanation.match(Float.NaN, toString(doc));
-        }
-
-        @Override
-        public String toString(int doc) {
-          return description() + "=" + objectVal(doc);//TODO truncate?
-        }
-
-      };
-    }
-
-    @Override
-    public boolean equals(Object o) {
-      if (this == o) return true;
-      if (o == null || getClass() != o.getClass()) return false;
-
-      ShapeDocValueSource that = (ShapeDocValueSource) o;
-
-      if (!fieldName.equals(that.fieldName)) return false;
-
-      return true;
-    }
-
-    @Override
-    public int hashCode() {
-      int result = fieldName.hashCode();
-      return result;
-    }
-
-    @Override
-    public String description() {
-      return "shapeDocVal(" + fieldName + ")";
-    }
-  }//ShapeDocValueSource
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/serialized/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/serialized/package-info.java b/lucene/spatial/src/java/org/apache/lucene/spatial/serialized/package-info.java
deleted file mode 100644
index 7a316d9..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/serialized/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.
- */
- 
-/** 
- * Strategies that serialize the shape (non-indexed).
- */
-package org.apache.lucene.spatial.serialized;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/Geo3dShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/Geo3dShape.java b/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/Geo3dShape.java
deleted file mode 100644
index bcfc9fa..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/Geo3dShape.java
+++ /dev/null
@@ -1,185 +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.spatial4j;
-
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.distance.DistanceUtils;
-import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.SpatialRelation;
-import com.spatial4j.core.shape.impl.RectangleImpl;
-import org.apache.lucene.geo3d.LatLonBounds;
-import org.apache.lucene.geo3d.GeoArea;
-import org.apache.lucene.geo3d.GeoAreaFactory;
-import org.apache.lucene.geo3d.GeoPoint;
-import org.apache.lucene.geo3d.GeoShape;
-import org.apache.lucene.geo3d.PlanetModel;
-
-/**
- * A Spatial4j Shape wrapping a {@link GeoShape} ("Geo3D") -- a 3D planar geometry based Spatial4j Shape implementation.
- * Geo3D implements shapes on the surface of a sphere or ellipsoid.
- *
- * @lucene.experimental
- */
-public class Geo3dShape implements Shape {
-  /** The required size of this adjustment depends on the actual planetary model chosen.
-   * This value is big enough to account for WGS84. */
-  protected static final double ROUNDOFF_ADJUSTMENT = 0.05;
-
-  public final SpatialContext ctx;
-  public final GeoShape shape;
-  public final PlanetModel planetModel;
-
-  private volatile Rectangle boundingBox = null; // lazy initialized
-
-  public Geo3dShape(final GeoShape shape, final SpatialContext ctx) {
-    this(PlanetModel.SPHERE, shape, ctx);
-  }
-  
-  public Geo3dShape(final PlanetModel planetModel, final GeoShape shape, final SpatialContext ctx) {
-    if (!ctx.isGeo()) {
-      throw new IllegalArgumentException("SpatialContext.isGeo() must be true");
-    }
-    this.ctx = ctx;
-    this.planetModel = planetModel;
-    this.shape = shape;
-  }
-
-  @Override
-  public SpatialContext getContext() {
-    return ctx;
-  }
-
-  @Override
-  public SpatialRelation relate(Shape other) {
-    if (other instanceof Rectangle)
-      return relate((Rectangle)other);
-    else if (other instanceof Point)
-      return relate((Point)other);
-    else
-      throw new RuntimeException("Unimplemented shape relationship determination: " + other.getClass());
-  }
-
-  protected SpatialRelation relate(Rectangle r) {
-    // Construct the right kind of GeoArea first
-    GeoArea geoArea = GeoAreaFactory.makeGeoArea(planetModel,
-        r.getMaxY() * DistanceUtils.DEGREES_TO_RADIANS,
-        r.getMinY() * DistanceUtils.DEGREES_TO_RADIANS,
-        r.getMinX() * DistanceUtils.DEGREES_TO_RADIANS,
-        r.getMaxX() * DistanceUtils.DEGREES_TO_RADIANS);
-    int relationship = geoArea.getRelationship(shape);
-    if (relationship == GeoArea.WITHIN)
-      return SpatialRelation.WITHIN;
-    else if (relationship == GeoArea.CONTAINS)
-      return SpatialRelation.CONTAINS;
-    else if (relationship == GeoArea.OVERLAPS)
-      return SpatialRelation.INTERSECTS;
-    else if (relationship == GeoArea.DISJOINT)
-      return SpatialRelation.DISJOINT;
-    else
-      throw new RuntimeException("Unknown relationship returned: "+relationship);
-  }
-
-  protected SpatialRelation relate(Point p) {
-    // Create a GeoPoint
-    GeoPoint point = new GeoPoint(planetModel, p.getY()* DistanceUtils.DEGREES_TO_RADIANS, p.getX()* DistanceUtils.DEGREES_TO_RADIANS);
-    if (shape.isWithin(point)) {
-      // Point within shape
-      return SpatialRelation.CONTAINS;
-    }
-    return SpatialRelation.DISJOINT;
-  }
-
-
-  
-  @Override
-  public Rectangle getBoundingBox() {
-    Rectangle bbox = this.boundingBox;//volatile read once
-    if (bbox == null) {
-      LatLonBounds bounds = new LatLonBounds();
-      shape.getBounds(bounds);
-      double leftLon;
-      double rightLon;
-      if (bounds.checkNoLongitudeBound()) {
-        leftLon = -180.0;
-        rightLon = 180.0;
-      } else {
-        leftLon = bounds.getLeftLongitude().doubleValue() * DistanceUtils.RADIANS_TO_DEGREES;
-        rightLon = bounds.getRightLongitude().doubleValue() * DistanceUtils.RADIANS_TO_DEGREES;
-      }
-      double minLat;
-      if (bounds.checkNoBottomLatitudeBound()) {
-        minLat = -90.0;
-      } else {
-        minLat = bounds.getMinLatitude().doubleValue() * DistanceUtils.RADIANS_TO_DEGREES;
-      }
-      double maxLat;
-      if (bounds.checkNoTopLatitudeBound()) {
-        maxLat = 90.0;
-      } else {
-        maxLat = bounds.getMaxLatitude().doubleValue() * DistanceUtils.RADIANS_TO_DEGREES;
-      }
-      bbox = new RectangleImpl(leftLon, rightLon, minLat, maxLat, ctx).getBuffered(ROUNDOFF_ADJUSTMENT, ctx);
-      this.boundingBox = bbox;
-    }
-    return bbox;
-  }
-
-  @Override
-  public boolean hasArea() {
-    return true;
-  }
-
-  @Override
-  public double getArea(SpatialContext ctx) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public Point getCenter() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public Shape getBuffered(double distance, SpatialContext ctx) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public boolean isEmpty() {
-    return false;
-  }
-
-  @Override
-  public String toString() {
-    return "Geo3dShape{planetmodel=" + planetModel + ", shape=" + shape + '}';
-  }
-
-  @Override
-  public boolean equals(Object other) {
-    if (!(other instanceof Geo3dShape))
-      return false;
-    Geo3dShape tr = (Geo3dShape)other;
-    return tr.ctx.equals(ctx) && tr.planetModel.equals(planetModel) && tr.shape.equals(shape);
-  }
-
-  @Override
-  public int hashCode() {
-    return planetModel.hashCode() + shape.hashCode();
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/package-info.java b/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/package-info.java
deleted file mode 100644
index 7815318..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/package-info.java
+++ /dev/null
@@ -1,19 +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.
- */
-
-/** Spatial4j stuff that ideally belongs in Spatial4j (isn't related to Lucene). */
-package org.apache.lucene.spatial.spatial4j;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/java/org/apache/lucene/spatial/util/CachingDoubleValueSource.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/util/CachingDoubleValueSource.java b/lucene/spatial/src/java/org/apache/lucene/spatial/util/CachingDoubleValueSource.java
deleted file mode 100644
index 73d25ca..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/util/CachingDoubleValueSource.java
+++ /dev/null
@@ -1,93 +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.util;
-
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.queries.function.FunctionValues;
-import org.apache.lucene.queries.function.ValueSource;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Caches the doubleVal of another value source in a HashMap
- * so that it is computed only once.
- * @lucene.internal
- */
-public class CachingDoubleValueSource extends ValueSource {
-
-  final ValueSource source;
-  final Map<Integer, Double> cache;
-
-  public CachingDoubleValueSource( ValueSource source )
-  {
-    this.source = source;
-    cache = new HashMap<>();
-  }
-
-  @Override
-  public String description() {
-    return "Cached["+source.description()+"]";
-  }
-
-  @Override
-  public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
-    final int base = readerContext.docBase;
-    final FunctionValues vals = source.getValues(context,readerContext);
-    return new FunctionValues() {
-
-      @Override
-      public double doubleVal(int doc) {
-        Integer key = Integer.valueOf( base+doc );
-        Double v = cache.get( key );
-        if( v == null ) {
-          v = Double.valueOf( vals.doubleVal(doc) );
-          cache.put( key, v );
-        }
-        return v.doubleValue();
-      }
-
-      @Override
-      public float floatVal(int doc) {
-        return (float)doubleVal(doc);
-      }
-
-      @Override
-      public String toString(int doc) {
-        return doubleVal(doc)+"";
-      }
-    };
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-
-    CachingDoubleValueSource that = (CachingDoubleValueSource) o;
-
-    if (source != null ? !source.equals(that.source) : that.source != null) return false;
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    return source != null ? source.hashCode() : 0;
-  }
-}


[43/50] [abbrv] lucene-solr git commit: SOLR-8375: ReplicaAssigner rejects valid nodes

Posted by ho...@apache.org.
SOLR-8375: ReplicaAssigner rejects valid nodes


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/e44eebf3
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/e44eebf3
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/e44eebf3

Branch: refs/heads/jira/SOLR-445
Commit: e44eebf39d62cb68e123c68ac94cecc700ae1087
Parents: 79b62ee
Author: Noble Paul <no...@apache.org>
Authored: Tue Mar 1 10:49:47 2016 +0530
Committer: Noble Paul <no...@apache.org>
Committed: Tue Mar 1 10:49:47 2016 +0530

----------------------------------------------------------------------
 solr/CHANGES.txt                                            | 2 ++
 .../java/org/apache/solr/cloud/rule/ReplicaAssigner.java    | 9 +++------
 2 files changed, 5 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e44eebf3/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 24501bb..fb64188 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -226,6 +226,8 @@ Bug Fixes
 * SOLR-8748: OverseerTaskProcessor limits number of concurrent tasks to just 10 even though the thread pool
   size is 100. The limit has now been increased to 100. (Scott Blum, shalin)
 
+* SOLR-8375: ReplicaAssigner rejects valid nodes (Kelvin Tan, noble)
+
 Optimizations
 ----------------------
 * SOLR-7876: Speed up queries and operations that use many terms when timeAllowed has not been

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e44eebf3/solr/core/src/java/org/apache/solr/cloud/rule/ReplicaAssigner.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/rule/ReplicaAssigner.java b/solr/core/src/java/org/apache/solr/cloud/rule/ReplicaAssigner.java
index 51d9848..c9f774f 100644
--- a/solr/core/src/java/org/apache/solr/cloud/rule/ReplicaAssigner.java
+++ b/solr/core/src/java/org/apache/solr/cloud/rule/ReplicaAssigner.java
@@ -44,11 +44,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import static java.util.Collections.singletonList;
-import static org.apache.solr.cloud.rule.Rule.MatchStatus.NODE_CAN_BE_ASSIGNED;
-import static org.apache.solr.cloud.rule.Rule.Phase.ASSIGN;
-import static org.apache.solr.cloud.rule.Rule.Phase.FUZZY_ASSIGN;
-import static org.apache.solr.cloud.rule.Rule.Phase.FUZZY_VERIFY;
-import static org.apache.solr.cloud.rule.Rule.Phase.VERIFY;
+import static org.apache.solr.cloud.rule.Rule.MatchStatus.*;
+import static org.apache.solr.cloud.rule.Rule.Phase.*;
 import static org.apache.solr.common.util.StrUtils.formatString;
 import static org.apache.solr.common.util.Utils.getDeepCopy;
 
@@ -280,7 +277,7 @@ public class ReplicaAssigner {
         Rule rule = rules.get(rulePermutation[i]);
         Rule.MatchStatus matchStatus = rule.tryAssignNodeToShard(e.getValue(),
             copyOfCurrentState, nodeVsTagsCopy, e.getKey().shard, fuzzyPhase ? FUZZY_VERIFY : VERIFY);
-        if (matchStatus != NODE_CAN_BE_ASSIGNED) return null;
+        if (matchStatus != NODE_CAN_BE_ASSIGNED && matchStatus != NOT_APPLICABLE) return null;
       }
     }
     return result;


[49/50] [abbrv] lucene-solr git commit: SOLR-8738: Fixed false success response when invalid deleteByQuery requests intially hit non-leader cloud nodes

Posted by ho...@apache.org.
SOLR-8738: Fixed false success response when invalid deleteByQuery requests intially hit non-leader cloud nodes


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/ff6557cb
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/ff6557cb
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/ff6557cb

Branch: refs/heads/master
Commit: ff6557cbcb5308d60f17114de1d0ad29003e9668
Parents: 2a7314b
Author: Chris Hostetter <ho...@apache.org>
Authored: Tue Mar 1 10:02:07 2016 -0700
Committer: Chris Hostetter <ho...@apache.org>
Committed: Tue Mar 1 10:02:07 2016 -0700

----------------------------------------------------------------------
 solr/CHANGES.txt                                |   3 +
 .../processor/DistributedUpdateProcessor.java   |   2 +-
 .../solr/cloud/TestCloudDeleteByQuery.java      | 245 +++++++++++++++++++
 3 files changed, 249 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ff6557cb/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index fb64188..c0d3d86 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -228,6 +228,9 @@ Bug Fixes
 
 * SOLR-8375: ReplicaAssigner rejects valid nodes (Kelvin Tan, noble)
 
+* SOLR-8738: Fixed false success response when invalid deleteByQuery requests intially hit non-leader
+  cloud nodes (hossman)
+
 Optimizations
 ----------------------
 * SOLR-7876: Speed up queries and operations that use many terms when timeAllowed has not been

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ff6557cb/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java
index c68445c..365de6c 100644
--- a/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java
+++ b/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java
@@ -1284,7 +1284,7 @@ public class DistributedUpdateProcessor extends UpdateRequestProcessor {
           // don't forward to ourself
           leaderForAnyShard = true;
         } else {
-          leaders.add(new StdNode(coreLeaderProps, collection, sliceName));
+          leaders.add(new RetryNode(coreLeaderProps, zkController.getZkStateReader(), collection, sliceName));
         }
       }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ff6557cb/solr/core/src/test/org/apache/solr/cloud/TestCloudDeleteByQuery.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestCloudDeleteByQuery.java b/solr/core/src/test/org/apache/solr/cloud/TestCloudDeleteByQuery.java
new file mode 100644
index 0000000..a0bb42a
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/cloud/TestCloudDeleteByQuery.java
@@ -0,0 +1,245 @@
+/*
+ * 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.solr.cloud;
+
+import java.io.File;
+import java.lang.invoke.MethodHandles;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.solr.cloud.SolrCloudTestCase;
+import org.apache.solr.client.solrj.SolrClient;
+import org.apache.solr.client.solrj.embedded.JettySolrRunner;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
+import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.request.UpdateRequest;
+import org.apache.solr.client.solrj.response.UpdateResponse;
+import org.apache.solr.common.SolrDocument;
+import org.apache.solr.common.SolrDocumentList;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.SolrInputField;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.cloud.ClusterState;
+import org.apache.solr.common.cloud.Replica;
+import org.apache.solr.common.cloud.Slice;
+import org.apache.solr.common.cloud.ZkStateReader;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.util.SimpleOrderedMap;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TestCloudDeleteByQuery extends SolrCloudTestCase {
+
+  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+  private static final int NUM_SHARDS = 2; 
+  private static final int REPLICATION_FACTOR = 2; 
+  private static final int NUM_SERVERS = 5; 
+  
+  private static final String COLLECTION_NAME = "test_col";
+  
+  /** A basic client for operations at the cloud level, default collection will be set */
+  private static CloudSolrClient CLOUD_CLIENT;
+
+  /** A client for talking directly to the leader of shard1 */
+  private static HttpSolrClient S_ONE_LEADER_CLIENT;
+  
+  /** A client for talking directly to the leader of shard2 */
+  private static HttpSolrClient S_TWO_LEADER_CLIENT;
+
+  /** A client for talking directly to a passive replica of shard1 */
+  private static HttpSolrClient S_ONE_NON_LEADER_CLIENT;
+  
+  /** A client for talking directly to a passive replica of shard2 */
+  private static HttpSolrClient S_TWO_NON_LEADER_CLIENT;
+
+  /** A client for talking directly to a node that has no piece of the collection */
+  private static HttpSolrClient NO_COLLECTION_CLIENT;
+  
+  /** id field doc routing prefix for shard1 */
+  private static final String S_ONE_PRE = "abc!";
+  
+  /** id field doc routing prefix for shard2 */
+  private static final String S_TWO_PRE = "XYZ!";
+  
+  @BeforeClass
+  private static void createMiniSolrCloudCluster() throws Exception {
+    
+    final String configName = "solrCloudCollectionConfig";
+    File configDir = new File(TEST_HOME() + File.separator + "collection1" + File.separator + "conf");
+    
+    configureCluster(NUM_SERVERS)
+      .addConfig(configName, configDir.toPath())
+      .configure();
+    
+    Map<String, String> collectionProperties = new HashMap<>();
+    collectionProperties.put("config", "solrconfig-tlog.xml");
+    collectionProperties.put("schema", "schema15.xml"); // string id for doc routing prefix
+
+    assertNotNull(cluster.createCollection(COLLECTION_NAME, NUM_SHARDS, REPLICATION_FACTOR,
+                                           configName, null, null, collectionProperties));
+    
+    CLOUD_CLIENT = cluster.getSolrClient();
+    CLOUD_CLIENT.setDefaultCollection(COLLECTION_NAME);
+    
+    ZkStateReader zkStateReader = CLOUD_CLIENT.getZkStateReader();
+    AbstractDistribZkTestBase.waitForRecoveriesToFinish(COLLECTION_NAME, zkStateReader, true, true, 330);
+
+
+    // really hackish way to get a URL for specific nodes based on shard/replica hosting
+    // inspired by TestMiniSolrCloudCluster
+    HashMap<String, String> urlMap = new HashMap<>();
+    for (JettySolrRunner jetty : cluster.getJettySolrRunners()) {
+      URL jettyURL = jetty.getBaseUrl();
+      String nodeKey = jettyURL.getHost() + ":" + jettyURL.getPort() + jettyURL.getPath().replace("/","_");
+      urlMap.put(nodeKey, jettyURL.toString());
+    }
+    zkStateReader.updateClusterState();
+    ClusterState clusterState = zkStateReader.getClusterState();
+    for (Slice slice : clusterState.getSlices(COLLECTION_NAME)) {
+      String shardName = slice.getName();
+      Replica leader = slice.getLeader();
+      assertNotNull("slice has null leader: " + slice.toString(), leader);
+      assertNotNull("slice leader has null node name: " + slice.toString(), leader.getNodeName());
+      String leaderUrl = urlMap.remove(leader.getNodeName());
+      assertNotNull("could not find URL for " + shardName + " leader: " + leader.getNodeName(),
+                    leaderUrl);
+      assertEquals("expected two total replicas for: " + slice.getName(),
+                   2, slice.getReplicas().size());
+      
+      String passiveUrl = null;
+      
+      for (Replica replica : slice.getReplicas()) {
+        if ( ! replica.equals(leader)) {
+          passiveUrl = urlMap.remove(replica.getNodeName());
+          assertNotNull("could not find URL for " + shardName + " replica: " + replica.getNodeName(),
+                        passiveUrl);
+        }
+      }
+      assertNotNull("could not find URL for " + shardName + " replica", passiveUrl);
+
+      if (shardName.equals("shard1")) {
+        S_ONE_LEADER_CLIENT = new HttpSolrClient(leaderUrl + "/" + COLLECTION_NAME + "/");
+        S_ONE_NON_LEADER_CLIENT = new HttpSolrClient(passiveUrl + "/" + COLLECTION_NAME + "/");
+      } else if (shardName.equals("shard2")) {
+        S_TWO_LEADER_CLIENT = new HttpSolrClient(leaderUrl + "/" + COLLECTION_NAME + "/");
+        S_TWO_NON_LEADER_CLIENT = new HttpSolrClient(passiveUrl + "/" + COLLECTION_NAME + "/");
+      } else {
+        fail("unexpected shard: " + shardName);
+      }
+    }
+    assertEquals("Should be exactly one server left (nost hosting either shard)", 1, urlMap.size());
+    NO_COLLECTION_CLIENT = new HttpSolrClient(urlMap.values().iterator().next() +
+                                              "/" + COLLECTION_NAME + "/");
+    
+    assertNotNull(S_ONE_LEADER_CLIENT);
+    assertNotNull(S_TWO_LEADER_CLIENT);
+    assertNotNull(S_ONE_NON_LEADER_CLIENT);
+    assertNotNull(S_TWO_NON_LEADER_CLIENT);
+    assertNotNull(NO_COLLECTION_CLIENT);
+
+    // sanity check that our S_ONE_PRE & S_TWO_PRE really do map to shard1 & shard2 with default routing
+    assertEquals(0, CLOUD_CLIENT.add(doc(f("id", S_ONE_PRE + random().nextInt()),
+                                         f("expected_shard_s", "shard1"))).getStatus());
+    assertEquals(0, CLOUD_CLIENT.add(doc(f("id", S_TWO_PRE + random().nextInt()),
+                                         f("expected_shard_s", "shard2"))).getStatus());
+    assertEquals(0, CLOUD_CLIENT.commit().getStatus());
+    SolrDocumentList docs = CLOUD_CLIENT.query(params("q", "*:*",
+                                                      "fl","id,expected_shard_s,[shard]")).getResults();
+    assertEquals(2, docs.getNumFound());
+    assertEquals(2, docs.size());
+    for (SolrDocument doc : docs) {
+      String expected = COLLECTION_NAME + "_" + doc.getFirstValue("expected_shard_s") + "_replica";
+      String docShard = doc.getFirstValue("[shard]").toString();
+      assertTrue("shard routing prefixes don't seem to be aligned anymore, " +
+                 "did someone change the default routing rules? " +
+                 "and/or the the default core name rules? " +
+                 "and/or the numShards used by this test? ... " +
+                 "couldn't find " + expected + " as substring of [shard] == '" + docShard +
+                 "' ... for docId == " + doc.getFirstValue("id"),
+                 docShard.contains(expected));
+    }
+  }
+  
+  @Before
+  private void clearCloudCollection() throws Exception {
+    assertEquals(0, CLOUD_CLIENT.deleteByQuery("*:*").getStatus());
+    assertEquals(0, CLOUD_CLIENT.commit().getStatus());
+  }
+
+  public void testMalformedDBQ(SolrClient client) throws Exception {
+    assertNotNull("client not initialized", client);
+    try {
+      UpdateResponse rsp = update(params()).deleteByQuery("foo_i:not_a_num").process(client);
+      fail("Expected DBQ failure: " + rsp.toString());
+    } catch (SolrException e) {
+      assertEquals("not the expected DBQ failure: " + e.getMessage(), 400, e.code());
+    }
+  }
+
+  //
+  public void testMalformedDBQViaCloudClient() throws Exception {
+    testMalformedDBQ(CLOUD_CLIENT);
+  }
+  public void testMalformedDBQViaShard1LeaderClient() throws Exception {
+    testMalformedDBQ(S_ONE_LEADER_CLIENT);
+  }
+  public void testMalformedDBQViaShard2LeaderClient() throws Exception {
+    testMalformedDBQ(S_TWO_LEADER_CLIENT);
+  }
+  public void testMalformedDBQViaShard1NonLeaderClient() throws Exception {
+    testMalformedDBQ(S_ONE_NON_LEADER_CLIENT);
+  }
+  public void testMalformedDBQViaShard2NonLeaderClient() throws Exception {
+    testMalformedDBQ(S_TWO_NON_LEADER_CLIENT);
+  }
+  public void testMalformedDBQViaNoCollectionClient() throws Exception {
+    testMalformedDBQ(NO_COLLECTION_CLIENT);
+  }
+
+  public static UpdateRequest update(SolrParams params, SolrInputDocument... docs) {
+    UpdateRequest r = new UpdateRequest();
+    r.setParams(new ModifiableSolrParams(params));
+    r.add(Arrays.asList(docs));
+    return r;
+  }
+  
+  public static SolrInputDocument doc(SolrInputField... fields) {
+    SolrInputDocument doc = new SolrInputDocument();
+    for (SolrInputField f : fields) {
+      doc.put(f.getName(), f);
+    }
+    return doc;
+  }
+  
+  public static SolrInputField f(String fieldName, Object... values) {
+    SolrInputField f = new SolrInputField(fieldName);
+    f.setValue(values, 1.0F);
+    return f;
+  }
+}


[46/50] [abbrv] lucene-solr git commit: LUCENE-7057: cleanup some sandiness around LatLonPoint

Posted by ho...@apache.org.
LUCENE-7057: cleanup some sandiness around LatLonPoint


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/2264600f
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/2264600f
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/2264600f

Branch: refs/heads/jira/SOLR-445
Commit: 2264600ffe4649abb0edbe7a6882ffc82f6e918b
Parents: b6ec959
Author: Robert Muir <rm...@apache.org>
Authored: Tue Mar 1 07:04:16 2016 -0500
Committer: Robert Muir <rm...@apache.org>
Committed: Tue Mar 1 07:04:45 2016 -0500

----------------------------------------------------------------------
 .../org/apache/lucene/document/LatLonPoint.java | 212 +++++++++++------
 .../document/LatLonPointDistanceQuery.java      | 193 ++++++++++++++++
 .../document/LatLonPointInPolygonQuery.java     | 226 +++++++++++++++++++
 .../org/apache/lucene/document/package.html     |   7 +-
 .../lucene/search/PointDistanceQuery.java       | 179 ---------------
 .../lucene/search/PointInPolygonQuery.java      | 207 -----------------
 .../apache/lucene/document/TestLatLonPoint.java | 197 ++++++++--------
 .../document/TestLatLonPointDistanceQuery.java  | 190 ++++++++++++++++
 .../lucene/search/TestLatLonPointQueries.java   |  62 ++---
 9 files changed, 874 insertions(+), 599 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2264600f/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
index 92b4a3a..b0902f5 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
@@ -19,11 +19,10 @@ package org.apache.lucene.document;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.NumericUtils;
 
+import org.apache.lucene.index.FieldInfo;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.ConstantScoreQuery;
-import org.apache.lucene.search.PointDistanceQuery;
-import org.apache.lucene.search.PointInPolygonQuery;
 import org.apache.lucene.search.PointRangeQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.spatial.util.GeoUtils;
@@ -49,36 +48,45 @@ import org.apache.lucene.spatial.util.GeoUtils;
 // to the field is not actually what gets indexed. Float would be 1E-5 error vs 1E-7, but it might be
 // a better tradeoff? then it would be completely transparent to the user and lucene would be "lossless".
 public class LatLonPoint extends Field {
+  /**
+   * Type for an indexed LatLonPoint
+   * <p>
+   * Each point stores two dimensions with 4 bytes per dimension.
+   */
   public static final FieldType TYPE = new FieldType();
   static {
     TYPE.setDimensions(2, Integer.BYTES);
     TYPE.freeze();
   }
+  
+  /**
+   * Change the values of this field
+   * @param latitude latitude value: must be within standard +/-90 coordinate bounds.
+   * @param longitude longitude value: must be within standard +/-180 coordinate bounds.
+   * @throws IllegalArgumentException if latitude or longitude are out of bounds
+   */
+  public void setLocationValue(double latitude, double longitude) {
+    byte[] bytes = new byte[8];
+    NumericUtils.intToBytes(encodeLatitude(latitude), bytes, 0);
+    NumericUtils.intToBytes(encodeLongitude(longitude), bytes, Integer.BYTES);
+    fieldsData = new BytesRef(bytes);
+  }
 
   /** 
-   * Creates a new LatLonPoint with the specified lat and lon
+   * Creates a new LatLonPoint with the specified latitude and longitude
    * @param name field name
-   * @param lat double latitude
-   * @param lon double longitude
-   * @throws IllegalArgumentException if the field name is null or lat or lon are out of bounds
+   * @param latitude latitude value: must be within standard +/-90 coordinate bounds.
+   * @param longitude longitude value: must be within standard +/-180 coordinate bounds.
+   * @throws IllegalArgumentException if the field name is null or latitude or longitude are out of bounds
    */
-  public LatLonPoint(String name, double lat, double lon) {
+  public LatLonPoint(String name, double latitude, double longitude) {
     super(name, TYPE);
-    if (GeoUtils.isValidLat(lat) == false) {
-      throw new IllegalArgumentException("invalid lat (" + lat + "): must be -90 to 90");
-    }
-    if (GeoUtils.isValidLon(lon) == false) {
-      throw new IllegalArgumentException("invalid lon (" + lon + "): must be -180 to 180");
-    }
-    byte[] bytes = new byte[8];
-    NumericUtils.intToBytes(encodeLat(lat), bytes, 0);
-    NumericUtils.intToBytes(encodeLon(lon), bytes, Integer.BYTES);
-    fieldsData = new BytesRef(bytes);
+    setLocationValue(latitude, longitude);
   }
 
   private static final int BITS = 32;
-  private static final double LON_SCALE = (0x1L<<BITS)/360.0D;
-  private static final double LAT_SCALE = (0x1L<<BITS)/180.0D;
+  private static final double LONGITUDE_SCALE = (0x1L<<BITS)/360.0D;
+  private static final double LATITUDE_SCALE = (0x1L<<BITS)/180.0D;
   
   @Override
   public String toString() {
@@ -89,9 +97,9 @@ public class LatLonPoint extends Field {
     result.append(':');
 
     BytesRef bytes = (BytesRef) fieldsData;
-    result.append(decodeLat(BytesRef.deepCopyOf(bytes).bytes, 0));
+    result.append(decodeLatitude(BytesRef.deepCopyOf(bytes).bytes, 0));
     result.append(',');
-    result.append(decodeLon(BytesRef.deepCopyOf(bytes).bytes, Integer.BYTES));
+    result.append(decodeLongitude(BytesRef.deepCopyOf(bytes).bytes, Integer.BYTES));
 
     result.append('>');
     return result.toString();
@@ -99,79 +107,125 @@ public class LatLonPoint extends Field {
 
   // public helper methods (e.g. for queries)
 
-  /** Quantizes double (64 bit) latitude into 32 bits */
-  public static int encodeLat(double lat) {
-    assert GeoUtils.isValidLat(lat): "lat=" + lat;
-    long x = (long) (lat * LAT_SCALE);
-    assert x < Integer.MAX_VALUE: "lat=" + lat + " mapped to Integer.MAX_VALUE + " + (x - Integer.MAX_VALUE);
-    assert x > Integer.MIN_VALUE: "lat=" + lat + " mapped to Integer.MIN_VALUE";
-    return (int) x;
+  /** 
+   * Quantizes double (64 bit) latitude into 32 bits 
+   * @param latitude latitude value: must be within standard +/-90 coordinate bounds.
+   * @return encoded value as a 32-bit {@code int}
+   * @throws IllegalArgumentException if latitude is out of bounds
+   */
+  public static int encodeLatitude(double latitude) {
+    if (GeoUtils.isValidLat(latitude) == false) {
+      throw new IllegalArgumentException("invalid latitude: " + latitude + ", must be -90 to 90");
+    }
+    // the maximum possible value cannot be encoded without overflow
+    if (latitude == 90.0D) {
+      latitude = Math.nextDown(latitude);
+    }
+    return Math.toIntExact((long) (latitude * LATITUDE_SCALE));
   }
 
-  /** Quantizes double (64 bit) longitude into 32 bits */
-  public static int encodeLon(double lon) {
-    assert GeoUtils.isValidLon(lon): "lon=" + lon;
-    long x = (long) (lon * LON_SCALE);
-    assert x < Integer.MAX_VALUE;
-    assert x > Integer.MIN_VALUE;
-    return (int) x;
+  /** 
+   * Quantizes double (64 bit) longitude into 32 bits 
+   * @param longitude longitude value: must be within standard +/-180 coordinate bounds.
+   * @return encoded value as a 32-bit {@code int}
+   * @throws IllegalArgumentException if longitude is out of bounds
+   */
+  public static int encodeLongitude(double longitude) {
+    if (GeoUtils.isValidLon(longitude) == false) {
+      throw new IllegalArgumentException("invalid longitude: " + longitude + ", must be -180 to 180");
+    }
+    // the maximum possible value cannot be encoded without overflow
+    if (longitude == 180.0D) {
+      longitude = Math.nextDown(longitude);
+    }
+    return Math.toIntExact((long) (longitude * LONGITUDE_SCALE));
   }
 
-  /** Turns quantized value from {@link #encodeLat} back into a double. */
-  public static double decodeLat(int x) {
-    return x / LAT_SCALE;
+  /** 
+   * Turns quantized value from {@link #encodeLatitude} back into a double. 
+   * @param encoded encoded value: 32-bit quantized value.
+   * @return decoded latitude value.
+   */
+  public static double decodeLatitude(int encoded) {
+    double result = encoded / LATITUDE_SCALE;
+    assert GeoUtils.isValidLat(result);
+    return result;
   }
   
-  /** Turns quantized value from byte array back into a double. */
-  public static double decodeLat(byte[] src, int offset) {
-    return decodeLat(NumericUtils.bytesToInt(src, offset));
+  /** 
+   * Turns quantized value from byte array back into a double. 
+   * @param src byte array containing 4 bytes to decode at {@code offset}
+   * @param offset offset into {@code src} to decode from.
+   * @return decoded latitude value.
+   */
+  public static double decodeLatitude(byte[] src, int offset) {
+    return decodeLatitude(NumericUtils.bytesToInt(src, offset));
   }
 
-  /** Turns quantized value from {@link #encodeLon} back into a double. */
-  public static double decodeLon(int x) {
-    return x / LON_SCALE;
+  /** 
+   * Turns quantized value from {@link #encodeLongitude} back into a double. 
+   * @param encoded encoded value: 32-bit quantized value.
+   * @return decoded longitude value.
+   */  
+  public static double decodeLongitude(int encoded) {
+    double result = encoded / LONGITUDE_SCALE;
+    assert GeoUtils.isValidLon(result);
+    return result;
   }
 
-  /** Turns quantized value from byte array back into a double. */
-  public static double decodeLon(byte[] src, int offset) {
-    return decodeLon(NumericUtils.bytesToInt(src, offset));
+  /** 
+   * Turns quantized value from byte array back into a double. 
+   * @param src byte array containing 4 bytes to decode at {@code offset}
+   * @param offset offset into {@code src} to decode from.
+   * @return decoded longitude value.
+   */
+  public static double decodeLongitude(byte[] src, int offset) {
+    return decodeLongitude(NumericUtils.bytesToInt(src, offset));
   }
   
   /** sugar encodes a single point as a 2D byte array */
-  private static byte[][] encode(double lat, double lon) {
+  private static byte[][] encode(double latitude, double longitude) {
     byte[][] bytes = new byte[2][];
     bytes[0] = new byte[4];
-    NumericUtils.intToBytes(encodeLat(lat), bytes[0], 0);
+    NumericUtils.intToBytes(encodeLatitude(latitude), bytes[0], 0);
     bytes[1] = new byte[4];
-    NumericUtils.intToBytes(encodeLon(lon), bytes[1], 0);
+    NumericUtils.intToBytes(encodeLongitude(longitude), bytes[1], 0);
     return bytes;
   }
-   
+
+  /** helper: checks a fieldinfo and throws exception if its definitely not a LatLonPoint */
+  static void checkCompatible(FieldInfo fieldInfo) {
+    if (fieldInfo.getPointDimensionCount() != TYPE.pointDimensionCount()) {
+      throw new IllegalArgumentException("field=\"" + fieldInfo.name + "\" was indexed with numDims=" + fieldInfo.getPointDimensionCount() + 
+                                         " but this point type has numDims=" + TYPE.pointDimensionCount() + 
+                                         ", is the field really a LatLonPoint?");
+    }
+    if (fieldInfo.getPointNumBytes() != TYPE.pointNumBytes()) {
+      throw new IllegalArgumentException("field=\"" + fieldInfo.name + "\" was indexed with bytesPerDim=" + fieldInfo.getPointNumBytes() + 
+                                         " but this point type has bytesPerDim=" + TYPE.pointNumBytes() + 
+                                         ", is the field really a LatLonPoint?");
+    }
+  }
+
   // static methods for generating queries
 
   /**
    * Create a query for matching a bounding box.
    * <p>
    * The box may cross over the dateline.
+   * @param field field name. cannot be null.
+   * @param minLatitude latitude lower bound: must be within standard +/-90 coordinate bounds.
+   * @param maxLatitude latitude upper bound: must be within standard +/-90 coordinate bounds.
+   * @param minLongitude longitude lower bound: must be within standard +/-180 coordinate bounds.
+   * @param maxLongitude longitude upper bound: must be within standard +/-180 coordinate bounds.
+   * @return query matching points within this box
+   * @throws IllegalArgumentException if {@code field} is null, or the box has invalid coordinates.
    */
-  public static Query newBoxQuery(String field, double minLat, double maxLat, double minLon, double maxLon) {
-    if (GeoUtils.isValidLat(minLat) == false) {
-      throw new IllegalArgumentException("minLat=" + minLat + " is not a valid latitude");
-    }
-    if (GeoUtils.isValidLat(maxLat) == false) {
-      throw new IllegalArgumentException("maxLat=" + maxLat + " is not a valid latitude");
-    }
-    if (GeoUtils.isValidLon(minLon) == false) {
-      throw new IllegalArgumentException("minLon=" + minLon + " is not a valid longitude");
-    }
-    if (GeoUtils.isValidLon(maxLon) == false) {
-      throw new IllegalArgumentException("maxLon=" + maxLon + " is not a valid longitude");
-    }
-    
-    byte[][] lower = encode(minLat, minLon);
-    byte[][] upper = encode(maxLat, maxLon);
+  public static Query newBoxQuery(String field, double minLatitude, double maxLatitude, double minLongitude, double maxLongitude) {
+    byte[][] lower = encode(minLatitude, minLongitude);
+    byte[][] upper = encode(maxLatitude, maxLongitude);
     // Crosses date line: we just rewrite into OR of two bboxes, with longitude as an open range:
-    if (maxLon < minLon) {
+    if (maxLongitude < minLongitude) {
       // Disable coord here because a multi-valued doc could match both rects and get unfairly boosted:
       BooleanQuery.Builder q = new BooleanQuery.Builder();
       q.setDisableCoord(true);
@@ -198,9 +252,9 @@ public class LatLonPoint extends Field {
       @Override
       protected String toString(int dimension, byte[] value) {
         if (dimension == 0) {
-          return Double.toString(decodeLat(value, 0));
+          return Double.toString(decodeLatitude(value, 0));
         } else if (dimension == 1) {
-          return Double.toString(decodeLon(value, 0));
+          return Double.toString(decodeLongitude(value, 0));
         } else {
           throw new AssertionError();
         }
@@ -210,17 +264,31 @@ public class LatLonPoint extends Field {
   
   /**
    * Create a query for matching points within the specified distance of the supplied location.
+   * @param field field name. cannot 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 PointDistanceQuery(field, latitude, longitude, radiusMeters);
+    return new LatLonPointDistanceQuery(field, latitude, longitude, radiusMeters);
   }
   
   /** 
    * Create a query for matching a polygon.
    * <p>
    * The supplied {@code polyLats}/{@code polyLons} must be clockwise or counter-clockwise.
+   * @param field field name. cannot be null.
+   * @param polyLats latitude values for points of the polygon: must be within standard +/-90 coordinate bounds.
+   * @param polyLons longitude values for points of the polygon: must be within standard +/-180 coordinate bounds.
+   * @return query matching points within this polygon
+   * @throws IllegalArgumentException if {@code field} is null, {@code polyLats} is null or has invalid coordinates, 
+   *                                  {@code polyLons} is null or has invalid coordinates, if {@code polyLats} has a different
+   *                                  length than {@code polyLons}, if the polygon has less than 4 points, or if polygon is 
+   *                                  not closed (first and last points should be the same)
    */
   public static Query newPolygonQuery(String field, double[] polyLats, double[] polyLons) {
-    return new PointInPolygonQuery(field, polyLats, polyLons);
+    return new LatLonPointInPolygonQuery(field, polyLats, polyLons);
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2264600f/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
new file mode 100644
index 0000000..de4805b
--- /dev/null
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java
@@ -0,0 +1,193 @@
+/*
+ * 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.index.FieldInfo;
+import org.apache.lucene.index.LeafReader;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.PointValues;
+import org.apache.lucene.index.PointValues.IntersectVisitor;
+import org.apache.lucene.index.PointValues.Relation;
+import org.apache.lucene.search.ConstantScoreScorer;
+import org.apache.lucene.search.ConstantScoreWeight;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.Weight;
+import org.apache.lucene.spatial.util.GeoDistanceUtils;
+import org.apache.lucene.spatial.util.GeoRect;
+import org.apache.lucene.spatial.util.GeoUtils;
+import org.apache.lucene.util.DocIdSetBuilder;
+
+/**
+ * Distance query for {@link LatLonPoint}.
+ */
+final class LatLonPointDistanceQuery extends Query {
+  final String field;
+  final double latitude;
+  final double longitude;
+  final double radiusMeters;
+
+  public LatLonPointDistanceQuery(String field, double latitude, double longitude, double radiusMeters) {
+    if (field == null) {
+      throw new IllegalArgumentException("field cannot be null");
+    }
+    if (Double.isFinite(radiusMeters) == false || radiusMeters < 0) {
+      throw new IllegalArgumentException("radiusMeters: '" + radiusMeters + "' is invalid");
+    }
+    if (GeoUtils.isValidLat(latitude) == false) {
+      throw new IllegalArgumentException("latitude: '" + latitude + "' is invalid");
+    }
+    if (GeoUtils.isValidLon(longitude) == false) {
+      throw new IllegalArgumentException("longitude: '" + longitude + "' is invalid");
+    }
+    this.field = field;
+    this.latitude = latitude;
+    this.longitude = longitude;
+    this.radiusMeters = radiusMeters;
+  }
+
+  @Override
+  public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
+    GeoRect box = GeoUtils.circleToBBox(longitude, latitude, radiusMeters);
+    final GeoRect box1;
+    final GeoRect box2;
+
+    // crosses dateline: split
+    if (box.maxLon < box.minLon) {
+      box1 = new GeoRect(-180.0, box.maxLon, box.minLat, box.maxLat);
+      box2 = new GeoRect(box.minLon, 180.0, box.minLat, box.maxLat);
+    } else {
+      box1 = box;
+      box2 = null;
+    }
+
+    return new ConstantScoreWeight(this) {
+
+      @Override
+      public Scorer scorer(LeafReaderContext context) throws IOException {
+        LeafReader reader = context.reader();
+        PointValues values = reader.getPointValues();
+        if (values == null) {
+          // No docs in this segment had any points fields
+          return null;
+        }
+        FieldInfo fieldInfo = reader.getFieldInfos().fieldInfo(field);
+        if (fieldInfo == null) {
+          // No docs in this segment indexed this field at all
+          return null;
+        }
+        LatLonPoint.checkCompatible(fieldInfo);
+        
+        DocIdSetBuilder result = new DocIdSetBuilder(reader.maxDoc());
+        values.intersect(field,
+                         new IntersectVisitor() {
+                           @Override
+                           public void visit(int docID) {
+                             result.add(docID);
+                           }
+
+                           @Override
+                           public void visit(int docID, byte[] packedValue) {
+                             assert packedValue.length == 8;
+                             double lat = LatLonPoint.decodeLatitude(packedValue, 0);
+                             double lon = LatLonPoint.decodeLongitude(packedValue, Integer.BYTES);
+                             if (GeoDistanceUtils.haversin(latitude, longitude, lat, lon) <= radiusMeters) {
+                               visit(docID);
+                             }
+                           }
+                           
+                           // algorithm: we create a bounding box (two bounding boxes if we cross the dateline).
+                           // 1. check our bounding box(es) first. if the subtree is entirely outside of those, bail.
+                           // 2. see if the subtree is fully contained. if the subtree is enormous along the x axis, wrapping half way around the world, etc: then this can't work, just go to step 3.
+                           // 3. recurse naively.
+                           @Override
+                           public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
+                             double latMin = LatLonPoint.decodeLatitude(minPackedValue, 0);
+                             double lonMin = LatLonPoint.decodeLongitude(minPackedValue, Integer.BYTES);
+                             double latMax = LatLonPoint.decodeLatitude(maxPackedValue, 0);
+                             double lonMax = LatLonPoint.decodeLongitude(maxPackedValue, Integer.BYTES);
+                             
+                             if ((latMax < box1.minLat || lonMax < box1.minLon || latMin > box1.maxLat || lonMin > box1.maxLon) && 
+                                 (box2 == null || latMax < box2.minLat || lonMax < box2.minLon || latMin > box2.maxLat || lonMin > box2.maxLon)) {
+                               // we are fully outside of bounding box(es), don't proceed any further.
+                               return Relation.CELL_OUTSIDE_QUERY;
+                             } else if (lonMax - longitude < 90 && longitude - lonMin < 90 &&
+                                 GeoDistanceUtils.haversin(latitude, longitude, latMin, lonMin) <= radiusMeters &&
+                                 GeoDistanceUtils.haversin(latitude, longitude, latMin, lonMax) <= radiusMeters &&
+                                 GeoDistanceUtils.haversin(latitude, longitude, latMax, lonMin) <= radiusMeters &&
+                                 GeoDistanceUtils.haversin(latitude, longitude, latMax, lonMax) <= radiusMeters) {
+                               // 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 new ConstantScoreScorer(this, score(), result.build().iterator());
+      }
+    };
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = super.hashCode();
+    result = prime * result + field.hashCode();
+    long temp;
+    temp = Double.doubleToLongBits(latitude);
+    result = prime * result + (int) (temp ^ (temp >>> 32));
+    temp = Double.doubleToLongBits(longitude);
+    result = prime * result + (int) (temp ^ (temp >>> 32));
+    temp = Double.doubleToLongBits(radiusMeters);
+    result = prime * result + (int) (temp ^ (temp >>> 32));
+    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;
+    LatLonPointDistanceQuery other = (LatLonPointDistanceQuery) obj;
+    if (!field.equals(other.field)) return false;
+    if (Double.doubleToLongBits(latitude) != Double.doubleToLongBits(other.latitude)) return false;
+    if (Double.doubleToLongBits(longitude) != Double.doubleToLongBits(other.longitude)) return false;
+    if (Double.doubleToLongBits(radiusMeters) != Double.doubleToLongBits(other.radiusMeters)) return false;
+    return true;
+  }
+
+  @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();
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2264600f/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
new file mode 100644
index 0000000..d75e615
--- /dev/null
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java
@@ -0,0 +1,226 @@
+/*
+ * 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 java.util.Arrays;
+
+import org.apache.lucene.index.PointValues.IntersectVisitor;
+import org.apache.lucene.index.PointValues.Relation;
+import org.apache.lucene.search.ConstantScoreScorer;
+import org.apache.lucene.search.ConstantScoreWeight;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.Weight;
+import org.apache.lucene.index.PointValues;
+import org.apache.lucene.index.FieldInfo;
+import org.apache.lucene.index.LeafReader;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.util.DocIdSetBuilder;
+import org.apache.lucene.spatial.util.GeoRelationUtils;
+import org.apache.lucene.spatial.util.GeoUtils;
+
+/** Finds all previously indexed points that fall within the specified polygon.
+ *
+ *  <p>The field must be indexed with using {@link org.apache.lucene.document.LatLonPoint} added per document.
+ *
+ *  @lucene.experimental */
+
+final class LatLonPointInPolygonQuery extends Query {
+  final String field;
+  final double minLat;
+  final double maxLat;
+  final double minLon;
+  final double maxLon;
+  final double[] polyLats;
+  final double[] polyLons;
+
+  /** The lats/lons must be clockwise or counter-clockwise. */
+  public LatLonPointInPolygonQuery(String field, double[] polyLats, double[] polyLons) {
+    this.field = field;
+    if (field == null) {
+      throw new IllegalArgumentException("field cannot be null");
+    }
+    if (polyLats == null) {
+      throw new IllegalArgumentException("polyLats cannot be null");
+    }
+    if (polyLons == null) {
+      throw new IllegalArgumentException("polyLons cannot be null");
+    }
+    if (polyLats.length != polyLons.length) {
+      throw new IllegalArgumentException("polyLats and polyLons must be equal length");
+    }
+    if (polyLats.length < 4) {
+      throw new IllegalArgumentException("at least 4 polygon points required");
+    }
+    if (polyLats[0] != polyLats[polyLats.length-1]) {
+      throw new IllegalArgumentException("first and last points of the polygon must be the same (it must close itself): polyLats[0]=" + polyLats[0] + " polyLats[" + (polyLats.length-1) + "]=" + polyLats[polyLats.length-1]);
+    }
+    if (polyLons[0] != polyLons[polyLons.length-1]) {
+      throw new IllegalArgumentException("first and last points of the polygon must be the same (it must close itself): polyLons[0]=" + polyLons[0] + " polyLons[" + (polyLons.length-1) + "]=" + polyLons[polyLons.length-1]);
+    }
+
+    this.polyLats = polyLats;
+    this.polyLons = polyLons;
+
+    // TODO: we could also compute the maximal inner bounding box, to make relations faster to compute?
+
+    double minLon = Double.POSITIVE_INFINITY;
+    double minLat = Double.POSITIVE_INFINITY;
+    double maxLon = Double.NEGATIVE_INFINITY;
+    double maxLat = Double.NEGATIVE_INFINITY;
+    for(int i=0;i<polyLats.length;i++) {
+      double lat = polyLats[i];
+      if (GeoUtils.isValidLat(lat) == false) {
+        throw new IllegalArgumentException("polyLats[" + i + "]=" + lat + " is not a valid latitude");
+      }
+      minLat = Math.min(minLat, lat);
+      maxLat = Math.max(maxLat, lat);
+      double lon = polyLons[i];
+      if (GeoUtils.isValidLon(lon) == false) {
+        throw new IllegalArgumentException("polyLons[" + i + "]=" + lat + " is not a valid longitude");
+      }
+      minLon = Math.min(minLon, lon);
+      maxLon = Math.max(maxLon, lon);
+    }
+    this.minLon = minLon;
+    this.maxLon = maxLon;
+    this.minLat = minLat;
+    this.maxLat = maxLat;
+  }
+
+  @Override
+  public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
+
+    // I don't use RandomAccessWeight here: it's no good to approximate with "match all docs"; this is an inverted structure and should be
+    // used in the first pass:
+
+    // TODO: except that the polygon verify is costly!  The approximation should be all docs in all overlapping cells, and matches() should
+    // then check the polygon
+
+    return new ConstantScoreWeight(this) {
+
+      @Override
+      public Scorer scorer(LeafReaderContext context) throws IOException {
+        LeafReader reader = context.reader();
+        PointValues values = reader.getPointValues();
+        if (values == null) {
+          // No docs in this segment had any points fields
+          return null;
+        }
+        FieldInfo fieldInfo = reader.getFieldInfos().fieldInfo(field);
+        if (fieldInfo == null) {
+          // No docs in this segment indexed this field at all
+          return null;
+        }
+        LatLonPoint.checkCompatible(fieldInfo);
+
+        DocIdSetBuilder result = new DocIdSetBuilder(reader.maxDoc());
+        values.intersect(field,
+                         new IntersectVisitor() {
+                           @Override
+                           public void visit(int docID) {
+                             result.add(docID);
+                           }
+
+                           @Override
+                           public void visit(int docID, byte[] packedValue) {
+                             assert packedValue.length == 8;
+                             double lat = LatLonPoint.decodeLatitude(packedValue, 0);
+                             double lon = LatLonPoint.decodeLongitude(packedValue, Integer.BYTES);
+                             if (GeoRelationUtils.pointInPolygon(polyLons, polyLats, lat, lon)) {
+                               result.add(docID);
+                             }
+                           }
+
+                           @Override
+                           public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
+                             double cellMinLat = LatLonPoint.decodeLatitude(minPackedValue, 0);
+                             double cellMinLon = LatLonPoint.decodeLongitude(minPackedValue, Integer.BYTES);
+                             double cellMaxLat = LatLonPoint.decodeLatitude(maxPackedValue, 0);
+                             double cellMaxLon = LatLonPoint.decodeLongitude(maxPackedValue, Integer.BYTES);
+
+                             if (cellMinLat <= minLat && cellMaxLat >= maxLat && cellMinLon <= minLon && cellMaxLon >= maxLon) {
+                               // Cell fully encloses the query
+                               return Relation.CELL_CROSSES_QUERY;
+                             } else  if (GeoRelationUtils.rectWithinPolyPrecise(cellMinLon, cellMinLat, cellMaxLon, cellMaxLat,
+                                                                 polyLons, polyLats,
+                                                                 minLon, minLat, maxLon, maxLat)) {
+                               return Relation.CELL_INSIDE_QUERY;
+                             } else if (GeoRelationUtils.rectCrossesPolyPrecise(cellMinLon, cellMinLat, cellMaxLon, cellMaxLat,
+                                                                 polyLons, polyLats,
+                                                                 minLon, minLat, maxLon, maxLat)) {
+                               return Relation.CELL_CROSSES_QUERY;
+                             } else {
+                               return Relation.CELL_OUTSIDE_QUERY;
+                             }
+                           }
+                         });
+
+        return new ConstantScoreScorer(this, score(), result.build().iterator());
+      }
+    };
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+    if (!super.equals(o)) return false;
+
+    LatLonPointInPolygonQuery that = (LatLonPointInPolygonQuery) o;
+
+    if (Arrays.equals(polyLons, that.polyLons) == false) {
+      return false;
+    }
+    if (Arrays.equals(polyLats, that.polyLats) == false) {
+      return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public final int hashCode() {
+    int result = super.hashCode();
+    result = 31 * result + Arrays.hashCode(polyLons);
+    result = 31 * result + Arrays.hashCode(polyLats);
+    return result;
+  }
+
+  @Override
+  public String toString(String field) {
+    final StringBuilder sb = new StringBuilder();
+    sb.append(getClass().getSimpleName());
+    sb.append(':');
+    if (this.field.equals(field) == false) {
+      sb.append(" field=");
+      sb.append(this.field);
+      sb.append(':');
+    }
+    sb.append(" Points: ");
+    for (int i=0; i<polyLons.length; ++i) {
+      sb.append("[")
+        .append(polyLons[i])
+        .append(", ")
+        .append(polyLats[i])
+        .append("] ");
+    }
+    return sb.toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2264600f/lucene/sandbox/src/java/org/apache/lucene/document/package.html
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/package.html b/lucene/sandbox/src/java/org/apache/lucene/document/package.html
index 6f26128..b6a077e 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/document/package.html
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/package.html
@@ -23,6 +23,11 @@
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 </head>
 <body>
-This package contains a single Field implementation, GeoPointField, to index a lat/lon geospatial point.
+This package contains several point types:
+<ul>
+   <li>{@link org.apache.lucene.document.BigIntegerPoint BigIntegerPoint} for 128-bit integers</li>
+   <li>{@link org.apache.lucene.document.InetAddressPoint InetAddressPoint} for IPv4 and IPv6 network addresses</li>
+   <li>{@link org.apache.lucene.document.LatLonPoint LatLonPoint} for latitude/longitude geospatial points</li> 
+</ul>
 </body>
 </html>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2264600f/lucene/sandbox/src/java/org/apache/lucene/search/PointDistanceQuery.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/PointDistanceQuery.java b/lucene/sandbox/src/java/org/apache/lucene/search/PointDistanceQuery.java
deleted file mode 100644
index 4cfeb2f..0000000
--- a/lucene/sandbox/src/java/org/apache/lucene/search/PointDistanceQuery.java
+++ /dev/null
@@ -1,179 +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.search;
-
-import java.io.IOException;
-
-import org.apache.lucene.document.LatLonPoint;
-import org.apache.lucene.index.LeafReader;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.PointValues;
-import org.apache.lucene.index.PointValues.IntersectVisitor;
-import org.apache.lucene.index.PointValues.Relation;
-import org.apache.lucene.spatial.util.GeoDistanceUtils;
-import org.apache.lucene.spatial.util.GeoRect;
-import org.apache.lucene.spatial.util.GeoUtils;
-import org.apache.lucene.util.DocIdSetBuilder;
-import org.apache.lucene.util.NumericUtils;
-
-/**
- * Distance query for {@link LatLonPoint}.
- */
-public class PointDistanceQuery extends Query {
-  final String field;
-  final double latitude;
-  final double longitude;
-  final double radiusMeters;
-
-  public PointDistanceQuery(String field, double latitude, double longitude, double radiusMeters) {
-    if (field == null) {
-      throw new IllegalArgumentException("field cannot be null");
-    }
-    if (GeoUtils.isValidLat(latitude) == false) {
-      throw new IllegalArgumentException("latitude: '" + latitude + "' is invalid");
-    }
-    if (GeoUtils.isValidLon(longitude) == false) {
-      throw new IllegalArgumentException("longitude: '" + longitude + "' is invalid");
-    }
-    this.field = field;
-    this.latitude = latitude;
-    this.longitude = longitude;
-    this.radiusMeters = radiusMeters;
-  }
-
-  @Override
-  public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
-    GeoRect box = GeoUtils.circleToBBox(longitude, latitude, radiusMeters);
-    final GeoRect box1;
-    final GeoRect box2;
-
-    // crosses dateline: split
-    if (box.maxLon < box.minLon) {
-      box1 = new GeoRect(-180.0, box.maxLon, box.minLat, box.maxLat);
-      box2 = new GeoRect(box.minLon, 180.0, box.minLat, box.maxLat);
-    } else {
-      box1 = box;
-      box2 = null;
-    }
-
-    return new ConstantScoreWeight(this) {
-
-      @Override
-      public Scorer scorer(LeafReaderContext context) throws IOException {
-        LeafReader reader = context.reader();
-        PointValues values = reader.getPointValues();
-        if (values == null) {
-          // No docs in this segment had any points fields
-          return null;
-        }
-        
-        DocIdSetBuilder result = new DocIdSetBuilder(reader.maxDoc());
-        values.intersect(field,
-                         new IntersectVisitor() {
-                           @Override
-                           public void visit(int docID) {
-                             result.add(docID);
-                           }
-
-                           @Override
-                           public void visit(int docID, byte[] packedValue) {
-                             assert packedValue.length == 8;
-                             double lat = LatLonPoint.decodeLat(NumericUtils.bytesToInt(packedValue, 0));
-                             double lon = LatLonPoint.decodeLon(NumericUtils.bytesToInt(packedValue, Integer.BYTES));
-                             if (GeoDistanceUtils.haversin(latitude, longitude, lat, lon) <= radiusMeters) {
-                               visit(docID);
-                             }
-                           }
-                           
-                           // algorithm: we create a bounding box (two bounding boxes if we cross the dateline).
-                           // 1. check our bounding box(es) first. if the subtree is entirely outside of those, bail.
-                           // 2. see if the subtree is fully contained. if the subtree is enormous along the x axis, wrapping half way around the world, etc: then this can't work, just go to step 3.
-                           // 3. recurse naively.
-                           @Override
-                           public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
-                             double latMin = LatLonPoint.decodeLat(NumericUtils.bytesToInt(minPackedValue, 0));
-                             double lonMin = LatLonPoint.decodeLon(NumericUtils.bytesToInt(minPackedValue, Integer.BYTES));
-                             double latMax = LatLonPoint.decodeLat(NumericUtils.bytesToInt(maxPackedValue, 0));
-                             double lonMax = LatLonPoint.decodeLon(NumericUtils.bytesToInt(maxPackedValue, Integer.BYTES));
-                             
-                             if ((latMax < box1.minLat || lonMax < box1.minLon || latMin > box1.maxLat || lonMin > box1.maxLon) && 
-                                 (box2 == null || latMax < box2.minLat || lonMax < box2.minLon || latMin > box2.maxLat || lonMin > box2.maxLon)) {
-                               // we are fully outside of bounding box(es), don't proceed any further.
-                               return Relation.CELL_OUTSIDE_QUERY;
-                             } else if (lonMax - longitude < 90 && longitude - lonMin < 90 &&
-                                 GeoDistanceUtils.haversin(latitude, longitude, latMin, lonMin) <= radiusMeters &&
-                                 GeoDistanceUtils.haversin(latitude, longitude, latMin, lonMax) <= radiusMeters &&
-                                 GeoDistanceUtils.haversin(latitude, longitude, latMax, lonMin) <= radiusMeters &&
-                                 GeoDistanceUtils.haversin(latitude, longitude, latMax, lonMax) <= radiusMeters) {
-                               // 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 new ConstantScoreScorer(this, score(), result.build().iterator());
-      }
-    };
-  }
-
-  @Override
-  public int hashCode() {
-    final int prime = 31;
-    int result = super.hashCode();
-    result = prime * result + field.hashCode();
-    long temp;
-    temp = Double.doubleToLongBits(latitude);
-    result = prime * result + (int) (temp ^ (temp >>> 32));
-    temp = Double.doubleToLongBits(longitude);
-    result = prime * result + (int) (temp ^ (temp >>> 32));
-    temp = Double.doubleToLongBits(radiusMeters);
-    result = prime * result + (int) (temp ^ (temp >>> 32));
-    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;
-    PointDistanceQuery other = (PointDistanceQuery) obj;
-    if (!field.equals(other.field)) return false;
-    if (Double.doubleToLongBits(latitude) != Double.doubleToLongBits(other.latitude)) return false;
-    if (Double.doubleToLongBits(longitude) != Double.doubleToLongBits(other.longitude)) return false;
-    if (Double.doubleToLongBits(radiusMeters) != Double.doubleToLongBits(other.radiusMeters)) return false;
-    return true;
-  }
-
-  @Override
-  public String toString(String field) {
-    StringBuilder sb = new StringBuilder();
-    if (!this.field.equals(field)) {
-      sb.append(field);
-      sb.append(':');
-    }
-    sb.append(latitude);
-    sb.append(",");
-    sb.append(longitude);
-    sb.append(" +/- ");
-    sb.append(radiusMeters);
-    sb.append(" meters");
-    return sb.toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2264600f/lucene/sandbox/src/java/org/apache/lucene/search/PointInPolygonQuery.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/PointInPolygonQuery.java b/lucene/sandbox/src/java/org/apache/lucene/search/PointInPolygonQuery.java
deleted file mode 100644
index 6ae7c03..0000000
--- a/lucene/sandbox/src/java/org/apache/lucene/search/PointInPolygonQuery.java
+++ /dev/null
@@ -1,207 +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.search;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-import org.apache.lucene.document.LatLonPoint;
-import org.apache.lucene.index.PointValues.IntersectVisitor;
-import org.apache.lucene.index.PointValues.Relation;
-import org.apache.lucene.index.PointValues;
-import org.apache.lucene.index.LeafReader;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.util.DocIdSetBuilder;
-import org.apache.lucene.util.NumericUtils;
-import org.apache.lucene.spatial.util.GeoRelationUtils;
-import org.apache.lucene.spatial.util.GeoUtils;
-
-/** Finds all previously indexed points that fall within the specified polygon.
- *
- *  <p>The field must be indexed with using {@link org.apache.lucene.document.LatLonPoint} added per document.
- *
- *  @lucene.experimental */
-
-public class PointInPolygonQuery extends Query {
-  final String field;
-  final double minLat;
-  final double maxLat;
-  final double minLon;
-  final double maxLon;
-  final double[] polyLats;
-  final double[] polyLons;
-
-  /** The lats/lons must be clockwise or counter-clockwise. */
-  public PointInPolygonQuery(String field, double[] polyLats, double[] polyLons) {
-    this.field = field;
-    if (polyLats.length != polyLons.length) {
-      throw new IllegalArgumentException("polyLats and polyLons must be equal length");
-    }
-    if (polyLats.length < 4) {
-      throw new IllegalArgumentException("at least 4 polygon points required");
-    }
-    if (polyLats[0] != polyLats[polyLats.length-1]) {
-      throw new IllegalArgumentException("first and last points of the polygon must be the same (it must close itself): polyLats[0]=" + polyLats[0] + " polyLats[" + (polyLats.length-1) + "]=" + polyLats[polyLats.length-1]);
-    }
-    if (polyLons[0] != polyLons[polyLons.length-1]) {
-      throw new IllegalArgumentException("first and last points of the polygon must be the same (it must close itself): polyLons[0]=" + polyLons[0] + " polyLons[" + (polyLons.length-1) + "]=" + polyLons[polyLons.length-1]);
-    }
-
-    this.polyLats = polyLats;
-    this.polyLons = polyLons;
-
-    // TODO: we could also compute the maximal inner bounding box, to make relations faster to compute?
-
-    double minLon = Double.POSITIVE_INFINITY;
-    double minLat = Double.POSITIVE_INFINITY;
-    double maxLon = Double.NEGATIVE_INFINITY;
-    double maxLat = Double.NEGATIVE_INFINITY;
-    for(int i=0;i<polyLats.length;i++) {
-      double lat = polyLats[i];
-      if (GeoUtils.isValidLat(lat) == false) {
-        throw new IllegalArgumentException("polyLats[" + i + "]=" + lat + " is not a valid latitude");
-      }
-      minLat = Math.min(minLat, lat);
-      maxLat = Math.max(maxLat, lat);
-      double lon = polyLons[i];
-      if (GeoUtils.isValidLon(lon) == false) {
-        throw new IllegalArgumentException("polyLons[" + i + "]=" + lat + " is not a valid longitude");
-      }
-      minLon = Math.min(minLon, lon);
-      maxLon = Math.max(maxLon, lon);
-    }
-    this.minLon = minLon;
-    this.maxLon = maxLon;
-    this.minLat = minLat;
-    this.maxLat = maxLat;
-  }
-
-  @Override
-  public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
-
-    // I don't use RandomAccessWeight here: it's no good to approximate with "match all docs"; this is an inverted structure and should be
-    // used in the first pass:
-
-    // TODO: except that the polygon verify is costly!  The approximation should be all docs in all overlapping cells, and matches() should
-    // then check the polygon
-
-    return new ConstantScoreWeight(this) {
-
-      @Override
-      public Scorer scorer(LeafReaderContext context) throws IOException {
-        LeafReader reader = context.reader();
-        PointValues values = reader.getPointValues();
-        if (values == null) {
-          // No docs in this segment had any points fields
-          return null;
-        }
-
-        DocIdSetBuilder result = new DocIdSetBuilder(reader.maxDoc());
-        values.intersect(field,
-                         new IntersectVisitor() {
-                           @Override
-                           public void visit(int docID) {
-                             result.add(docID);
-                           }
-
-                           @Override
-                           public void visit(int docID, byte[] packedValue) {
-                             assert packedValue.length == 8;
-                             double lat = LatLonPoint.decodeLat(NumericUtils.bytesToInt(packedValue, 0));
-                             double lon = LatLonPoint.decodeLon(NumericUtils.bytesToInt(packedValue, Integer.BYTES));
-                             if (GeoRelationUtils.pointInPolygon(polyLons, polyLats, lat, lon)) {
-                               result.add(docID);
-                             }
-                           }
-
-                           @Override
-                           public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
-                             double cellMinLat = LatLonPoint.decodeLat(NumericUtils.bytesToInt(minPackedValue, 0));
-                             double cellMinLon = LatLonPoint.decodeLon(NumericUtils.bytesToInt(minPackedValue, Integer.BYTES));
-                             double cellMaxLat = LatLonPoint.decodeLat(NumericUtils.bytesToInt(maxPackedValue, 0));
-                             double cellMaxLon = LatLonPoint.decodeLon(NumericUtils.bytesToInt(maxPackedValue, Integer.BYTES));
-
-                             if (cellMinLat <= minLat && cellMaxLat >= maxLat && cellMinLon <= minLon && cellMaxLon >= maxLon) {
-                               // Cell fully encloses the query
-                               return Relation.CELL_CROSSES_QUERY;
-                             } else  if (GeoRelationUtils.rectWithinPolyPrecise(cellMinLon, cellMinLat, cellMaxLon, cellMaxLat,
-                                                                 polyLons, polyLats,
-                                                                 minLon, minLat, maxLon, maxLat)) {
-                               return Relation.CELL_INSIDE_QUERY;
-                             } else if (GeoRelationUtils.rectCrossesPolyPrecise(cellMinLon, cellMinLat, cellMaxLon, cellMaxLat,
-                                                                 polyLons, polyLats,
-                                                                 minLon, minLat, maxLon, maxLat)) {
-                               return Relation.CELL_CROSSES_QUERY;
-                             } else {
-                               return Relation.CELL_OUTSIDE_QUERY;
-                             }
-                           }
-                         });
-
-        return new ConstantScoreScorer(this, score(), result.build().iterator());
-      }
-    };
-  }
-
-  @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;
-
-    PointInPolygonQuery that = (PointInPolygonQuery) o;
-
-    if (Arrays.equals(polyLons, that.polyLons) == false) {
-      return false;
-    }
-    if (Arrays.equals(polyLats, that.polyLats) == false) {
-      return false;
-    }
-
-    return true;
-  }
-
-  @Override
-  public final int hashCode() {
-    int result = super.hashCode();
-    result = 31 * result + Arrays.hashCode(polyLons);
-    result = 31 * result + Arrays.hashCode(polyLats);
-    return result;
-  }
-
-  @Override
-  public String toString(String field) {
-    final StringBuilder sb = new StringBuilder();
-    sb.append(getClass().getSimpleName());
-    sb.append(':');
-    if (this.field.equals(field) == false) {
-      sb.append(" field=");
-      sb.append(this.field);
-      sb.append(':');
-    }
-    sb.append(" Points: ");
-    for (int i=0; i<polyLons.length; ++i) {
-      sb.append("[")
-        .append(polyLons[i])
-        .append(", ")
-        .append(polyLats[i])
-        .append("] ");
-    }
-    return sb.toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2264600f/lucene/sandbox/src/test/org/apache/lucene/document/TestLatLonPoint.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/test/org/apache/lucene/document/TestLatLonPoint.java b/lucene/sandbox/src/test/org/apache/lucene/document/TestLatLonPoint.java
index 34f4304..b67dec8 100644
--- a/lucene/sandbox/src/test/org/apache/lucene/document/TestLatLonPoint.java
+++ b/lucene/sandbox/src/test/org/apache/lucene/document/TestLatLonPoint.java
@@ -16,40 +16,22 @@
  */
 package org.apache.lucene.document;
 
-import java.io.IOException;
-import java.util.BitSet;
-
-import org.apache.lucene.codecs.FilterCodec;
-import org.apache.lucene.codecs.PointFormat;
-import org.apache.lucene.codecs.PointReader;
-import org.apache.lucene.codecs.PointWriter;
-import org.apache.lucene.codecs.lucene60.Lucene60PointReader;
-import org.apache.lucene.codecs.lucene60.Lucene60PointWriter;
 import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.IndexWriterConfig;
 import org.apache.lucene.index.RandomIndexWriter;
-import org.apache.lucene.index.SegmentReadState;
-import org.apache.lucene.index.SegmentWriteState;
 import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.ScoreDoc;
-import org.apache.lucene.search.Sort;
-import org.apache.lucene.search.TopDocs;
-import org.apache.lucene.spatial.util.GeoDistanceUtils;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.LuceneTestCase;
-import org.apache.lucene.util.TestUtil;
-import org.apache.lucene.util.bkd.BKDWriter;
 
 /** Simple tests for {@link LatLonPoint} */
 public class TestLatLonPoint extends LuceneTestCase {
 
-  /** Add a single address and search for it in a box */
+  /** Add a single point and search for it in a box */
   // NOTE: we don't currently supply an exact search, only ranges, because of the lossiness...
-  public void testBasics() throws Exception {
+  public void testBoxQuery() throws Exception {
     Directory dir = newDirectory();
     RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
 
-    // add a doc with an address
+    // add a doc with a point
     Document document = new Document();
     document.add(new LatLonPoint("field", 18.313694, -65.227444));
     writer.addDocument(document);
@@ -70,93 +52,122 @@ public class TestLatLonPoint extends LuceneTestCase {
     
     // looks crazy due to lossiness
     assertEquals("field:[17.99999997485429 TO 18.999999999068677},[-65.9999999217689 TO -64.99999998137355}", LatLonPoint.newBoxQuery("field", 18, 19, -66, -65).toString());
+    
+    // distance query does not quantize inputs
+    assertEquals("field:18.0,19.0 +/- 25.0 meters", LatLonPoint.newDistanceQuery("field", 18, 19, 25).toString());
   }
   
-  public void testRadiusRandom() throws Exception {
-    for (int iters = 0; iters < 100; iters++) {
-      doRandomTest(10, 100);
-    }
+  /** Valid values that should not cause exception */
+  public void testExtremeValues() {
+    new LatLonPoint("foo", 90.0, 180.0);
+    new LatLonPoint("foo", 90.0, -180.0);
+    new LatLonPoint("foo", -90.0, 180.0);
+    new LatLonPoint("foo", -90.0, -180.0);
   }
   
-  @Nightly
-  public void testRadiusRandomHuge() throws Exception {
-    for (int iters = 0; iters < 10; iters++) {
-      doRandomTest(2000, 100);
-    }
+  /** Invalid values */
+  public void testOutOfRangeValues() {
+    IllegalArgumentException expected;
+
+    expected = expectThrows(IllegalArgumentException.class, () -> {
+      new LatLonPoint("foo", Math.nextUp(90.0), 50.0);
+    });
+    assertTrue(expected.getMessage().contains("invalid latitude"));
+    
+    expected = expectThrows(IllegalArgumentException.class, () -> {
+      new LatLonPoint("foo", Math.nextDown(-90.0), 50.0);
+    });
+    assertTrue(expected.getMessage().contains("invalid latitude"));
+    
+    expected = expectThrows(IllegalArgumentException.class, () -> {
+      new LatLonPoint("foo", 90.0, Math.nextUp(180.0));
+    });
+    assertTrue(expected.getMessage().contains("invalid longitude"));
+    
+    expected = expectThrows(IllegalArgumentException.class, () -> {
+      new LatLonPoint("foo", 90.0, Math.nextDown(-180.0));
+    });
+    assertTrue(expected.getMessage().contains("invalid longitude"));
   }
   
-  private void doRandomTest(int numDocs, int numQueries) throws IOException {
-    Directory dir = newDirectory();
-    IndexWriterConfig iwc = newIndexWriterConfig();
-    int pointsInLeaf = 2 + random().nextInt(4);
-    iwc.setCodec(new FilterCodec("Lucene60", TestUtil.getDefaultCodec()) {
-      @Override
-      public PointFormat pointFormat() {
-        return new PointFormat() {
-          @Override
-          public PointWriter fieldsWriter(SegmentWriteState writeState) throws IOException {
-            return new Lucene60PointWriter(writeState, pointsInLeaf, BKDWriter.DEFAULT_MAX_MB_SORT_IN_HEAP);
-          }
+  /** NaN: illegal */
+  public void testNaNValues() {
+    IllegalArgumentException expected;
 
-          @Override
-          public PointReader fieldsReader(SegmentReadState readState) throws IOException {
-            return new Lucene60PointReader(readState);
-          }
-        };
-      }
+    expected = expectThrows(IllegalArgumentException.class, () -> {
+      new LatLonPoint("foo", Double.NaN, 50.0);
+    });
+    assertTrue(expected.getMessage().contains("invalid latitude"));
+    
+    expected = expectThrows(IllegalArgumentException.class, () -> {
+      new LatLonPoint("foo", 50.0, Double.NaN);
     });
-    RandomIndexWriter writer = new RandomIndexWriter(random(), dir, iwc);
+    assertTrue(expected.getMessage().contains("invalid longitude"));
+  }
+  
+  /** Inf: illegal */
+  public void testInfValues() {
+    IllegalArgumentException expected;
 
-    for (int i = 0; i < numDocs; i++) {
-      double latRaw = -90 + 180.0 * random().nextDouble();
-      double lonRaw = -180 + 360.0 * random().nextDouble();
-      // pre-normalize up front, so we can just use quantized value for testing and do simple exact comparisons
-      double lat = LatLonPoint.decodeLat(LatLonPoint.encodeLat(latRaw));
-      double lon = LatLonPoint.decodeLon(LatLonPoint.encodeLon(lonRaw));
-      Document doc = new Document();
-      doc.add(new LatLonPoint("field", lat, lon));
-      doc.add(new StoredField("lat", lat));
-      doc.add(new StoredField("lon", lon));
-      writer.addDocument(doc);
-    }
-    IndexReader reader = writer.getReader();
-    IndexSearcher searcher = new IndexSearcher(reader);
+    expected = expectThrows(IllegalArgumentException.class, () -> {
+      new LatLonPoint("foo", Double.POSITIVE_INFINITY, 50.0);
+    });
+    assertTrue(expected.getMessage().contains("invalid latitude"));
+    
+    expected = expectThrows(IllegalArgumentException.class, () -> {
+      new LatLonPoint("foo", Double.NEGATIVE_INFINITY, 50.0);
+    });
+    assertTrue(expected.getMessage().contains("invalid latitude"));
+    
+    expected = expectThrows(IllegalArgumentException.class, () -> {
+      new LatLonPoint("foo", 50.0, Double.POSITIVE_INFINITY);
+    });
+    assertTrue(expected.getMessage().contains("invalid longitude"));
+    
+    expected = expectThrows(IllegalArgumentException.class, () -> {
+      new LatLonPoint("foo", 50.0, Double.NEGATIVE_INFINITY);
+    });
+    assertTrue(expected.getMessage().contains("invalid longitude"));
+  }
+   
+  public void testEncodeDecode() throws Exception {
+    // just for testing quantization error
+    final double ENCODING_TOLERANCE = 1e-7;
 
-    for (int i = 0; i < numQueries; i++) {
+    int iters = atLeast(10000);
+    for(int iter=0;iter<iters;iter++) {
       double lat = -90 + 180.0 * random().nextDouble();
+      double latEnc = LatLonPoint.decodeLatitude(LatLonPoint.encodeLatitude(lat));
+      assertEquals("lat=" + lat + " latEnc=" + latEnc + " diff=" + (lat - latEnc), lat, latEnc, ENCODING_TOLERANCE);
+
       double lon = -180 + 360.0 * random().nextDouble();
-      double radius = 50000000 * random().nextDouble();
+      double lonEnc = LatLonPoint.decodeLongitude(LatLonPoint.encodeLongitude(lon));
+      assertEquals("lon=" + lon + " lonEnc=" + lonEnc + " diff=" + (lon - lonEnc), lon, lonEnc, ENCODING_TOLERANCE);
+    }
+
+    // check edge/interesting cases explicitly
+    assertEquals(0.0, LatLonPoint.decodeLatitude(LatLonPoint.encodeLatitude(0.0)), ENCODING_TOLERANCE);
+    assertEquals(90.0, LatLonPoint.decodeLatitude(LatLonPoint.encodeLatitude(90.0)), ENCODING_TOLERANCE);
+    assertEquals(-90.0, LatLonPoint.decodeLatitude(LatLonPoint.encodeLatitude(-90.0)), ENCODING_TOLERANCE);
 
-      BitSet expected = new BitSet();
-      for (int doc = 0; doc < reader.maxDoc(); doc++) {
-        double docLatitude = reader.document(doc).getField("lat").numericValue().doubleValue();
-        double docLongitude = reader.document(doc).getField("lon").numericValue().doubleValue();
-        double distance = GeoDistanceUtils.haversin(lat, lon, docLatitude, docLongitude);
-        if (distance <= radius) {
-          expected.set(doc);
-        }
-      }
+    assertEquals(0.0, LatLonPoint.decodeLongitude(LatLonPoint.encodeLongitude(0.0)), ENCODING_TOLERANCE);
+    assertEquals(180.0, LatLonPoint.decodeLongitude(LatLonPoint.encodeLongitude(180.0)), ENCODING_TOLERANCE);
+    assertEquals(-180.0, LatLonPoint.decodeLongitude(LatLonPoint.encodeLongitude(-180.0)), ENCODING_TOLERANCE);
+  }
 
-      TopDocs topDocs = searcher.search(LatLonPoint.newDistanceQuery("field", lat, lon, radius), reader.maxDoc(), Sort.INDEXORDER);
-      BitSet actual = new BitSet();
-      for (ScoreDoc doc : topDocs.scoreDocs) {
-        actual.set(doc.doc);
-      }
+  public void testEncodeDecodeIsStable() throws Exception {
+    int iters = atLeast(1000);
+    for(int iter=0;iter<iters;iter++) {
+      double lat = -90 + 180.0 * random().nextDouble();
+      double lon = -180 + 360.0 * random().nextDouble();
 
-      try {
-        assertEquals(expected, actual);
-      } catch (AssertionError e) {
-        for (int doc = 0; doc < reader.maxDoc(); doc++) {
-          double docLatitude = reader.document(doc).getField("lat").numericValue().doubleValue();
-          double docLongitude = reader.document(doc).getField("lon").numericValue().doubleValue();
-          double distance = GeoDistanceUtils.haversin(lat, lon, docLatitude, docLongitude);
-          System.out.println("" + doc + ": (" + docLatitude + "," + docLongitude + "), distance=" + distance);
-        }
-        throw e;
-      }
+      double latEnc = LatLonPoint.decodeLatitude(LatLonPoint.encodeLatitude(lat));
+      double lonEnc = LatLonPoint.decodeLongitude(LatLonPoint.encodeLongitude(lon));
+
+      double latEnc2 = LatLonPoint.decodeLatitude(LatLonPoint.encodeLatitude(latEnc));
+      double lonEnc2 = LatLonPoint.decodeLongitude(LatLonPoint.encodeLongitude(lonEnc));
+      assertEquals(latEnc, latEnc2, 0.0);
+      assertEquals(lonEnc, lonEnc2, 0.0);
     }
-    reader.close();
-    writer.close();
-    dir.close();
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2264600f/lucene/sandbox/src/test/org/apache/lucene/document/TestLatLonPointDistanceQuery.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/test/org/apache/lucene/document/TestLatLonPointDistanceQuery.java b/lucene/sandbox/src/test/org/apache/lucene/document/TestLatLonPointDistanceQuery.java
new file mode 100644
index 0000000..3d47b44
--- /dev/null
+++ b/lucene/sandbox/src/test/org/apache/lucene/document/TestLatLonPointDistanceQuery.java
@@ -0,0 +1,190 @@
+/*
+ * 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 java.util.BitSet;
+
+import org.apache.lucene.codecs.FilterCodec;
+import org.apache.lucene.codecs.PointFormat;
+import org.apache.lucene.codecs.PointReader;
+import org.apache.lucene.codecs.PointWriter;
+import org.apache.lucene.codecs.lucene60.Lucene60PointReader;
+import org.apache.lucene.codecs.lucene60.Lucene60PointWriter;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.RandomIndexWriter;
+import org.apache.lucene.index.SegmentReadState;
+import org.apache.lucene.index.SegmentWriteState;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.Sort;
+import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.spatial.util.GeoDistanceUtils;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.util.TestUtil;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.bkd.BKDWriter;
+
+/** Simple tests for {@link LatLonPoint#newDistanceQuery} */
+public class TestLatLonPointDistanceQuery extends LuceneTestCase {
+
+  /** test we can search for a point */
+  public void testBasics() throws Exception {
+    Directory dir = newDirectory();
+    RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
+
+    // add a doc with a location
+    Document document = new Document();
+    document.add(new LatLonPoint("field", 18.313694, -65.227444));
+    writer.addDocument(document);
+    
+    // search within 50km and verify we found our doc
+    IndexReader reader = writer.getReader();
+    IndexSearcher searcher = newSearcher(reader);
+    assertEquals(1, searcher.count(LatLonPoint.newDistanceQuery("field", 18, -65, 50_000)));
+
+    reader.close();
+    writer.close();
+    dir.close();
+  }
+  
+  /** negative distance queries are not allowed */
+  public void testNegativeRadius() {
+    IllegalArgumentException expected = expectThrows(IllegalArgumentException.class, () -> {
+      LatLonPoint.newDistanceQuery("field", 18, 19, -1);
+    });
+    assertTrue(expected.getMessage().contains("radiusMeters"));
+    assertTrue(expected.getMessage().contains("is invalid"));
+  }
+  
+  /** NaN distance queries are not allowed */
+  public void testNaNRadius() {
+    IllegalArgumentException expected = expectThrows(IllegalArgumentException.class, () -> {
+      LatLonPoint.newDistanceQuery("field", 18, 19, Double.NaN);
+    });
+    assertTrue(expected.getMessage().contains("radiusMeters"));
+    assertTrue(expected.getMessage().contains("is invalid"));
+  }
+  
+  /** Inf distance queries are not allowed */
+  public void testInfRadius() {
+    IllegalArgumentException expected;
+    
+    expected = expectThrows(IllegalArgumentException.class, () -> {
+      LatLonPoint.newDistanceQuery("field", 18, 19, Double.POSITIVE_INFINITY);
+    });
+    assertTrue(expected.getMessage().contains("radiusMeters"));
+    assertTrue(expected.getMessage().contains("is invalid"));
+    
+    expected = expectThrows(IllegalArgumentException.class, () -> {
+      LatLonPoint.newDistanceQuery("field", 18, 19, Double.NEGATIVE_INFINITY);
+    });
+    assertTrue(expected.getMessage().contains("radiusMeters"));
+    assertTrue(expected.getMessage().contains("is invalid"));
+  }
+  
+  /** Run a few iterations with just 10 docs, hopefully easy to debug */
+  public void testRandom() throws Exception {
+    for (int iters = 0; iters < 100; iters++) {
+      doRandomTest(10, 100);
+    }
+  }
+  
+  /** Runs with thousands of docs */
+  @Nightly
+  public void testRandomHuge() throws Exception {
+    for (int iters = 0; iters < 10; iters++) {
+      doRandomTest(2000, 100);
+    }
+  }
+  
+  private void doRandomTest(int numDocs, int numQueries) throws IOException {
+    Directory dir = newDirectory();
+    IndexWriterConfig iwc = newIndexWriterConfig();
+    int pointsInLeaf = 2 + random().nextInt(4);
+    iwc.setCodec(new FilterCodec("Lucene60", TestUtil.getDefaultCodec()) {
+      @Override
+      public PointFormat pointFormat() {
+        return new PointFormat() {
+          @Override
+          public PointWriter fieldsWriter(SegmentWriteState writeState) throws IOException {
+            return new Lucene60PointWriter(writeState, pointsInLeaf, BKDWriter.DEFAULT_MAX_MB_SORT_IN_HEAP);
+          }
+
+          @Override
+          public PointReader fieldsReader(SegmentReadState readState) throws IOException {
+            return new Lucene60PointReader(readState);
+          }
+        };
+      }
+    });
+    RandomIndexWriter writer = new RandomIndexWriter(random(), dir, iwc);
+
+    for (int i = 0; i < numDocs; i++) {
+      double latRaw = -90 + 180.0 * random().nextDouble();
+      double lonRaw = -180 + 360.0 * random().nextDouble();
+      // pre-normalize up front, so we can just use quantized value for testing and do simple exact comparisons
+      double lat = LatLonPoint.decodeLatitude(LatLonPoint.encodeLatitude(latRaw));
+      double lon = LatLonPoint.decodeLongitude(LatLonPoint.encodeLongitude(lonRaw));
+      Document doc = new Document();
+      doc.add(new LatLonPoint("field", lat, lon));
+      doc.add(new StoredField("lat", lat));
+      doc.add(new StoredField("lon", lon));
+      writer.addDocument(doc);
+    }
+    IndexReader reader = writer.getReader();
+    IndexSearcher searcher = new IndexSearcher(reader);
+
+    for (int i = 0; i < numQueries; i++) {
+      double lat = -90 + 180.0 * random().nextDouble();
+      double lon = -180 + 360.0 * random().nextDouble();
+      double radius = 50000000 * random().nextDouble();
+
+      BitSet expected = new BitSet();
+      for (int doc = 0; doc < reader.maxDoc(); doc++) {
+        double docLatitude = reader.document(doc).getField("lat").numericValue().doubleValue();
+        double docLongitude = reader.document(doc).getField("lon").numericValue().doubleValue();
+        double distance = GeoDistanceUtils.haversin(lat, lon, docLatitude, docLongitude);
+        if (distance <= radius) {
+          expected.set(doc);
+        }
+      }
+
+      TopDocs topDocs = searcher.search(LatLonPoint.newDistanceQuery("field", lat, lon, radius), reader.maxDoc(), Sort.INDEXORDER);
+      BitSet actual = new BitSet();
+      for (ScoreDoc doc : topDocs.scoreDocs) {
+        actual.set(doc.doc);
+      }
+
+      try {
+        assertEquals(expected, actual);
+      } catch (AssertionError e) {
+        for (int doc = 0; doc < reader.maxDoc(); doc++) {
+          double docLatitude = reader.document(doc).getField("lat").numericValue().doubleValue();
+          double docLongitude = reader.document(doc).getField("lon").numericValue().doubleValue();
+          double distance = GeoDistanceUtils.haversin(lat, lon, docLatitude, docLongitude);
+          System.out.println("" + doc + ": (" + docLatitude + "," + docLongitude + "), distance=" + distance);
+        }
+        throw e;
+      }
+    }
+    reader.close();
+    writer.close();
+    dir.close();
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2264600f/lucene/sandbox/src/test/org/apache/lucene/search/TestLatLonPointQueries.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/test/org/apache/lucene/search/TestLatLonPointQueries.java b/lucene/sandbox/src/test/org/apache/lucene/search/TestLatLonPointQueries.java
index 7798b97..8eb1be0 100644
--- a/lucene/sandbox/src/test/org/apache/lucene/search/TestLatLonPointQueries.java
+++ b/lucene/sandbox/src/test/org/apache/lucene/search/TestLatLonPointQueries.java
@@ -23,9 +23,8 @@ import org.apache.lucene.spatial.util.GeoDistanceUtils;
 import org.apache.lucene.spatial.util.GeoRect;
 
 public class TestLatLonPointQueries extends BaseGeoPointTestCase {
-  // todo deconflict GeoPoint and BKD encoding methods and error tolerance
+  // TODO: remove this!
   public static final double BKD_TOLERANCE = 1e-7;
-  public static final double ENCODING_TOLERANCE = 1e-7;
 
   @Override
   protected void addPointToDoc(String field, Document doc, double lat, double lon) {
@@ -57,13 +56,13 @@ public class TestLatLonPointQueries extends BaseGeoPointTestCase {
 
     assert Double.isNaN(pointLat) == false;
 
-    int rectLatMinEnc = LatLonPoint.encodeLat(rect.minLat);
-    int rectLatMaxEnc = LatLonPoint.encodeLat(rect.maxLat);
-    int rectLonMinEnc = LatLonPoint.encodeLon(rect.minLon);
-    int rectLonMaxEnc = LatLonPoint.encodeLon(rect.maxLon);
+    int rectLatMinEnc = LatLonPoint.encodeLatitude(rect.minLat);
+    int rectLatMaxEnc = LatLonPoint.encodeLatitude(rect.maxLat);
+    int rectLonMinEnc = LatLonPoint.encodeLongitude(rect.minLon);
+    int rectLonMaxEnc = LatLonPoint.encodeLongitude(rect.maxLon);
 
-    int pointLatEnc = LatLonPoint.encodeLat(pointLat);
-    int pointLonEnc = LatLonPoint.encodeLon(pointLon);
+    int pointLatEnc = LatLonPoint.encodeLatitude(pointLat);
+    int pointLonEnc = LatLonPoint.encodeLongitude(pointLon);
 
     if (rect.minLon < rect.maxLon) {
       return pointLatEnc >= rectLatMinEnc &&
@@ -81,12 +80,12 @@ public class TestLatLonPointQueries extends BaseGeoPointTestCase {
 
   @Override
   protected double quantizeLat(double latRaw) {
-    return LatLonPoint.decodeLat(LatLonPoint.encodeLat(latRaw));
+    return LatLonPoint.decodeLatitude(LatLonPoint.encodeLatitude(latRaw));
   }
 
   @Override
   protected double quantizeLon(double lonRaw) {
-    return LatLonPoint.decodeLon(LatLonPoint.encodeLon(lonRaw));
+    return LatLonPoint.decodeLongitude(LatLonPoint.encodeLongitude(lonRaw));
   }
 
   // todo reconcile with GeoUtils (see LUCENE-6996)
@@ -112,13 +111,13 @@ public class TestLatLonPointQueries extends BaseGeoPointTestCase {
       return null;
     }
 
-    int rectLatMinEnc = LatLonPoint.encodeLat(rect.minLat);
-    int rectLatMaxEnc = LatLonPoint.encodeLat(rect.maxLat);
-    int rectLonMinEnc = LatLonPoint.encodeLon(rect.minLon);
-    int rectLonMaxEnc = LatLonPoint.encodeLon(rect.maxLon);
+    int rectLatMinEnc = LatLonPoint.encodeLatitude(rect.minLat);
+    int rectLatMaxEnc = LatLonPoint.encodeLatitude(rect.maxLat);
+    int rectLonMinEnc = LatLonPoint.encodeLongitude(rect.minLon);
+    int rectLonMaxEnc = LatLonPoint.encodeLongitude(rect.maxLon);
 
-    int pointLatEnc = LatLonPoint.encodeLat(pointLat);
-    int pointLonEnc = LatLonPoint.encodeLon(pointLon);
+    int pointLatEnc = LatLonPoint.encodeLatitude(pointLat);
+    int pointLonEnc = LatLonPoint.encodeLongitude(pointLon);
 
     if (rect.minLon < rect.maxLon) {
       return pointLatEnc >= rectLatMinEnc &&
@@ -147,35 +146,4 @@ public class TestLatLonPointQueries extends BaseGeoPointTestCase {
     final double d = GeoDistanceUtils.haversin(centerLat, centerLon, pointLat, pointLon);
     return d >= minRadiusMeters && d <= radiusMeters;
   }
-
-  public void testEncodeDecode() throws Exception {
-    int iters = atLeast(10000);
-    boolean small = random().nextBoolean();
-    for(int iter=0;iter<iters;iter++) {
-      double lat = randomLat(small);
-      double latEnc = LatLonPoint.decodeLat(LatLonPoint.encodeLat(lat));
-      assertEquals("lat=" + lat + " latEnc=" + latEnc + " diff=" + (lat - latEnc), lat, latEnc, ENCODING_TOLERANCE);
-
-      double lon = randomLon(small);
-      double lonEnc = LatLonPoint.decodeLon(LatLonPoint.encodeLon(lon));
-      assertEquals("lon=" + lon + " lonEnc=" + lonEnc + " diff=" + (lon - lonEnc), lon, lonEnc, ENCODING_TOLERANCE);
-    }
-  }
-
-  public void testScaleUnscaleIsStable() throws Exception {
-    int iters = atLeast(1000);
-    boolean small = random().nextBoolean();
-    for(int iter=0;iter<iters;iter++) {
-      double lat = randomLat(small);
-      double lon = randomLon(small);
-
-      double latEnc = LatLonPoint.decodeLat(LatLonPoint.encodeLat(lat));
-      double lonEnc = LatLonPoint.decodeLon(LatLonPoint.encodeLon(lon));
-
-      double latEnc2 = LatLonPoint.decodeLat(LatLonPoint.encodeLat(latEnc));
-      double lonEnc2 = LatLonPoint.decodeLon(LatLonPoint.encodeLon(lonEnc));
-      assertEquals(latEnc, latEnc2, 0.0);
-      assertEquals(lonEnc, lonEnc2, 0.0);
-    }
-  }
 }


[42/50] [abbrv] lucene-solr git commit: Merge remote-tracking branch 'origin/master'

Posted by ho...@apache.org.
Merge remote-tracking branch 'origin/master'


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/79b62ee7
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/79b62ee7
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/79b62ee7

Branch: refs/heads/jira/SOLR-445
Commit: 79b62ee731d81f2eb9abf084c86a5c2f1435af41
Parents: 1734d03 502b880
Author: Noble Paul <no...@apache.org>
Authored: Tue Mar 1 09:30:22 2016 +0530
Committer: Noble Paul <no...@apache.org>
Committed: Tue Mar 1 09:30:22 2016 +0530

----------------------------------------------------------------------
 dev-tools/idea/.idea/ant.xml                    |     1 +
 dev-tools/idea/.idea/modules.xml                |     1 +
 dev-tools/idea/.idea/workspace.xml              |    41 +-
 .../idea/lucene/benchmark/src/benchmark.iml     |     2 +-
 .../lucene/spatial-extras/spatial-extras.iml    |    32 +
 dev-tools/idea/lucene/spatial/spatial.iml       |    15 -
 dev-tools/idea/solr/core/src/java/solr-core.iml |     2 +-
 .../idea/solr/core/src/solr-core-tests.iml      |     2 +-
 dev-tools/maven/lucene/pom.xml.template         |     1 +
 .../lucene/spatial-extras/pom.xml.template      |    62 +
 dev-tools/maven/lucene/spatial/pom.xml.template |     2 +-
 dev-tools/scripts/smokeTestRelease.py           |     2 +-
 lucene/CHANGES.txt                              |    16 +-
 .../miscellaneous/StemmerOverrideFilter.java    |     2 +-
 lucene/benchmark/build.xml                      |     8 +-
 lucene/build.xml                                |     3 +-
 .../codecs/blockterms/BlockTermsReader.java     |     4 +-
 .../lucene/index/SortedDocValuesWriter.java     |     2 +-
 .../lucene/index/SortedSetDocValuesWriter.java  |     2 +-
 .../apache/lucene/index/TermsHashPerField.java  |     2 +-
 .../apache/lucene/search/FuzzyTermsEnum.java    |     5 +-
 .../lucene/search/LegacyNumericRangeQuery.java  |    12 +-
 .../apache/lucene/search/PointInSetQuery.java   |    92 +-
 .../apache/lucene/search/PointRangeQuery.java   |    20 +-
 .../apache/lucene/search/ScoringRewrite.java    |     2 +-
 .../org/apache/lucene/search/SortField.java     |     2 +-
 .../search/UsageTrackingQueryCachingPolicy.java |    16 +-
 .../org/apache/lucene/store/MMapDirectory.java  |    10 +-
 .../java/org/apache/lucene/util/ArrayUtil.java  |    20 +-
 .../java/org/apache/lucene/util/BytesRef.java   |   122 +-
 .../org/apache/lucene/util/BytesRefHash.java    |    10 +-
 .../org/apache/lucene/util/CollectionUtil.java  |     4 +-
 .../org/apache/lucene/util/DocIdSetBuilder.java |    14 +-
 .../apache/lucene/util/LegacyNumericUtils.java  |     4 -
 .../org/apache/lucene/util/OfflineSorter.java   |     2 +-
 .../apache/lucene/index/TestMultiFields.java    |     4 +-
 .../apache/lucene/search/TestPointQueries.java  |     7 +-
 .../apache/lucene/util/TestBytesRefArray.java   |     5 +-
 .../apache/lucene/util/TestBytesRefHash.java    |    12 +-
 .../lucene/util/TestInPlaceMergeSorter.java     |     4 +-
 .../org/apache/lucene/util/TestIntroSorter.java |     4 +-
 .../org/apache/lucene/util/TestTimSorter.java   |     3 +-
 .../org/apache/lucene/util/TestUnicodeUtil.java |    15 +-
 .../search/join/TermsIncludingScoreQuery.java   |     2 +-
 .../apache/lucene/search/join/TermsQuery.java   |    11 +-
 .../apache/lucene/search/join/TestJoinUtil.java |     2 +-
 .../apache/lucene/index/memory/MemoryIndex.java |    13 +-
 lucene/module-build.xml                         |    22 +
 .../apache/lucene/queries/TermsQueryTest.java   |    25 +
 .../org/apache/lucene/document/LatLonPoint.java |     9 +
 .../lucene/search/DocValuesTermsQuery.java      |     2 +-
 .../lucene/search/PointDistanceQuery.java       |   179 +
 .../lucene/search/PointInPolygonQuery.java      |     6 +-
 .../apache/lucene/document/TestLatLonPoint.java |   106 +
 .../lucene/search/TestLatLonPointQueries.java   |    62 +-
 lucene/spatial-extras/build.xml                 |    57 +
 lucene/spatial-extras/ivy.xml                   |    36 +
 .../apache/lucene/spatial/SpatialStrategy.java  |   149 +
 .../bbox/BBoxOverlapRatioValueSource.java       |   251 +
 .../spatial/bbox/BBoxSimilarityValueSource.java |   117 +
 .../lucene/spatial/bbox/BBoxStrategy.java       |   588 +
 .../lucene/spatial/bbox/BBoxValueSource.java    |   115 +
 .../lucene/spatial/bbox/package-info.java       |    23 +
 .../composite/CompositeSpatialStrategy.java     |   144 +
 .../spatial/composite/CompositeVerifyQuery.java |   120 +
 .../composite/IntersectsRPTVerifyQuery.java     |   235 +
 .../lucene/spatial/composite/package-info.java  |    19 +
 .../java/org/apache/lucene/spatial/package.html |    26 +
 .../spatial/prefix/AbstractPrefixTreeQuery.java |   133 +
 .../prefix/AbstractVisitingPrefixTreeQuery.java |   380 +
 .../prefix/BytesRefIteratorTokenStream.java     |    72 +
 .../spatial/prefix/CellToBytesRefIterator.java  |    49 +
 .../spatial/prefix/ContainsPrefixTreeQuery.java |   362 +
 .../spatial/prefix/HeatmapFacetCounter.java     |   310 +
 .../prefix/IntersectsPrefixTreeQuery.java       |    95 +
 .../prefix/NumberRangePrefixTreeStrategy.java   |   199 +
 .../PointPrefixTreeFieldCacheProvider.java      |    48 +
 .../spatial/prefix/PrefixTreeFacetCounter.java  |   201 +
 .../spatial/prefix/PrefixTreeStrategy.java      |   208 +
 .../prefix/RecursivePrefixTreeStrategy.java     |   192 +
 .../prefix/TermQueryPrefixTreeStrategy.java     |   111 +
 .../spatial/prefix/WithinPrefixTreeQuery.java   |   232 +
 .../lucene/spatial/prefix/package-info.java     |    21 +
 .../apache/lucene/spatial/prefix/tree/Cell.java |   109 +
 .../spatial/prefix/tree/CellIterator.java       |    76 +
 .../prefix/tree/DateRangePrefixTree.java        |   444 +
 .../spatial/prefix/tree/FilterCellIterator.java |    61 +
 .../spatial/prefix/tree/GeohashPrefixTree.java  |   162 +
 .../lucene/spatial/prefix/tree/LegacyCell.java  |   242 +
 .../spatial/prefix/tree/LegacyPrefixTree.java   |    84 +
 .../prefix/tree/NumberRangePrefixTree.java      |   989 +
 .../prefix/tree/PackedQuadPrefixTree.java       |   459 +
 .../spatial/prefix/tree/QuadPrefixTree.java     |   308 +
 .../prefix/tree/SingletonCellIterator.java      |    36 +
 .../spatial/prefix/tree/SpatialPrefixTree.java  |   117 +
 .../prefix/tree/SpatialPrefixTreeFactory.java   |    99 +
 .../spatial/prefix/tree/TreeCellIterator.java   |    87 +
 .../spatial/prefix/tree/package-info.java       |    30 +
 .../lucene/spatial/query/SpatialArgs.java       |   148 +
 .../lucene/spatial/query/SpatialArgsParser.java |   146 +
 .../lucene/spatial/query/SpatialOperation.java  |   179 +
 .../query/UnsupportedSpatialOperation.java      |    28 +
 .../lucene/spatial/query/package-info.java      |    21 +
 .../serialized/SerializedDVStrategy.java        |   278 +
 .../lucene/spatial/serialized/package-info.java |    21 +
 .../lucene/spatial/spatial4j/Geo3dShape.java    |   185 +
 .../lucene/spatial/spatial4j/package-info.java  |    19 +
 .../spatial/util/CachingDoubleValueSource.java  |    93 +
 .../util/DistanceToShapeValueSource.java        |   122 +
 .../spatial/util/ShapeAreaValueSource.java      |   116 +
 .../lucene/spatial/util/ShapeFieldCache.java    |    54 +
 .../ShapeFieldCacheDistanceValueSource.java     |   112 +
 .../spatial/util/ShapeFieldCacheProvider.java   |    87 +
 .../spatial/util/ShapePredicateValueSource.java |   113 +
 .../org/apache/lucene/spatial/util/package.html |    26 +
 .../spatial/vector/DistanceValueSource.java     |   120 +
 .../spatial/vector/PointVectorStrategy.java     |   178 +
 .../lucene/spatial/vector/package-info.java     |    21 +
 lucene/spatial-extras/src/java/overview.html    |    67 +
 .../src/test-files/cities-Intersects-BBox.txt   |     3 +
 .../src/test-files/data/LUCENE-4464.txt         |     3 +
 .../src/test-files/data/countries-bbox.txt      |   249 +
 .../src/test-files/data/countries-poly.txt      |   249 +
 .../src/test-files/data/geonames-IE.txt         | 22929 +++++++++++++++++
 .../src/test-files/data/simple-bbox.txt         |     4 +
 .../src/test-files/data/states-bbox.txt         |    52 +
 .../src/test-files/data/states-poly.txt         |    52 +
 .../src/test-files/data/world-cities-points.txt |  2680 ++
 .../src/test-files/simple-Queries-BBox.txt      |     9 +
 .../src/test-files/states-Intersects-BBox.txt   |     3 +
 .../src/test-files/states-IsWithin-BBox.txt     |     4 +
 .../lucene/spatial/DistanceStrategyTest.java    |   135 +
 .../apache/lucene/spatial/PortedSolr3Test.java  |   167 +
 .../lucene/spatial/QueryEqualsHashCodeTest.java |   119 +
 .../apache/lucene/spatial/SpatialArgsTest.java  |    50 +
 .../apache/lucene/spatial/SpatialExample.java   |   200 +
 .../lucene/spatial/SpatialMatchConcern.java     |    31 +
 .../apache/lucene/spatial/SpatialTestCase.java  |   280 +
 .../apache/lucene/spatial/SpatialTestData.java  |    71 +
 .../apache/lucene/spatial/SpatialTestQuery.java |    96 +
 .../apache/lucene/spatial/StrategyTestCase.java |   252 +
 .../lucene/spatial/TestTestFramework.java       |    68 +
 .../lucene/spatial/bbox/TestBBoxStrategy.java   |   301 +
 .../composite/CompositeStrategyTest.java        |   142 +
 .../prefix/CellToBytesRefIterator50.java        |    44 +
 .../spatial/prefix/DateNRStrategyTest.java      |   143 +
 .../spatial/prefix/HeatmapFacetCounterTest.java |   252 +
 .../lucene/spatial/prefix/JtsPolygonTest.java   |   117 +
 .../spatial/prefix/NumberRangeFacetsTest.java   |   275 +
 .../RandomSpatialOpFuzzyPrefixTree50Test.java   |    31 +
 .../RandomSpatialOpFuzzyPrefixTreeTest.java     |   533 +
 .../prefix/RandomSpatialOpStrategyTestCase.java |   141 +
 .../prefix/TestRecursivePrefixTreeStrategy.java |   122 +
 .../prefix/TestTermQueryPrefixGridStrategy.java |    63 +
 .../prefix/tree/DateRangePrefixTreeTest.java    |   175 +
 .../prefix/tree/SpatialPrefixTreeTest.java      |   114 +
 .../spatial/query/SpatialArgsParserTest.java    |    77 +
 .../serialized/SerializedStrategyTest.java      |    66 +
 .../lucene/spatial/spatial4j/Geo3dRptTest.java  |   227 +
 .../Geo3dShapeRectRelationTestCase.java         |   262 +
 .../Geo3dShapeSphereModelRectRelationTest.java  |    72 +
 .../Geo3dShapeWGS84ModelRectRelationTest.java   |    94 +
 .../spatial4j/RandomizedShapeTestCase.java      |   288 +
 .../spatial/spatial4j/geo3d/GeoPointTest.java   |    80 +
 .../spatial/vector/TestPointVectorStrategy.java |    63 +
 lucene/spatial/build.xml                        |    30 -
 lucene/spatial/ivy.xml                          |    15 -
 .../apache/lucene/spatial/SpatialStrategy.java  |   149 -
 .../bbox/BBoxOverlapRatioValueSource.java       |   251 -
 .../spatial/bbox/BBoxSimilarityValueSource.java |   117 -
 .../lucene/spatial/bbox/BBoxStrategy.java       |   591 -
 .../lucene/spatial/bbox/BBoxValueSource.java    |   115 -
 .../lucene/spatial/bbox/package-info.java       |    23 -
 .../composite/CompositeSpatialStrategy.java     |   144 -
 .../spatial/composite/CompositeVerifyQuery.java |   121 -
 .../composite/IntersectsRPTVerifyQuery.java     |   235 -
 .../lucene/spatial/composite/package-info.java  |    19 -
 .../geopoint/search/GeoPointDistanceQuery.java  |     5 +
 .../search/GeoPointDistanceRangeQuery.java      |     6 +
 .../geopoint/search/GeoPointInBBoxQuery.java    |    10 +
 .../geopoint/search/GeoPointInPolygonQuery.java |     6 +
 .../spatial/prefix/AbstractPrefixTreeQuery.java |   133 -
 .../prefix/AbstractVisitingPrefixTreeQuery.java |   380 -
 .../prefix/BytesRefIteratorTokenStream.java     |    72 -
 .../spatial/prefix/CellToBytesRefIterator.java  |    49 -
 .../spatial/prefix/ContainsPrefixTreeQuery.java |   362 -
 .../spatial/prefix/HeatmapFacetCounter.java     |   310 -
 .../prefix/IntersectsPrefixTreeQuery.java       |    95 -
 .../prefix/NumberRangePrefixTreeStrategy.java   |   199 -
 .../PointPrefixTreeFieldCacheProvider.java      |    48 -
 .../spatial/prefix/PrefixTreeFacetCounter.java  |   201 -
 .../spatial/prefix/PrefixTreeStrategy.java      |   208 -
 .../prefix/RecursivePrefixTreeStrategy.java     |   196 -
 .../prefix/TermQueryPrefixTreeStrategy.java     |   111 -
 .../spatial/prefix/WithinPrefixTreeQuery.java   |   233 -
 .../lucene/spatial/prefix/package-info.java     |    21 -
 .../apache/lucene/spatial/prefix/tree/Cell.java |   109 -
 .../spatial/prefix/tree/CellIterator.java       |    76 -
 .../prefix/tree/DateRangePrefixTree.java        |   444 -
 .../spatial/prefix/tree/FilterCellIterator.java |    61 -
 .../spatial/prefix/tree/GeohashPrefixTree.java  |   162 -
 .../lucene/spatial/prefix/tree/LegacyCell.java  |   242 -
 .../spatial/prefix/tree/LegacyPrefixTree.java   |    84 -
 .../prefix/tree/NumberRangePrefixTree.java      |   989 -
 .../prefix/tree/PackedQuadPrefixTree.java       |   459 -
 .../spatial/prefix/tree/QuadPrefixTree.java     |   308 -
 .../prefix/tree/SingletonCellIterator.java      |    36 -
 .../spatial/prefix/tree/SpatialPrefixTree.java  |   117 -
 .../prefix/tree/SpatialPrefixTreeFactory.java   |    99 -
 .../spatial/prefix/tree/TreeCellIterator.java   |    87 -
 .../spatial/prefix/tree/package-info.java       |    30 -
 .../lucene/spatial/query/SpatialArgs.java       |   148 -
 .../lucene/spatial/query/SpatialArgsParser.java |   146 -
 .../lucene/spatial/query/SpatialOperation.java  |   179 -
 .../query/UnsupportedSpatialOperation.java      |    28 -
 .../lucene/spatial/query/package-info.java      |    21 -
 .../serialized/SerializedDVStrategy.java        |   278 -
 .../lucene/spatial/serialized/package-info.java |    21 -
 .../lucene/spatial/spatial4j/Geo3dShape.java    |   185 -
 .../lucene/spatial/spatial4j/package-info.java  |    19 -
 .../spatial/util/CachingDoubleValueSource.java  |    93 -
 .../util/DistanceToShapeValueSource.java        |   122 -
 .../lucene/spatial/util/GeoEncodingUtils.java   |    26 +-
 .../org/apache/lucene/spatial/util/GeoRect.java |     7 +
 .../lucene/spatial/util/GeoRelationUtils.java   |     4 +
 .../spatial/util/ShapeAreaValueSource.java      |   116 -
 .../lucene/spatial/util/ShapeFieldCache.java    |    54 -
 .../ShapeFieldCacheDistanceValueSource.java     |   112 -
 .../spatial/util/ShapeFieldCacheProvider.java   |    87 -
 .../spatial/util/ShapePredicateValueSource.java |   113 -
 .../spatial/vector/DistanceValueSource.java     |   120 -
 .../spatial/vector/PointVectorStrategy.java     |   182 -
 .../lucene/spatial/vector/package-info.java     |    21 -
 lucene/spatial/src/java/overview.html           |    50 +-
 .../src/test-files/cities-Intersects-BBox.txt   |     3 -
 .../spatial/src/test-files/data/LUCENE-4464.txt |     3 -
 .../src/test-files/data/countries-bbox.txt      |   249 -
 .../src/test-files/data/countries-poly.txt      |   249 -
 .../spatial/src/test-files/data/geonames-IE.txt | 22929 -----------------
 .../spatial/src/test-files/data/simple-bbox.txt |     5 -
 .../spatial/src/test-files/data/states-bbox.txt |    52 -
 .../spatial/src/test-files/data/states-poly.txt |    52 -
 .../src/test-files/data/world-cities-points.txt |  2680 --
 .../src/test-files/simple-Queries-BBox.txt      |     9 -
 .../src/test-files/states-Intersects-BBox.txt   |     3 -
 .../src/test-files/states-IsWithin-BBox.txt     |     4 -
 .../lucene/spatial/DistanceStrategyTest.java    |   135 -
 .../apache/lucene/spatial/PortedSolr3Test.java  |   167 -
 .../lucene/spatial/QueryEqualsHashCodeTest.java |   119 -
 .../apache/lucene/spatial/SpatialArgsTest.java  |    50 -
 .../apache/lucene/spatial/SpatialExample.java   |   200 -
 .../lucene/spatial/SpatialMatchConcern.java     |    31 -
 .../apache/lucene/spatial/SpatialTestCase.java  |   281 -
 .../apache/lucene/spatial/SpatialTestData.java  |    71 -
 .../apache/lucene/spatial/SpatialTestQuery.java |    96 -
 .../apache/lucene/spatial/StrategyTestCase.java |   252 -
 .../lucene/spatial/TestTestFramework.java       |    68 -
 .../lucene/spatial/bbox/TestBBoxStrategy.java   |   301 -
 .../composite/CompositeStrategyTest.java        |   142 -
 .../prefix/CellToBytesRefIterator50.java        |    44 -
 .../spatial/prefix/DateNRStrategyTest.java      |   143 -
 .../spatial/prefix/HeatmapFacetCounterTest.java |   252 -
 .../lucene/spatial/prefix/JtsPolygonTest.java   |   117 -
 .../spatial/prefix/NumberRangeFacetsTest.java   |   275 -
 .../RandomSpatialOpFuzzyPrefixTree50Test.java   |    31 -
 .../RandomSpatialOpFuzzyPrefixTreeTest.java     |   533 -
 .../prefix/RandomSpatialOpStrategyTestCase.java |   141 -
 .../prefix/TestRecursivePrefixTreeStrategy.java |   122 -
 .../prefix/TestTermQueryPrefixGridStrategy.java |    63 -
 .../prefix/tree/DateRangePrefixTreeTest.java    |   175 -
 .../prefix/tree/SpatialPrefixTreeTest.java      |   114 -
 .../spatial/query/SpatialArgsParserTest.java    |    77 -
 .../serialized/SerializedStrategyTest.java      |    66 -
 .../lucene/spatial/spatial4j/Geo3dRptTest.java  |   227 -
 .../Geo3dShapeRectRelationTestCase.java         |   264 -
 .../Geo3dShapeSphereModelRectRelationTest.java  |    72 -
 .../Geo3dShapeWGS84ModelRectRelationTest.java   |    95 -
 .../spatial4j/RandomizedShapeTestCase.java      |   289 -
 .../spatial/spatial4j/geo3d/GeoPointTest.java   |    82 -
 .../spatial/util/BaseGeoPointTestCase.java      |    20 +-
 .../spatial/vector/TestPointVectorStrategy.java |    63 -
 .../lucene/geo3d/PointInGeo3DShapeQuery.java    |     6 +-
 .../search/suggest/SortedInputIterator.java     |     7 +-
 .../suggest/fst/FSTCompletionBuilder.java       |     5 +-
 .../lucene/search/suggest/tst/TSTLookup.java    |    51 +-
 .../search/suggest/TestInputIterator.java       |    21 +-
 .../search/suggest/fst/BytesRefSortersTest.java |     5 +-
 .../codecs/asserting/AssertingPointFormat.java  |    17 +-
 .../index/BaseDocValuesFormatTestCase.java      |     2 +-
 .../org/apache/lucene/index/RandomCodec.java    |    37 +-
 .../org/apache/lucene/util/LuceneTestCase.java  |    18 +
 .../java/org/apache/lucene/util/TestUtil.java   |    23 +-
 solr/CHANGES.txt                                |    27 +
 solr/common-build.xml                           |     8 +-
 .../solr/collection1/conf/solrconfig.xml        |     2 +-
 .../test-files/solr/minimr/conf/solrconfig.xml  |     2 +-
 .../test-files/solr/mrunit/conf/solrconfig.xml  |     2 +-
 .../collection1/conf/solrconfig.xml             |     2 +-
 .../solr/solrcloud/conf/solrconfig.xml          |     2 +-
 .../org/apache/solr/cloud/ElectionContext.java  |   114 +-
 .../java/org/apache/solr/cloud/Overseer.java    |   122 +-
 .../cloud/OverseerCollectionMessageHandler.java |    36 +-
 .../solr/cloud/OverseerNodePrioritizer.java     |     2 +-
 .../solr/cloud/OverseerTaskProcessor.java       |    14 +-
 .../solr/cloud/SizeLimitedDistributedMap.java   |     5 +-
 .../org/apache/solr/cloud/ZkController.java     |    15 +-
 .../solr/core/CachingDirectoryFactory.java      |     3 +-
 .../org/apache/solr/core/CoreDescriptor.java    |     1 +
 .../solr/handler/admin/CollectionsHandler.java  |     5 +-
 .../solr/handler/admin/CoreAdminOperation.java  |    22 +-
 .../handler/component/StatsValuesFactory.java   |    10 +-
 .../org/apache/solr/update/SolrIndexConfig.java |    12 +-
 .../processor/DistributedUpdateProcessor.java   |     2 +-
 .../org/apache/solr/cloud/DeleteShardTest.java  |     2 +-
 .../org/apache/solr/cloud/ForceLeaderTest.java  |     4 +-
 .../apache/solr/cloud/OverseerRolesTest.java    |     2 +-
 .../org/apache/solr/cloud/OverseerTest.java     |    28 +-
 .../cloud/TestRandomRequestDistribution.java    |     2 +-
 .../cloud/TestSizeLimitedDistributedMap.java    |    58 +
 .../solr/core/TestImplicitCoreProperties.java   |    61 +-
 .../handler/component/StatsComponentTest.java   |     6 +-
 .../example-DIH/solr/db/conf/solrconfig.xml     |     2 +-
 .../example-DIH/solr/mail/conf/solrconfig.xml   |     2 +-
 .../example-DIH/solr/rss/conf/solrconfig.xml    |     2 +-
 .../example-DIH/solr/solr/conf/solrconfig.xml   |     2 +-
 .../example-DIH/solr/tika/conf/solrconfig.xml   |     2 +-
 solr/example/files/conf/solrconfig.xml          |     2 +-
 .../conf/solrconfig.xml                         |     2 +-
 .../conf/solrconfig.xml                         |     4 +-
 .../cloud/AbstractFullDistribZkTestBase.java    |     2 +-
 .../apache/solr/cloud/SolrCloudTestCase.java    |   163 +
 solr/webapp/web/index.html                      |     2 +-
 332 files changed, 42843 insertions(+), 41759 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/79b62ee7/solr/example/files/conf/solrconfig.xml
----------------------------------------------------------------------


[10/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test-files/data/simple-bbox.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test-files/data/simple-bbox.txt b/lucene/spatial/src/test-files/data/simple-bbox.txt
deleted file mode 100644
index 174aa1b..0000000
--- a/lucene/spatial/src/test-files/data/simple-bbox.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-#id	name	shape	
-C5	CenterAt5	ENVELOPE(-5, 5, 5, -5)
-C10	CenterAt10	ENVELOPE(-10, 10, 10, -10)
-NW15	NorthWest	ENVELOPE(15, 20, 20, 15)
-

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test-files/data/states-bbox.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test-files/data/states-bbox.txt b/lucene/spatial/src/test-files/data/states-bbox.txt
deleted file mode 100644
index bfe041f..0000000
--- a/lucene/spatial/src/test-files/data/states-bbox.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-#id	name	shape	
-HI	Hawaii	ENVELOPE(-160.242406, -154.791096, 22.229120, 18.921786)
-WA	Washington	ENVELOPE(-124.732769, -116.919132, 48.999931, 45.543092)
-MT	Montana	ENVELOPE(-116.063531, -104.043072, 49.000026, 44.353639)
-ME	Maine	ENVELOPE(-71.087509, -66.969271, 47.453334, 43.091050)
-ND	North Dakota	ENVELOPE(-104.062991, -96.551931, 49.000026, 45.930822)
-SD	South Dakota	ENVELOPE(-104.061036, -96.439394, 45.943547, 42.488459)
-WY	Wyoming	ENVELOPE(-111.053428, -104.051705, 45.002793, 40.994289)
-WI	Wisconsin	ENVELOPE(-92.885397, -86.967712, 46.952479, 42.489152)
-ID	Idaho	ENVELOPE(-117.236921, -111.046771, 48.999950, 41.994599)
-VT	Vermont	ENVELOPE(-73.436000, -71.505372, 45.013351, 42.725852)
-MN	Minnesota	ENVELOPE(-97.229436, -89.530673, 49.371730, 43.498102)
-OR	Oregon	ENVELOPE(-124.559617, -116.470418, 46.236091, 41.987672)
-NH	New Hampshire	ENVELOPE(-72.553428, -70.734139, 45.301469, 42.698603)
-IA	Iowa	ENVELOPE(-96.640709, -90.142796, 43.501457, 40.371946)
-MA	Massachusetts	ENVELOPE(-73.498840, -69.917780, 42.886877, 41.238279)
-NE	Nebraska	ENVELOPE(-104.056219, -95.308697, 43.003062, 39.992595)
-NY	New York	ENVELOPE(-79.763235, -71.869986, 45.006138, 40.506003)
-PA	Pennsylvania	ENVELOPE(-80.526045, -74.700062, 42.267327, 39.719313)
-CT	Connecticut	ENVELOPE(-73.725237, -71.788249, 42.047428, 40.998392)
-RI	Rhode Island	ENVELOPE(-71.866678, -71.117132, 42.013713, 41.322769)
-NJ	New Jersey	ENVELOPE(-75.570234, -73.896148, 41.350573, 38.956682)
-IN	Indiana	ENVELOPE(-88.101490, -84.787446, 41.765540, 37.776224)
-NV	Nevada	ENVELOPE(-119.996324, -114.037392, 41.996637, 34.998914)
-UT	Utah	ENVELOPE(-114.047273, -109.043206, 42.002300, 36.991746)
-CA	California	ENVELOPE(-124.392638, -114.125230, 42.002191, 32.535781)
-OH	Ohio	ENVELOPE(-84.812070, -80.519996, 41.986872, 38.400511)
-IL	Illinois	ENVELOPE(-91.516284, -87.507909, 42.509363, 36.986822)
-DC	District of Columbia	ENVELOPE(-77.122328, -76.910904, 38.993541, 38.788234)
-DE	Delaware	ENVELOPE(-75.791094, -75.045623, 39.840119, 38.449602)
-WV	West Virginia	ENVELOPE(-82.647158, -77.727467, 40.637203, 37.204910)
-MD	Maryland	ENVELOPE(-79.489865, -75.045623, 39.725461, 37.970255)
-CO	Colorado	ENVELOPE(-109.055861, -102.037207, 41.003375, 36.988994)
-KY	Kentucky	ENVELOPE(-89.568231, -81.959575, 39.142063, 36.496570)
-KS	Kansas	ENVELOPE(-102.051535, -94.601224, 40.002987, 36.988875)
-VA	Virginia	ENVELOPE(-83.675177, -75.242219, 39.456998, 36.541623)
-MO	Missouri	ENVELOPE(-95.767479, -89.105034, 40.609784, 35.989656)
-AZ	Arizona	ENVELOPE(-114.821761, -109.045615, 37.003926, 31.335634)
-OK	Oklahoma	ENVELOPE(-102.997709, -94.428552, 37.001478, 33.621136)
-NC	North Carolina	ENVELOPE(-84.323773, -75.456580, 36.589767, 33.882164)
-TN	Tennessee	ENVELOPE(-90.305448, -81.652272, 36.679683, 34.988759)
-TX	Texas	ENVELOPE(-106.650062, -93.507389, 36.493912, 25.845557)
-NM	New Mexico	ENVELOPE(-109.051346, -102.997401, 36.999760, 31.343453)
-AL	Alabama	ENVELOPE(-88.472952, -84.894016, 35.016033, 30.233604)
-MS	Mississippi	ENVELOPE(-91.643682, -88.090468, 35.005041, 30.194935)
-GA	Georgia	ENVELOPE(-85.608960, -80.894753, 35.000366, 30.361291)
-SC	South Carolina	ENVELOPE(-83.350685, -78.579453, 35.208356, 32.068173)
-AR	Arkansas	ENVELOPE(-94.617257, -89.645479, 36.492811, 33.010151)
-LA	Louisiana	ENVELOPE(-94.041785, -89.021803, 33.023422, 28.939655)
-FL	Florida	ENVELOPE(-87.625711, -80.050911, 31.003157, 24.956376)
-MI	Michigan	ENVELOPE(-90.408200, -82.419836, 48.173795, 41.697494)
-AK	Alaska	ENVELOPE(-178.217598, -129.992235, 71.406235, 51.583032)


[33/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
LUCENE-7015: Refactor spatial module to spatial-extras

Refactors non GeoPoint* classes from existing spatial module to a new spatial-extras module. dev-tools, build, and project files are updated to include new spatial-extras module.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/89db4950
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/89db4950
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/89db4950

Branch: refs/heads/jira/SOLR-445
Commit: 89db4950b9e2aee605d4313592466ad699ea7523
Parents: a9aec24
Author: nknize <nk...@apache.org>
Authored: Mon Feb 29 16:15:16 2016 -0600
Committer: nknize <nk...@apache.org>
Committed: Mon Feb 29 16:18:39 2016 -0600

----------------------------------------------------------------------
 dev-tools/idea/.idea/ant.xml                    |     1 +
 dev-tools/idea/.idea/modules.xml                |     1 +
 dev-tools/idea/.idea/workspace.xml              |    41 +-
 .../idea/lucene/benchmark/src/benchmark.iml     |     2 +-
 .../lucene/spatial-extras/spatial-extras.iml    |    32 +
 dev-tools/idea/lucene/spatial/spatial.iml       |    15 -
 dev-tools/idea/solr/core/src/java/solr-core.iml |     2 +-
 .../idea/solr/core/src/solr-core-tests.iml      |     2 +-
 dev-tools/maven/lucene/pom.xml.template         |     1 +
 .../lucene/spatial-extras/pom.xml.template      |    62 +
 dev-tools/maven/lucene/spatial/pom.xml.template |     2 +-
 dev-tools/scripts/smokeTestRelease.py           |     2 +-
 lucene/benchmark/build.xml                      |     8 +-
 lucene/build.xml                                |     3 +-
 lucene/module-build.xml                         |    22 +
 lucene/spatial-extras/build.xml                 |    57 +
 lucene/spatial-extras/ivy.xml                   |    36 +
 .../apache/lucene/spatial/SpatialStrategy.java  |   149 +
 .../bbox/BBoxOverlapRatioValueSource.java       |   251 +
 .../spatial/bbox/BBoxSimilarityValueSource.java |   117 +
 .../lucene/spatial/bbox/BBoxStrategy.java       |   588 +
 .../lucene/spatial/bbox/BBoxValueSource.java    |   115 +
 .../lucene/spatial/bbox/package-info.java       |    23 +
 .../composite/CompositeSpatialStrategy.java     |   144 +
 .../spatial/composite/CompositeVerifyQuery.java |   120 +
 .../composite/IntersectsRPTVerifyQuery.java     |   235 +
 .../lucene/spatial/composite/package-info.java  |    19 +
 .../org/apache/lucene/spatial/package-info.java |    21 +
 .../spatial/prefix/AbstractPrefixTreeQuery.java |   133 +
 .../prefix/AbstractVisitingPrefixTreeQuery.java |   380 +
 .../prefix/BytesRefIteratorTokenStream.java     |    72 +
 .../spatial/prefix/CellToBytesRefIterator.java  |    49 +
 .../spatial/prefix/ContainsPrefixTreeQuery.java |   362 +
 .../spatial/prefix/HeatmapFacetCounter.java     |   310 +
 .../prefix/IntersectsPrefixTreeQuery.java       |    95 +
 .../prefix/NumberRangePrefixTreeStrategy.java   |   199 +
 .../PointPrefixTreeFieldCacheProvider.java      |    48 +
 .../spatial/prefix/PrefixTreeFacetCounter.java  |   201 +
 .../spatial/prefix/PrefixTreeStrategy.java      |   208 +
 .../prefix/RecursivePrefixTreeStrategy.java     |   192 +
 .../prefix/TermQueryPrefixTreeStrategy.java     |   111 +
 .../spatial/prefix/WithinPrefixTreeQuery.java   |   232 +
 .../lucene/spatial/prefix/package-info.java     |    21 +
 .../apache/lucene/spatial/prefix/tree/Cell.java |   109 +
 .../spatial/prefix/tree/CellIterator.java       |    76 +
 .../prefix/tree/DateRangePrefixTree.java        |   444 +
 .../spatial/prefix/tree/FilterCellIterator.java |    61 +
 .../spatial/prefix/tree/GeohashPrefixTree.java  |   162 +
 .../lucene/spatial/prefix/tree/LegacyCell.java  |   242 +
 .../spatial/prefix/tree/LegacyPrefixTree.java   |    84 +
 .../prefix/tree/NumberRangePrefixTree.java      |   989 +
 .../prefix/tree/PackedQuadPrefixTree.java       |   459 +
 .../spatial/prefix/tree/QuadPrefixTree.java     |   308 +
 .../prefix/tree/SingletonCellIterator.java      |    36 +
 .../spatial/prefix/tree/SpatialPrefixTree.java  |   117 +
 .../prefix/tree/SpatialPrefixTreeFactory.java   |    99 +
 .../spatial/prefix/tree/TreeCellIterator.java   |    87 +
 .../spatial/prefix/tree/package-info.java       |    30 +
 .../lucene/spatial/query/SpatialArgs.java       |   148 +
 .../lucene/spatial/query/SpatialArgsParser.java |   146 +
 .../lucene/spatial/query/SpatialOperation.java  |   179 +
 .../query/UnsupportedSpatialOperation.java      |    28 +
 .../lucene/spatial/query/package-info.java      |    21 +
 .../serialized/SerializedDVStrategy.java        |   278 +
 .../lucene/spatial/serialized/package-info.java |    21 +
 .../lucene/spatial/spatial4j/Geo3dShape.java    |   185 +
 .../lucene/spatial/spatial4j/package-info.java  |    19 +
 .../spatial/util/CachingDoubleValueSource.java  |    93 +
 .../util/DistanceToShapeValueSource.java        |   122 +
 .../spatial/util/ShapeAreaValueSource.java      |   116 +
 .../lucene/spatial/util/ShapeFieldCache.java    |    54 +
 .../ShapeFieldCacheDistanceValueSource.java     |   112 +
 .../spatial/util/ShapeFieldCacheProvider.java   |    87 +
 .../spatial/util/ShapePredicateValueSource.java |   113 +
 .../lucene/spatial/util/package-info.java       |    21 +
 .../spatial/vector/DistanceValueSource.java     |   120 +
 .../spatial/vector/PointVectorStrategy.java     |   178 +
 .../lucene/spatial/vector/package-info.java     |    21 +
 lucene/spatial-extras/src/java/overview.html    |    67 +
 .../src/test-files/cities-Intersects-BBox.txt   |     3 +
 .../src/test-files/data/LUCENE-4464.txt         |     3 +
 .../src/test-files/data/countries-bbox.txt      |   249 +
 .../src/test-files/data/countries-poly.txt      |   249 +
 .../src/test-files/data/geonames-IE.txt         | 22929 +++++++++++++++++
 .../src/test-files/data/simple-bbox.txt         |     4 +
 .../src/test-files/data/states-bbox.txt         |    52 +
 .../src/test-files/data/states-poly.txt         |    52 +
 .../src/test-files/data/world-cities-points.txt |  2680 ++
 .../src/test-files/simple-Queries-BBox.txt      |     9 +
 .../src/test-files/states-Intersects-BBox.txt   |     3 +
 .../src/test-files/states-IsWithin-BBox.txt     |     4 +
 .../lucene/spatial/DistanceStrategyTest.java    |   135 +
 .../apache/lucene/spatial/PortedSolr3Test.java  |   167 +
 .../lucene/spatial/QueryEqualsHashCodeTest.java |   119 +
 .../apache/lucene/spatial/SpatialArgsTest.java  |    50 +
 .../apache/lucene/spatial/SpatialExample.java   |   200 +
 .../lucene/spatial/SpatialMatchConcern.java     |    31 +
 .../apache/lucene/spatial/SpatialTestCase.java  |   280 +
 .../apache/lucene/spatial/SpatialTestData.java  |    71 +
 .../apache/lucene/spatial/SpatialTestQuery.java |    96 +
 .../apache/lucene/spatial/StrategyTestCase.java |   252 +
 .../lucene/spatial/TestTestFramework.java       |    68 +
 .../lucene/spatial/bbox/TestBBoxStrategy.java   |   301 +
 .../composite/CompositeStrategyTest.java        |   142 +
 .../prefix/CellToBytesRefIterator50.java        |    44 +
 .../spatial/prefix/DateNRStrategyTest.java      |   143 +
 .../spatial/prefix/HeatmapFacetCounterTest.java |   252 +
 .../lucene/spatial/prefix/JtsPolygonTest.java   |   117 +
 .../spatial/prefix/NumberRangeFacetsTest.java   |   275 +
 .../RandomSpatialOpFuzzyPrefixTree50Test.java   |    31 +
 .../RandomSpatialOpFuzzyPrefixTreeTest.java     |   533 +
 .../prefix/RandomSpatialOpStrategyTestCase.java |   141 +
 .../prefix/TestRecursivePrefixTreeStrategy.java |   122 +
 .../prefix/TestTermQueryPrefixGridStrategy.java |    63 +
 .../prefix/tree/DateRangePrefixTreeTest.java    |   175 +
 .../prefix/tree/SpatialPrefixTreeTest.java      |   114 +
 .../spatial/query/SpatialArgsParserTest.java    |    77 +
 .../serialized/SerializedStrategyTest.java      |    66 +
 .../lucene/spatial/spatial4j/Geo3dRptTest.java  |   227 +
 .../Geo3dShapeRectRelationTestCase.java         |   262 +
 .../Geo3dShapeSphereModelRectRelationTest.java  |    72 +
 .../Geo3dShapeWGS84ModelRectRelationTest.java   |    94 +
 .../spatial4j/RandomizedShapeTestCase.java      |   288 +
 .../spatial/spatial4j/geo3d/GeoPointTest.java   |    80 +
 .../spatial/vector/TestPointVectorStrategy.java |    63 +
 lucene/spatial/build.xml                        |    30 -
 lucene/spatial/ivy.xml                          |    15 -
 .../apache/lucene/spatial/SpatialStrategy.java  |   149 -
 .../bbox/BBoxOverlapRatioValueSource.java       |   251 -
 .../spatial/bbox/BBoxSimilarityValueSource.java |   117 -
 .../lucene/spatial/bbox/BBoxStrategy.java       |   591 -
 .../lucene/spatial/bbox/BBoxValueSource.java    |   115 -
 .../lucene/spatial/bbox/package-info.java       |    23 -
 .../composite/CompositeSpatialStrategy.java     |   144 -
 .../spatial/composite/CompositeVerifyQuery.java |   121 -
 .../composite/IntersectsRPTVerifyQuery.java     |   235 -
 .../lucene/spatial/composite/package-info.java  |    19 -
 .../geopoint/search/GeoPointDistanceQuery.java  |     5 +
 .../search/GeoPointDistanceRangeQuery.java      |     6 +
 .../geopoint/search/GeoPointInBBoxQuery.java    |    10 +
 .../geopoint/search/GeoPointInPolygonQuery.java |     6 +
 .../spatial/prefix/AbstractPrefixTreeQuery.java |   133 -
 .../prefix/AbstractVisitingPrefixTreeQuery.java |   380 -
 .../prefix/BytesRefIteratorTokenStream.java     |    72 -
 .../spatial/prefix/CellToBytesRefIterator.java  |    49 -
 .../spatial/prefix/ContainsPrefixTreeQuery.java |   362 -
 .../spatial/prefix/HeatmapFacetCounter.java     |   310 -
 .../prefix/IntersectsPrefixTreeQuery.java       |    95 -
 .../prefix/NumberRangePrefixTreeStrategy.java   |   199 -
 .../PointPrefixTreeFieldCacheProvider.java      |    48 -
 .../spatial/prefix/PrefixTreeFacetCounter.java  |   201 -
 .../spatial/prefix/PrefixTreeStrategy.java      |   208 -
 .../prefix/RecursivePrefixTreeStrategy.java     |   196 -
 .../prefix/TermQueryPrefixTreeStrategy.java     |   111 -
 .../spatial/prefix/WithinPrefixTreeQuery.java   |   233 -
 .../lucene/spatial/prefix/package-info.java     |    21 -
 .../apache/lucene/spatial/prefix/tree/Cell.java |   109 -
 .../spatial/prefix/tree/CellIterator.java       |    76 -
 .../prefix/tree/DateRangePrefixTree.java        |   444 -
 .../spatial/prefix/tree/FilterCellIterator.java |    61 -
 .../spatial/prefix/tree/GeohashPrefixTree.java  |   162 -
 .../lucene/spatial/prefix/tree/LegacyCell.java  |   242 -
 .../spatial/prefix/tree/LegacyPrefixTree.java   |    84 -
 .../prefix/tree/NumberRangePrefixTree.java      |   989 -
 .../prefix/tree/PackedQuadPrefixTree.java       |   459 -
 .../spatial/prefix/tree/QuadPrefixTree.java     |   308 -
 .../prefix/tree/SingletonCellIterator.java      |    36 -
 .../spatial/prefix/tree/SpatialPrefixTree.java  |   117 -
 .../prefix/tree/SpatialPrefixTreeFactory.java   |    99 -
 .../spatial/prefix/tree/TreeCellIterator.java   |    87 -
 .../spatial/prefix/tree/package-info.java       |    30 -
 .../lucene/spatial/query/SpatialArgs.java       |   148 -
 .../lucene/spatial/query/SpatialArgsParser.java |   146 -
 .../lucene/spatial/query/SpatialOperation.java  |   179 -
 .../query/UnsupportedSpatialOperation.java      |    28 -
 .../lucene/spatial/query/package-info.java      |    21 -
 .../serialized/SerializedDVStrategy.java        |   278 -
 .../lucene/spatial/serialized/package-info.java |    21 -
 .../lucene/spatial/spatial4j/Geo3dShape.java    |   185 -
 .../lucene/spatial/spatial4j/package-info.java  |    19 -
 .../spatial/util/CachingDoubleValueSource.java  |    93 -
 .../util/DistanceToShapeValueSource.java        |   122 -
 .../lucene/spatial/util/GeoEncodingUtils.java   |    26 +-
 .../org/apache/lucene/spatial/util/GeoRect.java |     7 +
 .../lucene/spatial/util/GeoRelationUtils.java   |     4 +
 .../spatial/util/ShapeAreaValueSource.java      |   116 -
 .../lucene/spatial/util/ShapeFieldCache.java    |    54 -
 .../ShapeFieldCacheDistanceValueSource.java     |   112 -
 .../spatial/util/ShapeFieldCacheProvider.java   |    87 -
 .../spatial/util/ShapePredicateValueSource.java |   113 -
 .../spatial/vector/DistanceValueSource.java     |   120 -
 .../spatial/vector/PointVectorStrategy.java     |   182 -
 .../lucene/spatial/vector/package-info.java     |    21 -
 lucene/spatial/src/java/overview.html           |    50 +-
 .../src/test-files/cities-Intersects-BBox.txt   |     3 -
 .../spatial/src/test-files/data/LUCENE-4464.txt |     3 -
 .../src/test-files/data/countries-bbox.txt      |   249 -
 .../src/test-files/data/countries-poly.txt      |   249 -
 .../spatial/src/test-files/data/geonames-IE.txt | 22929 -----------------
 .../spatial/src/test-files/data/simple-bbox.txt |     5 -
 .../spatial/src/test-files/data/states-bbox.txt |    52 -
 .../spatial/src/test-files/data/states-poly.txt |    52 -
 .../src/test-files/data/world-cities-points.txt |  2680 --
 .../src/test-files/simple-Queries-BBox.txt      |     9 -
 .../src/test-files/states-Intersects-BBox.txt   |     3 -
 .../src/test-files/states-IsWithin-BBox.txt     |     4 -
 .../lucene/spatial/DistanceStrategyTest.java    |   135 -
 .../apache/lucene/spatial/PortedSolr3Test.java  |   167 -
 .../lucene/spatial/QueryEqualsHashCodeTest.java |   119 -
 .../apache/lucene/spatial/SpatialArgsTest.java  |    50 -
 .../apache/lucene/spatial/SpatialExample.java   |   200 -
 .../lucene/spatial/SpatialMatchConcern.java     |    31 -
 .../apache/lucene/spatial/SpatialTestCase.java  |   281 -
 .../apache/lucene/spatial/SpatialTestData.java  |    71 -
 .../apache/lucene/spatial/SpatialTestQuery.java |    96 -
 .../apache/lucene/spatial/StrategyTestCase.java |   252 -
 .../lucene/spatial/TestTestFramework.java       |    68 -
 .../lucene/spatial/bbox/TestBBoxStrategy.java   |   301 -
 .../composite/CompositeStrategyTest.java        |   142 -
 .../prefix/CellToBytesRefIterator50.java        |    44 -
 .../spatial/prefix/DateNRStrategyTest.java      |   143 -
 .../spatial/prefix/HeatmapFacetCounterTest.java |   252 -
 .../lucene/spatial/prefix/JtsPolygonTest.java   |   117 -
 .../spatial/prefix/NumberRangeFacetsTest.java   |   275 -
 .../RandomSpatialOpFuzzyPrefixTree50Test.java   |    31 -
 .../RandomSpatialOpFuzzyPrefixTreeTest.java     |   533 -
 .../prefix/RandomSpatialOpStrategyTestCase.java |   141 -
 .../prefix/TestRecursivePrefixTreeStrategy.java |   122 -
 .../prefix/TestTermQueryPrefixGridStrategy.java |    63 -
 .../prefix/tree/DateRangePrefixTreeTest.java    |   175 -
 .../prefix/tree/SpatialPrefixTreeTest.java      |   114 -
 .../spatial/query/SpatialArgsParserTest.java    |    77 -
 .../serialized/SerializedStrategyTest.java      |    66 -
 .../lucene/spatial/spatial4j/Geo3dRptTest.java  |   227 -
 .../Geo3dShapeRectRelationTestCase.java         |   264 -
 .../Geo3dShapeSphereModelRectRelationTest.java  |    72 -
 .../Geo3dShapeWGS84ModelRectRelationTest.java   |    95 -
 .../spatial4j/RandomizedShapeTestCase.java      |   289 -
 .../spatial/spatial4j/geo3d/GeoPointTest.java   |    82 -
 .../spatial/vector/TestPointVectorStrategy.java |    63 -
 solr/common-build.xml                           |     8 +-
 241 files changed, 41526 insertions(+), 41272 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/dev-tools/idea/.idea/ant.xml
----------------------------------------------------------------------
diff --git a/dev-tools/idea/.idea/ant.xml b/dev-tools/idea/.idea/ant.xml
index 2cd14fd..8d454ad 100644
--- a/dev-tools/idea/.idea/ant.xml
+++ b/dev-tools/idea/.idea/ant.xml
@@ -31,6 +31,7 @@
     <buildFile url="file://$PROJECT_DIR$/lucene/replicator/build.xml" />
     <buildFile url="file://$PROJECT_DIR$/lucene/sandbox/build.xml" />
     <buildFile url="file://$PROJECT_DIR$/lucene/spatial/build.xml" />
+    <buildFile url="file://$PROJECT_DIR$/lucene/spatial-extras/build.xml" />
     <buildFile url="file://$PROJECT_DIR$/lucene/suggest/build.xml" />
     <buildFile url="file://$PROJECT_DIR$/lucene/test-framework/build.xml" />
     <buildFile url="file://$PROJECT_DIR$/lucene/tools/build.xml" />

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/dev-tools/idea/.idea/modules.xml
----------------------------------------------------------------------
diff --git a/dev-tools/idea/.idea/modules.xml b/dev-tools/idea/.idea/modules.xml
index 4497f18..75da2f5 100644
--- a/dev-tools/idea/.idea/modules.xml
+++ b/dev-tools/idea/.idea/modules.xml
@@ -36,6 +36,7 @@
       <module group="Lucene/Other" filepath="$PROJECT_DIR$/lucene/replicator/replicator.iml" />
       <module group="Lucene/Other" filepath="$PROJECT_DIR$/lucene/sandbox/sandbox.iml" />
       <module group="Lucene/Other" filepath="$PROJECT_DIR$/lucene/spatial/spatial.iml" />
+      <module group="Lucene/Other" filepath="$PROJECT_DIR$/lucene/spatial-extras/spatial-extras.iml" />
       <module group="Lucene/Other" filepath="$PROJECT_DIR$/lucene/spatial3d/spatial3d.iml" />
       <module group="Lucene/Other" filepath="$PROJECT_DIR$/lucene/suggest/suggest.iml" />
       <module group="Lucene/Other" filepath="$PROJECT_DIR$/lucene/tools/tools.iml" />

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/dev-tools/idea/.idea/workspace.xml
----------------------------------------------------------------------
diff --git a/dev-tools/idea/.idea/workspace.xml b/dev-tools/idea/.idea/workspace.xml
index 423350b..a7c68de 100644
--- a/dev-tools/idea/.idea/workspace.xml
+++ b/dev-tools/idea/.idea/workspace.xml
@@ -204,6 +204,14 @@
       <option name="TEST_SEARCH_SCOPE"><value defaultName="singleModule" /></option>
       <patterns><pattern testClass=".*\.Test[^.]*|.*\.[^.]*Test" /></patterns>
     </configuration>
+    <configuration default="false" name="Module spatial-extras" type="JUnit" factoryName="JUnit">
+      <module name="spatial-extras" />
+      <option name="TEST_OBJECT" value="pattern" />
+      <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/idea-build/lucene/spatial-extras" />
+      <option name="VM_PARAMETERS" value="-ea -DtempDir=temp" />
+      <option name="TEST_SEARCH_SCOPE"><value defaultName="singleModule" /></option>
+      <patterns><pattern testClass=".*\.Test[^.]*|.*\.[^.]*Test" /></patterns>
+    </configuration>
     <configuration default="false" name="Module spatial3d" type="JUnit" factoryName="JUnit">
       <module name="spatial3d" />
       <option name="TEST_OBJECT" value="pattern" />
@@ -333,7 +341,7 @@
       <patterns><pattern testClass=".*\.Test[^.]*|.*\.[^.]*Test" /></patterns>
     </configuration>
  
-    <list size="40">
+    <list size="41">
       <item index="0" class="java.lang.String" itemvalue="JUnit.Lucene core" />
       <item index="1" class="java.lang.String" itemvalue="JUnit.Module analyzers-common" />
       <item index="2" class="java.lang.String" itemvalue="JUnit.Module analyzers-icu" />
@@ -359,21 +367,22 @@
       <item index="22" class="java.lang.String" itemvalue="JUnit.Module replicator" />
       <item index="23" class="java.lang.String" itemvalue="JUnit.Module sandbox" />
       <item index="24" class="java.lang.String" itemvalue="JUnit.Module spatial" />
-      <item index="25" class="java.lang.String" itemvalue="JUnit.Module spatial3d" />
-      <item index="26" class="java.lang.String" itemvalue="JUnit.Module suggest" />
-      <item index="27" class="java.lang.String" itemvalue="JUnit.Solr core" />
-      <item index="28" class="java.lang.String" itemvalue="JUnit.Solr analysis-extras contrib" />
-      <item index="29" class="java.lang.String" itemvalue="JUnit.Solr clustering contrib" />
-      <item index="30" class="java.lang.String" itemvalue="JUnit.Solr dataimporthandler contrib" />
-      <item index="31" class="java.lang.String" itemvalue="JUnit.Solr dataimporthandler-extras contrib" />
-      <item index="32" class="java.lang.String" itemvalue="JUnit.Solr extraction contrib" />
-      <item index="33" class="java.lang.String" itemvalue="JUnit.Solr map-reduce contrib" />
-      <item index="34" class="java.lang.String" itemvalue="JUnit.Solr morphlines-cell contrib" />
-      <item index="35" class="java.lang.String" itemvalue="JUnit.Solr morphlines-core contrib" />
-      <item index="36" class="java.lang.String" itemvalue="JUnit.Solr langid contrib" />
-      <item index="37" class="java.lang.String" itemvalue="JUnit.Solr uima contrib" />
-      <item index="38" class="java.lang.String" itemvalue="JUnit.Solr velocity contrib" />
-      <item index="39" class="java.lang.String" itemvalue="JUnit.Solrj" />
+      <item index="25" class="java.lang.String" itemvalue="JUnit.Module spatial-extras" />
+      <item index="26" class="java.lang.String" itemvalue="JUnit.Module spatial3d" />
+      <item index="27" class="java.lang.String" itemvalue="JUnit.Module suggest" />
+      <item index="28" class="java.lang.String" itemvalue="JUnit.Solr core" />
+      <item index="29" class="java.lang.String" itemvalue="JUnit.Solr analysis-extras contrib" />
+      <item index="30" class="java.lang.String" itemvalue="JUnit.Solr clustering contrib" />
+      <item index="31" class="java.lang.String" itemvalue="JUnit.Solr dataimporthandler contrib" />
+      <item index="32" class="java.lang.String" itemvalue="JUnit.Solr dataimporthandler-extras contrib" />
+      <item index="33" class="java.lang.String" itemvalue="JUnit.Solr extraction contrib" />
+      <item index="34" class="java.lang.String" itemvalue="JUnit.Solr map-reduce contrib" />
+      <item index="35" class="java.lang.String" itemvalue="JUnit.Solr morphlines-cell contrib" />
+      <item index="36" class="java.lang.String" itemvalue="JUnit.Solr morphlines-core contrib" />
+      <item index="37" class="java.lang.String" itemvalue="JUnit.Solr langid contrib" />
+      <item index="38" class="java.lang.String" itemvalue="JUnit.Solr uima contrib" />
+      <item index="39" class="java.lang.String" itemvalue="JUnit.Solr velocity contrib" />
+      <item index="40" class="java.lang.String" itemvalue="JUnit.Solrj" />
     </list>
   </component>
 </project>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/dev-tools/idea/lucene/benchmark/src/benchmark.iml
----------------------------------------------------------------------
diff --git a/dev-tools/idea/lucene/benchmark/src/benchmark.iml b/dev-tools/idea/lucene/benchmark/src/benchmark.iml
index cecd54f..509d5ec 100644
--- a/dev-tools/idea/lucene/benchmark/src/benchmark.iml
+++ b/dev-tools/idea/lucene/benchmark/src/benchmark.iml
@@ -24,7 +24,7 @@
     <orderEntry type="library" scope="TEST" name="JUnit" level="project" />
     <orderEntry type="module" scope="TEST" module-name="lucene-test-framework" />
     <orderEntry type="module" scope="TEST" module-name="benchmark-conf" />
-    <orderEntry type="module" module-name="spatial" />
+    <orderEntry type="module" module-name="spatial-extras" />
     <orderEntry type="module" module-name="facet" />
     <orderEntry type="module" module-name="highlighter" />
     <orderEntry type="module" module-name="icu" />

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/dev-tools/idea/lucene/spatial-extras/spatial-extras.iml
----------------------------------------------------------------------
diff --git a/dev-tools/idea/lucene/spatial-extras/spatial-extras.iml b/dev-tools/idea/lucene/spatial-extras/spatial-extras.iml
new file mode 100644
index 0000000..5694371
--- /dev/null
+++ b/dev-tools/idea/lucene/spatial-extras/spatial-extras.iml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/../../idea-build/lucene/spatial-extras/classes/java" />
+    <output-test url="file://$MODULE_DIR$/../../idea-build/lucene/spatial-extras/classes/test" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test-files" type="java-test-resource" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module-library" exported="">
+      <library>
+        <CLASSES>
+          <root url="file://$MODULE_DIR$/lib" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+        <jarDirectory url="file://$MODULE_DIR$/lib" recursive="false" />
+      </library>
+    </orderEntry>
+    <orderEntry type="library" scope="TEST" name="JUnit" level="project" />
+    <orderEntry type="module" scope="TEST" module-name="lucene-test-framework" />
+    <orderEntry type="module" module-name="lucene-core" />
+    <orderEntry type="module" module-name="queries" />
+    <orderEntry type="module" module-name="misc" />
+    <orderEntry type="module" module-name="spatial3d" />
+    <orderEntry type="module" module-name="analysis-common" scope="TEST"/>
+  </component>
+</module>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/dev-tools/idea/lucene/spatial/spatial.iml
----------------------------------------------------------------------
diff --git a/dev-tools/idea/lucene/spatial/spatial.iml b/dev-tools/idea/lucene/spatial/spatial.iml
index f7cc723..f264467 100644
--- a/dev-tools/idea/lucene/spatial/spatial.iml
+++ b/dev-tools/idea/lucene/spatial/spatial.iml
@@ -7,27 +7,12 @@
     <content url="file://$MODULE_DIR$">
       <sourceFolder url="file://$MODULE_DIR$/src/java" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/src/test" isTestSource="true" />
-      <sourceFolder url="file://$MODULE_DIR$/src/test-files" type="java-test-resource" />
     </content>
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="module-library" exported="">
-      <library>
-        <CLASSES>
-          <root url="file://$MODULE_DIR$/lib" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES />
-        <jarDirectory url="file://$MODULE_DIR$/lib" recursive="false" />
-      </library>
-    </orderEntry>
     <orderEntry type="library" scope="TEST" name="JUnit" level="project" />
     <orderEntry type="module" scope="TEST" module-name="lucene-test-framework" />
     <orderEntry type="module" module-name="lucene-core" />
-    <orderEntry type="module" module-name="queries" />
-    <orderEntry type="module" module-name="misc" />
-    <orderEntry type="module" module-name="spatial3d" />
-    <orderEntry type="module" module-name="analysis-common" scope="TEST"/>
   </component>
 </module>
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/dev-tools/idea/solr/core/src/java/solr-core.iml
----------------------------------------------------------------------
diff --git a/dev-tools/idea/solr/core/src/java/solr-core.iml b/dev-tools/idea/solr/core/src/java/solr-core.iml
index 3ffd185..f03268c 100644
--- a/dev-tools/idea/solr/core/src/java/solr-core.iml
+++ b/dev-tools/idea/solr/core/src/java/solr-core.iml
@@ -16,7 +16,7 @@
     <orderEntry type="library" name="Solr example library" level="project" />
     <orderEntry type="module" module-name="solrj" />
     <orderEntry type="module" module-name="kuromoji" />
-    <orderEntry type="module" module-name="spatial" />
+    <orderEntry type="module" module-name="spatial-extras" />
     <orderEntry type="module" module-name="grouping" />
     <orderEntry type="module" module-name="highlighter" />
     <orderEntry type="module" module-name="icu" />

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/dev-tools/idea/solr/core/src/solr-core-tests.iml
----------------------------------------------------------------------
diff --git a/dev-tools/idea/solr/core/src/solr-core-tests.iml b/dev-tools/idea/solr/core/src/solr-core-tests.iml
index eb27c57..c9f722a 100644
--- a/dev-tools/idea/solr/core/src/solr-core-tests.iml
+++ b/dev-tools/idea/solr/core/src/solr-core-tests.iml
@@ -25,7 +25,7 @@
     <orderEntry type="module" scope="TEST" module-name="queryparser" />
     <orderEntry type="module" scope="TEST" module-name="queries" />
     <orderEntry type="module" scope="TEST" module-name="suggest" />
-    <orderEntry type="module" scope="TEST" module-name="spatial" />
+    <orderEntry type="module" scope="TEST" module-name="spatial-extras" />
     <orderEntry type="module" scope="TEST" module-name="misc" />
     <orderEntry type="module" scope="TEST" module-name="join" />
     <orderEntry type="module" scope="TEST" module-name="expressions" />

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/dev-tools/maven/lucene/pom.xml.template
----------------------------------------------------------------------
diff --git a/dev-tools/maven/lucene/pom.xml.template b/dev-tools/maven/lucene/pom.xml.template
index f49a60e..536290b 100644
--- a/dev-tools/maven/lucene/pom.xml.template
+++ b/dev-tools/maven/lucene/pom.xml.template
@@ -60,6 +60,7 @@
     <module>replicator</module>
     <module>sandbox</module>
     <module>spatial</module>
+    <module>spatial-extras</module>
     <module>spatial3d</module>
     <module>suggest</module>
   </modules>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/dev-tools/maven/lucene/spatial-extras/pom.xml.template
----------------------------------------------------------------------
diff --git a/dev-tools/maven/lucene/spatial-extras/pom.xml.template b/dev-tools/maven/lucene/spatial-extras/pom.xml.template
new file mode 100644
index 0000000..58a5aa8
--- /dev/null
+++ b/dev-tools/maven/lucene/spatial-extras/pom.xml.template
@@ -0,0 +1,62 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <!--
+    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.
+  -->
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.lucene</groupId>
+    <artifactId>lucene-parent</artifactId>
+    <version>@version@</version>
+    <relativePath>../pom.xml</relativePath>
+  </parent>
+  <groupId>org.apache.lucene</groupId>
+  <artifactId>lucene-spatial-extras</artifactId>
+  <packaging>jar</packaging>
+  <name>Lucene Spatial Extras</name>
+  <description>
+    Advanced Spatial Shape Strategies for Apache Lucene
+  </description>
+  <properties>
+    <module-directory>lucene/spatial-extras</module-directory>
+    <relative-top-level>../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
+  </properties>
+  <dependencies>
+    <dependency>
+      <!-- lucene-test-framework dependency must be declared before lucene-core -->
+      <groupId>org.apache.lucene</groupId>
+      <artifactId>lucene-test-framework</artifactId>
+      <scope>test</scope>
+    </dependency>
+@lucene-spatial-extras.internal.dependencies@
+@lucene-spatial-extras.external.dependencies@
+@lucene-spatial-extras.internal.test.dependencies@
+@lucene-spatial-extras.external.test.dependencies@
+  </dependencies>
+  <build>
+    <sourceDirectory>${module-path}/src/java</sourceDirectory>
+    <testSourceDirectory>${module-path}/src/test</testSourceDirectory>
+    <testResources>
+      <testResource>
+        <directory>${module-path}/src/test-files</directory>
+      </testResource>
+    </testResources>
+  </build>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/dev-tools/maven/lucene/spatial/pom.xml.template
----------------------------------------------------------------------
diff --git a/dev-tools/maven/lucene/spatial/pom.xml.template b/dev-tools/maven/lucene/spatial/pom.xml.template
index d4c5cd2..5f6420a 100644
--- a/dev-tools/maven/lucene/spatial/pom.xml.template
+++ b/dev-tools/maven/lucene/spatial/pom.xml.template
@@ -31,7 +31,7 @@
   <packaging>jar</packaging>
   <name>Lucene Spatial</name>
   <description>    
-  	Spatial Strategies for Apache Lucene
+	Geospatial Indexing and Query for Apache Lucene
   </description>
   <properties>
     <module-directory>lucene/spatial</module-directory>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/dev-tools/scripts/smokeTestRelease.py
----------------------------------------------------------------------
diff --git a/dev-tools/scripts/smokeTestRelease.py b/dev-tools/scripts/smokeTestRelease.py
index d76e8fa..aa367f6 100644
--- a/dev-tools/scripts/smokeTestRelease.py
+++ b/dev-tools/scripts/smokeTestRelease.py
@@ -643,7 +643,7 @@ def verifyUnpacked(java, project, artifact, unpackPath, gitRevision, version, te
 
   if project == 'lucene':
     # TODO: clean this up to not be a list of modules that we must maintain
-    extras = ('analysis', 'backward-codecs', 'benchmark', 'classification', 'codecs', 'core', 'demo', 'docs', 'expressions', 'facet', 'grouping', 'highlighter', 'join', 'memory', 'misc', 'queries', 'queryparser', 'replicator', 'sandbox', 'spatial', 'spatial3d', 'suggest', 'test-framework', 'licenses')
+    extras = ('analysis', 'backward-codecs', 'benchmark', 'classification', 'codecs', 'core', 'demo', 'docs', 'expressions', 'facet', 'grouping', 'highlighter', 'join', 'memory', 'misc', 'queries', 'queryparser', 'replicator', 'sandbox', 'spatial', 'spatial-extras', 'spatial3d', 'suggest', 'test-framework', 'licenses')
     if isSrc:
       extras += ('build.xml', 'common-build.xml', 'module-build.xml', 'ivy-settings.xml', 'ivy-versions.properties', 'ivy-ignore-conflicts.properties', 'version.properties', 'tools', 'site')
   else:

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/benchmark/build.xml
----------------------------------------------------------------------
diff --git a/lucene/benchmark/build.xml b/lucene/benchmark/build.xml
index cd47287..49a9f4c 100644
--- a/lucene/benchmark/build.xml
+++ b/lucene/benchmark/build.xml
@@ -171,7 +171,7 @@
       <pathelement path="${analyzers-common.jar}"/>
       <pathelement path="${queryparser.jar}"/>
       <pathelement path="${facet.jar}"/>
-      <pathelement path="${spatial.jar}"/>
+      <pathelement path="${spatial-extras.jar}"/>
       <pathelement path="${queries.jar}"/>
       <pathelement path="${codecs.jar}"/>
       <pathelement path="${join.jar}"/>
@@ -185,7 +185,7 @@
     </path>
 
     <target name="javadocs" depends="javadocs-memory,javadocs-highlighter,javadocs-analyzers-common,
-      javadocs-queryparser,javadocs-facet,javadocs-spatial,compile-core,check-javadocs-uptodate" 
+      javadocs-queryparser,javadocs-facet,javadocs-spatial-extras,compile-core,check-javadocs-uptodate"
             unless="javadocs-uptodate-${name}">
     <invoke-module-javadoc>
       <links>
@@ -194,7 +194,7 @@
         <link href="../analyzers-common"/>
         <link href="../queryparser"/>
         <link href="../facet"/>
-        <link href="../spatial"/>
+        <link href="../spatial-extras"/>
       </links>
     </invoke-module-javadoc>
     </target>
@@ -277,7 +277,7 @@
       <echo>Benchmark output in JIRA table format is in file: ${shingle.jira.output.file}</echo>
     </target>
 
-    <target name="init" depends="module-build.init,jar-memory,jar-highlighter,jar-analyzers-common,jar-queryparser,jar-facet,jar-spatial,jar-codecs,jar-join"/>
+    <target name="init" depends="module-build.init,jar-memory,jar-highlighter,jar-analyzers-common,jar-queryparser,jar-facet,jar-spatial-extras,jar-codecs,jar-join"/>
   
     <target name="compile-test" depends="copy-alg-files-for-testing,module-build.compile-test"/>
     <target name="copy-alg-files-for-testing" description="copy .alg files as resources for testing">

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/build.xml
----------------------------------------------------------------------
diff --git a/lucene/build.xml b/lucene/build.xml
index 9bd4492..117059e 100644
--- a/lucene/build.xml
+++ b/lucene/build.xml
@@ -179,7 +179,8 @@
     <!-- queries: problems -->
     <!-- queryparser: problems -->
     <!-- sandbox: problems -->
-    <!-- spatial: problems -->
+    <check-missing-javadocs dir="build/docs/spatial" level="method"/>
+    <!-- spatial-extras: problems -->
     <check-missing-javadocs dir="build/docs/suggest" level="method"/>
     <!-- test-framework: problems -->
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/module-build.xml
----------------------------------------------------------------------
diff --git a/lucene/module-build.xml b/lucene/module-build.xml
index 0263101..d48ae37 100644
--- a/lucene/module-build.xml
+++ b/lucene/module-build.xml
@@ -640,6 +640,28 @@
     <property name="spatial-javadocs.uptodate" value="true"/>
   </target>
 
+  <property name="spatial-extras.jar" value="${common.dir}/build/spatial-extras/lucene-spatial-extras-${version}.jar"/>
+  <target name="check-spatial-extras-uptodate" unless="spatial-extras.uptodate">
+    <module-uptodate name="spatial-extras" jarfile="${spatial-extras.jar}" property="spatial-extras.uptodate"/>
+  </target>
+  <target name="jar-spatial-extras" unless="spatial-extras.uptodate" depends="check-spatial-extras-uptodate">
+    <ant dir="${common.dir}/spatial-extras" target="jar-core" inheritAll="false">
+      <propertyset refid="uptodate.and.compiled.properties"/>
+    </ant>
+    <property name="spatial-extras.uptodate" value="true"/>
+  </target>
+
+  <property name="spatial-extras-javadoc.jar" value="${common.dir}/build/spatial-extras/lucene-spatial-extras-${version}-javadoc.jar"/>
+  <target name="check-spatial-extras-javadocs-uptodate" unless="spatial-extras-javadocs.uptodate">
+    <module-uptodate name="spatial-extras" jarfile="${spatial-extras-javadoc.jar}" property="spatial-extras-javadocs.uptodate"/>
+  </target>
+  <target name="javadocs-spatial-extras" unless="spatial-extras-javadocs.uptodate" depends="check-spatial-extras-javadocs-uptodate">
+    <ant dir="${common.dir}/spatial-extras" target="javadocs" inheritAll="false">
+      <propertyset refid="uptodate.and.compiled.properties"/>
+    </ant>
+    <property name="spatial-extras-javadocs.uptodate" value="true"/>
+  </target>
+
   <property name="suggest.jar" value="${common.dir}/build/suggest/lucene-suggest-${version}.jar"/>
   <target name="check-suggest-uptodate" unless="suggest.uptodate">
     <module-uptodate name="suggest" jarfile="${suggest.jar}" property="suggest.uptodate"/>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/build.xml
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/build.xml b/lucene/spatial-extras/build.xml
new file mode 100644
index 0000000..a77f9ea
--- /dev/null
+++ b/lucene/spatial-extras/build.xml
@@ -0,0 +1,57 @@
+<?xml version="1.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.
+-->
+<project name="spatial-extras" default="default">
+  <description>
+    Geospatial search
+  </description>
+
+  <import file="../module-build.xml"/>
+
+  <path id="spatialjar">
+     <fileset dir="lib"/>
+  </path>
+
+  <path id="classpath">
+    <path refid="base.classpath"/>
+    <path refid="spatialjar"/>
+    <pathelement path="${queries.jar}" />
+    <pathelement path="${misc.jar}" />
+    <pathelement path="${spatial3d.jar}" />
+  </path>
+
+  <path id="test.classpath">
+    <path refid="test.base.classpath" />
+    <path refid="spatialjar"/>
+    <pathelement path="src/test-files" />
+  </path>
+
+  <target name="compile-core" depends="jar-queries,jar-misc,jar-spatial3d,common.compile-core" />
+
+  <target name="javadocs" depends="javadocs-queries,javadocs-misc,javadocs-spatial3d,compile-core,check-javadocs-uptodate"
+          unless="javadocs-uptodate-${name}">
+    <invoke-module-javadoc>
+      <links>
+        <link href="../queries"/>
+        <link href="../misc"/>
+        <link href="../spatial3d"/>
+      </links>
+    </invoke-module-javadoc>
+  </target>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/ivy.xml
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/ivy.xml b/lucene/spatial-extras/ivy.xml
new file mode 100644
index 0000000..4fef30e
--- /dev/null
+++ b/lucene/spatial-extras/ivy.xml
@@ -0,0 +1,36 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+-->
+<ivy-module version="2.0"  xmlns:maven="http://ant.apache.org/ivy/maven">
+  <info organisation="org.apache.lucene" module="spatial-extras"/>
+  <configurations defaultconfmapping="compile->master;test->master">
+    <conf name="compile" transitive="false"/>
+    <conf name="test" transitive="false"/>
+  </configurations>
+  <dependencies>
+    <dependency org="com.spatial4j" name="spatial4j" rev="${/com.spatial4j/spatial4j}" conf="compile"/>
+
+    <dependency org="com.spatial4j" name="spatial4j" rev="${/com.spatial4j/spatial4j}" conf="test">
+      <artifact name="spatial4j" type="test" ext="jar" maven:classifier="tests" />
+    </dependency>
+
+    <dependency org="org.slf4j" name="slf4j-api" rev="${/org.slf4j/slf4j-api}" conf="test"/>
+
+    <exclude org="*" ext="*" matcher="regexp" type="${ivy.exclude.types}"/>
+  </dependencies>
+</ivy-module>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/SpatialStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/SpatialStrategy.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/SpatialStrategy.java
new file mode 100644
index 0000000..f433c11
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/SpatialStrategy.java
@@ -0,0 +1,149 @@
+/*
+ * 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;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.queries.function.valuesource.ReciprocalFloatFunction;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.spatial.query.SpatialArgs;
+
+/**
+ * The SpatialStrategy encapsulates an approach to indexing and searching based
+ * on shapes.
+ * <p>
+ * Different implementations will support different features. A strategy should
+ * document these common elements:
+ * <ul>
+ *   <li>Can it index more than one shape per field?</li>
+ *   <li>What types of shapes can be indexed?</li>
+ *   <li>What types of query shapes can be used?</li>
+ *   <li>What types of query operations are supported?
+ *   This might vary per shape.</li>
+ *   <li>Does it use some type of cache?  When?
+ * </ul>
+ * If a strategy only supports certain shapes at index or query time, then in
+ * general it will throw an exception if given an incompatible one.  It will not
+ * be coerced into compatibility.
+ * <p>
+ * Note that a SpatialStrategy is not involved with the Lucene stored field
+ * values of shapes, which is immaterial to indexing and search.
+ * <p>
+ * Thread-safe.
+ * <p>
+ * This API is marked as experimental, however it is quite stable.
+ *
+ * @lucene.experimental
+ */
+public abstract class SpatialStrategy {
+
+  protected final SpatialContext ctx;
+  private final String fieldName;
+
+  /**
+   * Constructs the spatial strategy with its mandatory arguments.
+   */
+  public SpatialStrategy(SpatialContext ctx, String fieldName) {
+    if (ctx == null)
+      throw new IllegalArgumentException("ctx is required");
+    this.ctx = ctx;
+    if (fieldName == null || fieldName.length() == 0)
+      throw new IllegalArgumentException("fieldName is required");
+    this.fieldName = fieldName;
+  }
+
+  public SpatialContext getSpatialContext() {
+    return ctx;
+  }
+
+  /**
+   * The name of the field or the prefix of them if there are multiple
+   * fields needed internally.
+   * @return Not null.
+   */
+  public String getFieldName() {
+    return fieldName;
+  }
+
+  /**
+   * Returns the IndexableField(s) from the {@code shape} that are to be
+   * added to the {@link org.apache.lucene.document.Document}.  These fields
+   * are expected to be marked as indexed and not stored.
+   * <p>
+   * Note: If you want to <i>store</i> the shape as a string for retrieval in
+   * search results, you could add it like this:
+   * <pre>document.add(new StoredField(fieldName,ctx.toString(shape)));</pre>
+   * The particular string representation used doesn't matter to the Strategy
+   * since it doesn't use it.
+   *
+   * @return Not null nor will it have null elements.
+   * @throws UnsupportedOperationException if given a shape incompatible with the strategy
+   */
+  public abstract Field[] createIndexableFields(Shape shape);
+
+  /**
+   * See {@link #makeDistanceValueSource(com.spatial4j.core.shape.Point, double)} called with
+   * a multiplier of 1.0 (i.e. units of degrees).
+   */
+  public ValueSource makeDistanceValueSource(Point queryPoint) {
+    return makeDistanceValueSource(queryPoint, 1.0);
+  }
+
+  /**
+   * Make a ValueSource returning the distance between the center of the
+   * indexed shape and {@code queryPoint}.  If there are multiple indexed shapes
+   * then the closest one is chosen. The result is multiplied by {@code multiplier}, which
+   * conveniently is used to get the desired units.
+   */
+  public abstract ValueSource makeDistanceValueSource(Point queryPoint, double multiplier);
+
+  /**
+   * Make a Query based principally on {@link org.apache.lucene.spatial.query.SpatialOperation}
+   * and {@link Shape} from the supplied {@code args}.  It should be constant scoring of 1.
+   *
+   * @throws UnsupportedOperationException If the strategy does not support the shape in {@code args}
+   * @throws org.apache.lucene.spatial.query.UnsupportedSpatialOperation If the strategy does not support the {@link
+   * org.apache.lucene.spatial.query.SpatialOperation} in {@code args}.
+   */
+  public abstract Query makeQuery(SpatialArgs args);
+
+  /**
+   * Returns a ValueSource with values ranging from 1 to 0, depending inversely
+   * on the distance from {@link #makeDistanceValueSource(com.spatial4j.core.shape.Point,double)}.
+   * The formula is {@code c/(d + c)} where 'd' is the distance and 'c' is
+   * one tenth the distance to the farthest edge from the center. Thus the
+   * scores will be 1 for indexed points at the center of the query shape and as
+   * low as ~0.1 at its furthest edges.
+   */
+  public final ValueSource makeRecipDistanceValueSource(Shape queryShape) {
+    Rectangle bbox = queryShape.getBoundingBox();
+    double diagonalDist = ctx.getDistCalc().distance(
+        ctx.makePoint(bbox.getMinX(), bbox.getMinY()), bbox.getMaxX(), bbox.getMaxY());
+    double distToEdge = diagonalDist * 0.5;
+    float c = (float)distToEdge * 0.1f;//one tenth
+    return new ReciprocalFloatFunction(makeDistanceValueSource(queryShape.getCenter(), 1.0), 1f, c, c);
+  }
+
+  @Override
+  public String toString() {
+    return getClass().getSimpleName()+" field:"+fieldName+" ctx="+ctx;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxOverlapRatioValueSource.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxOverlapRatioValueSource.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxOverlapRatioValueSource.java
new file mode 100644
index 0000000..9d0afe1
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxOverlapRatioValueSource.java
@@ -0,0 +1,251 @@
+/*
+ * 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.bbox;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.search.Explanation;
+
+import com.spatial4j.core.shape.Rectangle;
+
+/**
+ * The algorithm is implemented as envelope on envelope (rect on rect) overlays rather than
+ * complex polygon on complex polygon overlays.
+ * <p>
+ * Spatial relevance scoring algorithm:
+ * <DL>
+ *   <DT>queryArea</DT> <DD>the area of the input query envelope</DD>
+ *   <DT>targetArea</DT> <DD>the area of the target envelope (per Lucene document)</DD>
+ *   <DT>intersectionArea</DT> <DD>the area of the intersection between the query and target envelopes</DD>
+ *   <DT>queryTargetProportion</DT> <DD>A 0-1 factor that divides the score proportion between query and target.
+ *   0.5 is evenly.</DD>
+ *
+ *   <DT>queryRatio</DT> <DD>intersectionArea / queryArea; (see note)</DD>
+ *   <DT>targetRatio</DT> <DD>intersectionArea / targetArea; (see note)</DD>
+ *   <DT>queryFactor</DT> <DD>queryRatio * queryTargetProportion;</DD>
+ *   <DT>targetFactor</DT> <DD>targetRatio * (1 - queryTargetProportion);</DD>
+ *   <DT>score</DT> <DD>queryFactor + targetFactor;</DD>
+ * </DL>
+ * Additionally, note that an optional minimum side length {@code minSideLength} may be used whenever an
+ * area is calculated (queryArea, targetArea, intersectionArea). This allows for points or horizontal/vertical lines
+ * to be used as the query shape and in such case the descending order should have smallest boxes up front. Without
+ * this, a point or line query shape typically scores everything with the same value since there is 0 area.
+ * <p>
+ * Note: The actual computation of queryRatio and targetRatio is more complicated so that it considers
+ * points and lines. Lines have the ratio of overlap, and points are either 1.0 or 0.0 depending on whether
+ * it intersects or not.
+ * <p>
+ * Originally based on Geoportal's
+ * <a href="http://geoportal.svn.sourceforge.net/svnroot/geoportal/Geoportal/trunk/src/com/esri/gpt/catalog/lucene/SpatialRankingValueSource.java">
+ *   SpatialRankingValueSource</a> but modified quite a bit. GeoPortal's algorithm will yield a score of 0
+ * if either a line or point is compared, and it doesn't output a 0-1 normalized score (it multiplies the factors),
+ * and it doesn't support minSideLength, and it had dateline bugs.
+ *
+ * @lucene.experimental
+ */
+public class BBoxOverlapRatioValueSource extends BBoxSimilarityValueSource {
+
+  private final boolean isGeo;//-180/+180 degrees  (not part of identity; attached to parent strategy/field)
+
+  private final Rectangle queryExtent;
+  private final double queryArea;//not part of identity
+
+  private final double minSideLength;
+
+  private final double queryTargetProportion;
+
+  //TODO option to compute geodetic area
+
+  /**
+   *
+   * @param rectValueSource mandatory; source of rectangles
+   * @param isGeo True if ctx.isGeo() and thus dateline issues should be attended to
+   * @param queryExtent mandatory; the query rectangle
+   * @param queryTargetProportion see class javadocs. Between 0 and 1.
+   * @param minSideLength see class javadocs. 0.0 will effectively disable.
+   */
+  public BBoxOverlapRatioValueSource(ValueSource rectValueSource, boolean isGeo, Rectangle queryExtent,
+                                     double queryTargetProportion, double minSideLength) {
+    super(rectValueSource);
+    this.isGeo = isGeo;
+    this.minSideLength = minSideLength;
+    this.queryExtent = queryExtent;
+    this.queryArea = calcArea(queryExtent.getWidth(), queryExtent.getHeight());
+    assert queryArea >= 0;
+    this.queryTargetProportion = queryTargetProportion;
+    if (queryTargetProportion < 0 || queryTargetProportion > 1.0)
+      throw new IllegalArgumentException("queryTargetProportion must be >= 0 and <= 1");
+  }
+
+  /** Construct with 75% weighting towards target (roughly GeoPortal's default), geo degrees assumed, no
+   * minimum side length. */
+  public BBoxOverlapRatioValueSource(ValueSource rectValueSource, Rectangle queryExtent) {
+    this(rectValueSource, true, queryExtent, 0.25, 0.0);
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (!super.equals(o)) return false;
+
+    BBoxOverlapRatioValueSource that = (BBoxOverlapRatioValueSource) o;
+
+    if (Double.compare(that.minSideLength, minSideLength) != 0) return false;
+    if (Double.compare(that.queryTargetProportion, queryTargetProportion) != 0) return false;
+    if (!queryExtent.equals(that.queryExtent)) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = super.hashCode();
+    long temp;
+    result = 31 * result + queryExtent.hashCode();
+    temp = Double.doubleToLongBits(minSideLength);
+    result = 31 * result + (int) (temp ^ (temp >>> 32));
+    temp = Double.doubleToLongBits(queryTargetProportion);
+    result = 31 * result + (int) (temp ^ (temp >>> 32));
+    return result;
+  }
+
+  @Override
+  protected String similarityDescription() {
+    return queryExtent.toString() + "," + queryTargetProportion;
+  }
+
+  @Override
+  protected double score(Rectangle target, AtomicReference<Explanation> exp) {
+    // calculate "height": the intersection height between two boxes.
+    double top = Math.min(queryExtent.getMaxY(), target.getMaxY());
+    double bottom = Math.max(queryExtent.getMinY(), target.getMinY());
+    double height = top - bottom;
+    if (height < 0) {
+      if (exp != null) {
+        exp.set(Explanation.noMatch("No intersection"));
+      }
+      return 0;//no intersection
+    }
+
+    // calculate "width": the intersection width between two boxes.
+    double width = 0;
+    {
+      Rectangle a = queryExtent;
+      Rectangle b = target;
+      if (a.getCrossesDateLine() == b.getCrossesDateLine()) {
+        //both either cross or don't
+        double left = Math.max(a.getMinX(), b.getMinX());
+        double right = Math.min(a.getMaxX(), b.getMaxX());
+        if (!a.getCrossesDateLine()) {//both don't
+          if (left <= right) {
+            width = right - left;
+          } else if (isGeo && (Math.abs(a.getMinX()) == 180 || Math.abs(a.getMaxX()) == 180)
+              && (Math.abs(b.getMinX()) == 180 || Math.abs(b.getMaxX()) == 180)) {
+            width = 0;//both adjacent to dateline
+          } else {
+            if (exp != null) {
+              exp.set(Explanation.noMatch("No intersection"));
+            }
+            return 0;//no intersection
+          }
+        } else {//both cross
+          width = right - left + 360;
+        }
+      } else {
+        if (!a.getCrossesDateLine()) {//then flip
+          a = target;
+          b = queryExtent;
+        }
+        //a crosses, b doesn't
+        double qryWestLeft = Math.max(a.getMinX(), b.getMinX());
+        double qryWestRight = b.getMaxX();
+        if (qryWestLeft < qryWestRight)
+          width += qryWestRight - qryWestLeft;
+
+        double qryEastLeft = b.getMinX();
+        double qryEastRight = Math.min(a.getMaxX(), b.getMaxX());
+        if (qryEastLeft < qryEastRight)
+          width += qryEastRight - qryEastLeft;
+
+        if (qryWestLeft > qryWestRight && qryEastLeft > qryEastRight) {
+          if (exp != null) {
+            exp.set(Explanation.noMatch("No intersection"));
+          }
+          return 0;//no intersection
+        }
+      }
+    }
+
+    // calculate queryRatio and targetRatio
+    double intersectionArea = calcArea(width, height);
+    double queryRatio;
+    if (queryArea > 0) {
+      queryRatio = intersectionArea / queryArea;
+    } else if (queryExtent.getHeight() > 0) {//vert line
+      queryRatio = height / queryExtent.getHeight();
+    } else if (queryExtent.getWidth() > 0) {//horiz line
+      queryRatio = width / queryExtent.getWidth();
+    } else {
+      queryRatio = queryExtent.relate(target).intersects() ? 1 : 0;//could be optimized
+    }
+
+    double targetArea = calcArea(target.getWidth(), target.getHeight());
+    assert targetArea >= 0;
+    double targetRatio;
+    if (targetArea > 0) {
+      targetRatio = intersectionArea / targetArea;
+    } else if (target.getHeight() > 0) {//vert line
+      targetRatio = height / target.getHeight();
+    } else if (target.getWidth() > 0) {//horiz line
+      targetRatio = width / target.getWidth();
+    } else {
+      targetRatio = target.relate(queryExtent).intersects() ? 1 : 0;//could be optimized
+    }
+    assert queryRatio >= 0 && queryRatio <= 1 : queryRatio;
+    assert targetRatio >= 0 && targetRatio <= 1 : targetRatio;
+
+    // combine ratios into a score
+
+    double queryFactor = queryRatio * queryTargetProportion;
+    double targetFactor = targetRatio * (1.0 - queryTargetProportion);
+    double score = queryFactor + targetFactor;
+
+    if (exp!=null) {
+      String minSideDesc = minSideLength > 0.0 ? " (minSide="+minSideLength+")" : "";
+      exp.set(Explanation.match((float) score,
+          this.getClass().getSimpleName()+": queryFactor + targetFactor",
+          Explanation.match((float)intersectionArea, "IntersectionArea" + minSideDesc,
+              Explanation.match((float)width, "width"),
+              Explanation.match((float)height, "height"),
+              Explanation.match((float)queryTargetProportion, "queryTargetProportion")),
+          Explanation.match((float)queryFactor, "queryFactor",
+              Explanation.match((float)targetRatio, "ratio"),
+              Explanation.match((float)queryArea,  "area of " + queryExtent + minSideDesc)),
+          Explanation.match((float)targetFactor, "targetFactor",
+              Explanation.match((float)targetRatio, "ratio"),
+              Explanation.match((float)targetArea,  "area of " + target + minSideDesc))));
+    }
+
+    return score;
+  }
+
+  /** Calculates the area while applying the minimum side length. */
+  private double calcArea(double width, double height) {
+    return Math.max(minSideLength, width) * Math.max(minSideLength, height);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxSimilarityValueSource.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxSimilarityValueSource.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxSimilarityValueSource.java
new file mode 100644
index 0000000..15cd646
--- /dev/null
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxSimilarityValueSource.java
@@ -0,0 +1,117 @@
+/*
+ * 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.bbox;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
+import org.apache.lucene.search.Explanation;
+import org.apache.lucene.search.IndexSearcher;
+
+import com.spatial4j.core.shape.Rectangle;
+
+/**
+ * A base class for calculating a spatial relevance rank per document from a provided
+ * {@link ValueSource} in which {@link FunctionValues#objectVal(int)} returns a {@link
+ * com.spatial4j.core.shape.Rectangle}.
+ * <p>
+ * Implementers: remember to implement equals and hashCode if you have
+ * fields!
+ *
+ * @lucene.experimental
+ */
+public abstract class BBoxSimilarityValueSource extends ValueSource {
+
+  private final ValueSource bboxValueSource;
+
+  public BBoxSimilarityValueSource(ValueSource bboxValueSource) {
+    this.bboxValueSource = bboxValueSource;
+  }
+
+  @Override
+  public void createWeight(Map context, IndexSearcher searcher) throws IOException {
+    bboxValueSource.createWeight(context, searcher);
+  }
+
+  @Override
+  public String description() {
+    return getClass().getSimpleName()+"(" + bboxValueSource.description() + "," + similarityDescription() + ")";
+  }
+
+  /** A comma-separated list of configurable items of the subclass to put into {@link #description()}. */
+  protected abstract String similarityDescription();
+
+  @Override
+  public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
+
+    final FunctionValues shapeValues = bboxValueSource.getValues(context, readerContext);
+
+    return new DoubleDocValues(this) {
+      @Override
+      public double doubleVal(int doc) {
+        //? limit to Rect or call getBoundingBox()? latter would encourage bad practice
+        final Rectangle rect = (Rectangle) shapeValues.objectVal(doc);
+        return rect==null ? 0 : score(rect, null);
+      }
+
+      @Override
+      public boolean exists(int doc) {
+        return shapeValues.exists(doc);
+      }
+
+      @Override
+      public Explanation explain(int doc) {
+        final Rectangle rect = (Rectangle) shapeValues.objectVal(doc);
+        if (rect == null)
+          return Explanation.noMatch("no rect");
+        AtomicReference<Explanation> explanation = new AtomicReference<>();
+        score(rect, explanation);
+        return explanation.get();
+      }
+    };
+  }
+
+  /**
+   * Return a relevancy score. If {@code exp} is provided then diagnostic information is added.
+   * @param rect The indexed rectangle; not null.
+   * @param exp Optional diagnostic holder.
+   * @return a score.
+   */
+  protected abstract double score(Rectangle rect, AtomicReference<Explanation> exp);
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;//same class
+
+    BBoxSimilarityValueSource that = (BBoxSimilarityValueSource) o;
+
+    if (!bboxValueSource.equals(that.bboxValueSource)) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    return bboxValueSource.hashCode();
+  }
+}


[13/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial/src/test-files/data/countries-bbox.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test-files/data/countries-bbox.txt b/lucene/spatial/src/test-files/data/countries-bbox.txt
deleted file mode 100644
index 78e14e0..0000000
--- a/lucene/spatial/src/test-files/data/countries-bbox.txt
+++ /dev/null
@@ -1,249 +0,0 @@
-#id	name	shape	
-FLK	Falkland Is.	ENVELOPE(-61.148055, -57.733200, -51.249455, -52.343055)
-GUF	French Guiana	ENVELOPE(-54.603782, -51.648055, 5.755418, 2.113473)
-GUY	Guyana	ENVELOPE(-61.389727, -56.470636, 8.535273, 1.186873)
-PCN	Pitcairn Is.	ENVELOPE(-130.105055, -128.286118, -24.325836, -25.082227)
-SGS	South Georgia & the South Sandwich Is.	ENVELOPE(-38.023755, -26.241391, -53.989727, -58.498609)
-SHN	St. Helena	ENVELOPE(-5.792782, -5.645282, -15.903755, -16.021946)
-SUR	Suriname	ENVELOPE(-58.071400, -53.986118, 6.001809, 1.836245)
-TTO	Trinidad & Tobago	ENVELOPE(-61.921600, -60.520836, 11.345554, 10.040345)
-VEN	Venezuela	ENVELOPE(-73.378064, -59.803055, 12.197500, 0.649164)
-ASM	American Samoa	ENVELOPE(-170.823227, -170.561873, -14.254309, -14.375555)
-COK	Cook Is.	ENVELOPE(-165.848345, -157.703764, -10.881318, -21.940836)
-PYF	French Polynesia	ENVELOPE(-151.497773, -138.809755, -8.778191, -17.870836)
-UMI	Jarvis I.	ENVELOPE(-160.045164, -160.009464, -0.374309, -0.398055)
-NIU	Niue	ENVELOPE(-169.952236, -169.781555, -18.963336, -19.145555)
-WSM	Samoa	ENVELOPE(-172.780027, -171.429200, -13.460555, -14.057500)
-TKL	Tokelau	ENVELOPE(-171.862718, -171.843764, -9.170627, -9.218891)
-TON	Tonga	ENVELOPE(-175.360000, -173.906827, -18.568055, -21.268064)
-WLF	Wallis & Futuna	ENVELOPE(-178.190273, -176.121936, -13.214864, -14.323891)
-ARG	Argentina	ENVELOPE(-73.582300, -53.650009, -21.780518, -55.051673)
-BOL	Bolivia	ENVELOPE(-69.656191, -57.521118, -9.679191, -22.901109)
-BRA	Brazil	ENVELOPE(-74.004591, -34.792918, 5.272709, -33.741118)
-CHL	Chile	ENVELOPE(-109.446109, -66.420627, -17.505282, -55.902227)
-ECU	Ecuador	ENVELOPE(-91.663891, -75.216846, 1.437782, -5.000309)
-PRY	Paraguay	ENVELOPE(-62.643773, -54.243900, -19.296809, -27.584727)
-PER	Peru	ENVELOPE(-81.355146, -68.673909, -0.036873, -18.348546)
-URY	Uruguay	ENVELOPE(-58.438609, -53.098300, -30.096673, -34.943818)
-UMI	Baker I.	ENVELOPE(-176.467655, -176.455855, 0.222573, 0.215282)
-CAN	Canada	ENVELOPE(-141.002991, -52.617364, 83.113873, 41.675554)
-GTM	Guatemala	ENVELOPE(-92.246782, -88.214736, 17.821109, 13.745836)
-UMI	Howland I.	ENVELOPE(-176.643082, -176.631091, 0.808609, 0.790282)
-UMI	Johnston Atoll	ENVELOPE(-169.538936, -169.523927, 16.730273, 16.724164)
-MEX	Mexico	ENVELOPE(-118.404164, -86.738618, 32.718454, 14.550545)
-UMI	Midway Is.	ENVELOPE(-177.395845, -177.360545, 28.221518, 28.184154)
-BRB	Barbados	ENVELOPE(-59.659446, -59.427082, 13.337082, 13.050554)
-DMA	Dominica	ENVELOPE(-61.491391, -61.250700, 15.631945, 15.198054)
-GRD	Grenada	ENVELOPE(-61.785182, -61.596391, 12.237154, 11.996945)
-GLP	Guadeloupe	ENVELOPE(-61.796109, -61.187082, 16.512918, 15.870000)
-MTQ	Martinique	ENVELOPE(-61.231536, -60.816946, 14.880136, 14.402773)
-LCA	St. Lucia	ENVELOPE(-61.079582, -60.878064, 14.109309, 13.709445)
-SPM	St. Pierre & Miquelon	ENVELOPE(-56.397782, -56.145500, 47.135827, 46.747191)
-VCT	St. Vincent & the Grenadines	ENVELOPE(-61.280146, -61.120282, 13.383191, 13.130282)
-ABW	Aruba	ENVELOPE(-70.059664, -69.874864, 12.627773, 12.411109)
-BMU	Bermuda	ENVELOPE(-64.823064, -64.676809, 32.379509, 32.260554)
-DOM	Dominican Republic	ENVELOPE(-72.003064, -68.322927, 19.930827, 17.604164)
-HTI	Haiti	ENVELOPE(-74.467791, -71.629182, 20.091454, 18.022782)
-JAM	Jamaica	ENVELOPE(-78.373900, -76.221118, 18.522500, 17.697218)
-ANT	Netherlands Antilles	ENVELOPE(-69.163618, -68.192927, 12.383891, 12.020554)
-BHS	The Bahamas	ENVELOPE(-78.978900, -72.738891, 26.929164, 20.915273)
-TCA	Turks & Caicos Is.	ENVELOPE(-72.031464, -71.127573, 21.957773, 21.429918)
-BLZ	Belize	ENVELOPE(-89.216400, -87.779591, 18.489900, 15.889854)
-CYM	Cayman Is.	ENVELOPE(-81.400836, -81.093064, 19.354164, 19.265000)
-COL	Colombia	ENVELOPE(-81.720146, -66.870455, 12.590273, -4.236873)
-CRI	Costa Rica	ENVELOPE(-85.911391, -82.561400, 11.212845, 8.025673)
-CUB	Cuba	ENVELOPE(-84.952927, -74.131255, 23.194027, 19.821945)
-SLV	El Salvador	ENVELOPE(-90.108064, -87.694673, 14.431982, 13.156391)
-HND	Honduras	ENVELOPE(-89.350491, -83.131855, 16.435827, 12.985173)
-NIC	Nicaragua	ENVELOPE(-87.689827, -83.131855, 15.022218, 10.709691)
-PAN	Panama	ENVELOPE(-83.030291, -77.198336, 9.620136, 7.206109)
-AIA	Anguilla	ENVELOPE(-63.167782, -62.972709, 18.272982, 18.164445)
-ATG	Antigua & Barbuda	ENVELOPE(-61.891109, -61.666946, 17.724300, 16.989718)
-VGB	British Virgin Is.	ENVELOPE(-64.698482, -64.324527, 18.504854, 18.383891)
-MSR	Montserrat	ENVELOPE(-62.236946, -62.138891, 16.812354, 16.671391)
-PRI	Puerto Rico	ENVELOPE(-67.266400, -65.301118, 18.519445, 17.922218)
-KNA	St. Kitts & Nevis	ENVELOPE(-62.862782, -62.622509, 17.410136, 17.208882)
-VIR	Virgin Is.	ENVELOPE(-65.023509, -64.562573, 18.387673, 17.676664)
-FRO	Faroe Is.	ENVELOPE(-7.433473, -6.389718, 62.357500, 61.388327)
-GRL	Greenland	ENVELOPE(-73.053609, -12.157637, 83.623600, 59.790273)
-XGK	Guernsey	ENVELOPE(-2.668609, -2.500973, 49.508191, 49.422491)
-ISL	Iceland	ENVELOPE(-24.538400, -13.499446, 66.536100, 63.390000)
-IRL	Ireland	ENVELOPE(-10.474727, -6.013055, 55.379991, 51.445545)
-XIM	Isle of Man	ENVELOPE(-4.787155, -4.308682, 54.416382, 54.055545)
-SJM	Jan Mayen	ENVELOPE(-9.119909, -7.928509, 71.180818, 70.803863)
-XJE	Jersey	ENVELOPE(-2.247364, -2.015000, 49.261109, 49.167773)
-GBR	United Kingdom	ENVELOPE(-8.171664, 1.749445, 60.843327, 49.955273)
-CPV	Cape Verde	ENVELOPE(-25.360555, -22.666109, 17.192364, 14.811109)
-CIV	Cote d'Ivoire	ENVELOPE(-8.606382, -2.487782, 10.735254, 4.344718)
-GHA	Ghana	ENVELOPE(-3.248891, 1.202782, 11.155691, 4.727082)
-GIB	Gibraltar	ENVELOPE(-5.356173, -5.334509, 36.163309, 36.112073)
-LBR	Liberia	ENVELOPE(-11.492327, -7.368400, 8.512782, 4.343609)
-MAR	Morocco	ENVELOPE(-13.174964, -1.011809, 35.919164, 27.664236)
-PRT	Portugal	ENVELOPE(-31.289027, -6.190455, 42.150673, 32.637500)
-ESP	Spain	ENVELOPE(-18.169864, 4.316945, 43.764300, 27.637500)
-ESH	Western Sahara	ENVELOPE(-17.101527, -8.666391, 27.666954, 20.764100)
-BFA	Burkina Faso	ENVELOPE(-5.520837, 2.397927, 15.082773, 9.395691)
-GIN	Guinea	ENVELOPE(-15.080837, -7.653373, 12.677500, 7.193927)
-GNB	Guinea-Bissau	ENVELOPE(-16.717773, -13.643891, 12.684718, 10.925100)
-MLI	Mali	ENVELOPE(-12.244837, 4.251391, 25.000273, 10.142154)
-MRT	Mauritania	ENVELOPE(-17.075555, -4.806109, 27.290454, 14.725636)
-SEN	Senegal	ENVELOPE(-17.532782, -11.369927, 16.690618, 12.301745)
-SLE	Sierra Leone	ENVELOPE(-13.295609, -10.264309, 9.997500, 6.923609)
-GMB	The Gambia	ENVELOPE(-16.821664, -13.798609, 13.826391, 13.059973)
-DJI	Djibouti	ENVELOPE(41.759854, 43.420409, 12.708327, 10.942218)
-ERI	Eritrea	ENVELOPE(36.443282, 43.121382, 17.994882, 12.363891)
-ETH	Ethiopia	ENVELOPE(32.991800, 47.988245, 14.883609, 3.406664)
-MNG	Mongolia	ENVELOPE(87.761100, 119.931509, 52.142773, 41.586654)
-SDN	Sudan	ENVELOPE(21.829100, 38.607500, 22.232218, 3.493391)
-UGA	Uganda	ENVELOPE(29.574300, 35.009718, 4.222782, -1.476109)
-ISR	Gaza Strip	ENVELOPE(34.216663, 34.558891, 31.596100, 31.216545)
-IRQ	Iraq	ENVELOPE(38.794700, 48.560691, 37.383673, 29.061664)
-ISR	Israel	ENVELOPE(34.267582, 35.681109, 33.270273, 29.486709)
-JOR	Jordan	ENVELOPE(34.960418, 39.301109, 33.377591, 29.188891)
-KAZ	Kazakhstan	ENVELOPE(46.499163, 87.348209, 55.442627, 40.594436)
-NOR	Norway	ENVELOPE(4.789582, 31.073536, 71.154709, 57.987918)
-RUS	Russia	ENVELOPE(-180.000000, 180.000000, 81.851927, 41.196582)
-SWE	Sweden	ENVELOPE(11.113336, 24.167009, 69.060300, 55.339164)
-ISR	West Bank	ENVELOPE(34.888191, 35.570609, 32.546391, 31.350691)
-DZA	Algeria	ENVELOPE(-8.667218, 11.986473, 37.089854, 18.976391)
-AND	Andorra	ENVELOPE(1.421391, 1.781718, 42.655964, 42.436382)
-CMR	Cameroon	ENVELOPE(8.502363, 16.207000, 13.085000, 1.654164)
-CAF	Central African Republic	ENVELOPE(14.418891, 27.459718, 11.000836, 2.221264)
-LBY	Libya	ENVELOPE(9.311391, 25.151663, 33.171136, 19.499064)
-MCO	Monaco	ENVELOPE(7.390900, 7.439291, 43.768300, 43.727545)
-TUN	Tunisia	ENVELOPE(7.492218, 11.581663, 37.340409, 30.234391)
-BEN	Benin	ENVELOPE(0.776663, 3.855000, 12.396654, 6.218718)
-TCD	Chad	ENVELOPE(13.461945, 24.002745, 23.450554, 7.458536)
-GNQ	Equatorial Guinea	ENVELOPE(8.424163, 11.353891, 3.763336, 0.930154)
-KIR	Kiribati	ENVELOPE(-157.581700, 172.947509, 2.033054, 1.335991)
-NER	Niger	ENVELOPE(0.166663, 15.996663, 23.522309, 11.693273)
-NGA	Nigeria	ENVELOPE(2.692500, 14.649654, 13.891500, 4.272845)
-STP	Sao Tome & Principe	ENVELOPE(6.465136, 7.463473, 1.701245, 0.018336)
-TGO	Togo	ENVELOPE(-0.149764, 1.797800, 11.138536, 6.100545)
-ALB	Albania	ENVELOPE(19.288536, 21.053327, 42.660345, 39.645000)
-BIH	Bosnia & Herzegovina	ENVELOPE(15.740591, 19.619782, 45.265945, 42.565827)
-HRV	Croatia	ENVELOPE(13.504791, 19.425000, 46.535827, 42.399991)
-ITA	Italy	ENVELOPE(6.623963, 18.514445, 47.094582, 36.649164)
-MKD	Macedonia	ENVELOPE(20.458818, 23.030973, 42.358954, 40.855891)
-MLT	Malta	ENVELOPE(14.329100, 14.570000, 35.991936, 35.800000)
-SMR	San Marino	ENVELOPE(12.406945, 12.511109, 43.986873, 43.898682)
-SMN	Serbia & Montenegro	ENVELOPE(18.453327, 23.005000, 46.181109, 41.849000)
-VTC	Vatican City	ENVELOPE(12.444473, 12.457718, 41.908391, 41.900891)
-BGR	Bulgaria	ENVELOPE(22.365273, 28.605136, 44.224718, 41.243045)
-CYP	Cyprus	ENVELOPE(32.269863, 34.586036, 35.688609, 34.640273)
-EGY	Egypt	ENVELOPE(24.706800, 36.895827, 31.646945, 21.994164)
-GEO	Georgia	ENVELOPE(40.002963, 46.710818, 43.584718, 41.048045)
-GRC	Greece	ENVELOPE(19.640000, 28.238045, 41.747773, 34.930545)
-LBN	Lebanon	ENVELOPE(35.100827, 36.623745, 34.647500, 33.062082)
-SYR	Syria	ENVELOPE(35.614463, 42.378327, 37.290545, 32.313609)
-TUR	Turkey	ENVELOPE(25.665827, 44.820545, 42.109991, 35.818445)
-AUT	Austria	ENVELOPE(9.533573, 17.166382, 49.018745, 46.407491)
-CZE	Czech Republic	ENVELOPE(12.093700, 18.852218, 51.052491, 48.581382)
-DNK	Denmark	ENVELOPE(8.092918, 15.149163, 57.745973, 54.561936)
-HUN	Hungary	ENVELOPE(16.111800, 22.894800, 48.576173, 45.748327)
-POL	Poland	ENVELOPE(14.147636, 24.143473, 54.836036, 49.002918)
-SVK	Slovakia	ENVELOPE(16.844718, 22.558054, 49.600827, 47.737500)
-SVN	Slovenia	ENVELOPE(13.383473, 16.607873, 46.876245, 45.425818)
-SJM	Svalbard	ENVELOPE(10.487918, 33.637500, 80.764163, 74.343045)
-BEL	Belgium	ENVELOPE(2.541663, 6.398200, 51.501245, 49.508882)
-FRA	France	ENVELOPE(-4.790282, 9.562218, 51.091109, 41.364927)
-DEU	Germany	ENVELOPE(5.865000, 15.033818, 55.056527, 47.274718)
-LIE	Liechtenstein	ENVELOPE(9.474636, 9.633891, 47.274545, 47.057454)
-LUX	Luxembourg	ENVELOPE(5.734445, 6.524027, 50.181809, 49.448464)
-NLD	Netherlands	ENVELOPE(3.370863, 7.210973, 53.465827, 50.753882)
-CHE	Switzerland	ENVELOPE(5.967009, 10.488209, 47.806664, 45.829436)
-USA	United States	ENVELOPE(-178.216555, 179.775936, 71.351436, 18.925482)
-BLR	Belarus	ENVELOPE(23.165400, 32.740054, 56.167491, 51.251845)
-EST	Estonia	ENVELOPE(21.837354, 28.194091, 59.664718, 57.522636)
-FIN	Finland	ENVELOPE(19.511391, 31.581963, 70.088609, 59.806800)
-LVA	Latvia	ENVELOPE(20.968609, 28.235963, 58.083254, 55.674836)
-LTU	Lithuania	ENVELOPE(20.942836, 26.813054, 56.449854, 53.890336)
-MDA	Moldova	ENVELOPE(26.634991, 30.128709, 48.468318, 45.448645)
-ROM	Romania	ENVELOPE(20.261027, 29.672218, 48.263882, 43.623309)
-UKR	Ukraine	ENVELOPE(22.151445, 40.178745, 52.378600, 44.379154)
-IND	India	ENVELOPE(68.144227, 97.380536, 35.505618, 6.745827)
-MDV	Maldives	ENVELOPE(72.863391, 73.637272, 7.027773, -0.641664)
-OMN	Oman	ENVELOPE(51.999291, 59.847082, 26.368709, 16.642782)
-SOM	Somalia	ENVELOPE(40.988609, 51.411318, 11.979164, -1.674873)
-LKA	Sri Lanka	ENVELOPE(79.696091, 81.891663, 9.828191, 5.918054)
-TKM	Turkmenistan	ENVELOPE(51.250182, 66.670882, 42.796173, 35.145991)
-UZB	Uzbekistan	ENVELOPE(55.997491, 73.167545, 45.570591, 37.184991)
-YEM	Yemen	ENVELOPE(42.555973, 54.473473, 18.999345, 12.144718)
-ARM	Armenia	ENVELOPE(43.454163, 46.620536, 41.297054, 38.841145)
-AZE	Azerbaijan	ENVELOPE(44.778863, 51.677009, 42.710754, 38.262809)
-BHR	Bahrain	ENVELOPE(50.453327, 50.796391, 26.288891, 25.571945)
-IRN	Iran	ENVELOPE(44.034954, 63.330273, 39.779154, 25.075973)
-KWT	Kuwait	ENVELOPE(46.546945, 48.416591, 30.084164, 28.538882)
-QAT	Qatar	ENVELOPE(50.751936, 51.615827, 26.152500, 24.556045)
-SAU	Saudi Arabia	ENVELOPE(34.572145, 55.666109, 32.154945, 16.377500)
-ARE	United Arab Emirates	ENVELOPE(51.583327, 56.381663, 26.083882, 22.633327)
-AFG	Afghanistan	ENVELOPE(60.504163, 74.915736, 38.471982, 29.406109)
-KGZ	Kyrgyzstan	ENVELOPE(69.249500, 80.281582, 43.216900, 39.195473)
-NPL	Nepal	ENVELOPE(80.052200, 88.194554, 30.424718, 26.368364)
-PAK	Pakistan	ENVELOPE(60.866300, 77.823927, 37.060791, 23.688045)
-TJK	Tajikistan	ENVELOPE(67.364700, 75.187482, 41.049254, 36.671845)
-BGD	Bangladesh	ENVELOPE(88.043872, 92.669345, 26.626136, 20.744818)
-BTN	Bhutan	ENVELOPE(88.751936, 92.114218, 28.325000, 26.703609)
-BRN	Brunei	ENVELOPE(114.095082, 115.360263, 5.053054, 4.018191)
-CHN	China	ENVELOPE(73.620045, 134.768463, 53.553745, 18.168882)
-JPN	Japan	ENVELOPE(123.678863, 145.812409, 45.486382, 24.251391)
-PRK	North Korea	ENVELOPE(124.323954, 130.697418, 43.006100, 37.671382)
-PLW	Palau	ENVELOPE(134.452482, 134.658872, 7.729445, 7.305254)
-PHL	Philippines	ENVELOPE(116.950000, 126.598036, 19.391109, 5.049164)
-KOR	South Korea	ENVELOPE(126.099018, 129.586872, 38.625245, 33.192209)
-KHM	Cambodia	ENVELOPE(102.346509, 107.636382, 14.708618, 10.422736)
-LAO	Laos	ENVELOPE(100.091372, 107.695254, 22.499927, 13.926664)
-MYS	Malaysia	ENVELOPE(99.641936, 119.275818, 7.352918, 0.852782)
-MMR	Myanmar	ENVELOPE(92.204991, 101.169427, 28.546527, 9.839582)
-SGP	Singapore	ENVELOPE(103.640945, 103.997945, 1.445282, 1.259027)
-THA	Thailand	ENVELOPE(97.347272, 105.639291, 20.454582, 5.633473)
-VNM	Vietnam	ENVELOPE(102.140745, 109.464845, 23.324164, 8.559236)
-GUM	Guam	ENVELOPE(144.634154, 144.953309, 13.652291, 13.235000)
-MHL	Marshall Is.	ENVELOPE(162.324963, 171.378063, 14.594027, 5.600273)
-FSM	Micronesia	ENVELOPE(158.120100, 163.042891, 6.977636, 5.261664)
-MNP	Northern Mariana Is.	ENVELOPE(145.572682, 145.818082, 15.268191, 14.908054)
-UMI	Wake I.	ENVELOPE(166.608981, 166.662200, 19.324582, 19.279445)
-BWA	Botswana	ENVELOPE(19.996109, 29.373618, -17.782082, -26.875555)
-BDI	Burundi	ENVELOPE(28.985000, 30.853191, -2.301564, -4.448055)
-ATF	French Southern & Antarctic Lands	ENVELOPE(51.650836, 70.567491, -46.327645, -49.725009)
-HMD	Heard I. & McDonald Is.	ENVELOPE(73.234709, 73.773882, -52.965145, -53.199445)
-KEN	Kenya	ENVELOPE(33.907218, 41.905163, 4.622500, -4.669618)
-RWA	Rwanda	ENVELOPE(28.854445, 30.893263, -1.054446, -2.825491)
-TZA	Tanzania	ENVELOPE(29.340827, 40.436809, -0.997218, -11.740418)
-ZMB	Zambia	ENVELOPE(21.996391, 33.702282, -8.191664, -18.074918)
-ZWE	Zimbabwe	ENVELOPE(25.237918, 33.071591, -15.616527, -22.414764)
-ATA	Antarctica	ENVELOPE(-180.000000, 180.000000, -60.503336, -90.000000)
-NOR	Bouvet I.	ENVELOPE(3.342363, 3.484163, -54.383609, -54.462782)
-COM	Comoros	ENVELOPE(43.214027, 44.530418, -11.366946, -12.383055)
-REU	Juan De Nova I.	ENVELOPE(42.723818, 42.760900, -17.052018, -17.076118)
-LSO	Lesotho	ENVELOPE(27.013973, 29.455554, -28.570691, -30.650527)
-MWI	Malawi	ENVELOPE(32.681873, 35.920963, -9.376673, -17.135282)
-MOZ	Mozambique	ENVELOPE(30.213018, 40.846109, -10.471109, -26.860282)
-ZAF	South Africa	ENVELOPE(16.483327, 37.892218, -22.136391, -46.969727)
-SWZ	Swaziland	ENVELOPE(30.798336, 32.133400, -25.728336, -27.316391)
-AGO	Angola	ENVELOPE(11.731245, 24.084445, -4.388991, -18.016391)
-COG	Congo	ENVELOPE(11.140663, 18.643609, 3.711109, -5.015000)
-ZAR	Congo, DRC	ENVELOPE(12.214554, 31.302773, 5.380691, -13.458055)
-FJI	Fiji	ENVELOPE(-180.000000, 180.000000, -16.153473, -19.162782)
-GAB	Gabon	ENVELOPE(8.700836, 14.519582, 2.317900, -3.925282)
-NAM	Namibia	ENVELOPE(11.716391, 25.264427, -16.954173, -28.961873)
-NZL	New Zealand	ENVELOPE(-176.848755, 178.841063, -34.414718, -52.578055)
-IOT	British Indian Ocean Territory	ENVELOPE(72.357900, 72.494282, -7.233473, -7.436246)
-REU	Glorioso Is.	ENVELOPE(47.279091, 47.303054, -11.554100, -11.577782)
-MDG	Madagascar	ENVELOPE(43.236827, 50.501391, -11.945555, -25.588336)
-MUS	Mauritius	ENVELOPE(57.306309, 63.495754, -19.673336, -20.520555)
-MYT	Mayotte	ENVELOPE(45.039163, 45.293345, -12.662500, -12.992500)
-REU	Reunion	ENVELOPE(55.220554, 55.853054, -20.856527, -21.373891)
-SYC	Seychelles	ENVELOPE(46.205691, 55.540554, -4.551664, -9.463055)
-CXR	Christmas I.	ENVELOPE(105.629000, 105.751900, -10.384082, -10.510973)
-CCK	Cocos Is.	ENVELOPE(96.817491, 96.864845, -12.130418, -12.199446)
-IDN	Indonesia	ENVELOPE(95.210945, 141.007018, 5.913473, -10.929655)
-TLS	Timor Leste	ENVELOPE(124.046100, 127.308591, -8.140000, -9.463627)
-AUS	Australia	ENVELOPE(112.907209, 158.960372, -10.135691, -54.753891)
-NRU	Nauru	ENVELOPE(166.904418, 166.957045, -0.493336, -0.552218)
-NCL	New Caledonia	ENVELOPE(163.982745, 168.130509, -20.087918, -22.673891)
-NFK	Norfolk I.	ENVELOPE(167.910945, 167.998872, -29.000555, -29.081109)
-PNG	Papua New Guinea	ENVELOPE(140.858854, 155.966845, -1.355282, -11.642500)
-SLB	Solomon Is.	ENVELOPE(155.671300, 166.931836, -6.605518, -11.845836)
-TUV	Tuvalu	ENVELOPE(176.295254, 179.232281, -6.089446, -8.561291)
-VUT	Vanuatu	ENVELOPE(166.521636, 169.893863, -13.707218, -20.254173)


[04/50] [abbrv] lucene-solr git commit: SOLR-8696: Straighten out calls to ZkStateReader#createClusterStateWatchersAndUpdate.

Posted by ho...@apache.org.
SOLR-8696: Straighten out calls to ZkStateReader#createClusterStateWatchersAndUpdate.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/a9aec242
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/a9aec242
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/a9aec242

Branch: refs/heads/jira/SOLR-445
Commit: a9aec24236df61a3f1cfe533b64169fae84fc6f7
Parents: 3cc8b6f
Author: Mark Miller <ma...@gmail.com>
Authored: Mon Feb 29 13:08:33 2016 -0800
Committer: Mark Miller <ma...@gmail.com>
Committed: Mon Feb 29 13:09:09 2016 -0800

----------------------------------------------------------------------
 solr/core/src/java/org/apache/solr/cloud/ZkController.java | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a9aec242/solr/core/src/java/org/apache/solr/cloud/ZkController.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkController.java b/solr/core/src/java/org/apache/solr/cloud/ZkController.java
index f136307..2547f3b 100644
--- a/solr/core/src/java/org/apache/solr/cloud/ZkController.java
+++ b/solr/core/src/java/org/apache/solr/cloud/ZkController.java
@@ -254,6 +254,8 @@ public final class ZkController {
             log.info("ZooKeeper session re-connected ... refreshing core states after session expiration.");
 
             try {
+              zkStateReader.createClusterStateWatchersAndUpdate();
+
               // this is troublesome - we dont want to kill anything the old
               // leader accepted
               // though I guess sync will likely get those updates back? But
@@ -283,8 +285,6 @@ public final class ZkController {
 
               registerAllCoresAsDown(registerOnReconnect, false);
 
-              zkStateReader.createClusterStateWatchersAndUpdate();
-
               // we have to register as live first to pick up docs in the buffer
               createEphemeralLiveNode();
 
@@ -620,6 +620,7 @@ public final class ZkController {
 
     try {
       createClusterZkNodes(zkClient);
+      zkStateReader.createClusterStateWatchersAndUpdate();
 
       // start the overseer first as following code may need it's processing
       if (!zkRunOnly) {
@@ -632,10 +633,8 @@ public final class ZkController {
         overseerElector.joinElection(context, false);
       }
 
-      zkStateReader.createClusterStateWatchersAndUpdate();
       Stat stat = zkClient.exists(ZkStateReader.LIVE_NODES_ZKNODE, null, true);
       if (stat != null && stat.getNumChildren() > 0) {
-        zkStateReader.createClusterStateWatchersAndUpdate();
         publishAndWaitForDownStates();
       }
 


[21/50] [abbrv] lucene-solr git commit: LUCENE-7015: Refactor spatial module to spatial-extras

Posted by ho...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test-files/simple-Queries-BBox.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test-files/simple-Queries-BBox.txt b/lucene/spatial-extras/src/test-files/simple-Queries-BBox.txt
new file mode 100644
index 0000000..9f3d5b0
--- /dev/null
+++ b/lucene/spatial-extras/src/test-files/simple-Queries-BBox.txt
@@ -0,0 +1,9 @@
+C5 @ IsWithin(ENVELOPE(-6, 6, 6, -6))
+C5 @ BBoxWithin(ENVELOPE(-6, 6, 6, -6))
+C10 @ Contains(ENVELOPE(-6, 6, 6, -6))
+C10 @ IsEqualTo(ENVELOPE(-10, 10, 10, -10))
+C5 C10 @ Intersects(ENVELOPE(-2, 2, 2, -2))
+ @ Overlaps(ENVELOPE(-2, 2, 2, -2))
+C5 @ Overlaps(ENVELOPE(-2, 2, 8, -2))
+C5 C10 @ BBoxIntersects(ENVELOPE(-2, 2, 2, -2))
+NW15 @ IsDisjointTo(ENVELOPE(-10, 10, 10, -10))
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test-files/states-Intersects-BBox.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test-files/states-Intersects-BBox.txt b/lucene/spatial-extras/src/test-files/states-Intersects-BBox.txt
new file mode 100644
index 0000000..a45df7b
--- /dev/null
+++ b/lucene/spatial-extras/src/test-files/states-Intersects-BBox.txt
@@ -0,0 +1,3 @@
+WY CO	@ Intersects(ENVELOPE(-106.964844, -105.734375, 42.800781, 39.460938))
+TX @ Intersects(ENVELOPE(-99.669922, -98.439453, 32.253906, 30.583984))
+MS TX LA @ Intersects(ENVELOPE(-95.363281, -90.133789, 32.473633, 29.792969))
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test-files/states-IsWithin-BBox.txt
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test-files/states-IsWithin-BBox.txt b/lucene/spatial-extras/src/test-files/states-IsWithin-BBox.txt
new file mode 100644
index 0000000..6a504da
--- /dev/null
+++ b/lucene/spatial-extras/src/test-files/states-IsWithin-BBox.txt
@@ -0,0 +1,4 @@
+KS	@ IsWithin(ENVELOPE(-103.493164, -93.825195, 41.086914, 36.208984))
+WA @ IsWithin(ENVELOPE(-126.916016, -115.314453, 50.688965, 44.36084))
+MA CT RI @ IsWithin(ENVELOPE(-73.894043, -69.521484, 43.198242, 40.825195))
+AL GA @ IsWithin(ENVELOPE(-89.472656, -80.244141, 35.90332, 29.311523))
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/DistanceStrategyTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/DistanceStrategyTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/DistanceStrategyTest.java
new file mode 100644
index 0000000..9a29677
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/DistanceStrategyTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.document.FieldType;
+import org.apache.lucene.index.IndexOptions;
+import org.apache.lucene.spatial.bbox.BBoxStrategy;
+import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
+import org.apache.lucene.spatial.prefix.TermQueryPrefixTreeStrategy;
+import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.PackedQuadPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.spatial.serialized.SerializedDVStrategy;
+import org.apache.lucene.spatial.vector.PointVectorStrategy;
+import org.junit.Test;
+
+public class DistanceStrategyTest extends StrategyTestCase {
+  @ParametersFactory(argumentFormatting = "strategy=%s")
+  public static Iterable<Object[]> parameters() {
+    List<Object[]> ctorArgs = new ArrayList<>();
+
+    SpatialContext ctx = SpatialContext.GEO;
+    SpatialPrefixTree grid;
+    SpatialStrategy strategy;
+
+    grid = new QuadPrefixTree(ctx,25);
+    strategy = new RecursivePrefixTreeStrategy(grid, "recursive_quad");
+    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
+
+    grid = new GeohashPrefixTree(ctx,12);
+    strategy = new TermQueryPrefixTreeStrategy(grid, "termquery_geohash");
+    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
+
+    grid = new PackedQuadPrefixTree(ctx,25);
+    strategy = new RecursivePrefixTreeStrategy(grid, "recursive_packedquad");
+    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
+
+    strategy = new PointVectorStrategy(ctx, "pointvector");
+    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
+
+    strategy = new BBoxStrategy(ctx, "bbox");
+    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
+
+    strategy = new SerializedDVStrategy(ctx, "serialized");
+    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
+
+    return ctorArgs;
+  }
+
+  public DistanceStrategyTest(String suiteName, SpatialStrategy strategy) {
+    this.ctx = strategy.getSpatialContext();
+    this.strategy = strategy;
+  }
+
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    if (strategy instanceof BBoxStrategy && random().nextBoolean()) {//disable indexing sometimes
+      BBoxStrategy bboxStrategy = (BBoxStrategy)strategy;
+      final FieldType fieldType = new FieldType(bboxStrategy.getFieldType());
+      fieldType.setIndexOptions(IndexOptions.NONE);
+      bboxStrategy.setFieldType(fieldType);
+    }
+  }
+
+  @Override
+  protected boolean needsDocValues() {
+    return true;
+  }
+
+  @Test
+  public void testDistanceOrder() throws IOException {
+    adoc("100", ctx.makePoint(2, 1));
+    adoc("101", ctx.makePoint(-1, 4));
+    adoc("103", (Shape)null);//test score for nothing
+    adoc("999", ctx.makePoint(2, 1));//test deleted
+    commit();
+    deleteDoc("999");
+    commit();
+    //FYI distances are in docid order
+    checkDistValueSource(ctx.makePoint(4, 3), 2.8274937f, 5.0898066f, 180f);
+    checkDistValueSource(ctx.makePoint(0, 4), 3.6043684f, 0.9975641f, 180f);
+  }
+
+  @Test
+  public void testRecipScore() throws IOException {
+    Point p100 = ctx.makePoint(2, 1);
+    adoc("100", p100);
+    Point p101 = ctx.makePoint(-1, 4);
+    adoc("101", p101);
+    adoc("103", (Shape)null);//test score for nothing
+    adoc("999", ctx.makePoint(2, 1));//test deleted
+    commit();
+    deleteDoc("999");
+    commit();
+
+    double dist = ctx.getDistCalc().distance(p100, p101);
+    Shape queryShape = ctx.makeCircle(2.01, 0.99, dist);
+    checkValueSource(strategy.makeRecipDistanceValueSource(queryShape),
+        new float[]{1.00f, 0.10f, 0f}, 0.09f);
+  }
+
+  void checkDistValueSource(Point pt, float... distances) throws IOException {
+    float multiplier = random().nextFloat() * 100f;
+    float[] dists2 = Arrays.copyOf(distances, distances.length);
+    for (int i = 0; i < dists2.length; i++) {
+      dists2[i] *= multiplier;
+    }
+    checkValueSource(strategy.makeDistanceValueSource(pt, multiplier), dists2, 1.0e-3f);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/PortedSolr3Test.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/PortedSolr3Test.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/PortedSolr3Test.java
new file mode 100644
index 0000000..8506c86
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/PortedSolr3Test.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.distance.DistanceUtils;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
+import org.apache.lucene.spatial.prefix.TermQueryPrefixTreeStrategy;
+import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.apache.lucene.spatial.vector.PointVectorStrategy;
+import org.junit.Test;
+
+/**
+ * Based off of Solr 3's SpatialFilterTest.
+ */
+public class PortedSolr3Test extends StrategyTestCase {
+
+  @ParametersFactory(argumentFormatting = "strategy=%s")
+  public static Iterable<Object[]> parameters() {
+    List<Object[]> ctorArgs = new ArrayList<>();
+
+    SpatialContext ctx = SpatialContext.GEO;
+    SpatialPrefixTree grid;
+    SpatialStrategy strategy;
+
+    grid = new GeohashPrefixTree(ctx,12);
+    strategy = new RecursivePrefixTreeStrategy(grid, "recursive_geohash");
+    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
+
+    grid = new QuadPrefixTree(ctx,25);
+    strategy = new RecursivePrefixTreeStrategy(grid, "recursive_quad");
+    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
+
+    grid = new GeohashPrefixTree(ctx,12);
+    strategy = new TermQueryPrefixTreeStrategy(grid, "termquery_geohash");
+    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
+
+    strategy = new PointVectorStrategy(ctx, "pointvector");
+    ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
+
+    return ctorArgs;
+  }
+
+  public PortedSolr3Test(String suiteName, SpatialStrategy strategy) {
+    this.ctx = strategy.getSpatialContext();
+    this.strategy = strategy;
+  }
+
+  private void setupDocs() throws Exception {
+    super.deleteAll();
+    adoc("1", ctx.makePoint(-79.9289094, 32.7693246));
+    adoc("2", ctx.makePoint(-80.9289094, 33.7693246));
+    adoc("3", ctx.makePoint(50.9289094, -32.7693246));
+    adoc("4", ctx.makePoint(60.9289094, -50.7693246));
+    adoc("5", ctx.makePoint(0, 0));
+    adoc("6", ctx.makePoint(0.1, 0.1));
+    adoc("7", ctx.makePoint(-0.1, -0.1));
+    adoc("8", ctx.makePoint(179.9, 0));
+    adoc("9", ctx.makePoint(-179.9, 0));
+    adoc("10", ctx.makePoint(50, 89.9));
+    adoc("11", ctx.makePoint(-130, 89.9));
+    adoc("12", ctx.makePoint(50, -89.9));
+    adoc("13", ctx.makePoint(-130, -89.9));
+    commit();
+  }
+
+
+  @Test
+  public void testIntersections() throws Exception {
+    setupDocs();
+    //Try some edge cases
+      //NOTE: 2nd arg is distance in kilometers
+    checkHitsCircle(ctx.makePoint(1, 1), 175, 3, 5, 6, 7);
+    checkHitsCircle(ctx.makePoint(179.8, 0), 200, 2, 8, 9);
+    checkHitsCircle(ctx.makePoint(50, 89.8), 200, 2, 10, 11);//this goes over the north pole
+    checkHitsCircle(ctx.makePoint(50, -89.8), 200, 2, 12, 13);//this goes over the south pole
+    //try some normal cases
+    checkHitsCircle(ctx.makePoint(-80.0, 33.0), 300, 2);
+    //large distance
+    checkHitsCircle(ctx.makePoint(1, 1), 5000, 3, 5, 6, 7);
+    //Because we are generating a box based on the west/east longitudes and the south/north latitudes, which then
+    //translates to a range query, which is slightly more inclusive.  Thus, even though 0.0 is 15.725 kms away,
+    //it will be included, b/c of the box calculation.
+    checkHitsBBox(ctx.makePoint(0.1, 0.1), 15, 2, 5, 6);
+    //try some more
+    deleteAll();
+    adoc("14", ctx.makePoint(5, 0));
+    adoc("15", ctx.makePoint(15, 0));
+    //3000KM from 0,0, see http://www.movable-type.co.uk/scripts/latlong.html
+    adoc("16", ctx.makePoint(19.79750, 18.71111));
+    adoc("17", ctx.makePoint(-95.436643, 44.043900));
+    commit();
+
+    checkHitsCircle(ctx.makePoint(0, 0), 1000, 1, 14);
+    checkHitsCircle(ctx.makePoint(0, 0), 2000, 2, 14, 15);
+    checkHitsBBox(ctx.makePoint(0, 0), 3000, 3, 14, 15, 16);
+    checkHitsCircle(ctx.makePoint(0, 0), 3001, 3, 14, 15, 16);
+    checkHitsCircle(ctx.makePoint(0, 0), 3000.1, 3, 14, 15, 16);
+
+    //really fine grained distance and reflects some of the vagaries of how we are calculating the box
+    checkHitsCircle(ctx.makePoint(-96.789603, 43.517030), 109, 0);
+
+    // falls outside of the real distance, but inside the bounding box
+    checkHitsCircle(ctx.makePoint(-96.789603, 43.517030), 110, 0);
+    checkHitsBBox(ctx.makePoint(-96.789603, 43.517030), 110, 1, 17);
+  }
+
+  //---- these are similar to Solr test methods
+
+  private void checkHitsCircle(Point pt, double distKM, int assertNumFound, int... assertIds) {
+    _checkHits(false, pt, distKM, assertNumFound, assertIds);
+  }
+  private void checkHitsBBox(Point pt, double distKM, int assertNumFound, int... assertIds) {
+    _checkHits(true, pt, distKM, assertNumFound, assertIds);
+  }
+
+  private void _checkHits(boolean bbox, Point pt, double distKM, int assertNumFound, int... assertIds) {
+    SpatialOperation op = SpatialOperation.Intersects;
+    double distDEG = DistanceUtils.dist2Degrees(distKM, DistanceUtils.EARTH_MEAN_RADIUS_KM);
+    Shape shape = ctx.makeCircle(pt, distDEG);
+    if (bbox)
+      shape = shape.getBoundingBox();
+
+    SpatialArgs args = new SpatialArgs(op,shape);
+    //args.setDistPrecision(0.025);
+    Query query = strategy.makeQuery(args);
+    SearchResults results = executeQuery(query, 100);
+    assertEquals(""+shape,assertNumFound,results.numFound);
+    if (assertIds != null) {
+      Set<Integer> resultIds = new HashSet<>();
+      for (SearchResult result : results.results) {
+        resultIds.add(Integer.valueOf(result.document.get("id")));
+      }
+      for (int assertId : assertIds) {
+        assertTrue("has " + assertId, resultIds.contains(assertId));
+      }
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/QueryEqualsHashCodeTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/QueryEqualsHashCodeTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/QueryEqualsHashCodeTest.java
new file mode 100644
index 0000000..b1a5e54
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/QueryEqualsHashCodeTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.spatial.bbox.BBoxStrategy;
+import org.apache.lucene.spatial.composite.CompositeSpatialStrategy;
+import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
+import org.apache.lucene.spatial.prefix.TermQueryPrefixTreeStrategy;
+import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.apache.lucene.spatial.serialized.SerializedDVStrategy;
+import org.apache.lucene.spatial.vector.PointVectorStrategy;
+import org.apache.lucene.util.LuceneTestCase;
+import org.junit.Test;
+
+public class QueryEqualsHashCodeTest extends LuceneTestCase {
+
+  private final SpatialContext ctx = SpatialContext.GEO;
+
+  private SpatialOperation predicate;
+
+  @Test
+  public void testEqualsHashCode() {
+
+    switch (random().nextInt(4)) {//0-3
+      case 0: predicate = SpatialOperation.Contains; break;
+      case 1: predicate = SpatialOperation.IsWithin; break;
+
+      default: predicate = SpatialOperation.Intersects; break;
+    }
+    final SpatialPrefixTree gridQuad = new QuadPrefixTree(ctx,10);
+    final SpatialPrefixTree gridGeohash = new GeohashPrefixTree(ctx,10);
+
+    Collection<SpatialStrategy> strategies = new ArrayList<>();
+    RecursivePrefixTreeStrategy recursive_geohash = new RecursivePrefixTreeStrategy(gridGeohash, "recursive_geohash");
+    strategies.add(recursive_geohash);
+    strategies.add(new TermQueryPrefixTreeStrategy(gridQuad, "termquery_quad"));
+    strategies.add(new PointVectorStrategy(ctx, "pointvector"));
+    strategies.add(new BBoxStrategy(ctx, "bbox"));
+    final SerializedDVStrategy serialized = new SerializedDVStrategy(ctx, "serialized");
+    strategies.add(serialized);
+    strategies.add(new CompositeSpatialStrategy("composite", recursive_geohash, serialized));
+    for (SpatialStrategy strategy : strategies) {
+      testEqualsHashcode(strategy);
+    }
+  }
+
+  private void testEqualsHashcode(final SpatialStrategy strategy) {
+    final SpatialArgs args1 = makeArgs1();
+    final SpatialArgs args2 = makeArgs2();
+    testEqualsHashcode(args1, args2, new ObjGenerator() {
+      @Override
+      public Object gen(SpatialArgs args) {
+        return strategy.makeQuery(args);
+      }
+    });
+    testEqualsHashcode(args1, args2, new ObjGenerator() {
+      @Override
+      public Object gen(SpatialArgs args) {
+        return strategy.makeDistanceValueSource(args.getShape().getCenter());
+      }
+    });
+  }
+
+  private void testEqualsHashcode(SpatialArgs args1, SpatialArgs args2, ObjGenerator generator) {
+    Object first;
+    try {
+      first = generator.gen(args1);
+    } catch (UnsupportedOperationException e) {
+      return;
+    }
+    if (first == null)
+      return;//unsupported op?
+    Object second = generator.gen(args1);//should be the same
+    assertEquals(first, second);
+    assertEquals(first.hashCode(), second.hashCode());
+    assertTrue(args1.equals(args2) == false);
+    second = generator.gen(args2);//now should be different
+    assertTrue(first.equals(second) == false);
+    assertTrue(first.hashCode() != second.hashCode());
+  }
+
+  private SpatialArgs makeArgs1() {
+    final Shape shape1 = ctx.makeRectangle(0, 0, 10, 10);
+    return new SpatialArgs(predicate, shape1);
+  }
+
+  private SpatialArgs makeArgs2() {
+    final Shape shape2 = ctx.makeRectangle(0, 0, 20, 20);
+    return new SpatialArgs(predicate, shape2);
+  }
+
+  interface ObjGenerator {
+    Object gen(SpatialArgs args);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialArgsTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialArgsTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialArgsTest.java
new file mode 100644
index 0000000..09b5d46
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialArgsTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class SpatialArgsTest {
+
+  @Test
+  public void calcDistanceFromErrPct() {
+    final SpatialContext ctx = SpatialContext.GEO;
+    final double DEP = 0.5;//distErrPct
+
+    //the result is the diagonal distance from the center to the closest corner,
+    // times distErrPct
+
+    Shape superwide = ctx.makeRectangle(-180, 180, 0, 0);
+    //0 distErrPct means 0 distance always
+    assertEquals(0, SpatialArgs.calcDistanceFromErrPct(superwide, 0, ctx), 0);
+    assertEquals(180 * DEP, SpatialArgs.calcDistanceFromErrPct(superwide, DEP, ctx), 0);
+
+    Shape supertall = ctx.makeRectangle(0, 0, -90, 90);
+    assertEquals(90 * DEP, SpatialArgs.calcDistanceFromErrPct(supertall, DEP, ctx), 0);
+
+    Shape upperhalf = ctx.makeRectangle(-180, 180, 0, 90);
+    assertEquals(45 * DEP, SpatialArgs.calcDistanceFromErrPct(upperhalf, DEP, ctx), 0.0001);
+
+    Shape midCircle = ctx.makeCircle(0, 0, 45);
+    assertEquals(60 * DEP, SpatialArgs.calcDistanceFromErrPct(midCircle, DEP, ctx), 0.0001);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialExample.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialExample.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialExample.java
new file mode 100644
index 0000000..1bd7159
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialExample.java
@@ -0,0 +1,200 @@
+/*
+ * 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;
+
+import java.io.IOException;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.distance.DistanceUtils;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.NumericDocValuesField;
+import org.apache.lucene.document.StoredField;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Sort;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
+import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.query.SpatialArgsParser;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.LuceneTestCase;
+
+/**
+ * This class serves as example code to show how to use the Lucene spatial
+ * module.
+ */
+public class SpatialExample extends LuceneTestCase {
+
+  //Note: Test invoked via TestTestFramework.spatialExample()
+
+  public static void main(String[] args) throws Exception {
+    new SpatialExample().test();
+  }
+
+  public void test() throws Exception {
+    init();
+    indexPoints();
+    search();
+  }
+
+  /**
+   * The Spatial4j {@link SpatialContext} is a sort of global-ish singleton
+   * needed by Lucene spatial.  It's a facade to the rest of Spatial4j, acting
+   * as a factory for {@link Shape}s and provides access to reading and writing
+   * them from Strings.
+   */
+  private SpatialContext ctx;//"ctx" is the conventional variable name
+
+  /**
+   * The Lucene spatial {@link SpatialStrategy} encapsulates an approach to
+   * indexing and searching shapes, and providing distance values for them.
+   * It's a simple API to unify different approaches. You might use more than
+   * one strategy for a shape as each strategy has its strengths and weaknesses.
+   * <p />
+   * Note that these are initialized with a field name.
+   */
+  private SpatialStrategy strategy;
+
+  private Directory directory;
+
+  protected void init() {
+    //Typical geospatial context
+    //  These can also be constructed from SpatialContextFactory
+    this.ctx = SpatialContext.GEO;
+
+    int maxLevels = 11;//results in sub-meter precision for geohash
+    //TODO demo lookup by detail distance
+    //  This can also be constructed from SpatialPrefixTreeFactory
+    SpatialPrefixTree grid = new GeohashPrefixTree(ctx, maxLevels);
+
+    this.strategy = new RecursivePrefixTreeStrategy(grid, "myGeoField");
+
+    this.directory = new RAMDirectory();
+  }
+
+  private void indexPoints() throws Exception {
+    IndexWriterConfig iwConfig = new IndexWriterConfig(null);
+    IndexWriter indexWriter = new IndexWriter(directory, iwConfig);
+
+    //Spatial4j is x-y order for arguments
+    indexWriter.addDocument(newSampleDocument(
+        2, ctx.makePoint(-80.93, 33.77)));
+
+    //Spatial4j has a WKT parser which is also "x y" order
+    indexWriter.addDocument(newSampleDocument(
+        4, ctx.readShapeFromWkt("POINT(60.9289094 -50.7693246)")));
+
+    indexWriter.addDocument(newSampleDocument(
+        20, ctx.makePoint(0.1,0.1), ctx.makePoint(0, 0)));
+
+    indexWriter.close();
+  }
+
+  private Document newSampleDocument(int id, Shape... shapes) {
+    Document doc = new Document();
+    doc.add(new StoredField("id", id));
+    doc.add(new NumericDocValuesField("id", id));
+    //Potentially more than one shape in this field is supported by some
+    // strategies; see the javadocs of the SpatialStrategy impl to see.
+    for (Shape shape : shapes) {
+      for (Field f : strategy.createIndexableFields(shape)) {
+        doc.add(f);
+      }
+      //store it too; the format is up to you
+      //  (assume point in this example)
+      Point pt = (Point) shape;
+      doc.add(new StoredField(strategy.getFieldName(), pt.getX()+" "+pt.getY()));
+    }
+
+    return doc;
+  }
+
+  private void search() throws Exception {
+    IndexReader indexReader = DirectoryReader.open(directory);
+    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
+    Sort idSort = new Sort(new SortField("id", SortField.Type.INT));
+
+    //--Filter by circle (<= distance from a point)
+    {
+      //Search with circle
+      //note: SpatialArgs can be parsed from a string
+      SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects,
+          ctx.makeCircle(-80.0, 33.0, DistanceUtils.dist2Degrees(200, DistanceUtils.EARTH_MEAN_RADIUS_KM)));
+      Query query = strategy.makeQuery(args);
+      TopDocs docs = indexSearcher.search(query, 10, idSort);
+      assertDocMatchedIds(indexSearcher, docs, 2);
+      //Now, lets get the distance for the 1st doc via computing from stored point value:
+      // (this computation is usually not redundant)
+      Document doc1 = indexSearcher.doc(docs.scoreDocs[0].doc);
+      String doc1Str = doc1.getField(strategy.getFieldName()).stringValue();
+      //assume doc1Str is "x y" as written in newSampleDocument()
+      int spaceIdx = doc1Str.indexOf(' ');
+      double x = Double.parseDouble(doc1Str.substring(0, spaceIdx));
+      double y = Double.parseDouble(doc1Str.substring(spaceIdx+1));
+      double doc1DistDEG = ctx.calcDistance(args.getShape().getCenter(), x, y);
+      assertEquals(121.6d, DistanceUtils.degrees2Dist(doc1DistDEG, DistanceUtils.EARTH_MEAN_RADIUS_KM), 0.1);
+      //or more simply:
+      assertEquals(121.6d, doc1DistDEG * DistanceUtils.DEG_TO_KM, 0.1);
+    }
+    //--Match all, order by distance ascending
+    {
+      Point pt = ctx.makePoint(60, -50);
+      ValueSource valueSource = strategy.makeDistanceValueSource(pt, DistanceUtils.DEG_TO_KM);//the distance (in km)
+      Sort distSort = new Sort(valueSource.getSortField(false)).rewrite(indexSearcher);//false=asc dist
+      TopDocs docs = indexSearcher.search(new MatchAllDocsQuery(), 10, distSort);
+      assertDocMatchedIds(indexSearcher, docs, 4, 20, 2);
+      //To get the distance, we could compute from stored values like earlier.
+      // However in this example we sorted on it, and the distance will get
+      // computed redundantly.  If the distance is only needed for the top-X
+      // search results then that's not a big deal. Alternatively, try wrapping
+      // the ValueSource with CachingDoubleValueSource then retrieve the value
+      // from the ValueSource now. See LUCENE-4541 for an example.
+    }
+    //demo arg parsing
+    {
+      SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects,
+          ctx.makeCircle(-80.0, 33.0, 1));
+      SpatialArgs args2 = new SpatialArgsParser().parse("Intersects(BUFFER(POINT(-80 33),1))", ctx);
+      assertEquals(args.toString(),args2.toString());
+    }
+
+    indexReader.close();
+  }
+
+  private void assertDocMatchedIds(IndexSearcher indexSearcher, TopDocs docs, int... ids) throws IOException {
+    int[] gotIds = new int[docs.totalHits];
+    for (int i = 0; i < gotIds.length; i++) {
+      gotIds[i] = indexSearcher.doc(docs.scoreDocs[i].doc).getField("id").numericValue().intValue();
+    }
+    assertArrayEquals(ids,gotIds);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialMatchConcern.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialMatchConcern.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialMatchConcern.java
new file mode 100644
index 0000000..e995ee1
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialMatchConcern.java
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+public class SpatialMatchConcern {
+  public final boolean orderIsImportant;
+  public final boolean resultsAreSuperset; // if the strategy can not give exact answers, but used to limit results
+
+  private SpatialMatchConcern( boolean order, boolean superset ) {
+    this.orderIsImportant = order;
+    this.resultsAreSuperset = superset;
+  }
+
+  public static final SpatialMatchConcern EXACT = new SpatialMatchConcern( true, false );
+  public static final SpatialMatchConcern FILTER = new SpatialMatchConcern( false, false );
+  public static final SpatialMatchConcern SUPERSET = new SpatialMatchConcern( false, true );
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialTestCase.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialTestCase.java
new file mode 100644
index 0000000..94e5a8e
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialTestCase.java
@@ -0,0 +1,280 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.logging.Logger;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.distance.DistanceUtils;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.RandomIndexWriter;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.uninverting.UninvertingReader;
+import org.apache.lucene.uninverting.UninvertingReader.Type;
+import org.apache.lucene.util.IOUtils;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.LuceneTestCase.SuppressSysoutChecks;
+import org.apache.lucene.util.TestUtil;
+
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomDouble;
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomGaussian;
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomInt;
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween;
+
+/** A base test class for spatial lucene. It's mostly Lucene generic. */
+@SuppressSysoutChecks(bugUrl = "These tests use JUL extensively.")
+public abstract class SpatialTestCase extends LuceneTestCase {
+
+  protected Logger log = Logger.getLogger(getClass().getName());
+
+  private DirectoryReader indexReader;
+  protected RandomIndexWriter indexWriter;
+  private Directory directory;
+  private Analyzer analyzer;
+  protected IndexSearcher indexSearcher;
+
+  protected SpatialContext ctx;//subclass must initialize
+
+  protected Map<String,Type> uninvertMap = new HashMap<>();
+
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    // TODO: change this module to index docvalues instead of uninverting
+    uninvertMap.clear();
+    uninvertMap.put("pointvector__x", Type.DOUBLE);
+    uninvertMap.put("pointvector__y", Type.DOUBLE);
+
+    directory = newDirectory();
+    final Random random = random();
+    analyzer = new MockAnalyzer(random);
+    indexWriter = new RandomIndexWriter(random,directory, newIWConfig(random, analyzer));
+    indexReader = UninvertingReader.wrap(indexWriter.getReader(), uninvertMap);
+    indexSearcher = newSearcher(indexReader);
+  }
+
+  protected IndexWriterConfig newIWConfig(Random random, Analyzer analyzer) {
+    final IndexWriterConfig indexWriterConfig = LuceneTestCase.newIndexWriterConfig(random, analyzer);
+    //TODO can we randomly choose a doc-values supported format?
+    if (needsDocValues())
+      indexWriterConfig.setCodec( TestUtil.getDefaultCodec());
+    return indexWriterConfig;
+  }
+
+  protected boolean needsDocValues() {
+    return false;
+  }
+
+  @Override
+  public void tearDown() throws Exception {
+    IOUtils.close(indexWriter, indexReader, analyzer, directory);
+    super.tearDown();
+  }
+
+  // ================================================= Helper Methods ================================================
+
+  protected void addDocument(Document doc) throws IOException {
+    indexWriter.addDocument(doc);
+  }
+
+  protected void addDocumentsAndCommit(List<Document> documents) throws IOException {
+    for (Document document : documents) {
+      indexWriter.addDocument(document);
+    }
+    commit();
+  }
+
+  protected void deleteAll() throws IOException {
+    indexWriter.deleteAll();
+  }
+
+  protected void commit() throws IOException {
+    indexWriter.commit();
+    DirectoryReader newReader = DirectoryReader.openIfChanged(indexReader);
+    if (newReader != null) {
+      IOUtils.close(indexReader);
+      indexReader = newReader;
+    }
+    indexSearcher = newSearcher(indexReader);
+  }
+
+  protected void verifyDocumentsIndexed(int numDocs) {
+    assertEquals(numDocs, indexReader.numDocs());
+  }
+
+  protected SearchResults executeQuery(Query query, int numDocs) {
+    try {
+      TopDocs topDocs = indexSearcher.search(query, numDocs);
+
+      List<SearchResult> results = new ArrayList<>();
+      for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
+        results.add(new SearchResult(scoreDoc.score, indexSearcher.doc(scoreDoc.doc)));
+      }
+      return new SearchResults(topDocs.totalHits, results);
+    } catch (IOException ioe) {
+      throw new RuntimeException("IOException thrown while executing query", ioe);
+    }
+  }
+
+  protected Point randomPoint() {
+    final Rectangle WB = ctx.getWorldBounds();
+    return ctx.makePoint(
+        randomIntBetween((int) WB.getMinX(), (int) WB.getMaxX()),
+        randomIntBetween((int) WB.getMinY(), (int) WB.getMaxY()));
+  }
+
+  protected Rectangle randomRectangle() {
+    return randomRectangle(ctx.getWorldBounds());
+  }
+
+  protected Rectangle randomRectangle(Rectangle bounds) {
+    double[] xNewStartAndWidth = randomSubRange(bounds.getMinX(), bounds.getWidth());
+    double xMin = xNewStartAndWidth[0];
+    double xMax = xMin + xNewStartAndWidth[1];
+    if (bounds.getCrossesDateLine()) {
+      xMin = DistanceUtils.normLonDEG(xMin);
+      xMax = DistanceUtils.normLonDEG(xMax);
+    }
+
+    double[] yNewStartAndHeight = randomSubRange(bounds.getMinY(), bounds.getHeight());
+    double yMin = yNewStartAndHeight[0];
+    double yMax = yMin + yNewStartAndHeight[1];
+
+    return ctx.makeRectangle(xMin, xMax, yMin, yMax);
+  }
+
+  /** Returns new minStart and new length that is inside the range specified by the arguments. */
+  protected double[] randomSubRange(double boundStart, double boundLen) {
+    if (boundLen >= 3 && usually()) { // typical
+      // prefer integers for ease of debugability ... and prefer 1/16th of bound
+      int intBoundStart = (int) Math.ceil(boundStart);
+      int intBoundEnd = (int) (boundStart + boundLen);
+      int intBoundLen = intBoundEnd - intBoundStart;
+      int newLen = (int) randomGaussianMeanMax(intBoundLen / 16.0, intBoundLen);
+      int newStart = intBoundStart + randomInt(intBoundLen - newLen);
+      return new double[]{newStart, newLen};
+    } else { // (no int rounding)
+      double newLen = randomGaussianMeanMax(boundLen / 16, boundLen);
+      double newStart = boundStart + (boundLen - newLen == 0 ? 0 : (randomDouble() % (boundLen - newLen)));
+      return new double[]{newStart, newLen};
+    }
+  }
+
+  private double randomGaussianMinMeanMax(double min, double mean, double max) {
+    assert mean > min;
+    return randomGaussianMeanMax(mean - min, max - min) + min;
+  }
+
+  /**
+   * Within one standard deviation (68% of the time) the result is "close" to
+   * mean. By "close": when greater than mean, it's the lesser of 2*mean or half
+   * way to max, when lesser than mean, it's the greater of max-2*mean or half
+   * way to 0. The other 32% of the time it's in the rest of the range, touching
+   * either 0 or max but never exceeding.
+   */
+  private double randomGaussianMeanMax(double mean, double max) {
+    // DWS: I verified the results empirically
+    assert mean <= max && mean >= 0;
+    double g = randomGaussian();
+    double mean2 = mean;
+    double flip = 1;
+    if (g < 0) {
+      mean2 = max - mean;
+      flip = -1;
+      g *= -1;
+    }
+    // pivot is the distance from mean2 towards max where the boundary of
+    // 1 standard deviation alters the calculation
+    double pivotMax = max - mean2;
+    double pivot = Math.min(mean2, pivotMax / 2);//from 0 to max-mean2
+    assert pivot >= 0 && pivotMax >= pivot && g >= 0;
+    double pivotResult;
+    if (g <= 1)
+      pivotResult = pivot * g;
+    else
+      pivotResult = Math.min(pivotMax, (g - 1) * (pivotMax - pivot) + pivot);
+
+    double result = mean + flip * pivotResult;
+    return (result < 0 || result > max) ? mean : result; // due this due to computational numerical precision
+  }
+
+  // ================================================= Inner Classes =================================================
+
+  protected static class SearchResults {
+
+    public int numFound;
+    public List<SearchResult> results;
+
+    public SearchResults(int numFound, List<SearchResult> results) {
+      this.numFound = numFound;
+      this.results = results;
+    }
+
+    public StringBuilder toDebugString() {
+      StringBuilder str = new StringBuilder();
+      str.append("found: ").append(numFound).append('[');
+      for(SearchResult r : results) {
+        String id = r.getId();
+        str.append(id).append(", ");
+      }
+      str.append(']');
+      return str;
+    }
+
+    @Override
+    public String toString() {
+      return "[found:"+numFound+" "+results+"]";
+    }
+  }
+
+  protected static class SearchResult {
+
+    public float score;
+    public Document document;
+
+    public SearchResult(float score, Document document) {
+      this.score = score;
+      this.document = document;
+    }
+
+    public String getId() {
+      return document.get("id");
+    }
+
+    @Override
+    public String toString() {
+      return "["+score+"="+document+"]";
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialTestData.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialTestData.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialTestData.java
new file mode 100644
index 0000000..27d47b3
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialTestData.java
@@ -0,0 +1,71 @@
+/*
+ * 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;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Shape;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+// This class is modelled after SpatialTestQuery.
+// Before Lucene 4.7, this was a bit different in Spatial4j as SampleData & SampleDataReader.
+
+public class SpatialTestData {
+  public String id;
+  public String name;
+  public Shape shape;
+
+  /** Reads the stream, consuming a format that is a tab-separated values of 3 columns:
+   * an "id", a "name" and the "shape".  Empty lines and lines starting with a '#' are skipped.
+   * The stream is closed.
+   */
+  public static Iterator<SpatialTestData> getTestData(InputStream in, SpatialContext ctx) throws IOException {
+    List<SpatialTestData> results = new ArrayList<>();
+    BufferedReader bufInput = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
+    try {
+      String line;
+      while ((line = bufInput.readLine()) != null) {
+        if (line.length() == 0 || line.charAt(0) == '#')
+          continue;
+
+        SpatialTestData data = new SpatialTestData();
+        String[] vals = line.split("\t");
+        if (vals.length != 3)
+          throw new RuntimeException("bad format; expecting 3 tab-separated values for line: "+line);
+        data.id = vals[0];
+        data.name = vals[1];
+        try {
+          data.shape = ctx.readShapeFromWkt(vals[2]);
+        } catch (ParseException e) {
+          throw new RuntimeException(e);
+        }
+        results.add(data);
+      }
+    } finally {
+      bufInput.close();
+    }
+    return results.iterator();
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialTestQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialTestQuery.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialTestQuery.java
new file mode 100644
index 0000000..bac90cf
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialTestQuery.java
@@ -0,0 +1,96 @@
+/*
+ * 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;
+
+import com.spatial4j.core.context.SpatialContext;
+
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.query.SpatialArgsParser;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * Helper class to execute queries
+ */
+public class SpatialTestQuery {
+  public String testname;
+  public String line;
+  public int lineNumber = -1;
+  public SpatialArgs args;
+  public List<String> ids = new ArrayList<>();
+
+  /**
+   * Get Test Queries.  The InputStream is closed.
+   */
+  public static Iterator<SpatialTestQuery> getTestQueries(
+      final SpatialArgsParser parser,
+      final SpatialContext ctx,
+      final String name,
+      final InputStream in ) throws IOException {
+
+    List<SpatialTestQuery> results = new ArrayList<>();
+
+    BufferedReader bufInput = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
+    try {
+      String line;
+      for (int lineNumber = 1; (line = bufInput.readLine()) != null; lineNumber++) {
+        SpatialTestQuery test = new SpatialTestQuery();
+        test.line = line;
+        test.lineNumber = lineNumber;
+
+        try {
+          // skip a comment
+          if( line.startsWith( "[" ) ) {
+            int idx = line.indexOf( ']' );
+            if( idx > 0 ) {
+              line = line.substring( idx+1 );
+            }
+          }
+
+          int idx = line.indexOf('@');
+          StringTokenizer st = new StringTokenizer(line.substring(0, idx));
+          while (st.hasMoreTokens()) {
+            test.ids.add(st.nextToken().trim());
+          }
+          test.args = parser.parse(line.substring(idx + 1).trim(), ctx);
+          results.add(test);
+        }
+        catch( Exception ex ) {
+          throw new RuntimeException( "invalid query line: "+test.line, ex );
+        }
+      }
+    } finally {
+      bufInput.close();
+    }
+    return results.iterator();
+  }
+
+  @Override
+  public String toString() {
+    if (line != null)
+      return line;
+    return args.toString()+" "+ids;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/StrategyTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/StrategyTestCase.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/StrategyTestCase.java
new file mode 100644
index 0000000..00e437b
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/StrategyTestCase.java
@@ -0,0 +1,252 @@
+/*
+ * 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;
+
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.StoredField;
+import org.apache.lucene.document.StringField;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.queries.function.FunctionQuery;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.search.CheckHits;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.query.SpatialArgsParser;
+import org.apache.lucene.spatial.query.SpatialOperation;
+
+public abstract class StrategyTestCase extends SpatialTestCase {
+
+  public static final String DATA_SIMPLE_BBOX = "simple-bbox.txt";
+  public static final String DATA_STATES_POLY = "states-poly.txt";
+  public static final String DATA_STATES_BBOX = "states-bbox.txt";
+  public static final String DATA_COUNTRIES_POLY = "countries-poly.txt";
+  public static final String DATA_COUNTRIES_BBOX = "countries-bbox.txt";
+  public static final String DATA_WORLD_CITIES_POINTS = "world-cities-points.txt";
+
+  public static final String QTEST_States_IsWithin_BBox   = "states-IsWithin-BBox.txt";
+  public static final String QTEST_States_Intersects_BBox = "states-Intersects-BBox.txt";
+  public static final String QTEST_Cities_Intersects_BBox = "cities-Intersects-BBox.txt";
+  public static final String QTEST_Simple_Queries_BBox = "simple-Queries-BBox.txt";
+
+  protected Logger log = Logger.getLogger(getClass().getName());
+
+  protected final SpatialArgsParser argsParser = new SpatialArgsParser();
+
+  protected SpatialStrategy strategy;
+  protected boolean storeShape = true;
+
+  protected void executeQueries(SpatialMatchConcern concern, String... testQueryFile) throws IOException {
+    log.info("testing queried for strategy "+strategy);
+    for( String path : testQueryFile ) {
+      Iterator<SpatialTestQuery> testQueryIterator = getTestQueries(path, ctx);
+      runTestQueries(testQueryIterator, concern);
+    }
+  }
+
+  protected void getAddAndVerifyIndexedDocuments(String testDataFile) throws IOException {
+    List<Document> testDocuments = getDocuments(testDataFile);
+    addDocumentsAndCommit(testDocuments);
+    verifyDocumentsIndexed(testDocuments.size());
+  }
+
+  protected List<Document> getDocuments(String testDataFile) throws IOException {
+    return getDocuments(getSampleData(testDataFile));
+  }
+
+  protected List<Document> getDocuments(Iterator<SpatialTestData> sampleData) {
+    List<Document> documents = new ArrayList<>();
+    while (sampleData.hasNext()) {
+      SpatialTestData data = sampleData.next();
+      Document document = new Document();
+      document.add(new StringField("id", data.id, Field.Store.YES));
+      document.add(new StringField("name", data.name, Field.Store.YES));
+      Shape shape = data.shape;
+      shape = convertShapeFromGetDocuments(shape);
+      if (shape != null) {
+        for (Field f : strategy.createIndexableFields(shape)) {
+          document.add(f);
+        }
+        if (storeShape)//just for diagnostics
+          document.add(new StoredField(strategy.getFieldName(), shape.toString()));
+      }
+
+      documents.add(document);
+    }
+    return documents;
+  }
+
+  /** Subclasses may override to transform or remove a shape for indexing */
+  protected Shape convertShapeFromGetDocuments(Shape shape) {
+    return shape;
+  }
+
+  protected Iterator<SpatialTestData> getSampleData(String testDataFile) throws IOException {
+    String path = "data/" + testDataFile;
+    InputStream stream = getClass().getClassLoader().getResourceAsStream(path);
+    if (stream == null)
+      throw new FileNotFoundException("classpath resource not found: "+path);
+    return SpatialTestData.getTestData(stream, ctx);//closes the InputStream
+  }
+
+  protected Iterator<SpatialTestQuery> getTestQueries(String testQueryFile, SpatialContext ctx) throws IOException {
+    InputStream in = getClass().getClassLoader().getResourceAsStream(testQueryFile);
+    return SpatialTestQuery.getTestQueries(
+        argsParser, ctx, testQueryFile, in );//closes the InputStream
+  }
+
+  public void runTestQueries(
+      Iterator<SpatialTestQuery> queries,
+      SpatialMatchConcern concern) {
+    while (queries.hasNext()) {
+      SpatialTestQuery q = queries.next();
+      runTestQuery(concern, q);
+    }
+  }
+
+  public void runTestQuery(SpatialMatchConcern concern, SpatialTestQuery q) {
+    String msg = q.toString(); //"Query: " + q.args.toString(ctx);
+    SearchResults got = executeQuery(makeQuery(q), Math.max(100, q.ids.size()+1));
+    if (storeShape && got.numFound > 0) {
+      //check stored value is there
+      assertNotNull(got.results.get(0).document.get(strategy.getFieldName()));
+    }
+    if (concern.orderIsImportant) {
+      Iterator<String> ids = q.ids.iterator();
+      for (SearchResult r : got.results) {
+        String id = r.document.get("id");
+        if (!ids.hasNext()) {
+          fail(msg + " :: Did not get enough results.  Expect" + q.ids + ", got: " + got.toDebugString());
+        }
+        assertEquals("out of order: " + msg, ids.next(), id);
+      }
+
+      if (ids.hasNext()) {
+        fail(msg + " :: expect more results then we got: " + ids.next());
+      }
+    } else {
+      // We are looking at how the results overlap
+      if (concern.resultsAreSuperset) {
+        Set<String> found = new HashSet<>();
+        for (SearchResult r : got.results) {
+          found.add(r.document.get("id"));
+        }
+        for (String s : q.ids) {
+          if (!found.contains(s)) {
+            fail("Results are mising id: " + s + " :: " + found);
+          }
+        }
+      } else {
+        List<String> found = new ArrayList<>();
+        for (SearchResult r : got.results) {
+          found.add(r.document.get("id"));
+        }
+
+        // sort both so that the order is not important
+        Collections.sort(q.ids);
+        Collections.sort(found);
+        assertEquals(msg, q.ids.toString(), found.toString());
+      }
+    }
+  }
+
+  protected Query makeQuery(SpatialTestQuery q) {
+    return strategy.makeQuery(q.args);
+  }
+
+  protected void adoc(String id, String shapeStr) throws IOException, ParseException {
+    Shape shape = shapeStr==null ? null : ctx.readShapeFromWkt(shapeStr);
+    addDocument(newDoc(id, shape));
+  }
+  protected void adoc(String id, Shape shape) throws IOException {
+    addDocument(newDoc(id, shape));
+  }
+
+  protected Document newDoc(String id, Shape shape) {
+    Document doc = new Document();
+    doc.add(new StringField("id", id, Field.Store.YES));
+    if (shape != null) {
+      for (Field f : strategy.createIndexableFields(shape)) {
+        doc.add(f);
+      }
+      if (storeShape)
+        doc.add(new StoredField(strategy.getFieldName(), shape.toString()));//not to be parsed; just for debug
+    }
+    return doc;
+  }
+
+  protected void deleteDoc(String id) throws IOException {
+    indexWriter.deleteDocuments(new TermQuery(new Term("id", id)));
+  }
+
+  /** scores[] are in docId order */
+  protected void checkValueSource(ValueSource vs, float scores[], float delta) throws IOException {
+    FunctionQuery q = new FunctionQuery(vs);
+
+//    //TODO is there any point to this check?
+//    int expectedDocs[] = new int[scores.length];//fill with ascending 0....length-1
+//    for (int i = 0; i < expectedDocs.length; i++) {
+//      expectedDocs[i] = i;
+//    }
+//    CheckHits.checkHits(random(), q, "", indexSearcher, expectedDocs);
+
+    //TopDocs is sorted but we actually don't care about the order
+    TopDocs docs = indexSearcher.search(q, 1000);//calculates the score
+    for (int i = 0; i < docs.scoreDocs.length; i++) {
+      ScoreDoc gotSD = docs.scoreDocs[i];
+      float expectedScore = scores[gotSD.doc];
+      assertEquals("Not equal for doc "+gotSD.doc, expectedScore, gotSD.score, delta);
+    }
+
+    CheckHits.checkExplanations(q, "", indexSearcher);
+  }
+
+  protected void testOperation(Shape indexedShape, SpatialOperation operation,
+                               Shape queryShape, boolean match) throws IOException {
+    assertTrue("Faulty test",
+        operation.evaluate(indexedShape, queryShape) == match ||
+            indexedShape.equals(queryShape) &&
+              (operation == SpatialOperation.Contains || operation == SpatialOperation.IsWithin));
+    adoc("0", indexedShape);
+    commit();
+    Query query = strategy.makeQuery(new SpatialArgs(operation, queryShape));
+    SearchResults got = executeQuery(query, 1);
+    assert got.numFound <= 1 : "unclean test env";
+    if ((got.numFound == 1) != match)
+      fail(operation+" I:" + indexedShape + " Q:" + queryShape);
+    deleteAll();//clean up after ourselves
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestTestFramework.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestTestFramework.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestTestFramework.java
new file mode 100644
index 0000000..d31fdf6
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/TestTestFramework.java
@@ -0,0 +1,68 @@
+/*
+ * 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;
+
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Rectangle;
+import org.apache.lucene.spatial.query.SpatialArgsParser;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.apache.lucene.util.LuceneTestCase;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+/**
+ * Make sure we are reading the tests as expected
+ */
+public class TestTestFramework extends LuceneTestCase {
+
+  @Test
+  public void testQueries() throws IOException {
+    String name = StrategyTestCase.QTEST_Cities_Intersects_BBox;
+
+    InputStream in = getClass().getClassLoader().getResourceAsStream(name);
+    SpatialContext ctx = SpatialContext.GEO;
+    Iterator<SpatialTestQuery> iter = SpatialTestQuery.getTestQueries(
+        new SpatialArgsParser(), ctx, name, in );//closes the InputStream
+    List<SpatialTestQuery> tests = new ArrayList<>();
+    while( iter.hasNext() ) {
+      tests.add( iter.next() );
+    }
+    Assert.assertEquals( 3, tests.size() );
+
+    SpatialTestQuery sf = tests.get(0);
+    // assert
+    assertEquals( 1, sf.ids.size() );
+    Assert.assertTrue( sf.ids.get(0).equals( "G5391959" ) );
+    Assert.assertTrue( sf.args.getShape() instanceof Rectangle);
+    assertEquals(SpatialOperation.Intersects, sf.args.getOperation());
+  }
+
+  @Test
+  public void spatialExample() throws Exception {
+    //kind of a hack so that SpatialExample is tested despite
+    // it not starting or ending with "Test".
+    SpatialExample.main(null);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java
new file mode 100644
index 0000000..6140996
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java
@@ -0,0 +1,301 @@
+/*
+ * 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.bbox;
+
+import java.io.IOException;
+
+import com.carrotsearch.randomizedtesting.annotations.Repeat;
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.context.SpatialContextFactory;
+import com.spatial4j.core.distance.DistanceUtils;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.impl.RectangleImpl;
+import org.apache.lucene.document.FieldType;
+import org.apache.lucene.index.DocValuesType;
+import org.apache.lucene.index.IndexOptions;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.spatial.SpatialMatchConcern;
+import org.apache.lucene.spatial.prefix.RandomSpatialOpStrategyTestCase;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.apache.lucene.spatial.util.ShapeAreaValueSource;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class TestBBoxStrategy extends RandomSpatialOpStrategyTestCase {
+
+  @Override
+  protected boolean needsDocValues() {
+    return true;
+  }
+
+  @Override
+  protected Shape randomIndexedShape() {
+    Rectangle world = ctx.getWorldBounds();
+    if (random().nextInt(10) == 0) // increased chance of getting one of these
+      return world;
+
+    int worldWidth = (int) Math.round(world.getWidth());
+    int deltaLeft = nextIntInclusive(worldWidth);
+    int deltaRight = nextIntInclusive(worldWidth - deltaLeft);
+    int worldHeight = (int) Math.round(world.getHeight());
+    int deltaTop = nextIntInclusive(worldHeight);
+    int deltaBottom = nextIntInclusive(worldHeight - deltaTop);
+    if (ctx.isGeo() && (deltaLeft != 0 || deltaRight != 0)) {
+      //if geo & doesn't world-wrap, we shift randomly to potentially cross dateline
+      int shift = nextIntInclusive(360);
+      return ctx.makeRectangle(
+          DistanceUtils.normLonDEG(world.getMinX() + deltaLeft + shift),
+          DistanceUtils.normLonDEG(world.getMaxX() - deltaRight + shift),
+          world.getMinY() + deltaBottom, world.getMaxY() - deltaTop);
+    } else {
+      return ctx.makeRectangle(
+          world.getMinX() + deltaLeft, world.getMaxX() - deltaRight,
+          world.getMinY() + deltaBottom, world.getMaxY() - deltaTop);
+    }
+  }
+
+  /** next int, inclusive, rounds to multiple of 10 if given evenly divisible. */
+  private int nextIntInclusive(int toInc) {
+    final int DIVIS = 10;
+    if (toInc % DIVIS == 0) {
+      return random().nextInt(toInc/DIVIS + 1) * DIVIS;
+    } else {
+      return random().nextInt(toInc + 1);
+    }
+  }
+
+  @Override
+  protected Shape randomQueryShape() {
+    return randomIndexedShape();
+  }
+
+  @Test
+  @Repeat(iterations = 15)
+  public void testOperations() throws IOException {
+    //setup
+    if (random().nextInt(4) > 0) {//75% of the time choose geo (more interesting to test)
+      this.ctx = SpatialContext.GEO;
+    } else {
+      SpatialContextFactory factory = new SpatialContextFactory();
+      factory.geo = false;
+      factory.worldBounds = new RectangleImpl(-300, 300, -100, 100, null);
+      this.ctx = factory.newSpatialContext();
+    }
+    this.strategy = new BBoxStrategy(ctx, "bbox");
+    //test we can disable docValues for predicate tests
+    if (random().nextBoolean()) {
+      BBoxStrategy bboxStrategy = (BBoxStrategy) strategy;
+      FieldType fieldType = new FieldType(bboxStrategy.getFieldType());
+      fieldType.setDocValuesType(DocValuesType.NONE);
+      bboxStrategy.setFieldType(fieldType);
+    }
+    for (SpatialOperation operation : SpatialOperation.values()) {
+      if (operation == SpatialOperation.Overlaps)
+        continue;//unsupported
+      testOperationRandomShapes(operation);
+
+      deleteAll();
+      commit();
+    }
+  }
+
+  @Test
+  public void testIntersectsBugDatelineEdge() throws IOException {
+    setupGeo();
+    testOperation(
+        ctx.makeRectangle(160, 180, -10, 10),
+        SpatialOperation.Intersects,
+        ctx.makeRectangle(-180, -160, -10, 10), true);
+  }
+
+  @Test
+  public void testIntersectsWorldDatelineEdge() throws IOException {
+    setupGeo();
+    testOperation(
+        ctx.makeRectangle(-180, 180, -10, 10),
+        SpatialOperation.Intersects,
+        ctx.makeRectangle(180, 180, -10, 10), true);
+  }
+
+  @Test
+  public void testWithinBugDatelineEdge() throws IOException {
+    setupGeo();
+    testOperation(
+        ctx.makeRectangle(180, 180, -10, 10),
+        SpatialOperation.IsWithin,
+        ctx.makeRectangle(-180, -100, -10, 10), true);
+  }
+
+  @Test
+  public void testContainsBugDatelineEdge() throws IOException {
+    setupGeo();
+    testOperation(
+        ctx.makeRectangle(-180, -150, -10, 10),
+        SpatialOperation.Contains,
+        ctx.makeRectangle(180, 180, -10, 10), true);
+  }
+
+  @Test
+  public void testWorldContainsXDL() throws IOException {
+    setupGeo();
+    testOperation(
+        ctx.makeRectangle(-180, 180, -10, 10),
+        SpatialOperation.Contains,
+        ctx.makeRectangle(170, -170, -10, 10), true);
+  }
+
+  /** See https://github.com/spatial4j/spatial4j/issues/85 */
+  @Test
+  public void testAlongDatelineOppositeSign() throws IOException {
+    // Due to Spatial4j bug #85, we can't simply do:
+    //    testOperation(indexedShape,
+    //        SpatialOperation.IsWithin,
+    //        queryShape, true);
+
+    //both on dateline but expressed using opposite signs
+    setupGeo();
+    final Rectangle indexedShape = ctx.makeRectangle(180, 180, -10, 10);
+    final Rectangle queryShape = ctx.makeRectangle(-180, -180, -20, 20);
+    final SpatialOperation operation = SpatialOperation.IsWithin;
+    final boolean match = true;//yes it is within
+
+    //the rest is super.testOperation without leading assert:
+
+    adoc("0", indexedShape);
+    commit();
+    Query query = strategy.makeQuery(new SpatialArgs(operation, queryShape));
+    SearchResults got = executeQuery(query, 1);
+    assert got.numFound <= 1 : "unclean test env";
+    if ((got.numFound == 1) != match)
+      fail(operation+" I:" + indexedShape + " Q:" + queryShape);
+    deleteAll();//clean up after ourselves
+  }
+
+  private void setupGeo() {
+    this.ctx = SpatialContext.GEO;
+    this.strategy = new BBoxStrategy(ctx, "bbox");
+  }
+
+  // OLD STATIC TESTS (worthless?)
+
+  @Test @Ignore("Overlaps not supported")
+  public void testBasicOperaions() throws IOException {
+    setupGeo();
+    getAddAndVerifyIndexedDocuments(DATA_SIMPLE_BBOX);
+
+    executeQueries(SpatialMatchConcern.EXACT, QTEST_Simple_Queries_BBox);
+  }
+
+  @Test
+  public void testStatesBBox() throws IOException {
+    setupGeo();
+    getAddAndVerifyIndexedDocuments(DATA_STATES_BBOX);
+
+    executeQueries(SpatialMatchConcern.FILTER, QTEST_States_IsWithin_BBox);
+    executeQueries(SpatialMatchConcern.FILTER, QTEST_States_Intersects_BBox);
+  }
+
+  @Test
+  public void testCitiesIntersectsBBox() throws IOException {
+    setupGeo();
+    getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS);
+
+    executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_Intersects_BBox);
+  }
+
+  /* Convert DATA_WORLD_CITIES_POINTS to bbox */
+  @Override
+  protected Shape convertShapeFromGetDocuments(Shape shape) {
+    return shape.getBoundingBox();
+  }
+
+  public void testOverlapRatio() throws IOException {
+    setupGeo();
+
+    //Simply assert null shape results in 0
+    adoc("999", (Shape) null);
+    commit();
+    BBoxStrategy bboxStrategy = (BBoxStrategy) strategy;
+    checkValueSource(bboxStrategy.makeOverlapRatioValueSource(randomRectangle(), 0.0), new float[]{0f}, 0f);
+
+    //we test raw BBoxOverlapRatioValueSource without actual indexing
+    for (int SHIFT = 0; SHIFT < 360; SHIFT += 10) {
+      Rectangle queryBox = shiftedRect(0, 40, -20, 20, SHIFT);//40x40, 1600 area
+
+      final boolean MSL = random().nextBoolean();
+      final double minSideLength = MSL ? 0.1 : 0.0;
+      BBoxOverlapRatioValueSource sim = new BBoxOverlapRatioValueSource(null, true, queryBox, 0.5, minSideLength);
+      int nudge = SHIFT == 0 ? 0 : random().nextInt(3) * 10 - 10;//-10, 0, or 10.  Keep 0 on first round.
+
+      final double EPS = 0.0000001;
+
+      assertEquals("within", (200d/1600d * 0.5) + (0.5), sim.score(shiftedRect(10, 30, 0, 10, SHIFT + nudge), null), EPS);
+
+      assertEquals("in25%", 0.25, sim.score(shiftedRect(30, 70, -20, 20, SHIFT), null), EPS);
+
+      assertEquals("wrap", 0.2794117, sim.score(shiftedRect(30, 10, -20, 20, SHIFT + nudge), null), EPS);
+
+      assertEquals("no intersection H", 0.0, sim.score(shiftedRect(-10, -10, -20, 20, SHIFT), null), EPS);
+      assertEquals("no intersection V", 0.0, sim.score(shiftedRect(0, 20, -30, -30, SHIFT), null), EPS);
+
+      assertEquals("point", 0.5 + (MSL?(0.1*0.1/1600.0/2.0):0), sim.score(shiftedRect(0, 0, 0, 0, SHIFT), null), EPS);
+
+      assertEquals("line 25% intersection", 0.25/2 + (MSL?(10.0*0.1/1600.0/2.0):0.0), sim.score(shiftedRect(-30, 10, 0, 0, SHIFT), null), EPS);
+
+      //test with point query
+      sim = new BBoxOverlapRatioValueSource(null, true, shiftedRect(0, 0, 0, 0, SHIFT), 0.5, minSideLength);
+      assertEquals("same", 1.0, sim.score(shiftedRect(0, 0, 0, 0, SHIFT), null), EPS);
+      assertEquals("contains", 0.5 + (MSL?(0.1*0.1/(30*10)/2.0):0.0), sim.score(shiftedRect(0, 30, 0, 10, SHIFT), null), EPS);
+
+      //test with line query (vertical this time)
+      sim = new BBoxOverlapRatioValueSource(null, true, shiftedRect(0, 0, 20, 40, SHIFT), 0.5, minSideLength);
+      assertEquals("line 50%", 0.5, sim.score(shiftedRect(0, 0, 10, 30, SHIFT), null), EPS);
+      assertEquals("point", 0.5 + (MSL?(0.1*0.1/(20*0.1)/2.0):0.0), sim.score(shiftedRect(0, 0, 30, 30, SHIFT), null), EPS);
+    }
+
+  }
+
+  private Rectangle shiftedRect(double minX, double maxX, double minY, double maxY, int xShift) {
+    return ctx.makeRectangle(
+        DistanceUtils.normLonDEG(minX + xShift),
+        DistanceUtils.normLonDEG(maxX + xShift),
+        minY, maxY);
+  }
+
+  public void testAreaValueSource() throws IOException {
+    setupGeo();
+    //test we can disable indexed for this test
+    BBoxStrategy bboxStrategy = (BBoxStrategy) strategy;
+    if (random().nextBoolean()) {
+      FieldType fieldType = new FieldType(bboxStrategy.getFieldType());
+      fieldType.setIndexOptions(IndexOptions.NONE);
+      bboxStrategy.setFieldType(fieldType);
+    }
+
+    adoc("100", ctx.makeRectangle(0, 20, 40, 80));
+    adoc("999", (Shape) null);
+    commit();
+    checkValueSource(new ShapeAreaValueSource(bboxStrategy.makeShapeValueSource(), ctx, false, 1.0),
+        new float[]{800f, 0f}, 0f);
+    checkValueSource(new ShapeAreaValueSource(bboxStrategy.makeShapeValueSource(), ctx, true, 1.0),//geo
+        new float[]{391.93f, 0f}, 0.01f);
+    checkValueSource(new ShapeAreaValueSource(bboxStrategy.makeShapeValueSource(), ctx, true, 2.0),
+        new float[]{783.86f, 0f}, 0.01f); // testing with a different multiplier
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/composite/CompositeStrategyTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/composite/CompositeStrategyTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/composite/CompositeStrategyTest.java
new file mode 100644
index 0000000..8e1bb51
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/composite/CompositeStrategyTest.java
@@ -0,0 +1,142 @@
+/*
+ * 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.composite;
+
+import java.io.IOException;
+
+import com.carrotsearch.randomizedtesting.annotations.Repeat;
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.context.SpatialContextFactory;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.impl.RectangleImpl;
+import org.apache.lucene.spatial.prefix.RandomSpatialOpStrategyTestCase;
+import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
+import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.apache.lucene.spatial.serialized.SerializedDVStrategy;
+import org.junit.Test;
+
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomBoolean;
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomDouble;
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween;
+
+public class CompositeStrategyTest extends RandomSpatialOpStrategyTestCase {
+
+  private SpatialPrefixTree grid;
+  private RecursivePrefixTreeStrategy rptStrategy;
+
+  private void setupQuadGrid(int maxLevels) {
+    //non-geospatial makes this test a little easier (in gridSnap), and using boundary values 2^X raises
+    // the prospect of edge conditions we want to test, plus makes for simpler numbers (no decimals).
+    SpatialContextFactory factory = new SpatialContextFactory();
+    factory.geo = false;
+    factory.worldBounds = new RectangleImpl(0, 256, -128, 128, null);
+    this.ctx = factory.newSpatialContext();
+    //A fairly shallow grid
+    if (maxLevels == -1)
+      maxLevels = randomIntBetween(1, 8);//max 64k cells (4^8), also 256*256
+    this.grid = new QuadPrefixTree(ctx, maxLevels);
+    this.rptStrategy = newRPT();
+  }
+
+  private void setupGeohashGrid(int maxLevels) {
+    this.ctx = SpatialContext.GEO;
+    //A fairly shallow grid
+    if (maxLevels == -1)
+      maxLevels = randomIntBetween(1, 3);//max 16k cells (32^3)
+    this.grid = new GeohashPrefixTree(ctx, maxLevels);
+    this.rptStrategy = newRPT();
+  }
+
+  protected RecursivePrefixTreeStrategy newRPT() {
+    final RecursivePrefixTreeStrategy rpt = new RecursivePrefixTreeStrategy(this.grid,
+        getClass().getSimpleName() + "_rpt");
+    rpt.setDistErrPct(0.10);//not too many cells
+    return rpt;
+  }
+
+  @Test
+  @Repeat(iterations = 20)
+  public void testOperations() throws IOException {
+    //setup
+    if (randomBoolean()) {
+      setupQuadGrid(-1);
+    } else {
+      setupGeohashGrid(-1);
+    }
+    SerializedDVStrategy serializedDVStrategy = new SerializedDVStrategy(ctx, getClass().getSimpleName() + "_sdv");
+    this.strategy = new CompositeSpatialStrategy("composite_" + getClass().getSimpleName(),
+        rptStrategy, serializedDVStrategy);
+
+    //Do it!
+
+    for (SpatialOperation pred : SpatialOperation.values()) {
+      if (pred == SpatialOperation.BBoxIntersects || pred == SpatialOperation.BBoxWithin) {
+        continue;
+      }
+      if (pred == SpatialOperation.IsDisjointTo) {//TODO
+        continue;
+      }
+      testOperationRandomShapes(pred);
+      deleteAll();
+      commit();
+    }
+  }
+
+  @Override
+  protected boolean needsDocValues() {
+    return true;//due to SerializedDVStrategy
+  }
+
+  @Override
+  protected Shape randomIndexedShape() {
+    return randomShape();
+  }
+
+  @Override
+  protected Shape randomQueryShape() {
+    return randomShape();
+  }
+
+  private Shape randomShape() {
+    return random().nextBoolean() ? randomCircle() : randomRectangle();
+  }
+
+  //TODO move up
+  private Shape randomCircle() {
+    final Point point = randomPoint();
+    //TODO pick using gaussian
+    double radius;
+    if (ctx.isGeo()) {
+      radius = randomDouble() * 100;
+    } else {
+      //find distance to closest edge
+      final Rectangle worldBounds = ctx.getWorldBounds();
+      double maxRad = point.getX() - worldBounds.getMinX();
+      maxRad = Math.min(maxRad, worldBounds.getMaxX() - point.getX());
+      maxRad = Math.min(maxRad, point.getY() - worldBounds.getMinY());
+      maxRad = Math.min(maxRad, worldBounds.getMaxY() - point.getY());
+      radius = randomDouble() * maxRad;
+    }
+
+    return ctx.makeCircle(point, radius);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89db4950/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/CellToBytesRefIterator50.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/CellToBytesRefIterator50.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/CellToBytesRefIterator50.java
new file mode 100644
index 0000000..cccec8e
--- /dev/null
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/prefix/CellToBytesRefIterator50.java
@@ -0,0 +1,44 @@
+/*
+ * 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.prefix;
+
+import org.apache.lucene.spatial.prefix.tree.Cell;
+import org.apache.lucene.util.BytesRef;
+
+/** For testing Lucene <= 5.0. Index redundant prefixes for leaf cells. Fixed in LUCENE-4942. */
+class CellToBytesRefIterator50 extends CellToBytesRefIterator {
+
+  Cell repeatCell;
+
+  @Override
+  public BytesRef next() {
+    if (repeatCell != null) {
+      bytesRef = repeatCell.getTokenBytesWithLeaf(bytesRef);
+      repeatCell = null;
+      return bytesRef;
+    }
+    if (!cellIter.hasNext()) {
+      return null;
+    }
+    Cell cell = cellIter.next();
+    bytesRef = cell.getTokenBytesNoLeaf(bytesRef);
+    if (cell.isLeaf()) {
+      repeatCell = cell;
+    }
+    return bytesRef;
+  }
+}