/******************************************************************************* * Copyright (c) 2015 MITRE * All rights reserved. This program and the accompanying materials * are made available under the terms of the Apache License, Version 2.0 which * accompanies this distribution and is available at * http://www.apache.org/licenses/LICENSE-2.0.txt ******************************************************************************/ package org.locationtech.spatial4j.shape.impl; import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.shape.Rectangle; /** * INTERNAL: A numeric range between a pair of numbers. * Perhaps this class could become 1st class citizen extending Shape but not now. * Only public so is accessible from tests in another package. */ @Deprecated // See BBoxCalculator public class Range { protected final double min, max; public static Range xRange(Rectangle rect, SpatialContext ctx) { if (ctx.isGeo()) return new LongitudeRange(rect.getMinX(), rect.getMaxX()); else return new Range(rect.getMinX(), rect.getMaxX()); } public static Range yRange(Rectangle rect, SpatialContext ctx) { return new Range(rect.getMinY(), rect.getMaxY()); } public Range(double min, double max) { this.min = min; this.max = max; } public double getMin() { return min; } public double getMax() { return max; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Range range = (Range) o; if (Double.compare(range.max, max) != 0) return false; if (Double.compare(range.min, min) != 0) return false; return true; } @Override public int hashCode() { int result; long temp; temp = min != +0.0d ? Double.doubleToLongBits(min) : 0L; result = (int) (temp ^ (temp >>> 32)); temp = max != +0.0d ? Double.doubleToLongBits(max) : 0L; result = 31 * result + (int) (temp ^ (temp >>> 32)); return result; } @Override public String toString() { return "Range{" + min + " TO " + max + '}'; } public double getWidth() { return max - min; } public boolean contains(double v) { return v >= min && v <= max; } public double getCenter() { return min + getWidth()/2; } public Range expandTo(Range other) { assert this.getClass() == other.getClass(); return new Range(Math.min(min, other.min), Math.max(max, other.max)); } public double deltaLen(Range other) { double min3 = Math.max(min, other.min); double max3 = Math.min(max, other.max); return max3 - min3; } @Deprecated // See BBoxCalculator public static class LongitudeRange extends Range { public static final LongitudeRange WORLD_180E180W = new LongitudeRange(-180, 180); public LongitudeRange(double min, double max) { super(min, max); } public LongitudeRange(Rectangle r) { super(r.getMinX(), r.getMaxX()); } @Override public double getWidth() { double w = super.getWidth(); if (w < 0) w += 360; return w; } @Override public boolean contains(double v) { if (!crossesDateline()) return super.contains(v); return v >= min || v <= max;// the OR is the distinction from non-dateline cross } public boolean crossesDateline() { return min > max; } public double getCenter() { double ctr = super.getCenter(); if (ctr > 180) ctr -= 360; return ctr; } public double compareTo(LongitudeRange b) { return diff(getCenter(), b.getCenter()); } /** a - b (compareTo order). < 0 if a < b */ private static double diff(double a, double b) { double diff = a - b; if (diff <= 180) { if (diff >= -180) return diff; return diff + 360; } else { return diff - 360; } } @Override public Range expandTo(Range other) { return expandTo((LongitudeRange) other); } public LongitudeRange expandTo(LongitudeRange other) { LongitudeRange a, b;// a.ctr <= b.ctr if (this.compareTo(other) <= 0) { a = this; b = other; } else { a = other; b = this; } LongitudeRange newMin = b.contains(a.min) ? b : a;//usually 'a' LongitudeRange newMax = a.contains(b.max) ? a : b;//usually 'b' if (newMin == newMax) return newMin; if (newMin == b && newMax == a) return WORLD_180E180W; return new LongitudeRange(newMin.min, newMax.max); } } }