if (radius >= DistanceUtils.HALF_EARTH_CIRCUMFERENCE) {
return new Rectangle2D.Double(0.0, 0.0, 360.0, 180.0);
}
int numberOfCrossOvers = 0;
Path2D path = new Path2D.Double();
DirectPosition2D initPT = DistanceUtils.getPointOnGreatCircle(center.getOrdinate(1),
center.getOrdinate(0), radius, 0);
path.moveTo(initPT.x + 180.0, initPT.y + 90.0);
DirectPosition2D currPT = initPT;
for (int i = 1; i < 360; i++) {
DirectPosition2D pt = DistanceUtils.getPointOnGreatCircle(center.getOrdinate(1),
center.getOrdinate(0), radius, i);
path.lineTo(pt.x + 180.0, pt.y + 90.0);
if (dateLineCrossOver(Longitude.normalize(currPT.x), Longitude.normalize(pt.x))) {
numberOfCrossOvers++;
}
currPT = pt;
}
if (dateLineCrossOver(Longitude.normalize(initPT.x), Longitude.normalize(currPT.x))) {
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(center.getOrdinate(0) + 180.0, center.getOrdinate(1) + 90.0)) {
return lowerHalf;
} else {
return new Rectangle2D.Double(0.0, r.getMinY(), 360.0, 180.0 - r.getMinY());
}
}
if (path.contains(center.getOrdinate(0) + 180.0, center.getOrdinate(1) + 90.0)) {
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);