org.locationtech.spatial4j.shape.Rectangle Java Examples

The following examples show how to use org.locationtech.spatial4j.shape.Rectangle. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: SpatialPrefixTreeTest.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
@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());
  }
}
 
Example #2
Source File: Geo3dRptTest.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
@Test
public void testFailureLucene6535() throws IOException {
  setupStrategy();

  final List<GeoPoint> points = new ArrayList<>();
  points.add(new GeoPoint(planetModel, 18 * DEGREES_TO_RADIANS, -27 * DEGREES_TO_RADIANS));
  points.add(new GeoPoint(planetModel, -57 * DEGREES_TO_RADIANS, 146 * DEGREES_TO_RADIANS));
  points.add(new GeoPoint(planetModel, 14 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS));
  points.add(new GeoPoint(planetModel, -15 * DEGREES_TO_RADIANS, 153 * DEGREES_TO_RADIANS));
  final GeoPoint[] pathPoints = new GeoPoint[] {
      new GeoPoint(planetModel, 55.0 * DEGREES_TO_RADIANS, -26.0 * DEGREES_TO_RADIANS),
      new GeoPoint(planetModel, -90.0 * DEGREES_TO_RADIANS, 0.0),
      new GeoPoint(planetModel, 54.0 * DEGREES_TO_RADIANS, 165.0 * DEGREES_TO_RADIANS),
      new GeoPoint(planetModel, -90.0 * DEGREES_TO_RADIANS, 0.0)};
  final GeoPath path = GeoPathFactory.makeGeoPath(planetModel, 29 * DEGREES_TO_RADIANS, pathPoints);
  final Shape shape = new Geo3dShape<>(path,ctx);
  final Rectangle rect = ctx.makeRectangle(131, 143, 39, 54);
  testOperation(rect,SpatialOperation.Intersects,shape,true);
}
 
Example #3
Source File: TestTestFramework.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
@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());
}
 
Example #4
Source File: BBoxSimilarityValueSource.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
@Override
public DoubleValues getValues(LeafReaderContext readerContext, DoubleValues scores) throws IOException {

  final ShapeValues shapeValues = bboxValueSource.getValues(readerContext);
  return DoubleValues.withDefault(new DoubleValues() {
    @Override
    public double doubleValue() throws IOException {
      return score((Rectangle) shapeValues.value(), null);
    }

    @Override
    public boolean advanceExact(int doc) throws IOException {
      return shapeValues.advanceExact(doc);
    }
  }, 0);

}
 
Example #5
Source File: CompositeStrategyTest.java    From lucene-solr with Apache License 2.0 6 votes vote down vote 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);
}
 
Example #6
Source File: HeatmapFacetCounterTest.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
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 =  shapeFactory.pointXY(x, y);
      assertEquals(countMatchingDocsAtLevel(pt, facetLevel), facetCount);
    }
  }
}
 
Example #7
Source File: RandomSpatialOpFuzzyPrefixTreeTest.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
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;
}
 
Example #8
Source File: BBoxStrategy.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
@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);
}
 
Example #9
Source File: BBoxStrategy.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
@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);
}
 
