public void calcBoundingCircle() {
        int cxmin = Integer.MAX_VALUE;
        int cxmax = Integer.MIN_VALUE;
        int cymin = Integer.MAX_VALUE;
        int cymax = Integer.MIN_VALUE;

        // first calculate a starting center point as center of boundingbox
        for (int i = 0; i < points.size(); i++) {
            final Point p = points.get(i);
            if (p.x < cxmin) {
                cxmin = p.x;
            }
            if (p.x > cxmax) {
                cxmax = p.x;
            }
            if (p.y < cymin) {
                cymin = p.y;
            }
            if (p.y > cymax) {
                cymax = p.y;
            }
        }

        int cx = (cxmax + cxmin) / 2; // center of circle
        int cy = (cymax + cymin) / 2;

        double[] lonlat2m = CheapRulerHelper.getLonLatToMeterScales(cy); // conversion-factors at the center of circle
        double dlon2m = lonlat2m[0];
        double dlat2m = lonlat2m[1];

        double rad = 0;  // radius

        double dmax = 0; // length of vector from center to point
        int iMax = -1;

        do {
            // now identify the point outside of the circle that has the greatest distance
            for (int i = 0; i < points.size(); i++) {
                final Point p = points.get(i);

                // to get precisely the same results as in RoutingContext.calcDistance()
                // it's crucial to use the factors of the center!
                final double x1 = (cx - p.x) * dlon2m;
                final double y1 = (cy - p.y) * dlat2m;
                final double dist = Math.sqrt(x1 * x1 + y1 * y1);
                if (dist <= rad) {
                    continue;
                }
                if (dist > dmax) {
                    // new maximum distance found
                    dmax = dist;
                    iMax = i;
                }
            }
            if (iMax < 0) {
                break; // leave loop when no point outside the circle is found any more.
            }
            final double dd = 0.5 * (1 - rad / dmax);

            final Point p = points.get(iMax); // calculate new radius to just include this point
            cx += (int) (dd * (p.x - cx) + 0.5); // shift center toward point
            cy += (int) (dd * (p.y - cy) + 0.5);

            // get new factors at shifted centerpoint
            lonlat2m = CheapRulerHelper.getLonLatToMeterScales(cy);
            dlon2m = lonlat2m[0];
            dlat2m = lonlat2m[1];

            final double x1 = (cx - p.x) * dlon2m;
            final double y1 = (cy - p.y) * dlat2m;
            rad = Math.sqrt(x1 * x1 + y1 * y1);
            dmax = rad;
            iMax = -1;
        }
        while (true);

        ilon = cx;
        ilat = cy;
        radius = rad * 1.001 + 1.0; // ensure the outside-of-enclosing-circle test in RoutingContext.calcDistance() is not passed by segments ending very close to the radius due to limited numerical precision
    }
calcBoundingCircle is inspired by the algorithm described on
<a href="http://geomalgorithms.com/a08-_containers.html">...</a>
(fast computation of bounding circly in c). It is not as fast (the original
algorithm runs in linear time), as it may do more iterations but it takes
into account the coslat-factor being used for the linear approximation that
is also used in other places of brouter does change when moving the centerpoint
with each iteration.
This is done to ensure the calculated radius being used
in RoutingContext.calcDistance will actually contain the whole polygon.
<p>
For reasonable distributed vertices the implemented algorithm runs in O(n*ln(n)).
As this is only run once on initialization of OsmNogoPolygon this methods
overall usage of cpu is neglegible in comparism to the cpu-usage of the
actual routing algoritm.
main/src/main/java/cgeo/geocaching/brouter/core/OsmNogoPolygon.java