All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mapbox.mapboxsdk.geometry.BoundingBox Maven / Gradle / Ivy

There is a newer version: 9.2.1
Show newest version
package com.mapbox.mapboxsdk.geometry;

import android.os.Parcel;
import android.os.Parcelable;
import com.mapbox.mapboxsdk.api.ILatLng;
import com.mapbox.mapboxsdk.views.util.constants.MapViewConstants;
import java.io.Serializable;
import java.util.List;

/**
 * A rectangular geographical area defined in latitude and longitude units.
 */
public final class BoundingBox implements Parcelable, Serializable, MapViewConstants {

    static final long serialVersionUID = 2L;

    private final double mLatNorth;
    private final double mLatSouth;
    private final double mLonEast;
    private final double mLonWest;

    private final boolean mIsValid;

    /**
     * Construct a new bounding box based on its corners, given in NESW
     * order.
     *
     * @param north Northern Coordinate
     * @param east Eastern Coordinate
     * @param south Southern Coordinate
     * @param west Western Coordinate
     */
    public BoundingBox(final double north, final double east, final double south, final double west) {
        this.mLatNorth = north;
        this.mLonEast = east;
        this.mLatSouth = south;
        this.mLonWest = west;
        this.mIsValid = ((this.mLonWest < this.mLonEast) && (this.mLatNorth > this.mLatSouth));
    }

    /**
     * Construct a new bounding box based on its corners, given in NESW
     * order.
     *
     * @param northEast Coordinate
     * @param southWest Coordinate
     */
    public BoundingBox(final LatLng northEast, final LatLng southWest) {
        this(northEast.getLatitude(), northEast.getLongitude(), southWest.getLatitude(), southWest.getLongitude());
    }

    /**
     * Create a bounding box from another bounding box
     *
     * @param other the other bounding box
     */
    public BoundingBox(final BoundingBox other) {
        this.mLatNorth = other.getLatNorth();
        this.mLonEast = other.getLonEast();
        this.mLatSouth = other.getLatSouth();
        this.mLonWest = other.getLonWest();
        this.mIsValid = other.isValid();
    }

    /**
     * Create a new BoundingBox with no size centered at 0, 0, also known as null island
     */
    public BoundingBox() {
        this(0, 0, 0, 0);
    }

    /**
     * Calculates the centerpoint of this bounding box by simple interpolation and returns
     * it as a point. This is a non-geodesic calculation which is not the geographic center.
     *
     * @return LatLng center of this BoundingBox
     */
    public LatLng getCenter() {
        return new LatLng((this.mLatNorth + this.mLatSouth) / 2,
                (this.mLonEast + this.mLonWest) / 2);
    }

    public double getLatNorth() {
        return this.mLatNorth;
    }

    public double getLatSouth() {
        return this.mLatSouth;
    }

    public double getLonEast() {
        return this.mLonEast;
    }

    public double getLonWest() {
        return this.mLonWest;
    }

    public boolean isValid() {
        return this.mIsValid;
    }

    /**
     * Get the absolute distance, in degrees, between the north and
     * south boundaries of this bounding box
     *
     * @return Span distance
     */
    public double getLatitudeSpan() {
        return Math.abs(this.mLatNorth - this.mLatSouth);
    }

    /**
     * Get the absolute distance, in degrees, between the west and
     * east boundaries of this bounding box
     *
     * @return Span distance
     */
    public double getLongitudeSpan() {
        return Math.abs(this.mLonEast - this.mLonWest);
    }

    @Override
    public String toString() {
        return new StringBuffer().append("N:")
                .append(this.mLatNorth)
                .append("; E:")
                .append(this.mLonEast)
                .append("; S:")
                .append(this.mLatSouth)
                .append("; W:")
                .append(this.mLonWest)
                .toString();
    }

    /**
     * Constructs a bounding box that contains all of a list of LatLng
     * objects. Empty lists will yield invalid bounding boxes.
     *
     * @param latLngs List of LatLng objects
     * @return BoundingBox
     */
    public static BoundingBox fromLatLngs(final List latLngs) {
        double minLat = 90,
                minLon = 180,
                maxLat = -90,
                maxLon = -180;

        for (final ILatLng gp : latLngs) {
            final double latitude = gp.getLatitude();
            final double longitude = gp.getLongitude();

            minLat = Math.min(minLat, latitude);
            minLon = Math.min(minLon, longitude);
            maxLat = Math.max(maxLat, latitude);
            maxLon = Math.max(maxLon, longitude);
        }

        return new BoundingBox(maxLat, maxLon, minLat, minLon);
    }