Example #10
Source File: HeatmapFacetCounterTest.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
/** 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);
  }
}
 
Example #11
Source File: SpatialArgs.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
/**
 * 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;
}
 
Example #12
Source File: BBoxValueSource.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
@Override
public ShapeValues getValues(LeafReaderContext readerContext) throws IOException {

  final DoubleValues minX = DoubleValuesSource.fromDoubleField(strategy.field_minX).getValues(readerContext, null);
  final DoubleValues minY = DoubleValuesSource.fromDoubleField(strategy.field_minY).getValues(readerContext, null);
  final DoubleValues maxX = DoubleValuesSource.fromDoubleField(strategy.field_maxX).getValues(readerContext, null);
  final DoubleValues maxY = DoubleValuesSource.fromDoubleField(strategy.field_maxY).getValues(readerContext, null);

  //reused
  final Rectangle rect = strategy.getSpatialContext().makeRectangle(0,0,0,0);

  return new ShapeValues() {

    @Override
    public boolean advanceExact(int doc) throws IOException {
      return minX.advanceExact(doc) && maxX.advanceExact(doc) && minY.advanceExact(doc) && maxY.advanceExact(doc);
    }

    @Override
    public Shape value() throws IOException {
      rect.reset(minX.doubleValue(), maxX.doubleValue(), minY.doubleValue(), maxY.doubleValue());
      return rect;
    }

  };
}
 
Example #13
Source File: LatLonPointSpatialField.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
protected Query makeQueryFromIndex(Shape shape) {
      // note: latitude then longitude order for LLP's methods
      if (shape instanceof Circle) {
        Circle circle = (Circle) shape;
        double radiusMeters = circle.getRadius() * DistanceUtils.DEG_TO_KM * 1000;
        return LatLonPoint.newDistanceQuery(getFieldName(),
            circle.getCenter().getY(), circle.getCenter().getX(),
            radiusMeters);
      } else if (shape instanceof Rectangle) {
        Rectangle rect = (Rectangle) shape;
        return LatLonPoint.newBoxQuery(getFieldName(),
            rect.getMinY(), rect.getMaxY(), rect.getMinX(), rect.getMaxX());
      } else if (shape instanceof Point) {
        Point point = (Point) shape;
        return LatLonPoint.newDistanceQuery(getFieldName(),
            point.getY(), point.getX(), 0);
      } else {
        throw new UnsupportedOperationException("Shape " + shape.getClass() + " is not supported by " + getClass());
      }
//      } else if (shape instanceof LucenePolygonShape) {
//        // TODO support multi-polygon
//        Polygon poly = ((LucenePolygonShape)shape).lucenePolygon;
//        return LatLonPoint.newPolygonQuery(getFieldName(), poly);
    }
 
Example #14
Source File: QuadPrefixTree.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
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 + 1];
  levelH = new double[maxLevels + 1];

  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;

  for (int i = 1; i < levelW.length; i++) {
    levelW[i] = levelW[i - 1] / 2.0;
    levelH[i] = levelH[i - 1] / 2.0;
  }
}
 
Example #15
Source File: LatLonPointSpatialField.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
protected Query makeQueryFromDocValues(Shape shape) {
      // note: latitude then longitude order for LLP's methods
      if (shape instanceof Circle) {
        Circle circle = (Circle) shape;
        double radiusMeters = circle.getRadius() * DistanceUtils.DEG_TO_KM * 1000;
        return LatLonDocValuesField.newSlowDistanceQuery(getFieldName(),
            circle.getCenter().getY(), circle.getCenter().getX(),
            radiusMeters);
      } else if (shape instanceof Rectangle) {
        Rectangle rect = (Rectangle) shape;
        return LatLonDocValuesField.newSlowBoxQuery(getFieldName(),
            rect.getMinY(), rect.getMaxY(), rect.getMinX(), rect.getMaxX());
      } else if (shape instanceof Point) {
        Point point = (Point) shape;
        return LatLonDocValuesField.newSlowDistanceQuery(getFieldName(),
            point.getY(), point.getX(), 0);
      } else {
        throw new UnsupportedOperationException("Shape " + shape.getClass() + " is not supported by " + getClass());
      }
//      } else if (shape instanceof LucenePolygonShape) {
//        // TODO support multi-polygon
//        Polygon poly = ((LucenePolygonShape)shape).lucenePolygon;
//        return LatLonPoint.newPolygonQuery(getFieldName(), poly);
    }
 
Example #16
Source File: TestBBoxStrategy.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
@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.getShapeFactory().rect(
        DistanceUtils.normLonDEG(world.getMinX() + deltaLeft + shift),
        DistanceUtils.normLonDEG(world.getMaxX() - deltaRight + shift),
        world.getMinY() + deltaBottom, world.getMaxY() - deltaTop);
  } else {
    return ctx.getShapeFactory().rect(
        world.getMinX() + deltaLeft, world.getMaxX() - deltaRight,
        world.getMinY() + deltaBottom, world.getMaxY() - deltaTop);
  }
}
 
Example #17
Source File: Geo3dShape.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
@Override
public SpatialRelation relate(Shape other) {
  int relationship;
  if (other instanceof Geo3dShape<?>) {
    relationship = relate((Geo3dShape<?>) other);
  } else if (other instanceof Rectangle) {
    relationship = relate((Rectangle) other);
  } else if (other instanceof Point) {
    relationship = relate((Point) other);
  } else {
    throw new RuntimeException("Unimplemented shape relationship determination: " + other.getClass());
  }

  switch (relationship) {
    case GeoArea.DISJOINT:
      return SpatialRelation.DISJOINT;
    case GeoArea.OVERLAPS:
      return (other instanceof Point ? SpatialRelation.CONTAINS : SpatialRelation.INTERSECTS);
    case GeoArea.CONTAINS:
      return (other instanceof Point ? SpatialRelation.CONTAINS : SpatialRelation.WITHIN);
    case GeoArea.WITHIN:
      return SpatialRelation.CONTAINS;
  }

  throw new RuntimeException("Undetermined shape relationship: " + relationship);
}
 
Example #18
Source File: HiveQueryVisitor.java    From occurrence with Apache License 2.0 5 votes vote down vote up
/**
 * Given a bounding box, generates greater than / lesser than queries using decimalLatitude and
 * decimalLongitude to form a bounding box.
 */
