package org.activityinfo.legacy.shared.reports.util.mapping; /* * #%L * ActivityInfo Server * %% * Copyright (C) 2009 - 2013 UNICEF * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import org.activityinfo.model.type.geo.AiLatLng; import java.io.Serializable; /* * Bounding box for a map. * * This cannot be mapped 1:1 to a rectangle, since a lat/long combination is a coordinate on * a sphere as opposed to a coordinate on a 2D plane. */ public class Extents implements Serializable { private static final int LAT_MAX = 90; private static final int LNG_MAX = 180; private static final int LAT_MIN = -LAT_MAX; private static final int LNG_MIN = -180; private double minLat; private double maxLat; private double minLon; private double maxLon; private Extents() { } public Extents(double minLat, double maxLat, double minLon, double maxLon) { super(); this.minLat = minLat; this.maxLat = maxLat; this.minLon = minLon; this.maxLon = maxLon; } public Extents(Extents toCopy) { super(); this.minLat = toCopy.minLat; this.maxLat = toCopy.maxLat; this.minLon = toCopy.minLon; this.maxLon = toCopy.maxLon; } /** * @return maximum geographic bounds (-180, -90, 180, 90)s */ public static Extents maxGeoBounds() { return new Extents(LAT_MIN, LAT_MAX, LNG_MIN, LNG_MAX); } public double getMinLat() { return minLat; } public void setMinLat(double minLat) { this.minLat = minLat; } public double getMaxLat() { return maxLat; } public void setMaxLat(double maxLat) { this.maxLat = maxLat; } public double getMinLon() { return minLon; } public void setMinLon(double minLon) { this.minLon = minLon; } public double getMaxLon() { return maxLon; } public void setMaxLon(double maxLon) { this.maxLon = maxLon; } public void grow(double lat, double lng) { if (lat < minLat) { minLat = lat; } if (lat > maxLat) { maxLat = lat; } if (lng < minLon) { minLon = lng; } if (lng > maxLon) { maxLon = lng; } } /** * Calculates the intersection of this Extents with given Extents * * @param b another Extents with which to intersect this Extents * @return the intersection of the two Extentss */ public Extents intersect(Extents b) { return new Extents(Math.max(minLat, b.minLat), Math.min(maxLat, b.maxLat), Math.max(minLon, b.minLon), Math.min(maxLon, b.maxLon)); } /** * @return true if this Extents intersects with <code>b</code> */ public boolean intersects(Extents b) { return !(b.maxLon < minLon || b.minLon > maxLon || b.maxLat < minLat || b.minLat > maxLat); } public void grow(Extents extents) { if (!extents.isEmpty()) { grow(extents.minLat, extents.minLon); grow(extents.maxLat, extents.maxLon); } } public static Extents emptyExtents() { return new Extents(+90.0, -90.0, +180.0, -180.0); } public static Extents empty() { return emptyExtents(); } /** * @param b * @return true if this Extents contains <code>b</code> */ public boolean contains(Extents b) { return b.minLon >= minLon && b.maxLon <= maxLon && b.minLat >= minLat && b.maxLat <= maxLat; } public boolean contains(AiLatLng center) { return contains(center.getLng(), center.getLat()); } /** * @return true if this Extents contains the point at (x,y) */ public boolean contains(double x, double y) { return x >= minLon && x <= maxLon && y >= minLat && y <= maxLat; } public static Extents create(double x1, double y1, double x2, double y2) { return new Extents(y1, y2, x1, x2); } /** * @return the x (longitude) coordinate of the Extents's centroid, (x1+x2)/2 */ public double getCenterX() { return (minLon + maxLon) / 2; } /** * @return the y (latitudinal) coordinate of the Extents's centroid, * (y1+y2)/2 */ public double getCenterY() { return (minLat + maxLat) / 2; } public boolean isEmpty() { return minLat > maxLat || minLon > maxLon; } public AiLatLng center() { return new AiLatLng((minLat + maxLat) / 2.0, (minLon + maxLon) / 2.0); } @Override public int hashCode() { return (minLon + "").hashCode(); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Extents other = (Extents) obj; return minLat == other.minLat && maxLat == other.maxLat && minLon == other.minLon && maxLon == other.maxLon; } @Override public String toString() { return "Extents{" + "minLat=" + minLat + ", maxLat=" + maxLat + ", minLon=" + minLon + ", maxLon=" + maxLon + '}'; } }