Rev 605 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Copyright (c) 2009, Steve Ratcliffe
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* 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.
*/
package uk.me.parabola.splitter;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
/**
* A map area in map units. There is a constructor available for creating
* in lat/long form.
*
* @author Steve Ratcliffe
*/
public class Area {
public static final Area EMPTY =
new Area();
private int mapId
;
private String name
;
private final int minLat
;
private final int minLong
;
private final int maxLat
;
private final int maxLong
;
private Rectangle javaRect
;
private boolean isJoinable =
true;
private boolean isPseudoArea
;
public boolean isJoinable
() {
return isJoinable
;
}
public void setJoinable
(boolean isJoinable
) {
this.
isJoinable = isJoinable
;
}
/**
* Create an area from the given Garmin coordinates. We ensure that no dimension is zero.
*
* @param minLat The western latitude.
* @param minLong The southern longitude.
* @param maxLat The eastern lat.
* @param maxLong The northern long.
*/
public Area(int minLat,
int minLong,
int maxLat,
int maxLong
) {
this.
minLat = minLat
;
if (maxLat == minLat
)
this.
maxLat = minLat +
1;
else
this.
maxLat = maxLat
;
this.
minLong = minLong
;
if (minLong == maxLong
)
this.
maxLong = maxLong +
1;
else
this.
maxLong = maxLong
;
}
/**
* Apply bbox to area.
* @param area the area
* @param bbox the bounding box
* @return A new area instance that covers the intersection of area and bbox
* or null if they don't intersect
*/
public static Area calcArea
(Area area,
Rectangle bbox
) {
Rectangle dest =
new Rectangle();
Rectangle2D.
intersect(area.
getRect(), bbox, dest
);
if (dest.
getHeight() > 0 && dest.
getWidth() > 0)
return new Area(dest.
y, dest.
x, dest.
y + dest.
height, dest.
x + dest.
width);
return null;
}
/**
* Creates an empty area.
*/
private Area() {
minLat =
0;
maxLat =
0;
minLong =
0;
maxLong =
0;
}
public boolean verify
(){
return ! (minLat
> maxLat || minLong
> maxLong
|| minLong
< Utils.
MIN_LON_MAP_UNITS
|| maxLong
> Utils.
MAX_LON_MAP_UNITS
|| minLat
< Utils.
MIN_LAT_MAP_UNITS
|| maxLat
> Utils.
MAX_LAT_MAP_UNITS);
}
public Rectangle getRect
(){
if (javaRect ==
null)
javaRect =
new Rectangle(this.
minLong,
this.
minLat,
this.
maxLong-
this.
minLong,
this.
maxLat-
this.
minLat);
return javaRect
;
}
/**
*
* @return a new {@link java.awt.geom.Area} instance
*/
public java.
awt.
geom.
Area getJavaArea
(){
return new java.
awt.
geom.
Area(getRect
());
}
public void setMapId
(int mapId
) {
this.
mapId = mapId
;
}
public int getMapId
() {
return mapId
;
}
public String getName
() {
return name
;
}
public void setName
(String name
) {
this.
name = name
;
}
public int getMinLat
() {
return minLat
;
}
public int getMinLong
() {
return minLong
;
}
public int getMaxLat
() {
return maxLat
;
}
public int getMaxLong
() {
return maxLong
;
}
public int getWidth
() {
return maxLong - minLong
;
}
public int getHeight
() {
return maxLat - minLat
;
}
@
Override
public String toString
() {
return "("
+ Utils.
toDegrees(minLat
) +
','
+ Utils.
toDegrees(minLong
) +
") to ("
+ Utils.
toDegrees(maxLat
) +
','
+ Utils.
toDegrees(maxLong
) +
')';
}
public String toHexString
() {
return "(0x"
+
Integer.
toHexString(minLat
) +
",0x"
+
Integer.
toHexString(minLong
) +
") to (0x"
+
Integer.
toHexString(maxLat
) +
",0x"
+
Integer.
toHexString(maxLong
) +
')';
}
public boolean contains
(int lat,
int lon
) {
return lat
>= minLat
&& lat
<= maxLat
&& lon
>= minLong
&& lon
<= maxLong
;
}
public boolean contains
(Node node
) {
return contains
(node.
getMapLat(), node.
getMapLon());
}
/**
*
* @param other an area
* @return true if the other area is inside the Area (it may touch the boundary)
*/
public final boolean contains
(Area other
) {
return other.
getMinLat() >= minLat
&& other.
getMaxLat() <= maxLat
&& other.
getMinLong() >= minLong
&& other.
getMaxLong() <= maxLong
;
}
/**
* Checks if this area intersects the given bounding box at least
* in one point.
*
* @param bbox an area
* @return <code>true</code> if this area intersects the bbox;
* <code>false</code> else
*/
public final boolean intersects
(Area bbox
) {
return minLat
<= bbox.
getMaxLat() && maxLat
>= bbox.
getMinLat() &&
minLong
<= bbox.
getMaxLong() && maxLong
>= bbox.
getMinLong();
}
public final boolean overlaps
(Area bbox
) {
return minLat
< bbox.
getMaxLat() && maxLat
> bbox.
getMinLat() &&
minLong
< bbox.
getMaxLong() && maxLong
> bbox.
getMinLong();
}
public Area add
(Area area
) {
return new Area(
Math.
min(minLat, area.
minLat),
Math.
min(minLong, area.
minLong),
Math.
max(maxLat, area.
maxLat),
Math.
max(maxLong, area.
maxLong)
);
}
public boolean isPseudoArea
() {
return isPseudoArea
;
}
public void setPseudoArea
(boolean isPseudoArea
) {
this.
isPseudoArea = isPseudoArea
;
}
}