private void boundingBox(Rectangle bounds) {
  builder.append('(');

  // Latitude is easy:
  builder.append(HiveColumnsUtils.getHiveColumn(DwcTerm.decimalLatitude));
  builder.append(GREATER_THAN_EQUALS_OPERATOR);
  builder.append(bounds.getMinY());
  builder.append(CONJUNCTION_OPERATOR);
  builder.append(HiveColumnsUtils.getHiveColumn(DwcTerm.decimalLatitude));
  builder.append(LESS_THAN_EQUALS_OPERATOR);
  builder.append(bounds.getMaxY());

  builder.append(CONJUNCTION_OPERATOR);

  // Longitude must take account of crossing the antimeridian:
  if (bounds.getMinX() < bounds.getMaxX()) {
    builder.append(HiveColumnsUtils.getHiveColumn(DwcTerm.decimalLongitude));
    builder.append(GREATER_THAN_EQUALS_OPERATOR);
    builder.append(bounds.getMinX());
    builder.append(CONJUNCTION_OPERATOR);
    builder.append(HiveColumnsUtils.getHiveColumn(DwcTerm.decimalLongitude));
    builder.append(LESS_THAN_EQUALS_OPERATOR);
    builder.append(bounds.getMaxX());
  } else {
    builder.append('(');
    builder.append(HiveColumnsUtils.getHiveColumn(DwcTerm.decimalLongitude));
    builder.append(GREATER_THAN_EQUALS_OPERATOR);
    builder.append(bounds.getMinX());
    builder.append(DISJUNCTION_OPERATOR);
    builder.append(HiveColumnsUtils.getHiveColumn(DwcTerm.decimalLongitude));
    builder.append(LESS_THAN_EQUALS_OPERATOR);
    builder.append(bounds.getMaxX());
    builder.append(')');
  }

  builder.append(')');
}
 
