# LightOSM and OpenStreetMapX assigning inconsistent nearest node

**URL:** <https://discourse.julialang.org/t/lightosm-and-openstreetmapx-assigning-inconsistent-nearest-node/89633>\
**Category:** Geo\
**Created:** [November 1, 2022, 9:10pm UTC](https://discourse.julialang.org/t/lightosm-and-openstreetmapx-assigning-inconsistent-nearest-node/89633 "2022-11-01T21:10:19Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![ctrebbau](https://avatars.discourse-cdn.com/v4/letter/c/5f9b8f/32.png) [@ctrebbau](https://discourse.julialang.org/u/ctrebbau)\
**Post date:** [November 1, 2022, 9:10pm UTC](https://discourse.julialang.org/t/lightosm-and-openstreetmapx-assigning-inconsistent-nearest-node/89633/1 "2022-11-01T21:10:19Z")

</div>

100 randomly chosen real coordinates:  
`pts = collect(zip(df.cLat, df.cLng))[rand(1:size(df, 1), 100)]`

Conversion of points to appropriate package types:  
`losm_pts = [GeoLocation(pts[i][1], pts[i][2]) for i in 1:length(pts)]`  
`osmx_pts = [LLA(pts[i][1], pts[i][2]) for i in 1:length(pts)]`

Using appropiate API on self-same OSM map  
`losmNodes = LightOSM.nearest_node(g, losm_pts)[1]`  
`osmxNodes = [OpenStreetMapX.point_to_nodes(pt, m) for pt in osmx_pts]`

`sum(losmNodes .== osmxNodes)` =\> 26

 ![image](https://global.discourse-cdn.com/julialang/original/3X/2/e/2e333c64708fda2c33daf413d2e0b922ad62ceb6.png)

Is this expected behavior?  
Setup:

```julia
using LightOSM
using OpenStreetMapX

sol = GeoLocation(40.416775, -3.703790)
radius = 30 # km (you might wanna choose smaller radius)
data_file = joinpath(@ __DIR__ , "assets", "sol_30km.osm")

g_losm = LightOSM.graph_from_download(
                                    :point,
                                    point=sol,
                                    radius=radius,
                                    weight_type=:distance,
                                    download_format=:osm,
                                    save_to_file_location=data_file
                                    )

@time g = graph_from_file(
                        data_file, 
                        weight_type=:distance, 
                        precompute_dijkstra_states=false, 
                        largest_connected_component=true
                        )

@time m = get_map_data(
                    data_file,
                    use_cache=true,
                    trim_to_connected_graph=true
                    )
pts = [(40.45977619, -3.64972306), (40.4123686, -3.7043242), (40.4788906, -3.7418347), (40.4323104, -3.6872047), (40.4073795, -3.632668), (40.42164902, -3.69933352), (40.49180334, -3.65343723), (40.36011003, -3.68639991), (40.4440244, -3.6841504), (40.41666095, -3.71297909), (40.44113437, -3.68297474), (40.4263387, -3.70946389), (40.42662246, -3.68903793), (40.41527178, -3.68852225), (40.4328848, -3.6379967), (40.4286787, -3.7179097), (40.40717241, -3.68853017), (40.45314175, -3.62145994), (40.45770264, -3.68642494), (40.521698, -3.88468782), (40.449005, -3.7000483), (40.42022393, -3.70619079), (40.4469191, -3.6699378), (40.4134544, -3.6634627), (40.3987967, -3.6952302), (40.40771914, -3.61503991), (40.42921736, -3.70259969), (40.47553255, -3.67525063), (40.406528, -3.689373), (40.41838565, -3.70101392), (40.40617412, -3.69181302), (40.42593384, -3.69835465), (40.4267856, -3.6967374), (40.44563293, -3.60773659), (40.41691594, -3.69437511), (40.4320605, -3.6421621), (40.43600464, -3.68548169), (40.4031125, -3.6946819), (40.4269148, -3.6997695), (40.4510321, -3.5948981), (40.42525794, -3.6860182), (40.43395038, -3.69468391), (40.4327477, -3.5399445), (40.4399234, -3.7125539), (40.56665056, -3.61032285), (40.4399745, -3.7087431), (40.40122644, -3.59628875), (40.3778614, -3.7169789), (40.42983471, -3.69981565), (40.387983, -3.711779), (40.3755017, -3.6999926), (40.45898894, -3.67791139), (40.4313791, -3.6906561), (40.45213973, -3.6890672), (40.43873464, -3.70953597), (40.4072328, -3.6884097), (40.47051018, -3.67605186), (40.4334051, -3.6863526), (40.40317734, -3.6059012), (40.42540329, -3.66637956), (40.425744, -3.690308), (40.455769, -3.6976891), (40.3663398, -3.60001869), (40.3818695, -3.7172834), (40.4280238, -3.6966277), (40.4485723, -3.64852737), (40.44565562, -3.67175571), (40.4337923, -3.6844133), (40.41444787, -3.70027769), (40.43379095, -3.69128813), (40.42207866, -3.69764734), (40.40631031, -3.68845833), (40.3554854, -3.7784936), (40.49862671, -3.612889), (40.4166774, -3.7078537), (40.4102642, -3.6650068), (40.42832514, -3.67511261), (40.45329126, -3.69509295), (40.52252818, -3.63474827), (40.4488398, -3.6785424), (40.485591, -3.6346916), (40.42609397, -3.68794536), (40.4106581, -3.6644704), (40.52603672, -3.63684484), (40.4291194, -3.63469), (40.442856, -3.6401386), (40.4224859, -3.6825111), (40.41159154, -3.69779295), (40.42269689, -3.70753555), (40.46801, -3.57002), (40.43342104, -3.67312995), (40.46787479, -3.6951587), (40.4223607, -3.6938232), (40.491255, -3.594576), (40.44849247, -3.67053363), (40.39638871, -3.66900964), (40.4713565, -3.689335), (40.44038766, -3.69751196), (40.491111, -3.7010693), (40.3880102, -3.6889842)]

```

Comparisons along shortest paths between

```julia
strtPoints = [(40.40647374, -3.68861037), (40.4766087, -3.6876792), (40.423677, -3.6848885), (40.4429993, -3.67984459), (40.42625779, -3.69331498), (40.4170684, -3.6756673), (40.40042329, -3.61914136), (40.43208461, -3.68719853), (40.4431324, -3.6743115), (40.43723621, -3.66986241), (40.42985589, -3.69983482), (40.45574495, -3.68120812), (40.46254312, -3.67447646), (40.4379108, -3.8133623), (40.45347052, -3.69908986), (40.4012675, -3.5959367), (40.4637, -3.69354), (40.445051, -3.6868186), (40.52329745, -3.64814346), (40.42510453, -3.69224084), (40.46183075, -3.61775375), (40.5245128, -3.6421908), (40.47213, -3.73097), (40.43765982, -3.67690099), (40.4387251, -3.7935788), (40.44726613, -3.71879801), (40.43875567, -3.70335088), (40.4272168, -3.6941936), (40.43246741, -3.6846149), (40.4407972, -3.6560046), (40.48782021, -3.66446623), (40.43177402, -3.66691533), (40.45591005, -3.62149045), (40.43174292, -3.63298388), (40.48045716, -3.73669503), (40.46261203, -3.63156298), (40.42038172, -3.66242632), (40.4212875, -3.6746451), (40.4746587, -3.687773), (40.49027882, -3.6936422), (40.4845639, -3.7083036), (40.4499374, -3.6902337), (40.4496493, -3.6521805), (40.38325532, -3.7222768), (40.47642543, -3.63367572), (40.43369235, -3.69091547), (40.4261263, -3.6937435), (40.45233301, -3.67935441), (40.43818865, -3.69490725), (40.42890061, -3.67798448), (40.3898206, -3.7338412), (40.44515845, -3.63430437), (40.41638686, -3.68894669), (40.45800858, -3.69776577), (40.43452635, -3.70414138), (40.4087793, -3.6775419), (40.4984586, -3.6648577), (40.43783826, -3.69816423), (40.44177, -3.60804), (40.45812988, -3.71165466), (40.42070512, -3.72034594), (40.4272239, -3.6712037), (40.4452947, -3.6505415), (40.53185151, -3.63782066), (40.45851048, -3.67653007), (40.40761908, -3.68874793), (40.43407628, -3.68945539), (40.42286611, -3.68409065), (40.40729, -3.68812), (40.46720414, -3.81536923), (40.46278293, -3.6365346), (40.4343269, -3.6130739), (40.4476545, -3.6379286), (40.42884574, -3.71579692), (40.42950364, -3.68171499), (40.420539, -3.7040679), (40.43768199, -3.67672745), (40.4622958, -3.6162491), (40.4494742, -3.6678332), (40.43677637, -3.68522845), (40.45838766, -3.68166916), (40.4268809, -3.6536716), (40.43562835, -3.70148394), (40.44312908, -3.66818877), (40.43232727, -3.67701244), (40.4208559, -3.7061332), (40.43115412, -3.69265373), (40.4468401, -3.5953674), (40.44838244, -3.66544615), (40.47057237, -3.8209613), (40.42170849, -3.71839765), (40.42623004, -3.68971361), (40.42941808, -3.70031473), (40.4179008, -3.6984637), (40.4242752, -3.6662009), (40.47017751, -3.66643433), (40.49916614, -3.65650778), (40.44308108, -3.67445754), (40.39655069, -3.87176226), (40.4551661, -3.69450574)]
endPoints = [(40.40035, -3.70306), (40.47780807, -3.69849334), (40.4377299, -3.6800531), (40.4211153, -3.6879227), (40.41384654, -3.69493838), (40.471597, -3.682403), (40.48230943, -3.67061352), (40.4239884, -3.6864495), (40.406806, -3.691947), (40.44236981, -3.65546398), (40.4262522, -3.7068227), (40.4468401, -3.69488566), (40.447563, -3.656106), (40.4396692, -3.8073816), (40.43474505, -3.66857059), (40.42054213, -3.57832935), (40.491255, -3.594576), (40.4696799, -3.6698), (40.46801, -3.57002), (40.4296166, -3.6876464), (40.42423842, -3.68000284), (40.491255, -3.594576), (40.471597, -3.682403), (40.4358823, -3.6421008), (40.4354445, -3.7334977), (40.4585917, -3.6945422), (40.406806, -3.691947), (40.4730513, -3.6868434), (40.43313179, -3.73357988), (40.4227419, -3.6964978), (40.4256262, -3.6844591), (40.491255, -3.594576), (40.46801, -3.57002), (40.4806616, -3.6862549), (40.406806, -3.691947), (40.467844, -3.626451), (40.4637403, -3.6139041), (40.4431511, -3.6823055), (40.41807399, -3.68979726), (40.4867882, -3.6658943), (40.447689, -3.657577), (40.48837, -3.6959), (40.4295441, -3.6835559), (40.45766912, -3.66049308), (40.46682955, -3.65845665), (40.41458, -3.69028), (40.446625, -3.695867), (40.4466221, -3.6924595), (40.42212769, -3.69565118), (40.422233, -3.6923577), (40.432579, -3.7076952), (40.438277, -3.637089), (40.4465975, -3.6975215), (40.4277378, -3.7295722), (40.39943841, -3.68889302), (40.420281, -3.690747), (40.491255, -3.594576), (40.4167081, -3.6910361), (40.46575663, -3.61401077), (40.42791748, -3.71710682), (40.4427623, -3.7871334), (40.46801, -3.57002), (40.4349325, -3.6799566), (40.471754, -3.849293), (40.50185837, -3.66879389), (40.4348437, -3.6968111), (40.448043, -3.624555), (40.43067, -3.6822437), (40.4339336, -3.6924939), (40.44618, -3.71253), (40.4236729, -3.7072785), (40.4445497, -3.6543204), (40.4634108, -3.6967773), (40.4517406, -3.69269371), (40.4125946, -3.6937105), (40.465511, -3.616573), (40.385241, -3.717764), (40.422343, -3.686257), (40.472916, -3.6636556), (40.41819319, -3.68981805), (40.4235863, -3.6684468), (40.375187, -3.6470258), (40.446773, -3.6936392), (40.46801, -3.57002), (40.44898857, -3.6904071), (40.406806, -3.691947), (40.47537293, -3.68825234), (40.4063306, -3.6900896), (40.500982, -3.867037), (40.4481, -3.78518), (40.4209713, -3.7080051), (40.4489254, -3.6708406), (40.4556463, -3.6800522), (40.44954419, -3.69145327), (40.428623, -3.6951358), (40.44696788, -3.69304122), (40.42867831, -3.69419441), (40.406806, -3.691947), (40.45108855, -3.69518925), (40.471597, -3.682403)]

losm_oPoints = [GeoLocation(strtPoints[i][1], strtPoints[i][2]) for i in 1:length(strtPoints)]
losm_dPoints = [GeoLocation(endPoints[i][1], endPoints[i][2]) for i in 1:length(endPoints)]

osmx_oPoints = [LLA(strtPoints[i][1], strtPoints[i][2]) for i in 1:length(strtPoints)]
osmx_dPoints = [LLA(endPoints[i][1], endPoints[i][2]) for i in 1:length(endPoints)]

losm_oNodes = LightOSM.nearest_node(g, losm_oPoints)[1]
losm_dNodes = LightOSM.nearest_node(g, losm_dPoints)[1]

osmx_oNodes = [OpenStreetMapX.point_to_nodes(pt, m) for pt in osmx_oPoints]
osmx_dNodes = [OpenStreetMapX.point_to_nodes(pt, m) for pt in osmx_dPoints]

losm_paths = [LightOSM.shortest_path(g, losm_oNodes[i], losm_dNodes[i]) for i in 1:length(losm_oNodes)]
osmx_paths = [OpenStreetMapX.shortest_route(m, osmx_oNodes[i], osmx_dNodes[i], routing=:astar) for i in 1:length(osmx_oNodes)]

numLosmNodesInPath = [length(losm_paths[i]) for i in 1:length(losm_paths)]
numOsmxNodesInPath = [length(osmx_paths[i][1]) for i in 1:length(osmx_paths)]

diff_in_numOfNodes = numLosmNodesInPath .- numOsmxNodesInPath

osmxRouteDist = [osmx_paths[i][2] for i in 1:length(osmx_paths)] ./ 1000
losmRouteDist = [cumsum(weights_from_path(g, losm_paths[i]))[end] for i in 1:length(losm_paths)]

diff_in_distances = losmRouteDist .- osmxRouteDist

results = DataFrame(
    numLosmNodesInPath = numOfLosmNodes,
    numOsmxNodesInPath = numOfOsmxNodes,
    diff_in_numOfNodes = diff_in_numOfNodes,
    losmRouteDist = losmRouteDist,
    osmxRouteDist = osmxRouteDist,
    diff_in_distances = diff_in_distances
)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/a/7/a7fb03a9c3d469a4cd54fd966ae2f47efbaecc84.png)

`mean(diff_in_distances)` = 0.123  
`median(diff_in_distances)` = 0.015

```julia
histogram(losmRouteDist)
histogram(osmxRouteDist)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/f/0/f05c206ec821d835537a312e6bb4f940808041de.png)

Routes from OpenStreetMapX

 ![image](https://global.discourse-cdn.com/julialang/original/3X/0/f/0fce8812f558bd562c13c8b7aa1f20b30d5aedb5.jpeg)

Routes from LightOSM

 ![image](https://global.discourse-cdn.com/julialang/original/3X/d/0/d0c453421d203a7cc47ebb97ea805e743fcc792d.jpeg)

They do seem to match up pretty well, after all. But it is just still strange, I mean, check out the difference in the number of nodes between the two paths shown. There must be something wrong about my intuition about the underlying graphs. For instance, how can OpenStreetMapX draw such twisty path with only three nodes between them? There must be a fieldname in its graph that it’s using.

Anyways, would appreciate any insight you have about these if you do.

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [November 2, 2022, 7:26pm UTC](https://discourse.julialang.org/t/lightosm-and-openstreetmapx-assigning-inconsistent-nearest-node/89633/2 "2022-11-02T19:26:52Z")

</div>

Perhaps paths in one package are comprised of sub-paths and lengths calculated by aerial distance between nodes, and the other package polygonizes the path and thus gets a more accurate distance. According to this `Losm` polygonizes and `Osmx` has sub-paths. And also, `Losm` has longer distances accordingly. This fits with the table in the post.

---

<div class="post-metadata">

**Author:** ![ctrebbau](https://avatars.discourse-cdn.com/v4/letter/c/5f9b8f/32.png) [@ctrebbau](https://discourse.julialang.org/u/ctrebbau)\
**Post date:** [November 5, 2022, 11:17pm UTC](https://discourse.julialang.org/t/lightosm-and-openstreetmapx-assigning-inconsistent-nearest-node/89633/3 "2022-11-05T23:17:13Z")

</div>

HI @Dan, you mean like haversine or euclidean measures of distance? I’m pretty sure OpenStreetMapX implements euclidean in this case, I’m not quite as sure for LightOSM. I could measure the distance from each original point to its associated node and see who gets nearest but I wouldn’t put too much faith on the results, it would be interesting to see though.

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [November 6, 2022, 12:44am UTC](https://discourse.julialang.org/t/lightosm-and-openstreetmapx-assigning-inconsistent-nearest-node/89633/4 "2022-11-06T00:44:05Z")

</div>

I meant distances from point A to B directly or along a path. Haversine vs. Euclidean should make negligible difference here.
