Skip to content

Fixes bug where the only points involved in computePointAtDistanceThreshold #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

mdorford
Copy link

It can happen that both the starting point and the ending point that get passed to computePointAtDistanceThreshold are points in intersections rather than points BETWEEN intersections. When this happens, computePointAtDistanceThreshold will fail because the method does two things:

  1. Filters out any intersection points from the results at this line:
    PointList pointList = finalState.fetchWayGeometry(FetchMode.PILLAR_ONLY);
  2. attempts this if-block. If it enters this if-block then it tries pointList.reverse() (which cannot handle an empty PointList)
    // Reverse geometry when starting at adjacent node
    if (upstreamPath && finalState.getAdjNode() == endFeature.getNode() || !upstreamPath && finalState.getAdjNode() == endFeature.getNode()) {
    pointList.reverse();
    }

You can test that this is what is happening by replacing computePointAtDistanceThreshold with this logging-added modified computePointAtDistanceThreshold below and testing it on the north-carolina-latest.osm.pbf with
http://localhost:8989/buffer?point=35.1771105,-80.875977&roadName=South Boulevard&thresholdDistance=1609&buildUpstream=true

Note that the modified method shown below in this 'description' does NOT include the bug fix because it is desirable for the code to fail so that it displays the logging immediately before the failure.

private PointList computePointAtDistanceThreshold(BufferFeature startFeature, Double thresholdDistance,
                                                  BufferFeature endFeature, Boolean upstreamPath) {
    EdgeIteratorState finalState = graph.getEdgeIteratorState(endFeature.getEdge(), Integer.MIN_VALUE);
    PointList pointList = finalState.fetchWayGeometry(FetchMode.PILLAR_ONLY);

    PointList mdoPointList = finalState.fetchWayGeometry(FetchMode.ALL);
    List<GHPoint3D> towerPoints = new ArrayList<>();
    if (mdoPointList.size() != pointList.size()) {
        boolean isTowerPoint = true;
        for (GHPoint3D mdoPoint : mdoPointList) {
            for (GHPoint3D point : pointList) {
                if (point.getLat() == mdoPoint.getLat() && point.getLon() == mdoPoint.getLon()) {
                    isTowerPoint = false;
                    break;
                }

            }
            if (isTowerPoint) {
                towerPoints.add(mdoPoint);
            }
        }
        if (towerPoints.size() > 0) {
            StringBuilder builder = new StringBuilder();
            for (GHPoint3D towerPoint : towerPoints) {
                builder.append("\t" + towerPoint.getLat() + " " + towerPoint.getLon());
            }
            System.out.println("Number of pillar points: " + pointList.size() + "\tTower points: " + builder);
        }
    }

    // When the buffer is only as wide as a single edge, truncate one half of the
    // segment
    if (startFeature.getEdge().equals(endFeature.getEdge())) {
        return new PointList();
    }

    // Reverse geometry when starting at adjacent node
    if (upstreamPath && finalState.getAdjNode() == endFeature.getNode() || !upstreamPath && finalState.getAdjNode() == endFeature.getNode()) {
        pointList.reverse();
    }

    Double currentDistance = endFeature.getDistance();
    GHPoint3D previousPoint = pointList.get(0);

    return computePathListWithinThreshold(thresholdDistance, pointList, currentDistance, previousPoint);
}

@chansbtran chansbtran requested a review from mcook42 January 29, 2025 15:47
Copy link

@mcook42 mcook42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I had two non-blocking suggestions. It's up to you to apply them or not, but I do think they will provide slight improvements

Copy link

@payneBrandon payneBrandon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

@payneBrandon
Copy link

@mdorford looks like some of the tests are failing. I see this when running locally:
image

Copy link

@payneBrandon payneBrandon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks fine, but looks like we need to update the tests to match

@mdorford
Copy link
Author

I had misunderstood the purpose of this block. I needed to return it to its previous state.
if (startFeature.getEdge().equals(endFeature.getEdge())) {
return new PointList();
}

@payneBrandon payneBrandon merged commit 8b9ab35 into master Jan 31, 2025
4 checks passed
@payneBrandon payneBrandon deleted the bug/empty-points-when-buffer-call-tries-computePointAtDistanceThreshold-with-only-junction-points branch January 31, 2025 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants