/**
* This file is part of OSM2ShareNav
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
* See COPYING.
*
* Copyright (c) 2007 Harald Mueller
*/
package net.sharenav.osmToShareNav.model;
import net.sharenav.osmToShareNav.MyMath;
/**
* This class holds the four values of a bounding box and provides methods
* to makes checks against it.
*/
public class Bounds implements Cloneable {
public float minLat = 90f;
public float maxLat = -90f;
public float minLon = 180f;
public float maxLon = -180f;
/**
* @return Minimum latitude (southern edge) of the bounding box in degrees.
*/
public float getMinLat() {
return minLat;
}
/**
* @return Maximum latitude (northern edge) of the bounding box in degrees.
*/
public float getMaxLat() {
return maxLat;
}
/**
* @return Minimum longitude (western edge) of the bounding box in degrees.
*/
public float getMinLon() {
return minLon;
}
/**
* @return Maximum longitude (eastern edge) of the bounding box in degrees.
*/
public float getMaxLon() {
return maxLon;
}
/**
* Extends, if necessary, this bounding box so it also includes this point.
* @param lat Latitude in degrees
* @param lon Longitude in degrees
*/
public void extend(float lat, float lon) {
if (lat < minLat) {
minLat = lat;
}
if (lat > maxLat) {
maxLat = lat;
}
if (lon < minLon) {
minLon = lon;
}
if (lon > maxLon) {
maxLon = lon;
}
}
/**
* Extends, if necessary, this bounding box so it also includes this point.
* @param lat Latitude in degrees
* @param lon Longitude in degrees
*/
public void extend(double lat, double lon) {
extend((float)lat, (float)lon);
}
/**
* Extends, if necessary, this bounding box so it also includes the passed
* bounding box.
* @param b Bounding box to include
*/
public void extend(Bounds b) {
extend(b.minLat, b.minLon);
extend(b.maxLat, b.maxLon);
}
public boolean isMostlyIn(Bounds testBound) {
float centLat = (testBound.maxLat + testBound.minLat) / 2;
float centLon = (testBound.maxLon + testBound.minLon) / 2;
if (centLat < minLat) {
return false;
}
if (centLon < minLon) {
return false;
}
if (centLat > maxLat) {
return false;
}
if (centLon > maxLon) {
return false;
}
return true;
}
public boolean isCompleteIn(Bounds testBound) {
if (testBound.minLat < minLat) {
return false;
}
if (testBound.minLon < minLon) {
return false;
}
if (testBound.maxLat > maxLat) {
return false;
}
if (testBound.maxLon > maxLon) {
return false;
}
return true;
}
/**
* test if the tested coordinate is inside this boundaries
* @param lat lat part of tested coordinate
* @param lon lon part of tested coordinate
* @return true if test coordinate is inside of this boundaries
*/
public boolean isIn(float lat, float lon) {
if (lat < minLat) {
return false;
}
if (lon < minLon) {
return false;
}
if (lat > maxLat) {
return false;
}
if (lon > maxLon) {
return false;
}
return true;
}
public boolean isInOrAlmostIn(float lat, float lon) {
if (lat < minLat - 0.005) {
return false;
}
if (lon < minLon - 0.005) {
return false;
}
if (lat > maxLat + 0.005) {
return false;
}
if (lon > maxLon + 0.005) {
return false;
}
return true;
}
public boolean isIn(double lat, double lon) {
return isIn((float)lat, (float) lon);
}
/**
* Checks if the node is on the boundary.
* @param n Node to check
* @return True if n is on the boundary
*/
public boolean isOnBoundary(Node n) {
return (n.getLat() == minLat || n.getLat() == maxLat ||
n.getLon() == minLon || n.getLon() == maxLon);
}
@Override
public Bounds clone() {
Bounds b = new Bounds();
b.maxLat = maxLat;
b.minLat = minLat;
b.maxLon = maxLon;
b.minLon = minLon;
return b;
}
/**
* Create two boundaries out of this bound by dividing it into two pieces.
* The orientation will be chosen so that length:width will be nearest 1:1
* @return an array of two bounds.
*/
public Bounds[] split(){
Bounds[] ret = new Bounds[2];
if ((maxLat-minLat) > (maxLon-minLon)){
float splitLat=(minLat+maxLat)/2;
ret[0]=clone();
ret[0].maxLat=splitLat;
ret[1]=clone();
ret[1].minLat=splitLat;
} else {
float splitLon=(minLon+maxLon)/2;
ret[0]=clone();
ret[0].maxLon=splitLon;
ret[1]=clone();
ret[1].minLon=splitLon;
}
return ret;
}
@Override
public String toString() {
return ("[Bound (" + minLat + "|" + minLon+")(" + maxLat + "|" + maxLon +
") fixptlatspan=" + getFixPtLatSpan() +
" fixptlonspan=" + getFixPtLonSpan() +
"]");
}
/**
* @return
*/
private int getFixPtLonSpan() {
return (int)(MyMath.degToRad(maxLon - minLon) * MyMath.FIXPT_MULT);
}
/**
* @return
*/
private int getFixPtLatSpan() {
return (int)(MyMath.degToRad(maxLat - minLat) * MyMath.FIXPT_MULT);
}
public int getFixPtSpan(){
return Math.max(getFixPtLonSpan(), getFixPtLatSpan());
}
public String toPropertyString(int regionNr) {
return "region." + regionNr + ".lat.min = " + minLat + "\r\n" +
"region." + regionNr + ".lon.min = " + minLon + "\r\n" +
"region." + regionNr + ".lat.max = " + maxLat + "\r\n" +
"region." + regionNr + ".lon.max = " + maxLon + "\r\n";
}
}