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

[2/4] lucene-solr:branch_5x: LUCENE-7291: Fix spatial HeatmapFacetCounter bug with dateline and large non-point shapes (cherry picked from commit 7520d79)

LUCENE-7291: Fix spatial HeatmapFacetCounter bug with dateline and large non-point shapes
(cherry picked from commit 7520d79)


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

Branch: refs/heads/branch_5x
Commit: f6b0fb95dea43f9f508b613cf32f489aaa263c4e
Parents: 707bcc9b
Author: David Smiley <ds...@apache.org>
Authored: Fri Jun 10 13:36:07 2016 -0400
Committer: Steve Rowe <sa...@apache.org>
Committed: Thu Jun 16 14:30:37 2016 -0400

----------------------------------------------------------------------
 .../spatial/prefix/HeatmapFacetCounter.java     | 24 +++++++++++---------
 .../spatial/prefix/HeatmapFacetCounterTest.java |  9 ++++++++
 2 files changed, 22 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f6b0fb95/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
index ba4e65a..d0249f3 100644
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java
+++ b/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/HeatmapFacetCounter.java
@@ -201,8 +201,9 @@ public class HeatmapFacetCounter {
 
     int[] pair = new int[2];//output of intersectInterval
     for (Map.Entry<Rectangle, Integer> entry : ancestors.entrySet()) {
-      Rectangle rect = entry.getKey();
+      Rectangle rect = entry.getKey(); // from a cell (thus doesn't cross DL)
       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];
@@ -215,32 +216,33 @@ public class HeatmapFacetCounter {
         incrementRange(heatmap, startCol, endCol, startRow, endRow, count);
 
       } else {
+        // note: the cell rect might intersect 2 disjoint parts of the heatmap, so we do the left & right separately
+        final int leftColumns = (int) Math.round((180 - heatMinX) / cellWidth);
+        final int rightColumns = heatmap.columns - leftColumns;
         //left half of dateline:
-        if (rect.getMaxX() >= heatMinX) {
-          final int leftColumns = (int) Math.round((180 - heatMinX) / cellWidth) + 1;
+        if (rect.getMaxX() > heatMinX) {
           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];
+        if (rect.getMinX() < heatMaxX) {
+          intersectInterval(-180, heatMaxX, cellWidth, rightColumns, rect.getMinX(), rect.getMaxX(), pair);
+          final int startCol = pair[0] + leftColumns;
+          final int endCol = pair[1] + leftColumns;
           incrementRange(heatmap, startCol, endCol, startRow, endRow, count);
         }
       }
-
     }
 
     return heatmap;
   }
 
-  private static void intersectInterval(double heatMin, double heatMax, double heatCellLen, int heatLen,
+  private static void intersectInterval(double heatMin, double heatMax, double heatCellLen, int numCells,
                                         double cellMin, double cellMax,
                                         int[] out) {
+    assert heatMin < heatMax && cellMin < cellMax;
     //precondition: we know there's an intersection
     if (heatMin >= cellMin) {
       out[0] = 0;
@@ -248,7 +250,7 @@ public class HeatmapFacetCounter {
       out[0] = (int) Math.round((cellMin - heatMin) / heatCellLen);
     }
     if (heatMax <= cellMax) {
-      out[1] = heatLen - 1;
+      out[1] = numCells - 1;
     } else {
       out[1] = (int) Math.round((cellMax - heatMin) / heatCellLen) - 1;
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f6b0fb95/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
index 124af79..38e7ad8 100644
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/HeatmapFacetCounterTest.java
+++ b/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/HeatmapFacetCounterTest.java
@@ -83,6 +83,15 @@ public class HeatmapFacetCounterTest extends StrategyTestCase {
   }
 
   @Test
+  public void testLucene7291Dateline() throws IOException {
+    grid = new QuadPrefixTree(ctx, 2); // only 2, and we wind up with some big leaf cells
+    strategy = new RecursivePrefixTreeStrategy(grid, getTestClass().getSimpleName());
+    adoc("0", ctx.makeRectangle(-102, -83, 43, 52));
+    commit();
+    validateHeatmapResultLoop(ctx.makeRectangle(179, -179, 62, 63), 2, 100);// HM crosses dateline
+  }
+
+  @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();