class GeoBoxMaker implements BoxMaker {

    @Override
    // http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates
    public <N extends Number & Comparable<N>> Box<N> make(Point<N> center,
            N radius) {
        // angular distance in radians on a great circle
        double radDist = radiansFromUnits(radius.doubleValue());

        double radLat = degreesToRadians(center.getX().doubleValue());
        double radLon = degreesToRadians(center.getY().doubleValue());
        double minLat = radLat - radDist;
        double maxLat = radLat + radDist;

        double minLon, maxLon;
        if (minLat > MIN_LAT && maxLat < MAX_LAT) {
            double deltaLon = Math.asin(Math.sin(radDist) / Math.cos(radLat));
            minLon = radLon - deltaLon;
            maxLon = radLon + deltaLon;
            if (minLon < MIN_LON) {
                minLon += TWO_PI;
            }
            if (maxLon > MAX_LON) {
                maxLon -= TWO_PI;
            }
        } else {
            // a pole is within the distance
            minLat = Math.max(minLat, MIN_LAT);
            maxLat = Math.min(maxLat, MAX_LAT);
            minLon = MIN_LON;
            maxLon = MAX_LON;
        }
        
        // hack for the generic numbers
        N zero = subtract(radius, radius);
        N minLatN = add(zero, radiansToDegrees(minLat));
        N maxLatN = add(zero, radiansToDegrees(maxLat));
        N minLonN = add(zero, radiansToDegrees(minLon));
        N maxLonN = add(zero, radiansToDegrees(maxLon));

        return new Box<N>(
                new Point<N>(minLatN,minLonN),
                new Point<N>(maxLatN,maxLonN));
    }

    public  GeoBoxMaker(DistanceUnits units);

}