static double getHeadingOfGeometryNearPoint(EdgeIteratorState edgeState, GHPoint point, double maxDistance) {
        final DistanceCalc calcDist = DistanceCalcEarth.DIST_EARTH;
        double closestDistance = Double.POSITIVE_INFINITY;
        PointList points = edgeState.fetchWayGeometry(FetchMode.ALL);
        int closestPoint = -1;
        for (int i = 1; i < points.size(); i++) {
            double fromLat = points.getLat(i - 1), fromLon = points.getLon(i - 1);
            double toLat = points.getLat(i), toLon = points.getLon(i);
            // the 'distance' between the point and an edge segment is either the vertical distance to the segment or
            // the distance to the closer one of the two endpoints. here we save one call to calcDist per segment,
            // because each endpoint appears in two segments (except the first and last).
            double distance = calcDist.validEdgeDistance(point.lat, point.lon, fromLat, fromLon, toLat, toLon)
                    ? calcDist.calcDenormalizedDist(calcDist.calcNormalizedEdgeDistance(point.lat, point.lon, fromLat, fromLon, toLat, toLon))
                    : calcDist.calcDist(fromLat, fromLon, point.lat, point.lon);
            if (i == points.size() - 1)
                distance = Math.min(distance, calcDist.calcDist(toLat, toLon, point.lat, point.lon));
            if (distance > maxDistance)
                continue;
            if (distance < closestDistance) {
                closestDistance = distance;
                closestPoint = i;
            }
        }
        if (closestPoint < 0)
            return Double.NaN;

        double fromLat = points.getLat(closestPoint - 1), fromLon = points.getLon(closestPoint - 1);
        double toLat = points.getLat(closestPoint), toLon = points.getLon(closestPoint);
        return AngleCalc.ANGLE_CALC.calcAzimuth(fromLat, fromLon, toLat, toLon);
    }
@Test
    public void getHeading() {
        GHPoint point = new GHPoint(55.67093, 12.577294);
        BooleanEncodedValue carAccessEnc = new SimpleBooleanEncodedValue("car_access", true);
        DecimalEncodedValue carSpeedEnc = new DecimalEncodedValueImpl("car_speed", 5, 5, false);
        EncodingManager em = EncodingManager.start().add(carAccessEnc).add(carSpeedEnc).build();
        BaseGraph g = new BaseGraph.Builder(em).create();
        EdgeIteratorState edge = g.edge(0, 1);
        g.getNodeAccess().setNode(0, 55.671044, 12.5771583);
        g.getNodeAccess().setNode(1, 55.6704136, 12.5784324);
        // GHUtility.setSpeed(50, 0, carAccessEnc, carSpeedEnc, edge.getFlags());
        assertEquals(131.2, HeadingEdgeFilter.getHeadingOfGeometryNearPoint(edge, point, 20), .1);
    }