protected Rectangle makeNormRect(double minX, double maxX, double minY, double maxY) { if (ctx.isGeo()) { if (Math.abs(maxX - minX) >= 360) { minX = -180; maxX = 180; } else { minX = DistanceUtils.normLonDEG(minX); maxX = DistanceUtils.normLonDEG(maxX); } } else { if (maxX < minX) { double t = minX; minX = maxX; maxX = t; } minX = boundX(minX, ctx.getWorldBounds()); maxX = boundX(maxX, ctx.getWorldBounds()); } if (maxY < minY) { double t = minY; minY = maxY; maxY = t; } minY = boundY(minY, ctx.getWorldBounds()); maxY = boundY(maxY, ctx.getWorldBounds()); return ctx.makeRectangle(minX, maxX, minY, maxY); }
/** Normalize x & y (put in lon-lat ranges) & ensure geohash round-trip for given precision. */ private Point normPointXY(double x, double y) { // put x,y as degrees into double[] as radians double[] latLon = {Math.toRadians(y), Math.toRadians(x)}; DistanceUtils.normLatRAD(latLon); DistanceUtils.normLatRAD(latLon); double x2 = Math.toDegrees(latLon[1]); double y2 = Math.toDegrees(latLon[0]); // overwrite latLon, units is now degrees return GeohashUtils.decode(GeohashUtils.encodeLatLon(y2, x2, PRECISION), ctx); }
private Query query(GeoDistance geoDistance, SpatialStrategy spatialStrategy) { double kms = geoDistance.getValue(GeoDistanceUnit.KILOMETRES); double distance = DistanceUtils.dist2Degrees(kms, DistanceUtils.EARTH_MEAN_RADIUS_KM); Circle circle = spatialContext.makeCircle(longitude, latitude, distance); SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, circle); return spatialStrategy.makeQuery(args); }
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(); }
@Override public String toString() { // Add distance in km, which may be easier to recognize. double distKm = DistanceUtils.degrees2Dist(radiusDEG, DistanceUtils.EARTH_MEAN_RADIUS_KM); // instead of String.format() so that we get consistent output no matter the locale String dStr = new Formatter(Locale.getDefault()) .format("%.1f\u00B0 %.2fkm", radiusDEG, distKm) .toString(); return "Circle(" + point + ", d=" + dStr + ')'; }
private void init() { if (radiusDEG > 90) { // --spans more than half the globe assert enclosingBox.getWidth() == 360; double backDistDEG = 180 - radiusDEG; if (backDistDEG > 0) { double backRadius = 180 - radiusDEG; double backX = DistanceUtils.normLonDEG(getCenter().getX() + 180); double backY = DistanceUtils.normLatDEG(getCenter().getY() + 180); // Shrink inverseCircle as small as possible to avoid accidental overlap. // Note that this is tricky business to come up with a value small enough // but not too small or else numerical conditioning issues become a problem. backRadius -= Math.max( Math.ulp(Math.abs(backY) + backRadius), Math.ulp(Math.abs(backX) + backRadius)); if (inverseCircle != null) { inverseCircle.reset(backX, backY, backRadius); } else { inverseCircle = new GeoCircle(ctx.makePoint(backX, backY), backRadius, ctx); } } else { inverseCircle = null; // whole globe } horizAxisY = getCenter().getY(); // although probably not used } else { inverseCircle = null; double _horizAxisY = ctx.getDistCalc().calcBoxByDistFromPt_yHorizAxisDEG(getCenter(), radiusDEG, ctx); // some rare numeric conditioning cases can cause this to be barely beyond the box if (_horizAxisY > enclosingBox.getMaxY()) { horizAxisY = enclosingBox.getMaxY(); } else if (_horizAxisY < enclosingBox.getMinY()) { horizAxisY = enclosingBox.getMinY(); } else { horizAxisY = _horizAxisY; } // assert enclosingBox.relate_yRange(horizAxis,horizAxis,ctx).intersects(); } }
protected double normY(double y) { return ctx.isGeo() ? DistanceUtils.normLatDEG(y) : y; }
protected double normX(double x) { return ctx.isGeo() ? DistanceUtils.normLonDEG(x) : x; }