private double calcDist(Point p1, Point p2) {
   // TODO use ctx.calc?
   return DistanceUtils.distHaversineRAD(
           Math.toRadians(p1.getY()),
           Math.toRadians(p1.getX()),
           Math.toRadians(p2.getY()),
           Math.toRadians(p2.getX()))
       * ctx.getUnits().earthRadius();
 }
 @Test
 public void testBug1() {
   // AN ISSUE OF distPrec being 0 or the default
   clearIndex();
   final String fieldName = "geohashRecursiveRandom";
   Point pt = ctx.makePoint(8.751008491963148, -6.406441060826182);
   final int ID = 2;
   assertU(adoc("id", "" + ID, fieldName, pt.getY() + "," + pt.getX()));
   assertU(commit());
   final Point centerPt = ctx.makePoint(19.99999998137355, 20.00000006519258);
   final double queryDist = 3112.7;
   checkHits(fieldName, centerPt.getY() + "," + centerPt.getX(), queryDist, 0);
 }
예제 #3
0
 private static Shape fromSpatial4JShape(com.spatial4j.core.shape.Shape shape) {
   if (shape instanceof com.spatial4j.core.shape.Point) {
     com.spatial4j.core.shape.Point point = (com.spatial4j.core.shape.Point) shape;
     return point(point.getX(), point.getY());
   }
   if (shape instanceof com.spatial4j.core.shape.Circle) {
     com.spatial4j.core.shape.Circle circle = (com.spatial4j.core.shape.Circle) shape;
     return circle(
         point(circle.getCenter().getX(), circle.getCenter().getY()), circle.getRadius());
   }
   if (shape instanceof com.spatial4j.core.shape.Rectangle) {
     com.spatial4j.core.shape.Rectangle rectangle = (com.spatial4j.core.shape.Rectangle) shape;
     return rectangle(
         rectangle.getMinX(), rectangle.getMaxX(), rectangle.getMinY(), rectangle.getMaxY());
   }
   if (shape instanceof com.spatial4j.core.shape.impl.BufferedLineString) {
     com.spatial4j.core.shape.impl.BufferedLineString spatialLineString =
         (com.spatial4j.core.shape.impl.BufferedLineString) shape;
     List<com.spatial4j.core.shape.Point> spatialPoints = spatialLineString.getPoints();
     Point[] points = new Point[spatialPoints.size()];
     for (int i = 0; i < points.length; i++)
       points[i] = point(spatialPoints.get(i).getX(), spatialPoints.get(i).getY());
     return lineString(points);
   }
   if (shape instanceof com.spatial4j.core.shape.jts.JtsGeometry)
     return fromJtsGeometry((JtsGeometry) shape);
   throw new IllegalArgumentException("Unsupported shape type: " + shape.getClass().getName());
 }
예제 #4
0
 @Override
 public Point pointOnBearing(
     Point from, double distDEG, double bearingDEG, SpatialContext ctx, Point reuse) {
   if (distDEG == 0) {
     if (reuse == null) return from;
     reuse.reset(from.getX(), from.getY());
     return reuse;
   }
   double bearingRAD = DistanceUtils.toRadians(bearingDEG);
   double x = from.getX() + Math.sin(bearingRAD) * distDEG;
   double y = from.getY() + Math.cos(bearingRAD) * distDEG;
   if (reuse == null) {
     return ctx.makePoint(x, y);
   } else {
     reuse.reset(x, y);
     return reuse;
   }
 }
예제 #5
0
  @Override
  public double distance(Point from, double toX, double toY) {
    double deltaX = from.getX() - toX;
    double deltaY = from.getY() - toY;
    double xSquaredPlusYSquared = deltaX * deltaX + deltaY * deltaY;

    if (squared) return xSquaredPlusYSquared;

    return Math.sqrt(xSquaredPlusYSquared);
  }
예제 #6
0
 private Map<String, Object> buildGeoJsonPolygon(List<Point> points) throws IOException {
   Map<String, Object> json = new HashMap<String, Object>();
   json.put("type", "Polygon");
   List<double[]> newPoints = new ArrayList<double[]>();
   for (Point point : points) {
     newPoints.add(new double[] {point.getX(), point.getY()});
   }
   Object[] pointsArray = newPoints.toArray();
   Object[] envelopeArray = new Object[] {pointsArray};
   json.put("coordinates", envelopeArray);
   return json;
 }
 private double[] calcDistRange(Point startPoint, Point targetCenter, double targetSideDegrees) {
   double min = Double.MAX_VALUE;
   double max = Double.MIN_VALUE;
   for (double xLen : new double[] {targetSideDegrees, -targetSideDegrees}) {
     for (double yLen : new double[] {targetSideDegrees, -targetSideDegrees}) {
       Point p2 = normPointXY(targetCenter.getX() + xLen / 2, targetCenter.getY() + yLen / 2);
       double d = calcDist(startPoint, p2);
       min = Math.min(min, d);
       max = Math.max(max, d);
     }
   }
   return new double[] {min, max};
 }
예제 #8
0
 @Override
 public Rectangle calcBoxByDistFromPt(
     Point from, double distDEG, SpatialContext ctx, Rectangle reuse) {
   double minX = from.getX() - distDEG;
   double maxX = from.getX() + distDEG;
   double minY = from.getY() - distDEG;
   double maxY = from.getY() + distDEG;
   if (reuse == null) {
     return ctx.makeRectangle(minX, maxX, minY, maxY);
   } else {
     reuse.reset(minX, maxX, minY, maxY);
     return reuse;
   }
 }
예제 #9
0
 @Override
 public double calcBoxByDistFromPt_yHorizAxisDEG(Point from, double distDEG, SpatialContext ctx) {
   return from.getY();
 }
예제 #10
0
 @Override
 public boolean within(Point from, double toX, double toY, double distance) {
   double deltaX = from.getX() - toX;
   double deltaY = from.getY() - toY;
   return deltaX * deltaX + deltaY * deltaY <= distance * distance;
 }
  @Test
  public void geohashRecursiveRandom() {
    final String fieldName = "geohashRecursiveRandom"; // has length 12

    // 1. Iterate test with the cluster at some worldly point of interest
    Point[] clusterCenters =
        new Point[] {new PointImpl(0, 0), new PointImpl(0, 90), new PointImpl(0, -90)};
    for (Point clusterCenter : clusterCenters) {
      // 2. Iterate on size of cluster (a really small one and a large one)
      String hashCenter =
          GeohashUtils.encodeLatLon(clusterCenter.getY(), clusterCenter.getX(), PRECISION);
      // calculate the number of degrees in the smallest grid box size (use for both lat & lon)
      String smallBox = hashCenter.substring(0, hashCenter.length() - 1); // chop off leaf precision
      Rectangle clusterDims = GeohashUtils.decodeBoundary(smallBox, ctx);
      double smallDegrees =
          Math.max(
              clusterDims.getMaxX() - clusterDims.getMinX(),
              clusterDims.getMaxY() - clusterDims.getMinY());
      assert smallDegrees < 1;
      double largeDegrees = 20d; // good large size; don't use >=45 for this test code to work
      double[] sideDegrees = {largeDegrees, smallDegrees};
      for (double sideDegree : sideDegrees) {
        // 3. Index random points in this cluster box
        clearIndex();
        List<Point> points = new ArrayList<Point>();
        for (int i = 0; i < 20; i++) {
          double x = random.nextDouble() * sideDegree - sideDegree / 2 + clusterCenter.getX();
          double y = random.nextDouble() * sideDegree - sideDegree / 2 + clusterCenter.getY();
          final Point pt = normPointXY(x, y);
          points.add(pt);
          assertU(adoc("id", "" + i, fieldName, pt.getY() + "," + pt.getX()));
        }
        assertU(commit());

        // 3. Use 4 query centers. Each is radially out from each corner of cluster box by twice
        // distance to box edge.
        for (double qcXoff :
            new double[] {sideDegree, -sideDegree}) { // query-center X offset from cluster center
          for (double qcYoff :
              new double[] {sideDegree, -sideDegree}) { // query-center Y offset from cluster center
            Point queryCenter =
                normPointXY(qcXoff + clusterCenter.getX(), qcYoff + clusterCenter.getY());
            double[] distRange = calcDistRange(queryCenter, clusterCenter, sideDegree);
            // 4.1 query a small box getting nothing
            final String queryCenterStr = queryCenter.getY() + "," + queryCenter.getX();
            checkHits(fieldName, queryCenterStr, distRange[0] * 0.99, 0);
            // 4.2 Query a large box enclosing the cluster, getting everything
            checkHits(fieldName, queryCenterStr, distRange[1] * 1.01, points.size());
            // 4.3 Query a medium box getting some (calculate the correct solution and verify)
            double queryDist = distRange[0] + (distRange[1] - distRange[0]) / 2; // average

            // Find matching points.  Put into int[] of doc ids which is the same thing as the index
            // into points list.
            int[] ids = new int[points.size()];
            int ids_sz = 0;
            for (int i = 0; i < points.size(); i++) {
              Point point = points.get(i);
              if (calcDist(queryCenter, point) <= queryDist) ids[ids_sz++] = i;
            }
            ids = Arrays.copyOf(ids, ids_sz);
            // assert ids_sz > 0 (can't because randomness keeps us from being able to)

            checkHits(fieldName, queryCenterStr, queryDist, ids.length, ids);
          }
        }
      } // for sideDegree
    } // for clusterCenter
  } // randomTest()
 @Override
 public double distance(Point from, Point to) {
   return distance(from, to.getX(), to.getY());
 }