    /**
     * Determines whether this bounding box matches another one via coordinates.
     *
     * @param other another bounding box
     * @return a boolean indicating whether the bounding boxes are equal
     */
    public boolean equals(final BoundingBox other) {

        if (other == null) {
            return false;
        }
        if (other == this) {
            return true;
        }

        return mLatNorth == other.getLatNorth()
                && mLatSouth == other.getLatSouth()
                && mLonEast == other.getLonEast()
                && mLonWest == other.getLonWest();
    }

    /**
     * Determines whether this bounding box contains a point and the point
     * does not touch its boundary.
     *
     * @param pGeoPoint the point which may be contained
     * @return true, if the point is contained within the box.
     */
    public boolean contains(final ILatLng pGeoPoint) {
        final double latitude = pGeoPoint.getLatitude();
        final double longitude = pGeoPoint.getLongitude();
        return ((latitude < this.mLatNorth) && (latitude > this.mLatSouth)) && ((longitude
                < this.mLonEast) && (longitude > this.mLonWest));
    }

    /**
     * Returns a new BoundingBox that stretches to contain both this and another BoundingBox.
     *
     * @param box BoundingBox to add
     * @return BoundingBox
     */
    public BoundingBox union(BoundingBox box) {
        return union(box.getLatNorth(), box.getLonEast(), box.getLatSouth(), box.getLonWest());
    }

    /**
     * Returns a new BoundingBox that stretches to include another bounding box,
     * given by corner points.
     *
     * @param pLatNorth Northern Coordinate
     * @param pLonEast Eastern Coordinate
     * @param pLatSouth Southern Coordinate
     * @param pLonWest Western Coordinate
     * @return BoundingBox
     */
    public BoundingBox union(final double pLatNorth, final double pLonEast, final double pLatSouth,
            final double pLonWest) {
        return new BoundingBox((this.mLatNorth < pLatNorth) ? pLatNorth : this.mLatNorth,
                (this.mLonEast < pLonEast) ? pLonEast : this.mLonEast,
                (this.mLatSouth > pLatSouth) ? pLatSouth : this.mLatSouth,
                (this.mLonWest > pLonWest) ? pLonWest : this.mLonWest);
    }

    /**
     * Returns a new BoundingBox that is the intersection of this with another box
     *
     * @param box BoundingBox to intersect with
     * @return BoundingBox
     */
    public BoundingBox intersect(BoundingBox box) {
        double maxLonWest = Math.max(this.mLonWest, box.getLonWest());
        double minLonEast = Math.min(this.mLonEast, box.getLonEast());
        double maxLatNorth = Math.min(this.mLatNorth, box.getLatNorth());
        double minLatSouth = Math.max(this.mLatSouth, box.getLatSouth());
        return new BoundingBox(maxLatNorth, minLonEast, minLatSouth, maxLonWest);
    }

    /**
     * Returns a new BoundingBox that is the intersection of this with another box
     *
     * @param north Northern Coordinate
     * @param east Eastern Coordinate
     * @param south Southern Coordinate
     * @param west Western Coordinate
     * @return BoundingBox
     */
    public BoundingBox intersect(double north, double east, double south, double west) {
        return intersect(new BoundingBox(north, east, south, west));
    }

    public static final Parcelable.Creator CREATOR =
            new Parcelable.Creator() {
                @Override
                public BoundingBox createFromParcel(final Parcel in) {
                    return readFromParcel(in);
                }

                @Override
                public BoundingBox[] newArray(final int size) {
                    return new BoundingBox[size];
                }
            };

    @Override
    public int hashCode() {
        return (int) ((mLatNorth + 90)
                + ((mLatSouth + 90) * 1000)
                + ((mLonEast + 180) * 1000000)
                + ((mLonEast + 180) * 1000000000));
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(final Parcel out, final int arg1) {
        out.writeDouble(this.mLatNorth);
        out.writeDouble(this.mLonEast);
        out.writeDouble(this.mLatSouth);
        out.writeDouble(this.mLonWest);
    }

    private static BoundingBox readFromParcel(final Parcel in) {
        final double latNorth = in.readDouble();
        final double lonEast = in.readDouble();
        final double latSouth = in.readDouble();
        final double lonWest = in.readDouble();
        return new BoundingBox(latNorth, lonEast, latSouth, lonWest);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy