What is the purpose of the following function?

I’m reading the package OpenStreetMapX, and the following function confused me.

#############################################
### Find the Closest Point  Within Bounds ###
#############################################

# only for points where inbounds(p1) != inbounds(p2)
function boundary_point(p1::T, p2::T, bounds::OpenStreetMapX.Bounds{T}) where T<:Union{OpenStreetMapX.LLA,OpenStreetMapX.ENU}
    x1, y1 = OpenStreetMapX.getX(p1), OpenStreetMapX.getY(p1)
    x2, y2 = OpenStreetMapX.getX(p2), OpenStreetMapX.getY(p2)

    x, y = Inf, Inf

    if bounds.min_x >  bounds.max_x && x1*x2 < 0 
        
        if x1 < bounds.min_x && x2 < bounds.max_x || x2 < bounds.min_x && x1 < bounds.max_x
            x = bounds.min_x
            y = y1 + (y2 - y1) * (bounds.min_x - x1) / (x2 - x1)
        elseif x1 > bounds.max_x && x2 > bounds.min_x || x2 > bounds.max_x && x1 > bounds.min_x 
            x = bounds.max_x
            y = y1 + (y2 - y1) * (bounds.max_x - x1) / (x2 - x1)
        end
        
        p3 = T(OpenStreetMapX.XY(x, y))
        OpenStreetMapX.inbounds(p3, bounds) && return p3
    end
    
    # Move x to x bound if segment crosses boundary
    if x1 < bounds.min_x < x2 || x1 > bounds.min_x > x2
        x = bounds.min_x
        y = y1 + (y2 - y1) * (bounds.min_x - x1) / (x2 - x1)
    elseif x1 < bounds.max_x < x2 || x1 > bounds.max_x > x2
        x = bounds.max_x
        y = y1 + (y2 - y1) * (bounds.max_x - x1) / (x2 - x1)
    end

    p3 = T(OpenStreetMapX.XY(x, y))
    OpenStreetMapX.inbounds(p3, bounds) && return p3

    # Move y to y bound if segment crosses boundary
    if y1 < bounds.min_y < y2 || y1 > bounds.min_y > y2
        x = x1 + (x2 - x1) * (bounds.min_y - y1) / (y2 - y1)
        y = bounds.min_y
    elseif y1 < bounds.max_y < y2 || y1 > bounds.max_y > y2
        x = x1 + (x2 - x1) * (bounds.max_y - y1) / (y2 - y1)
        y = bounds.max_y
    end

    p3 = T(OpenStreetMapX.XY(x, y))
    OpenStreetMapX.inbounds(p3, bounds) && return p3

    error("Failed to find boundary point.")
end

I can see that, it is like drawing a straight line from the two points (x1,y1) and (x2,y2). Then, find the crossing point between this line and the bounds boundary? Is it so? Any comments are greatly appreciated.

@pszufe

Hi,

As one of the authors of the library I will try to answer your question:

Yeah, that is exactly what this function is doing. It finds the crossing point and add it as a new node to the mapfile.
The reason why is pretty simple, some ways (polylines used to define routes, buildings, etc.) in .osm files may contain nodes lying outside the selected boundary of the map and this might generate lots of problems when other functions from the library are used. Because of that, when it is possible, nodes should be replaced with the one inside the bounded region or just removed from the file.
At the first glance this function might look somehow convoluted, however all those conditions inside are necessary because without them working with two different coordinates systems will be impossible.
If you have more questions feel free to ask

3 Likes