在 OSMNx 中查找到最近边缘的距离时发现错误的距离

问题描述 投票:0回答:2

代码

您好,我正在尝试使用 OSMNx(OpenStreetMap + NetworkX)包查找到最近边缘的距离(以米为单位)。 这是我的代码:

def main():
lat = 51.217309
lon = 4.418449
get_d_to_nearest_edge(lat, lon, 'node_area.graphml')

请注意,“node_area.graphml”是包含此特定位置的离线地图。 get_d_to_nearest_edge() 函数如下:

def get_d_to_nearest_edge(latitude, longitude, file_name):
print("-Now the nearest edge will be found-")
G = ox.load_graphml(filename=file_name, folder='BAPenvironment')
_, _, _, distance = get_nearest_edge(G, (latitude, longitude))
print('The distance to the nearest edge is ' + to_str(distance) + ' m')

在上面的代码中,访问了函数 get_nearest_edge()。该函数的代码如下:

def get_nearest_edge(G, point):
"""
Return the nearest edge to a pair of coordinates. Pass in a graph and a tuple
with the coordinates. We first get all the edges in the graph. Secondly we compute
the euclidean distance from the coordinates to the segments determined by each edge.
The last step is to sort the edge segments in ascending order based on the distance
from the coordinates to the edge. In the end, the first element in the list of edges
will be the closest edge that we will return as a tuple containing the shapely
geometry and the u, v nodes.
Parameters
----------
G : networkx multidigraph
point : tuple
    The (lat, lng) or (y, x) point for which we will find the nearest edge
    in the graph
Returns
-------
closest_edge_to_point : tuple (shapely.geometry, u, v)
    A geometry object representing the segment and the coordinates of the two
    nodes that determine the edge section, u and v, the OSM ids of the nodes.
"""
start_time = time.time()

gdf = ox.graph_to_gdfs(G, nodes=False, fill_edge_geometry=True)
graph_edges = gdf[["geometry", "u", "v"]].values.tolist()

edges_with_distances = [
    (
        graph_edge,
        ox.Point(tuple(reversed(point))).distance(graph_edge[0])
    )
    for graph_edge in graph_edges
]

edges_with_distances = sorted(edges_with_distances, key=lambda x: x[1])
closest_edge_to_point, distance = edges_with_distances[0]

geometry, u, v = closest_edge_to_point

ox.log('Found nearest edge ({}) to point {} in {:,.2f} seconds'.format((u, v), point, time.time() - start_time))
print(distance)
return geometry, u, v, distance

这与 OSMNx 函数中内置的原始函数几乎相同,但已被修改为也返回距离。 最后一个函数 to_str() 在这里:

 # convert everything into the same type (np.array) and then convert it to a string 
   def to_str(var):
       return str(list(np.reshape(np.asarray(var), (1, np.size(var)))[0]))[1:-1]

输出

但是输出似乎不正确。当我在 Google 地图中验证到最近边缘的距离时,我发现这是 18.57m。

> Now the nearest edge will be found Converting node and edge attribute
> data types Loaded graph with 36 nodes and 62 edges in 0.01 seconds
> from "BAPenvironment\node_area.graphml" Created GeoDataFrame
> "unnamed_edges" from graph in 0.00 seconds Found nearest edge
> ((247670339, 247527633)) to point (51.217309, 4.418449) in 0.00 seconds
> 0.00018056587349098678 
> The distance to the nearest edge is 0.00018056587349098678 m

我刚刚添加了“m”,因为我认为这是以米为单位的。有人知道如何以米为单位吗?还是以米为单位,我的代码是否错误?

python networkx openstreetmap osmnx
2个回答
1
投票

OSMnx 的

nearest_edges
确实返回距离。请参阅文档,其中说“可以选择返回点与最近边缘之间的图形坐标单位的距离”。如果您不想使用度作为单位,只需投影您的图表:

import osmnx as ox
from shapely import Point

# lat-long point
point = 34.081076, -118.351811
G = ox.graph_from_point(point, dist=1000, network_type='drive')

# project the graph (and point) to a meter projection
Gp = ox.project_graph(G)
point_geom_proj, crs = ox.projection.project_geometry(Point(reversed(point)), to_crs=Gp.graph['crs'])
x, y = point_geom_proj.x, point_geom_proj.y

# find nearest edge as (u, v, key) and distance to it
(u, v, k), dist = ox.nearest_edges(Gp, x, y, return_dist=True)
dist # 40.2 meters

0
投票

我通过更改 Ox.Point 函数解决了这个问题。我编写了一个新函数来计算到 LineString 对象中每个坐标的半正弦距离。

from haversine import haversine, Unit

def closest_point_on_haversine(point,edge):
    closest_point = None
    
    for c in edge[0].coords:
        if closest_point == None:
            closest_point = haversine(tuple(reversed(point)), c, unit='m')
        else:
            if haversine(tuple(reversed(point)), c, unit='m') < closest_point:
                closest_point = haversine(tuple(reversed(point)), c, unit='m')
                
    return closest_point

def get_nearest_edge_with_dist(G, point):

    start_time = time.time()

    gdf = graph_to_gdfs(G, nodes=False, fill_edge_geometry=True)
    graph_edges = gdf[["geometry", "u", "v"]].values.tolist()

    edges_with_distances = [
        (
            graph_edge,
            # Point(tuple(reversed(point))).distance(graph_edge[0])
            closest_point_on_haversine(point,graph_edge)
        )
        for graph_edge in graph_edges
    ]

    edges_with_distances = sorted(edges_with_distances, key=lambda x: x[1])
    closest_edge_to_point, distance = edges_with_distances[0]

    geometry, u, v = closest_edge_to_point

    return geometry, u, v, distance
© www.soinside.com 2019 - 2024. All rights reserved.