if (super.getOrdinate(2) >= DistanceUtils.HALF_EARTH_CIRCUMFERENCE) {
return new Rectangle2D.Double(0.0, 0.0, 360.0, 180.0);
}
int numberOfCrossOvers = 0;
Path2D path = new Path2D.Double();
LatLon initPT = DistanceUtils.getPointOnGreatCircle(super.getOrdinate(1),
super.getOrdinate(0), super.getOrdinate(2), 0);
path.moveTo(initPT.getShiftedLon(), initPT.getShiftedLat());
LatLon currPT = initPT;
for (int i = 1; i < 360; i++) {
LatLon pt = DistanceUtils.getPointOnGreatCircle(super.getOrdinate(1),
super.getOrdinate(0), super.getOrdinate(2), i);
path.lineTo(pt.getShiftedLon(), pt.getShiftedLat());
if (dateLineCrossOver(currPT.getNormLon(), pt.getNormLon())) {
numberOfCrossOvers++;
}
currPT = pt;
}
if (dateLineCrossOver(initPT.getNormLon(), currPT.getNormLon())) {
numberOfCrossOvers++;
}
/**
* If the path crosses the dateline once, it's a special case, so take care
* of it differently. It will need to include areas around the pole.
*/
if (numberOfCrossOvers == 1) {
Rectangle2D r = path.getBounds2D();
Rectangle2D lowerHalf = new Rectangle2D.Double(0.0, 0.0, 360.0, r
.getMaxY());
if (lowerHalf.contains(super.getOrdinate(0) + 180, super.getOrdinate(1) + 90)) {
return lowerHalf;
} else {
return new Rectangle2D.Double(0.0, r.getMinY(), 360.0, 180.0 - r
.getMinY());
}
}
if (path.contains(super.getOrdinate(0) + 180, super.getOrdinate(1) + 90)) {
Rectangle2D r = path.getBounds2D();
if ((r.getMaxX() - r.getMinX()) > 359.0) {
return new Rectangle2D.Double(0.0, 0.0, 360.0, 180.0);
} else if (r.getMinX() < 0 || r.getMaxX() > 360.0) {
/**
* For circles that crosses the dateline instead of splitting in half
* and having to go down the tree twice, for first version span
* longitude 360.0 and use the exact height of the box
*/
return new Rectangle2D.Double(0.0, r.getY(), 360.0, r.getHeight());
} else {
return path.getBounds2D();
}
} else {
Area pathArea = new Area(path);
Area wholeMap = new Area(new Rectangle2D.Double(0.0, 0.0, 360.0, 180.0));
wholeMap.subtract(pathArea);