wannesm / leuvenmapmatching Goto Github PK
View Code? Open in Web Editor NEWLeuven.MapMatching toolbox for aligning GPS measurements to locations on a map.
License: Other
Leuven.MapMatching toolbox for aligning GPS measurements to locations on a map.
License: Other
I run the code shows:
File "/Users/xiguan/anaconda/lib/python3.6/urllib/request.py", line 650, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
HTTPError: Forbidden
But I run the code successfully before.Why is this happening recently?
Thank you!
hello,
I want to zoom in a specific part of a map to see the results. So I wrote this Code:
plot_map(map_con,
matcher=matcher,
use_osm=True,
zoom_path=True,
show_graph=True,
show_matching=False,
linewidth=1,
bb=[-105.0224, 37.9344, -104.9961, 37.9637],
filename=str(directory / "Foto.png"))
But it doesn't work. What am I doing wrong? Is this correct to write bb=[] like this or does it have another format?
I would be thankful for your help.
Looking through the code it seems like it returns the subtrajectory that matches the graph. Is there any way to get the matched part from the graph instead?
Apparently i cannot access it from
http://users.telenet.be/meirenwi/Leuven%20Stadswandeling%20-%205%20km%20RT.zip
And i can see no files in test directory. It would make it easier with it to test my solution as for my case it couldn't find the matching :)
Hi,
Something is going wrong when I am converting an OSMNX graph to a map object. I noticed the matching was a bit off, and when I compare the original graph to the map object I can see it is very simplified - edges simply connect all nodes.
Map object after adding nodes and edges from original graph
I noted that there are about 1000 less edges in the map object than the original graph. The number of nodes is identical. I am using "Approach 2" in the examples to add nodes and edges to an InMemMap. No errors are thrown when looping through the edges and using map_con.add_edge()
, and the loop runs through all edges of the original graph. But when I count the edges with len(list(map_con.all_nodes()))
immediately after the loop it is lower by around 1000. Is this something to do with OSMNX having linestring geometry between edges while the map object is a straight line from node to node? If so, is there a way to include the linestring geometry?
Am I missing something here? Any help would be greatly appreciated. The matching works fantastically for the incorrect network, so I am really hoping I can get it working on the original!
Here is the code block for adding the graph edges, nodes to the map object:
from leuvenmapmatching.map.inmem import InMemMap
from leuvenmapmatching.util.gpx import gpx_to_path
graph_proj = ox.project_graph(graph) # graph of downloaded OSM roads
map_con = InMemMap("myosm", use_latlon=True,
use_rtree=False, index_edges=False)
nodes, edges = ox.graph_to_gdfs(graph_proj, nodes=True, edges=True)
nodes_proj = nodes.to_crs("EPSG:4326")
edges_proj = edges.to_crs("EPSG:4326")
for nid, row in nodes_proj.iterrows():
map_con.add_node(nid, (row['lat'], row['lon']))
for nid1, nid2, _ in graph.edges:
map_con.add_edge(nid1, nid2)
print(graph_proj.number_of_edges()) # gives 28440
print(len(list(map_con.all_edges()))) # gives 27309
The details are as follows:
File "D:\Anaconda3\lib\site-packages\leuvenmapmatching\map\sqlite.py", line 393, in all_edges
c.execute(q, (min_x, max_x, min_y, max_y))
OperationalError: no such module: rtree
Hi, dear developer! The package is quite helpful for me, I appreciate it. But I have two questions:
I want to find the corresponding way id of my GPS points, by the way, my GPS data has non-zero speed.
But when I debug the "BaseMatcher", as shown in the first picture, I find "states" is an empty list. However, the matching picture is fine as shown in the second picture.
I don't know why the list is empty. Is there anyone kindful to help me?
I have tested several times that if I set "use_latlon=True" then the matching will be perfect, however, "matcher.path_pred_onlynodes" will return an empty list, which means that I cannot extract the matched points and output.
What is interesting is that if I set "use_latlon=False", I can get the nodes list while the matching result is not so good.
I am wondering how this could happen and how to address it.
Hello,
Here's the example code
matcher = DistanceMatcher(graph, max_dist=12000, max_lattice_width=2)
coordinates = [[40.756470508651724, -73.97319052003208]]
matcher.match(coordinates)
nodes = matcher.path_pred_onlynodes
print(len(nodes))
When I run this code I get 2 nodes while I only had one coordinate.
The nodes are ['7737876085', '6452768049']
Can you explain this please ?
Thanks a lot
In the graph structure of Example 1, in the list of nodes D is connected to, D should be replaced with F:
("D", (2, 4), ["B", "C", "D", "E", "K", "L"]) -> ("D", (2, 4), ["B", "C", "F", "E", "K", "L"])
When I pip install and try to run an example, I get
File "/usr/local/lib/python2.7/dist-packages/leuvenmapmatching/util.py", line 152
raise Exception(f"Should not happen")
^
SyntaxError: invalid syntax
Dear developers,
I do appreciate your hard work to produce this nice and handy package.
However, I'm struggling when it comes to tuning the hyperparameters of the matcher. In particular, I am testing it with GPS locations recorded during a motorway trip, in which we crossed few tunnels. Tunnels seem to be difficult to handle and I wanted to ask your opinion on whether it is best to:
Also, I did not get exactly how the non_emitting_length_factor parameter is exploited in the code and how it should be tuned (eg. increasing it we obtain less or more penalty for a sequence of non-emitting states? And what is the neutral value to get no penalty neither reward for the sequence of non-emitting states against a normal sequence?)
Most of these fails are because some test data files are missing, for e.g. LeuvenMapMatching/tests/rsrc/newson_krumm_2009/ground_truth_route.txt
.
======================================================================================================= test session starts ========================================================================================================
platform linux -- Python 3.6.8, pytest-3.2.1, py-1.4.34, pluggy-0.4.0 -- /opt/anaconda3/bin/python
cachedir: .cache
rootdir: /....../LeuvenMapMatching, inifile: setup.cfg
plugins: anyio-3.3.0
collected 53 items
tests/test_bugs.py::test_bug1 PASSED
tests/test_bugs.py::test_bug2 FAILED
tests/test_conversion.py::test_path_to_gpx PASSED
tests/test_conversion.py::test_grs80 PASSED
tests/test_conversion.py::test_distance1 PASSED
tests/test_conversion.py::test_distance2 PASSED
tests/test_conversion.py::test_bearing1 PASSED
tests/test_conversion.py::test_destination1 FAILED
tests/test_conversion.py::test_distance_segment_to_segment1 PASSED
tests/test_conversion.py::test_distance_segment_to_segment2 PASSED
tests/test_conversion.py::test_distance_segment_to_segment3 PASSED
tests/test_conversion.py::test_distance_segment_to_segment4 PASSED
tests/test_conversion.py::test_distance_point_to_segment1 PASSED
tests/test_newsonkrumm2009.py::test_route_slice1 FAILED
tests/test_newsonkrumm2009.py::test_bug1 PASSED
tests/test_newsonkrumm2009.py::test_route SKIPPED
tests/test_newsonkrumm2009.py::test_bug2 SKIPPED
tests/test_nonemitting.py::test_path1 PASSED
tests/test_nonemitting.py::test_path1_inc PASSED
tests/test_nonemitting.py::test_path1_dist PASSED
tests/test_nonemitting.py::test_path2 PASSED
tests/test_nonemitting.py::test_path2_dist PASSED
tests/test_nonemitting.py::test_path2_incremental PASSED
tests/test_nonemitting.py::test_path_duplicate PASSED
tests/test_nonemitting.py::test_path3_many_obs PASSED
tests/test_nonemitting.py::test_path3_few_obs_en PASSED
tests/test_nonemitting.py::test_path3_few_obs_e PASSED
tests/test_nonemitting.py::test_path3_dist PASSED
tests/test_nonemitting_circle.py::test_path1 PASSED
tests/test_nonemitting_circle.py::test_path1_dist PASSED
tests/test_nonemitting_circle.py::test_path2 PASSED
tests/test_nonemitting_circle.py::test_path2_dist PASSED
tests/test_parallelroads.py::test_parallel PASSED
tests/test_parallelroads.py::test_bb1 PASSED
tests/test_parallelroads.py::test_merge1 PASSED
tests/test_parallelroads.py::test_path1 PASSED
tests/test_path.py::test_path1 PASSED
tests/test_path.py::test_path1_dist PASSED
tests/test_path.py::test_path2 PASSED
tests/test_path.py::test_path2_inc PASSED
tests/test_path.py::test_path2_dist PASSED
tests/test_path.py::test_path_outlier PASSED
tests/test_path.py::test_path_outlier2 PASSED
tests/test_path.py::test_path_outlier_dist PASSED
tests/test_path.py::test_path3 PASSED
tests/test_path.py::test_path3_dist PASSED
tests/test_path_latlon.py::test_path1 FAILED
tests/test_path_latlon.py::test_path1_full SKIPPED
tests/test_path_latlon.py::test_path2_proj FAILED
tests/test_path_latlon.py::test_path2 FAILED
tests/test_path_latlon.py::test_path3 FAILED
tests/test_path_onlyedges.py::test_path1 PASSED
tests/test_path_onlyedges.py::test_path3 PASSED
Hi,
i'm trying to run the example that is posted here:
https://leuvenmapmatching.readthedocs.io/en/latest/usage/openstreetmap.html
anyway i keep getting this erros: RuntimeError: b'no arguments in initialization list.
Any suggestion to fix it? Here's the code
I used pip command to install the package on my laptop and desktop respectively, and their versions are both 1.1.3. However, the following code can successfully match a route on my laptop, while the same code doesn't work on the desktop
import panda as pd
import geopandas as gpd
import osmnx as ox
G = ox.load_graphml('./graph/hangzhou.graphml')
G_p = ox.project_graph(G, to_crs=4549)
nodes, edges = ox.graph_to_gdfs(G_p, nodes=True, edges=True)
map_con = InMemMap(name='HZnetwork', use_latlon=False, use_rtree=True, index_edges=True)
for node_id, row in nodes.iterrows():
map_con.add_node(node_id, (row['y'], row['x']))
for node_id_1, node_id_2, _ in G_p.edges:
map_con.add_edge(node_id_1, node_id_2)
matcher = DistanceMatcher(map_con, max_dist=500, max_dist_init=500,
min_prob_norm=0.1, non_emitting_length_factor=0.95,
obs_noise=50, obs_noise_ne=50, dist_noise=50,
max_lattice_width=20, non_emitting_states=True)
gps_data = pd.read_csv('./test_data.csv')
geo_data = gpd.GeoDataFrame(data, geometry=gpd.points_from_xy(data.lng, data.lat), crs=4326)
geo_data = geo_data.to_crs(4549)
path = list(zip(geo_data.geometry.y, geo_data.geometry.x))
states, _ = matcher.match(path, unique=False)
mmviz.plot_map(map_con, matcher=matcher, show_lattice=True,
show_labels=True, show_matching=True, show_graph=False, filename=None)
"""
laptop result
states = [(314934753, 314934751), (314934751, 5338584732), .......
desktop result
states = []
"""
All the inputs, params and codes are sure to be the same. I have tried to reinstall the package but it had no effects.
Can it be used to find unmapped routes in the map ?
I want to add routes to the map using gps traces .
Hi, thank for your contribution you have made.
I wonder if i could use copy_lastinterface and then using match_incremental. Can you give me an example ?
thanks a lot
Hello dear developers! Is it possible to get an access to your publication : “HMM with Non-Emitting States for Map Matching” ?
I suppose not only me but all LeuvenMapMatching users will be glad if it will be possible
Thank you!
This is my code and I want to visualize the gpx data for testing.
`from leuvenmapmatching.util.gpx import gpx_to_path
from leuvenmapmatching.matcher.distance import DistanceMatcher
from leuvenmapmatching.map.inmem import InMemMap
from leuvenmapmatching import visualization as mmviz
map_con = InMemMap("mymap", use_latlon=False)
track = gpx_to_path("route.gpx")
matcher = DistanceMatcher(map_con,
max_dist=100, max_dist_init=25, # meter
min_prob_norm=0.001,
non_emitting_length_factor=0.75,
obs_noise=50, obs_noise_ne=75, # meter
dist_noise=50, # meter
non_emitting_states=True,
max_lattice_width=5)
states, lastidx = matcher.match(track)
mmviz.plot_map(map_con, matcher=matcher,
use_osm=True, zoom_path=True,
show_labels=False, show_matching=True, show_graph=False,
filename="my_osm_plot.png")`
However, the following error appear.
Traceback (most recent call last):
File "C:\Users\Jason...\Data_prep\MapMatching.py", line 20, in
mmviz.plot_map(map_con, matcher=matcher,
File "C:\Users\Jason...\Data_prep\venv\Lib\site-packages\leuvenmapmatching\visualization.py", line 62, in plot_map
bb = map_con.bb()
^^^^^^^^^^^^
File "C:\Users\Jason...\Data_prep\venv\Lib\site-packages\leuvenmapmatching\map\inmem.py", line 187, in bb
glat, glon = zip(*[t[0] for t in self.graph.values()])
^^^^^^^^^^
ValueError: not enough values to unpack (expected 2, got 0)
Please, I wanna know how to fix it.
Hello! I've already gotten the matching section of the graph from returned values by DistanceMatcher.match(). But I couldn't get the accurate matching point by this method. What should I do? AND please give me a guide of the main classes if possible. THX!
File "D:\Anaconda3\lib\site-packages\leuvenmapmatching\map\sqlite.py", line 151, in create_db
c.execute(q)
OperationalError: no such module: rtree
I've recompiled sqlite succefully.Then how could i use the python code with sqlite?I am a green hand,Beg for help.I've been working on it for a long time.Please
Hello dear developers! I am trying to use LeuvenMapMatching
in my Master thesis.
I am using the example with osmnx from documentation
https://leuvenmapmatching.readthedocs.io/en/latest/usage/openstreetmap.html#using-osmnx-and-geopandas
I have created map_con
, graph osmnx from the example. Then, transformed GPS Points to CRS which Project graph
use. Then ,implemented code from example :
matcher = DistanceMatcher(map_con, max_dist=2, obs_noise=1, min_prob_norm=0.5)
states, _ = matcher.match(path)
nodes = matcher.path_pred_onlynodes
print("States\n------")
print(states)
print("Nodes\n------")
print(nodes)
print("")
matcher.print_lattice_stats()
But it doesn't return any "states" or "nodes"
I just find the abstract of "HMM with Non-Emitting States for Map Matching" https://lirias.kuleuven.be/retrieve/512781. Where can I read the paper?
After using mmviz.plot_map, the route matching result map is already drawn.
However, when I want to further observe which routes are matched to the road network, I found that matcher.path_pred_onlynodes is empty.
How can I check which routes of the network are matched?
Hi,
I am trying to run the example, but I got this error. Do you have any suggestion to this error?
the error is.
File "test_match.py", line 2, in <module>
from leuvenmapmatching.matcher.distance import DistanceMatcher
File "/home/aa/aa/py37/lib/python3.7/site-packages/leuvenmapmatching/matcher/distance.py", line 13, in <module>
from .base import BaseMatching, BaseMatcher
File "<fstring>", line 1
(prune_thr=)
^
SyntaxError: invalid syntax
And here is my example code.
from leuvenmapmatching import visualization as mmviz
from leuvenmapmatching.matcher.distance import DistanceMatcher
from leuvenmapmatching.map.inmemmap import InMemMap
map_con = InMemMap("mymap", graph={
"A": ((1, 1), ["B", "C", "X"]),
"B": ((1, 3), ["A", "C", "D", "K"]),
"C": ((2, 2), ["A", "B", "D", "E", "X", "Y"]),
"D": ((2, 4), ["B", "C", "D", "E", "K", "L"]),
"E": ((3, 3), ["C", "D", "F", "Y"]),
"F": ((3, 5), ["D", "E", "L"]),
"X": ((2, 0), ["A", "C", "Y"]),
"Y": ((3, 1), ["X", "C", "E"]),
"K": ((1, 5), ["B", "D", "L"]),
"L": ((2, 6), ["K", "D", "F"])
}, use_latlon=False)
path = [(0.8, 0.7), (0.9, 0.7), (1.1, 1.0), (1.2, 1.5), (1.2, 1.6), (1.1, 2.0),
(1.1, 2.3), (1.3, 2.9), (1.2, 3.1), (1.5, 3.2), (1.8, 3.5), (2.0, 3.7),
(2.3, 3.5), (2.4, 3.2), (2.6, 3.1), (2.9, 3.1), (3.0, 3.2),
(3.1, 3.8), (3.0, 4.0), (3.1, 4.3), (3.1, 4.6), (3.0, 4.9)]
matcher = DistanceMatcher(map_con, max_dist=2, obs_noise=1, min_prob_norm=0.5)
states, _ = matcher.match_incremental(path[:5])
states, _ = matcher.match_incremental(path[5:], backtrace_len=-1)
nodes = matcher.path_pred_onlynodes
mmviz.plot_map(map_con, matcher=matcher,
show_labels=True, show_matching=True, show_graph=True,
filename="my_plot.png")
Thanks for your help.
Hi,
my question is, how can I combine osmnx, Geopandas and DistanceMatcher together? Can you show me this with an example please? for example with this Data:
I would be happy, if you could give me the answer.
Mostly using examples in the docu, I do the following:
from pathlib import Path
import requests
xml_file = Path(".") / "osm.xml"
url = 'http://overpass-api.de/api/map?bbox=4.694933,50.870047,4.709256000000001,50.879628'
r = requests.get(url, stream=True)
with xml_file.open('wb') as ofile:
for chunk in r.iter_content(chunk_size=1024):
if chunk:
ofile.write(chunk)
'highway in entity.tags'
from leuvenmapmatching.map.inmem import InMemMap
import osmread
map_con = InMemMap("myosm", use_latlon=True, use_rtree=True, index_edges=True)
for entity in osmread.parse_file(str(xml_file)):
#if isinstance(entity, osmread.Way) and 'highway' in entity.tags:
if isinstance(entity, osmread.Way):
for node_a, node_b in zip(entity.nodes, entity.nodes[1:]):
map_con.add_edge(node_a, node_b)
# Some roads are one-way. We'll add both directions.
map_con.add_edge(node_b, node_a)
if isinstance(entity, osmread.Node):
map_con.add_node(entity.id, (entity.lat, entity.lon))
map_con.purge()
track = [(50.87158705419287, 4.701149818142195),
(50.87162768899347, 4.701342872760166),
(50.87164800638049, 4.701557377891264),
(50.8716818686725, 4.70172898199615),
(50.87169541358241, 4.701932761870685),
(50.87173604828854, 4.702157992258305),
(50.87178345540092, 4.70228669533694),
(50.87179700028131, 4.7025012004680375),
(50.87168864112794, 4.702608453033586),
(50.87161414406387, 4.702554826750811),
(50.87155996430614, 4.702587002520461),
(50.871444832111806, 4.702694255086009),
(50.87131615461689, 4.702822958164683),
(50.87132292712548, 4.70291948547367),
(50.87132292712548, 4.703048188552304),
(50.87123488443708, 4.70314471586129),
(50.87111975143977, 4.703155441117853),
(50.87103170836759, 4.703198342144065),
(50.87093012000073, 4.703348495735825),
(50.870889484592006, 4.70347719881446),
(50.87080821366827, 4.703509374584148),
(50.87077435074152, 4.703595176636571),
(50.87075403297369, 4.703670253432471),
(50.87071339741144, 4.703713154458683),
(50.87064567139563, 4.703788231254543)]
from leuvenmapmatching.util.gpx import gpx_to_path
matcher = DistanceMatcher(map_con,
max_dist=100, max_dist_init=25, # meter
min_prob_norm=0.001,
non_emitting_length_factor=0.75,
obs_noise=50, obs_noise_ne=75, # meter
dist_noise=50, # meter
non_emitting_states=True,
max_lattice_width=5)
states, lastidx = matcher.match(track)
assert not [l for l in matcher.lattice.values() if l.values_all()]
Could you please help me with that?
Hello dear developer, I appreciate that you have developed such a useful tool that has been very helpful to me. I have two questions : )
First question:
I use osmnx to get the road network. The following figure shows some node information in the road network. The nodes in the map match result are "osmid" sequence, is there any way to use "fid"?
Second question:
As shown in the figure below, I used the parameters in the examples you gave to match the map. Most match paths are complete, but some match paths are short ( not complete ) or are even empty. How can I modify these parameters or do something else to make the match more complete?
In osm, u
and v
represent the start and end points respectively, and there is also a field key
to represent the multiple edges between u
and v
. How can we use the information of key
in the matcher?
I am attempting to load map data from a pickle file using map_connn = InMemMap.deserialize(map_conn). After exporting the map data from memory with map_con.dump() as a dictionary, an error occurs:
TreeError: Error in "Index_CreateWithStream": Spatial Index Error: IllegalArgumentException: SpatialIndex::DiskStorageManager: Index/Data file cannot be created." 1.
map_con.dump()
import pickle
import os
map_data_file = 'E:\jupyternotebook\共享单车路径匹配\map_con\myosm.pkl'
if os.path.exists(map_data_file):
with open(map_data_file, 'rb') as f:
map_conn = pickle.load(f)
map_connn = InMemMap.deserialize(map_conn)
RTreeError Traceback (most recent call last)
Cell In[5], line 1
----> 1 map_connn = InMemMap.deserialize(map_conn)
File D:\miniconda3\envs\Map_Matching\lib\site-packages\leuvenmapmatching\map\inmem.py:144, in InMemMap.deserialize(cls, data)
141 @classmethod
142 def deserialize(cls, data):
143 """Create a new instance from a dictionary."""
--> 144 nmap = cls(data["name"], dir=data.get("dir", None),
145 use_latlon=data["use_latlon"], use_rtree=data["use_rtree"],
146 index_edges=data["index_edges"],
147 crs_lonlat=data.get("crs_lonlat", None), crs_xy=data.get("crs_xy", None),
148 graph=data.get("graph", None), linked_edges=data.get("linked_edges", None),
149 deserializing=True)
150 return nmap
File D:\miniconda3\envs\Map_Matching\lib\site-packages\leuvenmapmatching\map\inmem.py:81, in InMemMap.init(self, name, use_latlon, use_rtree, index_edges, crs_lonlat, crs_xy, graph, linked_edges, dir, deserializing)
79 self.use_rtree = use_rtree
80 if self.use_rtree:
---> 81 self.setup_index(deserializing=deserializing)
83 self.crs_lonlat = 'EPSG:4326' if crs_lonlat is None else crs_lonlat # GPS
84 self.crs_xy = 'EPSG:3395' if crs_xy is None else crs_xy # Mercator projection
File D:\miniconda3\envs\Map_Matching\lib\site-packages\leuvenmapmatching\map\inmem.py:384, in InMemMap.setup_index(self, force, deserializing)
382 else:
383 logger.debug(f"Creating new in-memory rtree index (args={args}) ...")
--> 384 self.rtree = rtree.index.Index(*args)
385 t_delta = time.time() - t_start
386 logger.debug(f"... done: rtree size = {self.rtree_size()}, time = {t_delta} sec")
File D:\miniconda3\envs\Map_Matching\lib\site-packages\rtree\index.py:273, in Index.init(self, *args, **kwargs)
271 if stream and self.properties.type == RT_RTree:
272 self._exception = None
--> 273 self.handle = self._create_idx_from_stream(stream)
274 if self._exception:
275 raise self._exception
File D:\miniconda3\envs\Map_Matching\lib\site-packages\rtree\index.py:1263, in Index._create_idx_from_stream(self, stream)
1260 return 0
1262 stream = core.NEXTFUNC(py_next_item)
-> 1263 return IndexStreamHandle(self.properties.handle, stream)
File D:\miniconda3\envs\Map_Matching\lib\site-packages\rtree\index.py:1396, in Handle.init(self, *args, **kwargs)
1395 def init(self, *args: Any, **kwargs: Any) -> None:
-> 1396 self._ptr = self._create(*args, **kwargs)
File D:\miniconda3\envs\Map_Matching\lib\site-packages\rtree\core.py:25, in check_void(result, func, cargs)
23 msg = f'Error in "{func.name}": {s}'
24 rt.Error_Reset()
---> 25 raise RTreeError(msg)
26 return result
RTreeError: Error in "Index_CreateWithStream": Spatial Index Error: IllegalArgumentException: SpatialIndex::DiskStorageManager: Index/Data file cannot be created.
Whenever I create a map in-memory object, it requires a significant amount of computation, including importing points, importing edges, and performing deduplication operations. This results in a long processing time each time I generate an in-memory map object. To overcome this, I attempted to export my pre-computed map in-memory object and load it directly from a file for future use.
Initially, I tried using Python's built-in pickle module. However, when I read the exported .pkl file, I found that it couldn't be used for path matching, as the matched paths were empty. I suspected that certain attributes, such as R-tree, might have been lost during the export of the map in-memory object.
To address this, I consulted the official documentation of LeuvenMap and discovered the dump() and deserialize() methods provided by the package. I attempted to use these recommended backup and loading methods. However, during the process, I encountered the aforementioned error.
I would greatly appreciate assistance in resolving this issue.
Hello! First of all, thank you for developing this model, it helps me a lot in my project.
Now I have difficulty understanding "non-emitting states". The Annotation in newsonkrumm.py says:
Newson and Krumm use shortest path to handle situations where the distances between observations are larger than distances between nodes in the graph. The LeuvenMapMatching toolbox uses non-emitting states to handle this. We thus do not implement the shortest path algorithm in this class.
So what is the main difference between the two algorithm?
I noticed that your model refers to the paper:
Meert Wannes, Mathias Verbeke, "HMM with Non-Emitting States for Map Matching", European Conference on Data Analysis (ECDA), Paderborn, Germany, 2018.
But I failed to find it on the internet. If you can help me on the question, or tell me where to find the paper, I'd be very grateful.
Thanks for reading!
Dear community,
Map matching doesn't work for me. "states" is an empty list and "lastidx" is zero. Do you have any idea what the problem is? I would be grateful for any help. Here is my code:
import numpy as np
import scipy
from datetime import datetime
#--------------------------------------------------------------
#Download a map
from pathlib import Path
import requests
start1 = datetime.now()
xml_file = Path(".") / "osm.xml"
url = 'http://overpass-api.de/api/map?bbox=4.694933,50.870047,4.709256000000001,50.879628'
r = requests.get(url, stream=True)
with xml_file.open('wb') as ofile:
for chunk in r.iter_content(chunk_size=2230):
if chunk:
ofile.write(chunk)
print('Time to download: ' , datetime.now()-start1)
#--------------------------------------------------------------
#Creating graph (use osmread)
from leuvenmapmatching.map.inmem import InMemMap
import osmread
start2 = datetime.now()
map_con = InMemMap("myosm", use_latlon=True, use_rtree=True, index_edges=True)
for entity in osmread.parse_file(str(xml_file)):
if isinstance(entity, osmread.Way) and 'highway' in entity.tags:
for node_a, node_b in zip(entity.nodes, entity.nodes[1:]):
map_con.add_edge(node_a, node_b)
# Some roads are one-way. We'll add both directions.
map_con.add_edge(node_b, node_a)
if isinstance(entity, osmread.Node):
map_con.add_node(entity.id, (entity.lat, entity.lon))
map_con.purge()
print('Time to Create graph: ' , datetime.now()-start2)
#--------------------------------------------------------------
#Perform map matching on an OpenStreetMap
from leuvenmapmatching.util.gpx import gpx_to_path
from leuvenmapmatching.matcher.distance import DistanceMatcher
start3 = datetime.now()
track = gpx_to_path("Seattle.gpx")
matcher = DistanceMatcher(map_con,
max_dist=100, max_dist_init=25,
min_prob_norm=0.001,
non_emitting_length_factor=0.75,
obs_noise=50, obs_noise_ne=75,
dist_noise=50,
non_emitting_states=True,
max_lattice_width=5)
states, lastidx = matcher.match(track)
print('Time to perform map matching: ' , datetime.now() - start3)
#---------------------------------------------------------------
#visualization
from leuvenmapmatching import visualization as mmviz
start4 = datetime.now()
mmviz.plot_map(map_con, matcher=matcher,
use_osm=True, zoom_path=True,
show_labels=False, show_matching=True, show_graph=False,
filename="Seattle.png")
print('Time to make a visualization: ' , datetime.now() - start4)
print('---------------------------------------------------------')
#---------------------------------------------------------------
and here is the GPS-Data:
Hi,
I am trying to run the "Create graph using osmread" code, but I got this error. Do you have any suggestions for this error?
The error is:
AttributeError Traceback (most recent call last)
C:\Users\203345~1\AppData\Local\Temp/ipykernel_5252/840127675.py in
25 map_con.add_edge(node_b, node_a)
26 if isinstance(entity, osmread.Node):
---> 27 map_con.add_node(entity.id, (entity.lat, entity.lon))
28 map_con.purge()
~\anaconda\envs\sxpipei3\lib\site-packages\leuvenmapmatching\map\inmem.py in add_node(self, node, loc)
191 if type(node) is not int:
192 raise Exception(f"Rtree index only supports integer keys for vertices")
--> 193 self.rtree.upsert(node, (loc[0], loc[1], loc[0], loc[1]))
194
195 def del_node(self, node):
AttributeError: 'Index' object has no attribute 'upsert'
When I run this:
from leuvenmapmatching.map.inmem import InMemMap
map_con = InMemMap("myosm", use_latlon=True, use_rtree=True, index_edges=True)
I get this warning:
/home/user/anaconda3/envs/ox/lib/python3.8/site-packages/pyproj/crs/crs.py:55: FutureWarning: '+init=<authority>:<code>' syntax is deprecated. '<authority>:<code>' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6
return _prepare_from_string(" ".join(pjargs))
/home/user/anaconda3/envs/ox/lib/python3.8/site-packages/pyproj/crs/crs.py:55: FutureWarning: '+init=<authority>:<code>' syntax is deprecated. '<authority>:<code>' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6
return _prepare_from_string(" ".join(pjargs))
pip freeze gives me:
attrs==19.3.0
backcall==0.1.0
branca==0.4.0
certifi==2019.11.28
cffi==1.13.2
chardet==3.0.4
Click==7.0
click-plugins==1.1.1
cligj==0.5.0
cryptography==2.8
cycler==0.10.0
decorator==4.4.2
descartes==1.1.0
entrypoints==0.3
Fiona==1.8.13
folium==0.10.1
GDAL==3.0.4
geographiclib==1.50
geopandas==0.7.0
geopy==1.21.0
idna==2.9
ipykernel==5.1.4
ipython==7.13.0
ipython-genutils==0.2.0
jedi==0.16.0
Jinja2==2.11.1
joblib==0.14.1
jupyter-client==6.0.0
jupyter-core==4.6.3
kiwisolver==1.1.0
leuvenmapmatching==0.5.3
MarkupSafe==1.1.1
matplotlib==3.1.3
munch==2.5.0
networkx==2.4
numpy==1.18.1
osmnx==0.11.4
pandas==1.0.1
parso==0.6.2
pexpect==4.8.0
pickleshare==0.7.5
Pillow==7.0.0
prompt-toolkit==3.0.3
ptyprocess==0.6.0
pycparser==2.19
Pygments==2.5.2
pyOpenSSL==19.1.0
pyparsing==2.4.6
pyproj==2.5.0
PySocks==1.7.1
python-dateutil==2.8.1
pytz==2019.3
pyzmq==19.0.0
requests==2.23.0
Rtree==0.9.4
scikit-learn==0.22.1
scipy==1.4.1
Shapely==1.7.0
six==1.14.0
smopy==0.0.7
tornado==6.0.3
traitlets==4.3.3
urllib3==1.25.7
vincent==0.4.4
wcwidth==0.1.8
I am trying to use the NoisePlanet which uses the Leuven DistanceMatcher on its backend for map matching. I am getting the following error
---------------------------------------------------------------------------
Exception Traceback (most recent call last)
<ipython-input-82-5396cffaa114> in <module>
----> 1 track_coor, route_corr, edgeid, stats = matching.match(G, track, method='hmm')
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/noiseplanet/matcher/matching.py in match(graph, track, method)
61 track_corr, route_corr, edgeid, stats = model.match_nearest_edge(graph, track)
62 elif method == 'hmm':
---> 63 track_corr, route_corr, edgeid, stats = model.match_leuven(graph, track)
64 return track_corr, route_corr, edgeid, stats
65
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/noiseplanet/matcher/model/leuven.py in match_leuven(graph, track)
111 dist_noise=50, # meter
112 non_emitting_edgeid=False)
--> 113 edgeid, lastidx = matcher.match(path)
114
115 proj_dist = np.zeros(len(track))
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/leuvenmapmatching/matcher/base.py in match(self, path, unique, tqdm)
463 else:
464 start_idx = len(self.path) - 1
--> 465 node_path = self._build_node_path(start_idx, unique)
466 return node_path, start_idx
467
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/leuvenmapmatching/matcher/base.py in _build_node_path(self, start_idx, unique, max_depth, last_is_e)
1031 node_max = m
1032 if node_max is None:
-> 1033 raise Exception("Did not find a matching node for path point at index {}".format(start_idx))
1034 if __debug__ and logger.isEnabledFor(logging.DEBUG):
1035 logger.debug(self.matching.repr_header(stop=" "))
Exception: Did not find a matching node for path point at index 3723
Is there a way in which we can skip the non matching nodes in the function? Or is there a way to bypass this error as it dosent matter for me if some nodes are not matched and it shouldnt stop my program.
Please do let me know if there is any more information required.
now we input one gps, output the most probably road network path, can we output the most n-best path? this is very useful, for we can get more information. and i think, it can realization at "Backtrack to find best path"
How can we exclude the nodes 8 and/or 6 from the result if only a small portion of the edges 8-2 and 5-6 overlaps with the source trajectory? E.g., enforcing an overlap of >90%, otherwise removing these nodes from the result?
Thanks for any ideas!
matcher = DistanceMatcher(map_con)
matcher.match(path)
nodes = matcher.path_pred_onlynodes
# result: [8, 2, 1, 5, 6]
Hello,
is it possible to interrupt the matched path and start a new matched path as soon as the algorithm finds a match with the graph again?
So far, the whole matching stops whenever the state cannot find a match. In my case, it is not due to very strict parameters but rather a missing road network. It would be nice if the matching did not stop after the first fail.
Thank you!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.