Example #19
Source File: BBoxField.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
@Override
protected DoubleValuesSource getValueSourceFromSpatialArgs(QParser parser, SchemaField field, SpatialArgs spatialArgs, String scoreParam, BBoxStrategy strategy) {
  if (scoreParam == null) {
    return null;
  }

  switch (scoreParam) {
    //TODO move these to superclass after LUCENE-5804 ?
    case OVERLAP_RATIO:
      double queryTargetProportion = 0.25;//Suggested default; weights towards target area

      String v = parser.getParam(PARAM_QUERY_TARGET_PROPORTION);
      if (v != null)
        queryTargetProportion = Double.parseDouble(v);

      double minSideLength = 0.0;
      v = parser.getParam(PARAM_MIN_SIDE_LENGTH);
      if (v != null)
        minSideLength = Double.parseDouble(v);

      return new BBoxOverlapRatioValueSource(
          strategy.makeShapeValueSource(), ctx.isGeo(),
          (Rectangle) spatialArgs.getShape(),
          queryTargetProportion, minSideLength);

    case AREA:
      return new ShapeAreaValueSource(strategy.makeShapeValueSource(), ctx, ctx.isGeo(),
          distanceUnits.multiplierFromDegreesToThisUnit() * distanceUnits.multiplierFromDegreesToThisUnit());

    case AREA2D:
      return new ShapeAreaValueSource(strategy.makeShapeValueSource(), ctx, false,
          distanceUnits.multiplierFromDegreesToThisUnit() * distanceUnits.multiplierFromDegreesToThisUnit());

    default:
      return super.getValueSourceFromSpatialArgs(parser, field, spatialArgs, scoreParam, strategy);
  }
}
 
Example #20
Source File: PointVectorStrategy.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
/**
 * 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();
}
 
Example #21
Source File: AbstractSpatialFieldType.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
@Override
protected Query getSpecializedRangeQuery(QParser parser, SchemaField field, String part1, String part2, boolean minInclusive, boolean maxInclusive) {
  if (!minInclusive || !maxInclusive)
    throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Both sides of spatial range query must be inclusive: " + field.getName());
  Point p1 = SpatialUtils.parsePointSolrException(part1, ctx);
  Point p2 = SpatialUtils.parsePointSolrException(part2, ctx);

  Rectangle bbox = ctx.makeRectangle(p1, p2);
  SpatialArgs spatialArgs = new SpatialArgs(SpatialOperation.Intersects, bbox);
  return getQueryFromSpatialArgs(parser, field, spatialArgs);//won't score by default
}
 
Example #22
Source File: SpatialUtils.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
/**
 * Calls {@link #parseRectangle(String, org.locationtech.spatial4j.context.SpatialContext)} and wraps the exception with
 * {@link org.apache.solr.common.SolrException} with a helpful message.
 */
public static Rectangle parseRectangeSolrException(String externalVal, SpatialContext ctx) throws SolrException {
  try {
    return parseRectangle(externalVal, ctx);
  } catch (InvalidShapeException e) {
    String message = e.getMessage();
    if (!message.contains(externalVal))
      message = "Can't parse rectangle '" + externalVal + "' because: " + message;
    throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, message, e);
  }
}
 
Example #23
Source File: BBoxStrategy.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
/**
 * 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();
}
 
Example #24
Source File: Geo3dBinaryCodec.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
@Override
public Rectangle readRect(DataInput dataInput) throws IOException {
  SerializableObject serializableObject = SerializableObject.readObject(planetModel, (InputStream) dataInput);
  if (serializableObject instanceof GeoBBox) {
    GeoBBox shape = (GeoBBox) serializableObject;
    return new Geo3dRectangleShape(shape, ctx);
  }
  throw new IllegalArgumentException("trying to read a not supported rectangle shape: " + serializableObject.getClass());
}
 
Example #25
Source File: BBoxStrategy.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
/**
 * 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);
}
 
Example #26
Source File: RandomSpatialOpFuzzyPrefixTreeTest.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
@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;
}
 
Example #27
Source File: HeatmapFacetCounterTest.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
/** 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;
}
 
Example #28
Source File: SpatialTestCase.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
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.getShapeFactory().rect(xMin, xMax, yMin, yMax);
}
 
Example #29
Source File: Geo3dPointShape.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
@Override
public Rectangle getBoundingBox() {
  Rectangle bbox = this.boundingBox;//volatile read once
  if (bbox == null) {
    bbox = new Geo3dRectangleShape(shape, spatialcontext);
    this.boundingBox = bbox;
  }
  return bbox;
}
 
Example #30
Source File: PointVectorStrategy.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
/**
 * 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();
}