001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data;
003
004import org.openstreetmap.josm.data.coor.EastNorth;
005import org.openstreetmap.josm.tools.Utils;
006
007/**
008 * This is a simple data class for "rectangular" areas of the world, given in
009 * east/north min/max values.
010 *
011 * @author imi
012 */
013public class ProjectionBounds {
014    /**
015     * The minimum and maximum coordinates.
016     */
017    public double minEast, minNorth, maxEast, maxNorth;
018
019    /**
020     * Construct bounds out of two points.
021     */
022    public ProjectionBounds(EastNorth min, EastNorth max) {
023        this.minEast = min.east();
024        this.minNorth = min.north();
025        this.maxEast = max.east();
026        this.maxNorth = max.north();
027    }
028
029    public ProjectionBounds(EastNorth p) {
030        this.minEast = this.maxEast = p.east();
031        this.minNorth = this.maxNorth = p.north();
032    }
033
034    public ProjectionBounds(EastNorth center, double east, double north) {
035        this.minEast = center.east()-east/2.0;
036        this.minNorth = center.north()-north/2.0;
037        this.maxEast = center.east()+east/2.0;
038        this.maxNorth = center.north()+north/2.0;
039    }
040
041    public ProjectionBounds(double minEast, double minNorth, double maxEast, double maxNorth) {
042        this.minEast = minEast;
043        this.minNorth = minNorth;
044        this.maxEast = maxEast;
045        this.maxNorth = maxNorth;
046    }
047
048    public void extend(EastNorth e) {
049        if (e.east() < minEast) {
050            minEast = e.east();
051        }
052        if (e.east() > maxEast) {
053            maxEast = e.east();
054        }
055        if (e.north() < minNorth) {
056            minNorth = e.north();
057        }
058        if (e.north() > maxNorth) {
059            maxNorth = e.north();
060        }
061    }
062
063    public EastNorth getCenter() {
064        return new EastNorth((minEast + maxEast) / 2.0, (minNorth + maxNorth) / 2.0);
065    }
066
067    @Override
068    public String toString() {
069        return "ProjectionBounds["+minEast+","+minNorth+","+maxEast+","+maxNorth+']';
070    }
071
072    /**
073     * The two bounds intersect? Compared to java Shape.intersects, if does not use
074     * the interior but the closure. ("&gt;=" instead of "&gt;")
075     */
076    public boolean intersects(ProjectionBounds b) {
077        return b.maxEast >= minEast &&
078        b.maxNorth >= minNorth &&
079        b.minEast <= maxEast &&
080        b.minNorth <= maxNorth;
081    }
082
083    public EastNorth getMin() {
084        return new EastNorth(minEast, minNorth);
085    }
086
087    public EastNorth getMax() {
088        return new EastNorth(maxEast, maxNorth);
089    }
090
091    /**
092     * Determines if the bounds area is not null
093     * @return {@code true} if the area is not null
094     */
095    public boolean hasExtend() {
096        return !Utils.equalsEpsilon(minEast, maxEast) || !Utils.equalsEpsilon(minNorth, maxNorth);
097    }
098}