@Override public Point getCenter() { return bbox.getCenter(); }
@Override public Point getCenter() { return getBoundingBox().getCenter(); }
public SpatialRelation relate(Rectangle r) { //Check BBox for disjoint & within. SpatialRelation bboxR = bbox.relate(r); if (bboxR == DISJOINT || bboxR == WITHIN) return bboxR; //Either CONTAINS, INTERSECTS, or DISJOINT Point scratch = new PointImpl(0, 0, null); Point prC = r.getCenter(); SpatialRelation result = linePrimary.relate(r, prC, scratch); if (result == DISJOINT) return DISJOINT; SpatialRelation resultOpp = linePerp.relate(r, prC, scratch); if (resultOpp == DISJOINT) return DISJOINT; if (result == resultOpp)//either CONTAINS or INTERSECTS return result; return INTERSECTS; }
SpatialRelation relate(Rectangle r, Point prC, Point scratch) { assert r.getCenter().equals(prC); int cQuad = quadrant(prC); Point nearestP = scratch; cornerByQuadrant(r, oppositeQuad[cQuad], nearestP); boolean nearestContains = contains(nearestP); if (nearestContains) { Point farthestP = scratch; nearestP = null;//just to be safe (same scratch object) cornerByQuadrant(r, cQuad, farthestP); boolean farthestContains = contains(farthestP); if (farthestContains) return CONTAINS; return INTERSECTS; } else {// not nearestContains if (quadrant(nearestP) == cQuad) return DISJOINT;//out of buffer on same side as center return INTERSECTS;//nearest & farthest points straddle the line } }
@Override public Point getCenter() { Point center = this.center;//volatile read once if (center == null) { center = getBoundingBox().getCenter(); this.center = center; } return center; }
public double getDistanceForLevel(int level) { if (level < 1 || level > getMaxLevels()) throw new IllegalArgumentException("Level must be in 1 to maxLevels range"); //TODO cache for each level Cell cell = getCell(ctx.getWorldBounds().getCenter(), level); Rectangle bbox = cell.getShape().getBoundingBox(); double width = bbox.getWidth(); double height = bbox.getHeight(); //Use standard cartesian hypotenuse. For geospatial, this answer is larger // than the correct one but it's okay to over-estimate. return Math.sqrt(width * width + height * height); }
/** * 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; }