You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ds...@apache.org on 2015/02/09 04:49:16 UTC

svn commit: r1658302 - in /lucene/dev/branches/branch_5x: ./ lucene/ lucene/spatial/ lucene/spatial/src/java/org/apache/lucene/spatial/prefix/ lucene/spatial/src/test/org/apache/lucene/spatial/ lucene/spatial/src/test/org/apache/lucene/spatial/prefix/

Author: dsmiley
Date: Mon Feb  9 03:49:16 2015
New Revision: 1658302

URL: http://svn.apache.org/r1658302
Log:
LUCENE-6191: Spatial 2D heatmap for PrefixTreeStrategy

Added:
    lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java
      - copied, changed from r1658298, lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java
    lucene/dev/branches/branch_5x/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/HeatmapFacetCounterTest.java
      - copied unchanged from r1658298, lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/HeatmapFacetCounterTest.java
Modified:
    lucene/dev/branches/branch_5x/   (props changed)
    lucene/dev/branches/branch_5x/lucene/   (props changed)
    lucene/dev/branches/branch_5x/lucene/CHANGES.txt   (contents, props changed)
    lucene/dev/branches/branch_5x/lucene/spatial/   (props changed)
    lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java
    lucene/dev/branches/branch_5x/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestCase.java

Modified: lucene/dev/branches/branch_5x/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/CHANGES.txt?rev=1658302&r1=1658301&r2=1658302&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/CHANGES.txt (original)
+++ lucene/dev/branches/branch_5x/lucene/CHANGES.txt Mon Feb  9 03:49:16 2015
@@ -5,9 +5,13 @@ http://s.apache.org/luceneversions
 
 ======================= Lucene 5.1.0 =======================
 
+New Features
+
+* LUCENE-6191: New spatial 2D heatmap faceting for PrefixTreeStrategy. (David Smiley)
+
 Bug Fixes
 
-* Spatial pointsOnly flag on PrefixTreeStrategy shouldn't switch all predicates to
+* LUCENE-6190: Spatial pointsOnly flag on PrefixTreeStrategy shouldn't switch all predicates to
   Intersects. (David Smiley)
 
 Optimizations

Copied: lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java (from r1658298, lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java)
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java?p2=lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java&p1=lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java&r1=1658298&r2=1658302&rev=1658302&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java (original)
+++ lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java Mon Feb  9 03:49:16 2015
@@ -42,9 +42,6 @@ public class HeatmapFacetCounter {
 
   /** 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 {
@@ -148,9 +145,9 @@ public class HeatmapFacetCounter {
     //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
+    final 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<>();
+    final Map<Rectangle,Integer> ancestors = new HashMap<>();
 
     //Now lets count some facets!
     PrefixTreeFacetCounter.compute(strategy, context, filter, inputShape, facetLevel,

Modified: lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java?rev=1658302&r1=1658301&r2=1658302&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java (original)
+++ lucene/dev/branches/branch_5x/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java Mon Feb  9 03:49:16 2015
@@ -17,6 +17,7 @@ package org.apache.lucene.spatial.prefix
  * limitations under the License.
  */
 
+import java.io.IOException;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -27,7 +28,9 @@ import org.apache.lucene.analysis.TokenS
 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.search.Filter;
 import org.apache.lucene.spatial.SpatialStrategy;
 import org.apache.lucene.spatial.prefix.tree.Cell;
 import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
@@ -87,6 +90,10 @@ public abstract class PrefixTreeStrategy
     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
@@ -180,7 +187,14 @@ public abstract class PrefixTreeStrategy
     return new ShapeFieldCacheDistanceValueSource(ctx, p, queryPoint, multiplier);
   }
 
-  public SpatialPrefixTree getGrid() {
-    return grid;
+  /**
+   * Computes spatial facets in two dimensions as a grid of numbers.  The data is often visualized as a so-called
+   * "heatmap".
+   *
+   * @see org.apache.lucene.spatial.prefix.HeatmapFacetCounter#calcFacets(PrefixTreeStrategy, org.apache.lucene.index.IndexReaderContext, org.apache.lucene.search.Filter, com.spatial4j.core.shape.Shape, int, int)
+   */
+  public HeatmapFacetCounter.Heatmap calcFacets(IndexReaderContext context, Filter filter,
+                                   Shape inputShape, final int facetLevel, int maxCells) throws IOException {
+    return HeatmapFacetCounter.calcFacets(this, context, filter, inputShape, facetLevel, maxCells);
   }
 }

Modified: lucene/dev/branches/branch_5x/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestCase.java?rev=1658302&r1=1658301&r2=1658302&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestCase.java (original)
+++ lucene/dev/branches/branch_5x/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestCase.java Mon Feb  9 03:49:16 2015
@@ -17,7 +17,16 @@ package org.apache.lucene.spatial;
  * limitations under the License.
  */
 
+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.MockAnalyzer;
@@ -39,20 +48,17 @@ import org.apache.lucene.util.TestUtil;
 import org.junit.After;
 import org.junit.Before;
 
-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 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;
@@ -151,18 +157,42 @@ public abstract class SpatialTestCase ex
   }
 
   protected Rectangle randomRectangle() {
-    final Rectangle WB = ctx.getWorldBounds();
-    int rW = (int) randomGaussianMeanMax(10, WB.getWidth());
-    double xMin = randomIntBetween((int) WB.getMinX(), (int) WB.getMaxX() - rW);
-    double xMax = xMin + rW;
-
-    int yH = (int) randomGaussianMeanMax(Math.min(rW, WB.getHeight()), WB.getHeight());
-    double yMin = randomIntBetween((int) WB.getMinY(), (int) WB.getMaxY() - yH);
-    double yMax = yMin + yH;
+    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;