public static PointList sample(PointList input, double maxDistance, DistanceCalc distCalc, ElevationProvider elevation) {
        PointList output = new PointList(input.size() * 2, input.is3D());
        if (input.isEmpty()) return output;
        int nodes = input.size();
        double lastLat = input.getLat(0), lastLon = input.getLon(0), lastEle = input.getEle(0),
                thisLat, thisLon, thisEle;
        for (int i = 0; i < nodes; i++) {
            thisLat = input.getLat(i);
            thisLon = input.getLon(i);
            thisEle = input.getEle(i);
            if (i > 0) {
                double segmentLength = distCalc.calcDist3D(lastLat, lastLon, lastEle, thisLat, thisLon, thisEle);
                int segments = (int) Math.round(segmentLength / maxDistance);
                // for small distances, we use a simple and fast approximation to interpolate between points
                // for longer distances (or when crossing international date line) we use great circle interpolation
                boolean exact = segmentLength > GREAT_CIRCLE_SEGMENT_LENGTH || distCalc.isCrossBoundary(lastLon, thisLon);
                for (int segment = 1; segment < segments; segment++) {
                    double ratio = (double) segment / segments;
                    double lat, lon;
                    if (exact) {
                        GHPoint point = distCalc.intermediatePoint(ratio, lastLat, lastLon, thisLat, thisLon);
                        lat = point.getLat();
                        lon = point.getLon();
                    } else {
                        lat = lastLat + (thisLat - lastLat) * ratio;
                        lon = lastLon + (thisLon - lastLon) * ratio;
                    }
                    double ele = elevation.getEle(lat, lon);
                    if (!Double.isNaN(ele)) {
                        output.add(lat, lon, ele);
                    }
                }
            }
            output.add(thisLat, thisLon, thisEle);
            lastLat = thisLat;
            lastLon = thisLon;
            lastEle = thisEle;
        }
        return output;
    }
@Test
    public void doesntAddPointsCrossingInternationalDateLine() {
        PointList in = new PointList(2, true);
        in.add(0, -178.5, 0);
        in.add(0.0, 178.5, 0);

        PointList out = EdgeSampling.sample(
                in,
                DistanceCalcEarth.METERS_PER_DEGREE,
                new DistanceCalcEarth(),
                elevation
        );

        assertEquals("(0.0,-178.5,0.0), (0.0,-179.5,10.0), (0.0,179.5,10.0), (0.0,178.5,0.0)", round(out).toString());
    }