/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* 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/>
******************************************************************************/
package org.jdesktop.swingx.mapviewer;
import java.awt.geom.Rectangle2D;
import java.util.Set;
/**
* The <code>GeoBounds</code> class provides access the the North East and South West corners of the bounds and provides
* an intersects method.
* @author Dan Andrews
*/
public class GeoBounds
{
/** Internal representation of the bounds */
private Rectangle2D[] rects;
/**
* Constructor.
* @param minLat The minimum latitude.
* @param minLng The minimum longitude.
* @param maxLat The maximum latitude.
* @param maxLng The maximum longitude.
*/
public GeoBounds(double minLat, double minLng, double maxLat, double maxLng)
{
setRect(minLat, minLng, maxLat, maxLng);
}
/**
* Constructor.
* @param geoPositions A non null list of 2 or more different <code>GeoBounds</code> objects.
*/
public GeoBounds(Set<GeoPosition> geoPositions)
{
if (geoPositions == null || geoPositions.size() < 2)
{
throw new IllegalArgumentException("The attribute 'geoPositions' cannot be null and must "
+ "have 2 or more elements.");
}
double minLat = Integer.MAX_VALUE;
double minLng = Integer.MAX_VALUE;
double maxLat = Integer.MIN_VALUE;
double maxLng = Integer.MIN_VALUE;
for (GeoPosition position : geoPositions)
{
minLat = Math.min(minLat, position.getLatitude());
minLng = Math.min(minLng, position.getLongitude());
maxLat = Math.max(maxLat, position.getLatitude());
maxLng = Math.max(maxLng, position.getLongitude());
}
setRect(minLat, minLng, maxLat, maxLng);
}
/**
* Sets the internal rectangle representation.
* @param minLat The minimum latitude.
* @param minLng The minimum longitude.
* @param maxLat The maximum latitude.
* @param maxLng The maximum longitude.
*/
private void setRect(double minLat, double minLng, double maxLat, double maxLng)
{
if (!(minLat < maxLat))
{
throw new IllegalArgumentException("GeoBounds is not valid - minLat must be less that maxLat.");
}
if (!(minLng < maxLng))
{
if (minLng > 0 && minLng < 180 && maxLng < 0)
{
rects = new Rectangle2D[] {
// split into two rects e.g. 176.8793 to 180 and -180 to
// -175.0104
new Rectangle2D.Double(minLng, minLat, 180 - minLng, maxLat - minLat),
new Rectangle2D.Double(-180, minLat, maxLng + 180, maxLat - minLat) };
}
else
{
rects = new Rectangle2D[] { new Rectangle2D.Double(minLng, minLat, maxLng - minLng, maxLat - minLat) };
throw new IllegalArgumentException("GeoBounds is not valid - minLng must be less that maxLng or "
+ "minLng must be greater than 0 and maxLng must be less than 0.");
}
}
else
{
rects = new Rectangle2D[] { new Rectangle2D.Double(minLng, minLat, maxLng - minLng, maxLat - minLat) };
}
}
/**
* Determines if this bounds intersects the other bounds.
* @param other The other bounds to test for intersection with.
* @return Returns true if bounds intersect.
*/
public boolean intersects(GeoBounds other)
{
boolean rv = false;
for (Rectangle2D r1 : rects)
{
for (Rectangle2D r2 : other.rects)
{
rv = r1.intersects(r2);
if (rv)
{
break;
}
}
if (rv)
{
break;
}
}
return rv;
}
/**
* Gets the north west position.
* @return Returns the north west position.
*/
public GeoPosition getNorthWest()
{
return new GeoPosition(rects[0].getX(), rects[0].getMaxY());
}
/**
* Gets the south east position.
* @return Returns the south east position.
*/
public GeoPosition getSouthEast()
{
Rectangle2D r = rects[0];
if (rects.length > 1)
{
r = rects[1];
}
return new GeoPosition(r.getMaxX(), r.getY());
}
}