Java Code Examples for org.locationtech.spatial4j.shape.Rectangle#getMaxX()

The following examples show how to use org.locationtech.spatial4j.shape.Rectangle#getMaxX() . 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: 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 2
Source File: Geo3dShapeFactory.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
@Override
public void verifyX(double x) {
  Rectangle bounds = this.context.getWorldBounds();
  if (x < bounds.getMinX() || x > bounds.getMaxX()) {
    throw new InvalidShapeException("Bad X value " + x + " is not in boundary " + bounds);
  }
}
 
Example 3
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 4
Source File: BBoxStrategy.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
/**
 * 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 = this.makeNumericRangeQuery(field_minY, bbox.getMinY(), null, true, false);
  Query qMaxY = this.makeNumericRangeQuery(field_maxY, 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 = this.makeNumericRangeQuery(field_minX, bbox.getMinX(), null, true, false);
    Query qMaxX = this.makeNumericRangeQuery(field_maxX, 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 = this.makeNumericRangeQuery(field_minX, bbox.getMinX(), null, true, false);
    Query qMaxXLeft = this.makeNumericRangeQuery(field_maxX, 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 = this.makeNumericRangeQuery(field_minX, -180.0, null, true, false);
    Query qMaxXRight = this.makeNumericRangeQuery(field_maxX, 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 = this.makeNumericRangeQuery(field_minX, bbox.getMinX(), null, true, false);
    Query qXDLRight = this.makeNumericRangeQuery(field_maxX, 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);
}
 
Example 5
Source File: BBoxStrategy.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
/**
 * 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 = this.makeNumericRangeQuery(field_minY, bbox.getMinY(), null, true, false);
  Query qMaxY = this.makeNumericRangeQuery(field_maxY, 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 = this.makeNumericRangeQuery(field_minX, bbox.getMinX(), null, true, false);
    Query qMaxX = this.makeNumericRangeQuery(field_maxX, 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 = this.makeNumericRangeQuery(field_minX, bbox.getMinX(), null, true, false);
    Query qMaxXLeft = this.makeNumericRangeQuery(field_maxX, 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 = this.makeNumericRangeQuery(field_minX, -180.0, null, true, false);
    Query qMaxXRight = this.makeNumericRangeQuery(field_maxX, 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 = this.makeNumericRangeQuery(field_minX, bbox.getMinX(), null, true, false);
    Query qXDLRight = this.makeNumericRangeQuery(field_maxX, 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);
}
 
Example 6
Source File: LatLonType.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
@Override
public Query createSpatialQuery(QParser parser, SpatialOptions options) {
  Point point = SpatialUtils.parsePointSolrException(options.pointStr, SpatialContext.GEO);

  // lat & lon in degrees
  double latCenter = point.getY();
  double lonCenter = point.getX();
  
  double distDeg = DistanceUtils.dist2Degrees(options.distance, options.radius);
  Rectangle bbox = DistanceUtils.calcBoxByDistFromPtDEG(latCenter, lonCenter, distDeg, SpatialContext.GEO, null);
  double latMin = bbox.getMinY();
  double latMax = bbox.getMaxY();
  double lonMin, lonMax, lon2Min, lon2Max;
  if (bbox.getCrossesDateLine()) {
     lonMin = -180;
     lonMax = bbox.getMaxX();
     lon2Min = bbox.getMinX();
     lon2Max = 180;
  } else {
     lonMin = bbox.getMinX();
     lonMax = bbox.getMaxX();
     lon2Min = -180;
     lon2Max = 180;
  }
  
  IndexSchema schema = parser.getReq().getSchema();
  
  // Now that we've figured out the ranges, build them!
  SchemaField latSF = subField(options.field, LAT, schema);
  SchemaField lonSF = subField(options.field, LON, schema);

  SpatialDistanceQuery spatial = new SpatialDistanceQuery();


  if (options.bbox) {
    BooleanQuery.Builder result = new BooleanQuery.Builder();

    Query latRange = latSF.getType().getRangeQuery(parser, latSF,
              String.valueOf(latMin),
              String.valueOf(latMax),
              true, true);
    result.add(latRange, BooleanClause.Occur.MUST);

    if (lonMin != -180 || lonMax != 180) {
      Query lonRange = lonSF.getType().getRangeQuery(parser, lonSF,
              String.valueOf(lonMin),
              String.valueOf(lonMax),
              true, true);
      if (lon2Min != -180 || lon2Max != 180) {
        // another valid longitude range
        BooleanQuery.Builder bothLons = new BooleanQuery.Builder();
        bothLons.add(lonRange, BooleanClause.Occur.SHOULD);

        lonRange = lonSF.getType().getRangeQuery(parser, lonSF,
              String.valueOf(lon2Min),
              String.valueOf(lon2Max),
              true, true);
        bothLons.add(lonRange, BooleanClause.Occur.SHOULD);

        lonRange = bothLons.build();
      }

      result.add(lonRange, BooleanClause.Occur.MUST);
    }

    spatial.bboxQuery = result.build();
  }


  spatial.origField = options.field.getName();
  spatial.latSource = latSF.getType().getValueSource(latSF, parser);
  spatial.lonSource = lonSF.getType().getValueSource(lonSF, parser);
  spatial.latMin = latMin;
  spatial.latMax = latMax;
  spatial.lonMin = lonMin;
  spatial.lonMax = lonMax;
  spatial.lon2Min = lon2Min;
  spatial.lon2Max = lon2Max;
  spatial.lon2 = lon2Min != -180 || lon2Max != 180;

  spatial.latCenter = latCenter;
  spatial.lonCenter = lonCenter;
  spatial.dist = options.distance;
  spatial.planetRadius = options.radius;

  spatial.calcDist = !options.bbox;

  return spatial;
}
 
Example 7
Source File: TestSolr4Spatial.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
private void checkHits(String fieldName, boolean exact, String ptStr, double distKM, double sphereRadius, int count, int ... docIds) throws ParseException {
  if (exact && isBBoxField(fieldName)) {
    return; // bbox field only supports rectangular query
  }
  String [] tests = new String[docIds != null && docIds.length > 0 ? docIds.length + 1 : 1];
  //test for presence of required ids first
  int i = 0;
  if (docIds != null && docIds.length > 0) {
    for (int docId : docIds) {
      tests[i++] = "//result/doc/*[@name='id'][.='" + docId + "']";
    }
  }
  //check total length last; maybe response includes ids it shouldn't.  Nicer to check this last instead of first so
  // that there may be a more specific detailed id to investigate.
  tests[i++] = "*[count(//doc)=" + count + "]";

  //Test using the Lucene spatial syntax
  {
    //never actually need the score but lets test
    String score = randomScoreMode();

    double distDEG = DistanceUtils.dist2Degrees(distKM, DistanceUtils.EARTH_MEAN_RADIUS_KM);
    Point point = SpatialUtils.parsePoint(ptStr, SpatialContext.GEO);
    String circleStr = "BUFFER(POINT(" + point.getX()+" "+point.getY()+")," + distDEG + ")";
    String shapeStr;
    if (exact) {
      shapeStr = circleStr;
    } else {//bbox
      //the GEO is an assumption
      SpatialContext ctx = SpatialContext.GEO;
      Rectangle bbox = ctx.readShapeFromWkt(circleStr).getBoundingBox();
      shapeStr = "ENVELOPE(" + bbox.getMinX() + ", " + bbox.getMaxX() +
          ", " + bbox.getMaxY() + ", " + bbox.getMinY() + ")";
    }

    //FYI default distErrPct=0.025 works with the tests in this file
    assertQ(req(
          "fl", "id", "q","*:*", "rows", "1000",
          "fq", "{!field f=" + fieldName + (score==null?"":" score="+score)
            + "}Intersects(" + shapeStr + ")"),
        tests);
  }
  //Test using geofilt
  {
    assertQ(req(
        "fl", "id", "q", "*:*", "rows", "1000",
        "fq", "{!" + (exact ? "geofilt" : "bbox") + " sfield=" + fieldName + " pt='" + ptStr + "' d=" + distKM + " sphere_radius=" + sphereRadius + "}"),
        tests);
  }

}