/* * Copyright (c) 2015 Daimler AG / Moovel GmbH * * All rights reserved */ package com.car2go.maps.model; import android.os.Parcel; import android.os.Parcelable; /** * (Pseudo)Rectangular region on the map. * Immutable. */ public class LatLngBounds implements Parcelable { /** * South-West point of the region. */ public final LatLng southwest; /** * North-East point of the region. */ public final LatLng northeast; public LatLngBounds(LatLng southwest, LatLng northeast) { this.southwest = southwest; this.northeast = northeast; } protected LatLngBounds(Parcel in) { this.southwest = in.readParcelable(LatLng.class.getClassLoader()); this.northeast = in.readParcelable(LatLng.class.getClassLoader()); } /** * @return {@link com.car2go.maps.model.LatLngBounds.Builder} for {@link LatLngBounds} */ public static Builder builder() { return new Builder(); } /** * @return center of the region */ public LatLng getCenter() { // Implementation copied from original obfuscated version of LatLngBounds double var1 = (this.southwest.latitude + this.northeast.latitude) / 2.0D; double var3 = this.northeast.longitude; double var5 = this.southwest.longitude; double var7; if (var5 <= var3) { var7 = (var3 + var5) / 2.0D; } else { var7 = (var3 + 360.0D + var5) / 2.0D; } return new LatLng(var1, var7); } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof LatLngBounds)) return false; LatLngBounds that = (LatLngBounds) o; return southwest.equals(that.southwest) && northeast.equals(that.northeast); } @Override public int hashCode() { int result = southwest.hashCode(); result = 31 * result + northeast.hashCode(); return result; } @Override public String toString() { return "LatLngBounds{" + "southwest=" + southwest + ", northeast=" + northeast + '}'; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeParcelable(this.southwest, 0); dest.writeParcelable(this.northeast, 0); } public static final Parcelable.Creator<LatLngBounds> CREATOR = new Parcelable.Creator<LatLngBounds>() { public LatLngBounds createFromParcel(Parcel source) { return new LatLngBounds(source); } public LatLngBounds[] newArray(int size) { return new LatLngBounds[size]; } }; /** * Builds new instances of {@link LatLngBounds} */ public static class Builder { private double southWestLattitude = 1.0D / 0.0; private double northEastLattitude = -1.0D / 0.0; private double southWestLongitude = 0.0D / 0.0; private double northEastLongitude = 0.0D / 0.0; /** * Ensures that given point will be within output bounds. Output bounds guaranteed to be * as small as possible and enclose all given points. * * @return same {@link com.car2go.maps.model.LatLngBounds.Builder} */ public Builder include(LatLng point) { southWestLattitude = Math.min(southWestLattitude, point.latitude); northEastLattitude = Math.max(northEastLattitude, point.latitude); if (Double.isNaN(southWestLongitude)) { southWestLongitude = point.longitude; northEastLongitude = point.longitude; } else if (!withinBounds(point.longitude)) { if (degreeDifference(southWestLongitude, point.longitude) < degreeDifference(point.longitude, northEastLongitude)) { southWestLongitude = point.longitude; } else { northEastLongitude = point.longitude; } } return this; } private double degreeDifference(double first, double second) { return (first - second + 360.0D) % 360.0D; } private boolean withinBounds(double longitude) { return this.southWestLongitude <= this.northEastLongitude ? this.southWestLongitude <= longitude && longitude <= this.northEastLongitude : this.southWestLongitude <= longitude || longitude <= this.northEastLongitude; } /** * @return new instance of {@link LatLngBounds} * @throws IllegalStateException if less than 2 unique points were specified */ public LatLngBounds build() { if (Double.isNaN(southWestLongitude)) { throw new IllegalStateException("No included points"); } return new LatLngBounds( new LatLng(southWestLattitude, southWestLongitude), new LatLng(northEastLattitude, northEastLongitude) ); } } }