public int calcDistance(int lon1, int lat1, int lon2, int lat2) {
        final double[] lonlat2m = CheapRulerHelper.getLonLatToMeterScales((lat1 + lat2) >> 1);
        final double dlon2m = lonlat2m[0];
        final double dlat2m = lonlat2m[1];
        double dx = (lon2 - lon1) * dlon2m;
        double dy = (lat2 - lat1) * dlat2m;
        double d = Math.sqrt(dy * dy + dx * dx);

        shortestmatch = false;

        if (nogopoints != null && !nogopoints.isEmpty() && d > 0.) {
            for (int ngidx = 0; ngidx < nogopoints.size(); ngidx++) {
                final OsmNodeNamed nogo = nogopoints.get(ngidx);
                final double x1 = (lon1 - nogo.ilon) * dlon2m;
                final double y1 = (lat1 - nogo.ilat) * dlat2m;
                final double x2 = (lon2 - nogo.ilon) * dlon2m;
                final double y2 = (lat2 - nogo.ilat) * dlat2m;
                final double r12 = x1 * x1 + y1 * y1;
                final double r22 = x2 * x2 + y2 * y2;
                double radius = Math.abs(r12 < r22 ? y1 * dx - x1 * dy : y2 * dx - x2 * dy) / d;

                if (radius < nogo.radius) { // 20m
                    double s1 = x1 * dx + y1 * dy;
                    double s2 = x2 * dx + y2 * dy;


                    if (s1 < 0.) {
                        s1 = -s1;
                        s2 = -s2;
                    }
                    if (s2 > 0.) {
                        radius = Math.sqrt(s1 < s2 ? r12 : r22);
                        if (radius > nogo.radius) {
                            continue;
                        }
                    }
                    if (nogo.isNogo) {
                        if (!(nogo instanceof OsmNogoPolygon)) {  // nogo is a circle
                            if (Double.isNaN(nogo.nogoWeight)) {
                                // default nogo behaviour (ignore completely)
                                nogoCost = -1;
                            } else {
                                // nogo weight, compute distance within the circle
                                nogoCost = nogo.distanceWithinRadius(lon1, lat1, lon2, lat2, d) * nogo.nogoWeight;
                            }
                        } else if (((OsmNogoPolygon) nogo).intersects(lon1, lat1, lon2, lat2)) {
                            // nogo is a polyline/polygon, we have to check there is indeed
                            // an intersection in this case (radius check is not enough).
                            if (Double.isNaN(nogo.nogoWeight)) {
                                // default nogo behaviour (ignore completely)
                                nogoCost = -1;
                            } else {
                                if (((OsmNogoPolygon) nogo).isClosed) {
                                    // compute distance within the polygon
                                    nogoCost = ((OsmNogoPolygon) nogo).distanceWithinPolygon(lon1, lat1, lon2, lat2) * nogo.nogoWeight;
                                } else {
                                    // for a polyline, just add a constant penalty
                                    nogoCost = nogo.nogoWeight;
                                }
                            }
                        }
                    } else {
                        shortestmatch = true;
                        nogo.radius = radius; // shortest distance to way
                        // calculate remaining distance
                        if (s2 < 0.) {
                            wayfraction = -s2 / (d * d);
                            final double xm = x2 - wayfraction * dx;
                            final double ym = y2 - wayfraction * dy;
                            ilonshortest = (int) (xm / dlon2m + nogo.ilon);
                            ilatshortest = (int) (ym / dlat2m + nogo.ilat);
                        } else if (s1 > s2) {
                            wayfraction = 0.;
                            ilonshortest = lon2;
                            ilatshortest = lat2;
                        } else {
                            wayfraction = 1.;
                            ilonshortest = lon1;
                            ilatshortest = lat1;
                        }

                        // here it gets nasty: there can be nogo-points in the list
                        // *after* the shortest distance point. In case of a shortest-match
                        // we use the reduced way segment for nogo-matching, in order not
                        // to cut our escape-way if we placed a nogo just in front of where we are
                        if (isEndpoint) {
                            wayfraction = 1. - wayfraction;
                            lon2 = ilonshortest;
                            lat2 = ilatshortest;
                        } else {
                            nogoCost = 0.;
                            lon1 = ilonshortest;
                            lat1 = ilatshortest;
                        }
                        dx = (lon2 - lon1) * dlon2m;
                        dy = (lat2 - lat1) * dlat2m;
                        d = Math.sqrt(dy * dy + dx * dx);
                    }
                }
            }
        }
        return (int) Math.max(1.0, Math.round(d));
    }
clean the nogolist (previoulsy saved by saveFullNogolist())
by removing nogos with waypoints within
main/src/main/java/cgeo/geocaching/brouter/core/RoutingContext.java