gotrackit 0.2.3__tar.gz → 0.2.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. {gotrackit-0.2.3/src/gotrackit.egg-info → gotrackit-0.2.4}/PKG-INFO +25 -22
  2. {gotrackit-0.2.3 → gotrackit-0.2.4}/README.md +24 -21
  3. {gotrackit-0.2.3 → gotrackit-0.2.4}/pyproject.toml +1 -1
  4. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/gps/GpsTrip.py +7 -4
  5. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/map/Link.py +16 -1
  6. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/map/Net.py +16 -3
  7. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/model/Markov.py +29 -236
  8. {gotrackit-0.2.3 → gotrackit-0.2.4/src/gotrackit.egg-info}/PKG-INFO +25 -22
  9. {gotrackit-0.2.3 → gotrackit-0.2.4}/LICENSE +0 -0
  10. {gotrackit-0.2.3 → gotrackit-0.2.4}/setup.cfg +0 -0
  11. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/__init__.py +0 -0
  12. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/GlobalVal.py +0 -0
  13. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/MapMatch.py +0 -0
  14. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/WrapsFunc.py +0 -0
  15. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/__init__.py +0 -0
  16. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/generation/GpsGen.py +0 -0
  17. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/generation/__init__.py +0 -0
  18. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/gps/GpsArray.py +0 -0
  19. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/gps/GpsXfer.py +0 -0
  20. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/gps/LocGps.py +0 -0
  21. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/gps/__init__.py +0 -0
  22. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/map/Node.py +0 -0
  23. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/map/__init__.py +0 -0
  24. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/model/__init__.py +0 -0
  25. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/GlobalVal.py +0 -0
  26. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/NetGen.py +0 -0
  27. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/Parse/__init__.py +0 -0
  28. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/Parse/gd_car_path.py +0 -0
  29. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/PublicTools/GeoProcess.py +0 -0
  30. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/PublicTools/GraphAna.py +0 -0
  31. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/PublicTools/IndexAna.py +0 -0
  32. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/PublicTools/MapProcess.py +0 -0
  33. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/PublicTools/__init__.py +0 -0
  34. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/PublicTools/od.py +0 -0
  35. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/Request/__init__.py +0 -0
  36. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/Request/api/WebApi.py +0 -0
  37. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/Request/api/__init__.py +0 -0
  38. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/Request/request_path.py +0 -0
  39. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/Request/usage/__init__.py +0 -0
  40. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/Request/usage/bd_ts.py +0 -0
  41. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/Request/usage/gd_car_path.py +0 -0
  42. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/DupProcess/DupLinks.py +0 -0
  43. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/DupProcess/__init__.py +0 -0
  44. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/Merge/__init__.py +0 -0
  45. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/Merge/get_merged_link_seq.py +0 -0
  46. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/Merge/limit/__init__.py +0 -0
  47. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/Merge/limit/attr_limit.py +0 -0
  48. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/Merge/limit/direction_limit.py +0 -0
  49. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/Merge/limit/same_head_tail_limit.py +0 -0
  50. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/Merge/limit/two_degrees_group.py +0 -0
  51. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/Merge/merge_links.py +0 -0
  52. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/Merge/merge_short.py +0 -0
  53. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/MultiCoreMerge/__init__.py +0 -0
  54. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/MultiCoreMerge/limit/__init__.py +0 -0
  55. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/MultiCoreMerge/limit/attr_limit.py +0 -0
  56. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/MultiCoreMerge/limit/direction_limit.py +0 -0
  57. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/MultiCoreMerge/limit/same_head_tail_limit.py +0 -0
  58. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/MultiCoreMerge/limit/two_degrees_group.py +0 -0
  59. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/MultiCoreMerge/merge_links_multi.py +0 -0
  60. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/SaveStreets/__init__.py +0 -0
  61. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/SaveStreets/streets.py +0 -0
  62. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/Split/SplitPath.py +0 -0
  63. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/Split/__init__.py +0 -0
  64. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/Tools/__init__.py +0 -0
  65. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/Tools/process.py +0 -0
  66. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/__init__.py +0 -0
  67. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/conn.py +0 -0
  68. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/increment.py +0 -0
  69. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/net_reverse.py +0 -0
  70. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/optimize_net.py +0 -0
  71. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/RoadNet/save_file.py +0 -0
  72. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/__init__.py +0 -0
  73. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/book_mark.py +0 -0
  74. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netreverse/format_od.py +0 -0
  75. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netxfer/SumoConvert.py +0 -0
  76. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/netxfer/__init__.py +0 -0
  77. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/solver/Viterbi.py +0 -0
  78. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/solver/__init__.py +0 -0
  79. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/tools/__init__.py +0 -0
  80. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/tools/coord_trans.py +0 -0
  81. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/tools/geo_process.py +0 -0
  82. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/tools/group.py +0 -0
  83. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/tools/save_file.py +0 -0
  84. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit/visualization.py +0 -0
  85. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit.egg-info/SOURCES.txt +0 -0
  86. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit.egg-info/dependency_links.txt +0 -0
  87. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit.egg-info/requires.txt +0 -0
  88. {gotrackit-0.2.3 → gotrackit-0.2.4}/src/gotrackit.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: gotrackit
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: A Python Package for Map Matching Algorithm Based on Hidden Markov Model
5
5
  Author-email: Kai Tang <794568794@qq.com>
6
6
  License: LICENCE
@@ -49,47 +49,50 @@ Developed by Tang Kai, Email: 794568794@qq.com & tangkai@zhechengdata.com
49
49
  更新命令:pip install --upgrade -i https://pypi.org/simple/ gotrackit
50
50
 
51
51
 
52
- - 效率优化, 相较于v0.2.2小幅度提升
52
+ - 地图匹配接口效率优化, 相较于v0.2.2小幅度提升
53
53
 
54
- - crs判断BUG修复、境外路网构建失败BUG修复
54
+ - 地图匹配接口报错机制优化
55
55
 
56
- - 报错机制优化
56
+ - 地图匹配接口移除html_fldr参数, 使用out_fldr替代
57
57
 
58
- - 输出文件目录指定参数html_fldr废除, 改为out_fldr
58
+ - 地图匹配接口增加即时输出开关instant_output, 打开后, 每匹配完一条轨迹马上进行结果存储
59
59
 
60
- - 增加环路处理功能
61
-
62
- - 增加匹配结果即时输出参数, 每匹配完一条轨迹可马上进行结果存储
60
+ - 路网构建: crs判断BUG修复、境外路网构建失败BUG修复
61
+
62
+ - 增加 环路 处理功能
63
+
64
+
65
+ **不要下载GitHub仓库上的代码来使用!!! 直接pip安装gotrackit为第三方库即可使用**
63
66
 
64
67
 
65
68
  <br>
66
69
 
67
70
  <div align=center>
68
- ~ v0.2.2效率将大幅度提升, 最高可以提升10倍的性能 !~
71
+ ~ v0.2.4(相较于0.2.1)效率将大幅度提升, 最高可以提升10倍的性能 !~
69
72
  </div>
70
73
 
71
74
  <br>
72
75
 
73
76
  与上一版本对比:
74
77
 
75
- | 样例数据 | 有效的GPS点数 | top_k(k邻近候选参数) | gps_buffer(临域半径) | 候选路段条数 | 状态转移次数 | v0.2.1版解算时间 | v0.2.2版解算时间 |
76
- |----------------|----------|----------------|------------------|---------|------------|-------------|-----------|
77
- | 1辆车,深圳稀疏轨迹点样例1 | 190 | 60 | 500m | 10615 | 629788次 | 28秒 | **3.3秒** |
78
- | 1辆车,深圳稀疏轨迹点样例2 | 400 | 20 | 120m | 5137 | 82006次 | 7.8秒 | **1.7秒** |
78
+ | 样例数据 | 有效的GPS点数 | top_k(k邻近候选参数) | gps_buffer(临域半径) | 候选路段条数 | 状态转移次数 | v0.2.1版解算时间 | v0.2.4版解算时间 |
79
+ |----------------|----------|----------------|------------------|---------|------------|-------------|-------------|
80
+ | 1辆车,深圳稀疏轨迹点样例1 | 190 | 60 | 500m | 10615 | 629788次 | 28秒 | **1.87秒** |
81
+ | 1辆车,深圳稀疏轨迹点样例2 | 400 | 20 | 120m | 5137 | 82006次 | 7.8秒 | **0.89秒** |
79
82
 
80
83
 
81
- v0.2.2多核效率对比:
84
+ v0.2.4多核效率对比:
82
85
 
83
- 基于上表深圳稀疏轨迹点样例2,我们将他复制150份,进行多核测试,可以看到到6核时, 效率已经不再提升,最快96s解算完150条轨迹,平均每条轨迹0.64s,相较于1.7s再次提升了60%,在车辆数较多时,多核的效率提升很明显。
86
+ 基于上表深圳稀疏轨迹点样例2,我们将他复制150份,进行多核测试,可以看到到6核时, 效率已经不再提升,最快89s解算完150条轨迹,平均每条轨迹0.59s,相较于0.89s再次提升了30%,在车辆数较多时,多核的效率提升很明显。
84
87
 
85
- | 样例数据 | 有效的GPS点数 | top_k | gps_buffer | 候选路段条数 | 状态转移次数 | v0.2.2解算时间 |
88
+ | 样例数据 | 有效的GPS点数 | top_k | gps_buffer | 候选路段条数 | 状态转移次数 | v0.2.4解算时间 |
86
89
  |-------------------------------------------|----------|----------------|------------------|-----|--------|------------|
87
- | 150辆车的GPS轨迹(单核串行,子图搜索,有构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 300.0秒 |
88
- | 150辆车的GPS轨迹(3核并行,子图搜索,有构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 139.6秒 |
89
- | 150辆车的GPS轨迹(3核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 120.3秒 |
90
- | 150辆车的GPS轨迹(4核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 104.9 |
91
- | 150辆车的GPS轨迹(5核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 96.4秒 |
92
- | 150辆车的GPS轨迹(6核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 97.5秒 |
90
+ | 150辆车的GPS轨迹(单核串行,子图搜索,有构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 290.0秒 |
91
+ | 150辆车的GPS轨迹(3核并行,子图搜索,有构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 130.6秒 |
92
+ | 150辆车的GPS轨迹(3核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 113.3秒 |
93
+ | 150辆车的GPS轨迹(4核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 97.3 |
94
+ | 150辆车的GPS轨迹(5核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 89.4秒 |
95
+ | 150辆车的GPS轨迹(6核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 91.5秒 |
93
96
 
94
97
 
95
98
  <br>
@@ -27,47 +27,50 @@ Developed by Tang Kai, Email: 794568794@qq.com & tangkai@zhechengdata.com
27
27
  更新命令:pip install --upgrade -i https://pypi.org/simple/ gotrackit
28
28
 
29
29
 
30
- - 效率优化, 相较于v0.2.2小幅度提升
30
+ - 地图匹配接口效率优化, 相较于v0.2.2小幅度提升
31
31
 
32
- - crs判断BUG修复、境外路网构建失败BUG修复
32
+ - 地图匹配接口报错机制优化
33
33
 
34
- - 报错机制优化
34
+ - 地图匹配接口移除html_fldr参数, 使用out_fldr替代
35
35
 
36
- - 输出文件目录指定参数html_fldr废除, 改为out_fldr
36
+ - 地图匹配接口增加即时输出开关instant_output, 打开后, 每匹配完一条轨迹马上进行结果存储
37
37
 
38
- - 增加环路处理功能
39
-
40
- - 增加匹配结果即时输出参数, 每匹配完一条轨迹可马上进行结果存储
38
+ - 路网构建: crs判断BUG修复、境外路网构建失败BUG修复
39
+
40
+ - 增加 环路 处理功能
41
+
42
+
43
+ **不要下载GitHub仓库上的代码来使用!!! 直接pip安装gotrackit为第三方库即可使用**
41
44
 
42
45
 
43
46
  <br>
44
47
 
45
48
  <div align=center>
46
- ~ v0.2.2效率将大幅度提升, 最高可以提升10倍的性能 !~
49
+ ~ v0.2.4(相较于0.2.1)效率将大幅度提升, 最高可以提升10倍的性能 !~
47
50
  </div>
48
51
 
49
52
  <br>
50
53
 
51
54
  与上一版本对比:
52
55
 
53
- | 样例数据 | 有效的GPS点数 | top_k(k邻近候选参数) | gps_buffer(临域半径) | 候选路段条数 | 状态转移次数 | v0.2.1版解算时间 | v0.2.2版解算时间 |
54
- |----------------|----------|----------------|------------------|---------|------------|-------------|-----------|
55
- | 1辆车,深圳稀疏轨迹点样例1 | 190 | 60 | 500m | 10615 | 629788次 | 28秒 | **3.3秒** |
56
- | 1辆车,深圳稀疏轨迹点样例2 | 400 | 20 | 120m | 5137 | 82006次 | 7.8秒 | **1.7秒** |
56
+ | 样例数据 | 有效的GPS点数 | top_k(k邻近候选参数) | gps_buffer(临域半径) | 候选路段条数 | 状态转移次数 | v0.2.1版解算时间 | v0.2.4版解算时间 |
57
+ |----------------|----------|----------------|------------------|---------|------------|-------------|-------------|
58
+ | 1辆车,深圳稀疏轨迹点样例1 | 190 | 60 | 500m | 10615 | 629788次 | 28秒 | **1.87秒** |
59
+ | 1辆车,深圳稀疏轨迹点样例2 | 400 | 20 | 120m | 5137 | 82006次 | 7.8秒 | **0.89秒** |
57
60
 
58
61
 
59
- v0.2.2多核效率对比:
62
+ v0.2.4多核效率对比:
60
63
 
61
- 基于上表深圳稀疏轨迹点样例2,我们将他复制150份,进行多核测试,可以看到到6核时, 效率已经不再提升,最快96s解算完150条轨迹,平均每条轨迹0.64s,相较于1.7s再次提升了60%,在车辆数较多时,多核的效率提升很明显。
64
+ 基于上表深圳稀疏轨迹点样例2,我们将他复制150份,进行多核测试,可以看到到6核时, 效率已经不再提升,最快89s解算完150条轨迹,平均每条轨迹0.59s,相较于0.89s再次提升了30%,在车辆数较多时,多核的效率提升很明显。
62
65
 
63
- | 样例数据 | 有效的GPS点数 | top_k | gps_buffer | 候选路段条数 | 状态转移次数 | v0.2.2解算时间 |
66
+ | 样例数据 | 有效的GPS点数 | top_k | gps_buffer | 候选路段条数 | 状态转移次数 | v0.2.4解算时间 |
64
67
  |-------------------------------------------|----------|----------------|------------------|-----|--------|------------|
65
- | 150辆车的GPS轨迹(单核串行,子图搜索,有构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 300.0秒 |
66
- | 150辆车的GPS轨迹(3核并行,子图搜索,有构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 139.6秒 |
67
- | 150辆车的GPS轨迹(3核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 120.3秒 |
68
- | 150辆车的GPS轨迹(4核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 104.9 |
69
- | 150辆车的GPS轨迹(5核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 96.4秒 |
70
- | 150辆车的GPS轨迹(6核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 97.5秒 |
68
+ | 150辆车的GPS轨迹(单核串行,子图搜索,有构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 290.0秒 |
69
+ | 150辆车的GPS轨迹(3核并行,子图搜索,有构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 130.6秒 |
70
+ | 150辆车的GPS轨迹(3核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 113.3秒 |
71
+ | 150辆车的GPS轨迹(4核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 97.3 |
72
+ | 150辆车的GPS轨迹(5核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 89.4秒 |
73
+ | 150辆车的GPS轨迹(6核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 91.5秒 |
71
74
 
72
75
 
73
76
  <br>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "gotrackit"
7
- version = "0.2.3"
7
+ version = "0.2.4"
8
8
  dependencies = ["geopandas>=0.14.1", "shapely", "networkx", "pandas", "numpy", "keplergl", "geopy"]
9
9
  requires-python = ">=3.8"
10
10
  authors = [
@@ -57,10 +57,13 @@ class GpsTrip(GpsArray):
57
57
  # 时间差和距离差
58
58
  group_gps_gdf[next_time_field] = group_gps_gdf[time_field].shift(-1).fillna(group_gps_gdf[time_field])
59
59
  group_gps_gdf[next_p_field] = group_gps_gdf[geometry_field].shift(-1).fillna(group_gps_gdf[geometry_field])
60
- group_gps_gdf[time_gap_field] = group_gps_gdf.apply(
61
- lambda row: (row[next_time_field] - row[time_field]).seconds, axis=1)
62
- group_gps_gdf[dis_gap_field] = group_gps_gdf.apply(
63
- lambda row: row[next_p_field].distance(row[geometry_field]), axis=1)
60
+ group_gps_gdf[time_gap_field] = group_gps_gdf[next_time_field] - group_gps_gdf[time_field]
61
+ group_gps_gdf[time_gap_field] = group_gps_gdf[time_gap_field].apply(lambda t: t.seconds)
62
+ group_gps_gdf[dis_gap_field] = group_gps_gdf[next_p_field].distance(group_gps_gdf[geometry_field])
63
+ # group_gps_gdf[time_gap_field] = group_gps_gdf.apply(
64
+ # lambda row: (row[next_time_field] - row[time_field]).seconds, axis=1)
65
+ # group_gps_gdf[dis_gap_field] = group_gps_gdf.apply(
66
+ # lambda row: row[next_p_field].distance(row[geometry_field]), axis=1)
64
67
 
65
68
  # 切分主行程
66
69
  group_gps_gdf['main_label'] = (group_gps_gdf[time_gap_field] > self.group_gap_threshold).astype(int)
@@ -55,6 +55,8 @@ class Link(object):
55
55
  self.__ud_graph = nx.Graph()
56
56
  self.__one_out_degree_nodes = None
57
57
  self.__link_ft_mapping: dict[int, tuple[int, int]] = dict()
58
+ self.__link_f_mapping: dict[int, int] = dict()
59
+ self.__link_t_mapping: dict[int, int] = dict()
58
60
  self.done_link_vec = False
59
61
 
60
62
  def check(self):
@@ -94,7 +96,8 @@ class Link(object):
94
96
 
95
97
  def init_link_from_existing_single_link(self, single_link_gdf: gpd.GeoDataFrame = None,
96
98
  ft_link_mapping: dict = None,
97
- double_single_mapping: dict = None, link_ft_mapping: dict = None):
99
+ double_single_mapping: dict = None, link_ft_mapping: dict = None,
100
+ link_t_mapping: dict = None, link_f_mapping: dict = None):
98
101
  """通过给定的single_link_gdf初始化link, 用在子net的初始化上"""
99
102
  self.__single_link_gdf = single_link_gdf.copy()
100
103
 
@@ -102,6 +105,8 @@ class Link(object):
102
105
  self.__ft_link_mapping = ft_link_mapping
103
106
  # single_link: (f, t)
104
107
  self.__link_ft_mapping = link_ft_mapping
108
+ self.__link_t_mapping = link_t_mapping
109
+ self.__link_f_mapping = link_f_mapping
105
110
 
106
111
  def create_single_link(self, link_gdf: gpd.GeoDataFrame):
107
112
  """
@@ -135,6 +140,8 @@ class Link(object):
135
140
  zip(self.__single_link_gdf[net_field.FROM_NODE_FIELD],
136
141
  self.__single_link_gdf[net_field.TO_NODE_FIELD],
137
142
  self.__single_link_gdf[net_field.SINGLE_LINK_ID_FIELD])}
143
+ self.__link_f_mapping = {v: k[0] for k, v in self.__ft_link_mapping.items()}
144
+ self.__link_t_mapping = {v: k[1] for k, v in self.__ft_link_mapping.items()}
138
145
 
139
146
  def create_graph(self, weight_field: str = None):
140
147
  """
@@ -394,6 +401,14 @@ class Link(object):
394
401
  def link_ft_map(self) -> dict[int, tuple[int, int]]:
395
402
  return self.__link_ft_mapping
396
403
 
404
+ @property
405
+ def link_f_map(self) -> dict[int, int]:
406
+ return self.__link_f_mapping
407
+
408
+ @property
409
+ def link_t_map(self) -> dict[int, int]:
410
+ return self.__link_t_mapping
411
+
397
412
  def vertex_degree(self, node: int = None) -> int:
398
413
  """无向图的节点度"""
399
414
  return self.__ud_graph.degree[node]
@@ -47,6 +47,7 @@ class Net(object):
47
47
  node_gdf: gpd.GeoDataFrame = None, weight_field: str = 'length', init_from_existing: bool = False,
48
48
  is_check: bool = True, create_single: bool = True, search_method: str = 'dijkstra',
49
49
  ft_link_mapping: dict = None, double_single_mapping: dict = None, link_ft_mapping: dict = None,
50
+ link_t_mapping: dict = None, link_f_mapping: dict = None,
50
51
  not_conn_cost: float = 999.0, cache_path: bool = True, cache_id: bool = True,
51
52
  is_sub_net: bool = False, fmm_cache: bool = False, cache_cn: int = 2, cache_slice: int = None,
52
53
  fmm_cache_fldr: str = None,
@@ -64,6 +65,8 @@ class Net(object):
64
65
  :param init_from_existing: 是否直接从内存中的gdf创建single_link_gdf, 该参数用于类内部创建子net, 用户不用关心该参数, 使用默认值即可
65
66
  :param double_single_mapping:
66
67
  :param link_ft_mapping:
68
+ :param link_f_mapping:
69
+ :param link_t_mapping:
67
70
  :param ft_link_mapping:
68
71
  :param not_conn_cost: 不连通路径的阻抗(m), 默认999.0米
69
72
  :param is_sub_net: 是否是子网络, 默认False
@@ -135,7 +138,9 @@ class Net(object):
135
138
  self.__link.init_link_from_existing_single_link(single_link_gdf=link_gdf,
136
139
  double_single_mapping=double_single_mapping,
137
140
  ft_link_mapping=ft_link_mapping,
138
- link_ft_mapping=link_ft_mapping)
141
+ link_ft_mapping=link_ft_mapping,
142
+ link_t_mapping=link_t_mapping,
143
+ link_f_mapping=link_f_mapping)
139
144
  if is_check:
140
145
  self.check()
141
146
 
@@ -315,6 +320,14 @@ class Net(object):
315
320
  def link_ft_map(self) -> dict[int, tuple[int, int]]:
316
321
  return self.__link.link_ft_map
317
322
 
323
+ @property
324
+ def link_t_map(self) -> dict[int, int]:
325
+ return self.__link.link_t_map
326
+
327
+ @property
328
+ def link_f_map(self) -> dict[int, int]:
329
+ return self.__link.link_f_map
330
+
318
331
  @property
319
332
  def available_link_id(self) -> int:
320
333
  return self.__link.available_link_id
@@ -355,7 +368,7 @@ class Net(object):
355
368
  init_from_existing=True, is_check=False, cache_path=cache_path, cache_id=cache_id,
356
369
  not_conn_cost=not_conn_cost, is_sub_net=True, fmm_cache=fmm_cache,
357
370
  ft_link_mapping=self.get_ft_node_link_mapping(),
358
- link_ft_mapping=self.link_ft_map,
371
+ link_ft_mapping=self.link_ft_map, link_f_mapping=self.link_f_map, link_t_mapping=self.link_t_map,
359
372
  double_single_mapping=self.bilateral_unidirectional_mapping, cut_off=self.cut_off,
360
373
  delete_circle=False)
361
374
  sub_net.init_net(stp_cost_cache_df=self.get_path_cache(), cache_prj_inf=self.get_prj_cache())
@@ -646,7 +659,7 @@ class Net(object):
646
659
  pool.join()
647
660
  for res in result_list:
648
661
  done_stp_cost_df = pd.concat([done_stp_cost_df, res.get()])
649
- done_stp_cost_df.reset_index(inplace=True, drop=False)
662
+ done_stp_cost_df.reset_index(inplace=True, drop=True)
650
663
  _ = self.__link.get_link_data()[[net_field.FROM_NODE_FIELD, net_field.TO_NODE_FIELD,
651
664
  self.weight_field]].rename(
652
665
  columns={net_field.FROM_NODE_FIELD: o_node_field, net_field.TO_NODE_FIELD: d_node_field,
@@ -273,14 +273,15 @@ class HiddenMarkov(object):
273
273
  else:
274
274
  done_stp_cost_df = self.net.get_path_cache()
275
275
  cache_prj_info = self.net.get_prj_cache()
276
-
276
+ single_link_f_map, single_link_t_map = self.net.link_f_map, self.net.link_t_map
277
277
  adj_seq_path_dict, ft_transition_dict, ft_idx_map, s2s_route_l, prj_done_df, \
278
278
  done_stp_cost_df = \
279
279
  self.generate_transition_mat_beta(single_link_ft_df, self.gps_candidate_link,
280
280
  gps_pre_next_dis_df, g, self.net.search_method,
281
281
  self.net.weight_field, self.net.cache_path, self.net.not_conn_cost,
282
282
  done_stp_cost_df, is_sub_net, fmm_cache,
283
- cut_off, max_cut_off, cache_prj_info, add_single_ft)
283
+ cut_off, max_cut_off, cache_prj_info, add_single_ft, single_link_f_map,
284
+ single_link_t_map)
284
285
  # print(len(done_stp_cost_df))
285
286
  ft_idx_map.reset_index(inplace=True, drop=True)
286
287
  s2s_route_l.reset_index(inplace=True, drop=True)
@@ -303,7 +304,8 @@ class HiddenMarkov(object):
303
304
  done_stp_cost_df: pd.DataFrame = None,
304
305
  is_sub_net: bool = True, fmm_cache: bool = False, cut_off: float = 600.0,
305
306
  max_cut_off: float = 2000.0, cache_prj_inf: dict = None,
306
- add_single_ft: list[bool] = None) -> \
307
+ add_single_ft: list[bool] = None, link_f_map: dict = None,
308
+ link_t_map: dict = None) -> \
307
309
  tuple[dict, dict, pd.DataFrame, pd.DataFrame, pd.DataFrame, pd.DataFrame]:
308
310
  # K候选
309
311
  seq_k_candidate_info = \
@@ -311,68 +313,50 @@ class HiddenMarkov(object):
311
313
  top_k=self.top_k, cache_prj_inf=cache_prj_inf)
312
314
  # print(rf'{len(seq_k_candidate_info)}个候选路段...')
313
315
  seq_k_candidate_info.sort_values(by=[gps_field.POINT_SEQ_FIELD, net_field.SINGLE_LINK_ID_FIELD], inplace=True)
316
+ now_source_node = set(seq_k_candidate_info[net_field.FROM_NODE_FIELD])
314
317
 
315
318
  seq_k_candidate_info['idx'] = seq_k_candidate_info.groupby(gps_field.POINT_SEQ_FIELD)[
316
319
  net_field.SINGLE_LINK_ID_FIELD].rank(method='min').astype(int) - 1
317
320
 
318
321
  ft_idx_map = seq_k_candidate_info[[gps_field.POINT_SEQ_FIELD, net_field.SINGLE_LINK_ID_FIELD, 'idx']].copy()
319
322
 
320
- # ft_idx_map.sort_values(by=[gps_field.POINT_SEQ_FIELD, net_field.SINGLE_LINK_ID_FIELD], inplace=True)
321
323
  del seq_k_candidate_info['idx']
322
324
  del pre_seq_candidate
323
-
324
325
  seq_k_candidate = seq_k_candidate_info.groupby(gps_field.POINT_SEQ_FIELD).agg(
325
326
  {net_field.SINGLE_LINK_ID_FIELD: list, gps_field.POINT_SEQ_FIELD: list,
326
- net_field.FROM_NODE_FIELD: 'count'}).rename(
327
+ 'route_dis': list, net_field.FROM_NODE_FIELD: 'count'}).rename(
327
328
  columns={gps_field.POINT_SEQ_FIELD: 'g_s', net_field.FROM_NODE_FIELD: 'count'})
328
329
  seq_len_dict = {s: l for s, l in zip(seq_k_candidate.index, seq_k_candidate['count'])}
329
- gps_match_link_route_dis = seq_k_candidate_info[
330
- [gps_field.POINT_SEQ_FIELD, net_field.SINGLE_LINK_ID_FIELD, 'route_dis']].copy()
331
330
  seq_k_candidate.rename(columns={net_field.SINGLE_LINK_ID_FIELD: markov_field.FROM_STATE,
331
+ 'route_dis': 'from_route_dis',
332
332
  'g_s': gps_field.FROM_GPS_SEQ}, inplace=True)
333
333
 
334
334
  seq_k_candidate[markov_field.TO_STATE] = seq_k_candidate[markov_field.FROM_STATE].shift(-1)
335
335
  seq_k_candidate[gps_field.TO_GPS_SEQ] = seq_k_candidate[gps_field.FROM_GPS_SEQ].shift(-1)
336
-
336
+ seq_k_candidate['to_route_dis'] = seq_k_candidate['from_route_dis'].shift(-1)
337
337
  seq_k_candidate.dropna(subset=[markov_field.TO_STATE], inplace=True)
338
338
 
339
- from_state = seq_k_candidate[[markov_field.FROM_STATE, gps_field.FROM_GPS_SEQ]].reset_index(drop=False).rename(
339
+ from_state = seq_k_candidate[[markov_field.FROM_STATE, gps_field.FROM_GPS_SEQ, 'from_route_dis']].reset_index(
340
+ drop=False).rename(
340
341
  columns={gps_field.POINT_SEQ_FIELD: 'g'}).explode(
341
- column=[markov_field.FROM_STATE, gps_field.FROM_GPS_SEQ], ignore_index=True)
342
-
342
+ column=[markov_field.FROM_STATE, gps_field.FROM_GPS_SEQ, 'from_route_dis'], ignore_index=True)
343
343
  to_state = seq_k_candidate[
344
- [markov_field.TO_STATE, gps_field.TO_GPS_SEQ]].reset_index(drop=False).rename(
345
- columns={gps_field.POINT_SEQ_FIELD: 'g'}).explode(column=[markov_field.TO_STATE, gps_field.TO_GPS_SEQ],
346
- ignore_index=True)
344
+ [markov_field.TO_STATE, gps_field.TO_GPS_SEQ, 'to_route_dis']].reset_index(drop=False).rename(
345
+ columns={gps_field.POINT_SEQ_FIELD: 'g'}).explode(
346
+ column=[markov_field.TO_STATE, gps_field.TO_GPS_SEQ, 'to_route_dis'],
347
+ ignore_index=True)
348
+ from_state['from_route_dis'] = from_state['from_route_dis'].astype(float)
349
+ to_state['to_route_dis'] = to_state['to_route_dis'].astype(float)
347
350
 
348
351
  transition_df = pd.merge(from_state, to_state, on='g', how='outer')
349
352
  transition_df.reset_index(inplace=True, drop=True)
350
353
  # print(rf'{len(transition_df)}次状态转移...')
351
- transition_df = self.diy_merge(left_df=transition_df,
352
- right_df=single_link_ft_df[
353
- [net_field.SINGLE_LINK_ID_FIELD, net_field.FROM_NODE_FIELD,
354
- net_field.TO_NODE_FIELD]],
355
- left_key=markov_field.FROM_STATE, right_key=net_field.SINGLE_LINK_ID_FIELD,
356
- label='from')
357
- transition_df = self.diy_merge(left_df=transition_df,
358
- right_df=single_link_ft_df[
359
- [net_field.SINGLE_LINK_ID_FIELD, net_field.FROM_NODE_FIELD,
360
- net_field.TO_NODE_FIELD]],
361
- left_key=markov_field.TO_STATE, right_key=net_field.SINGLE_LINK_ID_FIELD,
362
- label='to')
363
- transition_df = self.diy_merge(left_df=transition_df,
364
- right_df=gps_match_link_route_dis,
365
- left_key=[gps_field.FROM_GPS_SEQ, markov_field.FROM_STATE],
366
- right_key=[gps_field.POINT_SEQ_FIELD, net_field.SINGLE_LINK_ID_FIELD],
367
- label='from', merge_type='prj')
368
- transition_df = self.diy_merge(left_df=transition_df,
369
- right_df=gps_match_link_route_dis,
370
- left_key=[gps_field.TO_GPS_SEQ, markov_field.TO_STATE],
371
- right_key=[gps_field.POINT_SEQ_FIELD, net_field.SINGLE_LINK_ID_FIELD],
372
- label='to', merge_type='prj')
373
- del gps_match_link_route_dis
374
-
375
- now_source_node = set(transition_df['from_link_f'])
354
+ transition_df['from_link_f'] = transition_df[markov_field.FROM_STATE].map(link_f_map)
355
+ transition_df['from_link_t'] = transition_df[markov_field.FROM_STATE].map(link_t_map)
356
+ transition_df['to_link_f'] = transition_df[markov_field.TO_STATE].map(link_f_map)
357
+ transition_df['to_link_t'] = transition_df[markov_field.TO_STATE].map(link_t_map)
358
+
359
+ # now_source_node = set(transition_df['from_link_f'])
376
360
  if not fmm_cache:
377
361
  # 先计算所有要计算的path
378
362
  if o_node_field in done_stp_cost_df.columns:
@@ -391,8 +375,11 @@ class HiddenMarkov(object):
391
375
  add_single_ft=add_single_ft)
392
376
  del single_link_ft_df, g
393
377
 
394
- transition_df = pd.merge(transition_df, done_stp_cost_df, left_on=['from_link_f', 'to_link_f'],
378
+ _done_stp_cost_df = done_stp_cost_df[done_stp_cost_df[o_node_field].isin(now_source_node) &
379
+ done_stp_cost_df[d_node_field].isin(now_source_node)].copy()
380
+ transition_df = pd.merge(transition_df, _done_stp_cost_df, left_on=['from_link_f', 'to_link_f'],
395
381
  right_on=[o_node_field, d_node_field], how='left')
382
+ del _done_stp_cost_df
396
383
  del transition_df[o_node_field], transition_df[d_node_field]
397
384
  # sub_net do not share path within different agents
398
385
  if is_sub_net or fmm_cache or not cache_path:
@@ -416,8 +403,7 @@ class HiddenMarkov(object):
416
403
  transition_df.loc[same_link_idx, :]['to_route_dis'])
417
404
  transition_df['2nd_node'] = -1
418
405
  transition_df['-2nd_node'] = -1
419
- # normal_path_idx_a = transition_df[cost_field] > 0
420
- # normal_path_idx_a可能全是False
406
+ # normal_path_idx_a = transition_df[cost_field] > 0, normal_path_idx_a可能全是False
421
407
  try:
422
408
  transition_df.loc[normal_path_idx_a, '2nd_node'] = transition_df.loc[normal_path_idx_a, :][
423
409
  path_field].apply(
@@ -448,11 +434,6 @@ class HiddenMarkov(object):
448
434
  transition_df['trans_values'] = \
449
435
  self.transition_probability(self.beta, transition_df[markov_field.DIS_GAP].values, self.dis_para)
450
436
 
451
- # ft_transition_dict = {f_gps_seq: df[
452
- # [markov_field.FROM_STATE, markov_field.TO_STATE, 'trans_values']].set_index(
453
- # [markov_field.FROM_STATE, markov_field.TO_STATE]).unstack().values for (f_gps_seq, t_gps_seq), df in
454
- # transition_df.groupby([gps_field.FROM_GPS_SEQ, gps_field.TO_GPS_SEQ])}
455
-
456
437
  ft_transition_dict = {f_gps_seq: df['trans_values'].values.reshape(seq_len_dict[f_gps_seq],
457
438
  int(len(df) / seq_len_dict[f_gps_seq])) for
458
439
  (f_gps_seq, t_gps_seq), df in
@@ -505,22 +486,6 @@ class HiddenMarkov(object):
505
486
  stp_cost_df.reset_index(inplace=True, drop=True)
506
487
  return stp_cost_df
507
488
 
508
- @staticmethod
509
- def diy_merge(left_df: pd.DataFrame, right_df: pd.DataFrame or gpd.GeoDataFrame = None,
510
- left_key: str or list[str] = None,
511
- right_key: str or list[str] = None, label: str = 'from', merge_type: str = 'ft'):
512
- df = pd.merge(left_df, right_df, left_on=left_key, right_on=right_key, how='left')
513
-
514
- if merge_type == 'ft':
515
- df.rename(columns={net_field.FROM_NODE_FIELD: label + '_link_f',
516
- net_field.TO_NODE_FIELD: label + '_link_t'}, inplace=True)
517
-
518
- df.drop(columns=[right_key], axis=1, inplace=True)
519
- else:
520
- df.rename(columns={'route_dis': label + '_route_dis'}, inplace=True)
521
- df.drop(columns=right_key, axis=1, inplace=True)
522
- return df
523
-
524
489
  @staticmethod
525
490
  def _single_source_path_alpha(g: nx.DiGraph = None, source: int = None, method: str = 'dijkstra',
526
491
  weight_field: str = None, cut_off: float = 600.0) -> \
@@ -900,180 +865,8 @@ class HiddenMarkov(object):
900
865
  del self.warn_info
901
866
 
902
867
 
903
- # @function_time_cost
904
- # def generate_transition_mat_beta1(self, gps_ft_list: list = None, single_link_ft_df: pd.DataFrame = None,
905
- # pre_seq_candidate: pd.DataFrame = None,
906
- # gps_pre_next_dis_df: pd.DataFrame = None,
907
- # g: nx.DiGraph = None,
908
- # method: str = None, weight_field: str = 'length',
909
- # cache_path: bool = True, not_conn_cost: float = 999.0,
910
- # done_stp_cost_df: pd.DataFrame = None,
911
- # is_sub_net: bool = True, fmm_cache: bool = False, cut_off: float = 600.0,
912
- # max_cut_off: float = 2000.0, cache_prj_inf: dict = None) -> \
913
- # tuple[dict, dict, pd.DataFrame, pd.DataFrame, pd.DataFrame, pd.DataFrame]:
914
- # gps_ft_df = pd.DataFrame(gps_ft_list, columns=['f_gps_seq', 't_gps_seq'])
915
- # used_gps_seq = list(set(gps_ft_df['f_gps_seq']) | set(gps_ft_df['t_gps_seq']))
916
- #
917
- # # 确定最终的top_k候选
918
- # pre_seq_candidate = pre_seq_candidate[
919
- # pre_seq_candidate[gps_field.POINT_SEQ_FIELD].isin(used_gps_seq)].copy()
920
- # seq_k_candidate_info = self.filter_k_candidates(preliminary_candidate_link=pre_seq_candidate,
921
- # top_k=self.top_k, cache_prj_inf=cache_prj_inf)
922
- #
923
- # # 存储状态的索引和状态序列的映射
924
- # seq_k_candidate_info['idx'] = seq_k_candidate_info.groupby(gps_field.POINT_SEQ_FIELD)[
925
- # net_field.SINGLE_LINK_ID_FIELD].rank(method='min').astype(int) - 1
926
- # ft_idx_map = seq_k_candidate_info[[gps_field.POINT_SEQ_FIELD, net_field.SINGLE_LINK_ID_FIELD, 'idx']].copy()
927
- # ft_idx_map.sort_values(by=[gps_field.POINT_SEQ_FIELD, net_field.SINGLE_LINK_ID_FIELD], inplace=True)
928
- # del seq_k_candidate_info['idx']
929
- #
930
- # del pre_seq_candidate
931
- # del used_gps_seq
932
- #
933
- # s = time.time()
934
- # # 构造状态转移表
935
- # seq_k_candidate = seq_k_candidate_info.groupby(gps_field.POINT_SEQ_FIELD).agg(
936
- # {net_field.SINGLE_LINK_ID_FIELD: list, gps_field.POINT_SEQ_FIELD: list,
937
- # net_field.FROM_NODE_FIELD: list, net_field.TO_NODE_FIELD: list, 'route_dis': list}).rename(
938
- # columns={gps_field.POINT_SEQ_FIELD: gps_field.FROM_GPS_SEQ,
939
- # net_field.SINGLE_LINK_ID_FIELD: markov_field.FROM_STATE,
940
- # net_field.FROM_NODE_FIELD: 'from_link_f', net_field.TO_NODE_FIELD: 'from_link_t',
941
- # 'route_dis': 'from_route_dis'})
942
- #
943
- # seq_k_candidate[[gps_field.TO_GPS_SEQ, markov_field.TO_STATE, 'to_link_f', 'to_link_t', 'to_route_dis']] = \
944
- # seq_k_candidate[[gps_field.FROM_GPS_SEQ, markov_field.FROM_STATE, 'from_link_f', 'from_link_t',
945
- # 'from_route_dis']].shift(-1)
946
- # seq_k_candidate.dropna(subset=[markov_field.TO_STATE], inplace=True)
947
- #
948
- # from_state = seq_k_candidate[
949
- # [markov_field.FROM_STATE, gps_field.FROM_GPS_SEQ,
950
- # 'from_link_f', 'from_link_t', 'from_route_dis']].reset_index(drop=False).explode(
951
- # column=[markov_field.FROM_STATE, gps_field.FROM_GPS_SEQ, 'from_link_f', 'from_link_t',
952
- # 'from_route_dis'], ignore_index=True)
953
- #
954
- # to_state = seq_k_candidate[
955
- # [markov_field.TO_STATE, gps_field.TO_GPS_SEQ, 'to_link_f', 'to_link_t', 'to_route_dis']].reset_index(
956
- # drop=False).explode(
957
- # column=[markov_field.TO_STATE, gps_field.TO_GPS_SEQ, 'to_link_f', 'to_link_t', 'to_route_dis'],
958
- # ignore_index=True)
959
- # del seq_k_candidate
960
- # transition_df = pd.merge(from_state, to_state, on=gps_field.POINT_SEQ_FIELD, how='outer')
961
- # del transition_df[gps_field.POINT_SEQ_FIELD]
962
- # del from_state, to_state
963
- # transition_df.reset_index(inplace=True, drop=True)
964
- # print(rf'构造: {time.time() - s}')
965
- # t = time.time()
966
- # del single_link_ft_df
967
- #
968
- # now_source_node = set(transition_df['from_link_f'])
969
- # if not fmm_cache:
970
- # # 先计算所有要计算的path
971
- # already_cache_node = set(done_stp_cost_df['o_node'])
972
- # gap = now_source_node - already_cache_node
973
- # if not gap:
974
- # done_stp_cost_df = self.add_path_cache(done_stp_cost_df=done_stp_cost_df,
975
- # source_node_list=gap, cut_off=cut_off,
976
- # weight_field=weight_field, method=method, g=g)
977
- # now_source_node = set(done_stp_cost_df['o_node'])
978
- #
979
- # # 如果某些点除开自身-自身没有其他点, 则加一个5km搜索
980
- # done_stp_cost_df.drop(index=done_stp_cost_df[done_stp_cost_df['o_node'] == done_stp_cost_df['d_node']].index,
981
- # inplace=True)
982
- # no_path_node = now_source_node - set(done_stp_cost_df['o_node'])
983
- # if no_path_node:
984
- # done_stp_cost_df = self.add_path_cache(done_stp_cost_df=done_stp_cost_df,
985
- # source_node_list=no_path_node, cut_off=max_cut_off,
986
- # weight_field=weight_field, method=method, g=g)
987
- # del g
988
- #
989
- # # transition_df['from_route_dis'] = transition_df['from_route_dis'].astype(float)
990
- # # transition_df['to_route_dis'] = transition_df['to_route_dis'].astype(float)
991
- #
992
- # transition_df = pd.merge(transition_df, done_stp_cost_df, left_on=['from_link_f', 'to_link_f'],
993
- # right_on=['o_node', 'd_node'], how='left')
994
- # del transition_df['o_node'], transition_df['d_node']
995
- # # sub_net do not share path within different agents
996
- # if is_sub_net or fmm_cache or not cache_path:
997
- # del done_stp_cost_df
998
- # done_stp_cost_df = pd.DataFrame()
999
- #
1000
- # transition_df['cost'] = transition_df['cost'].fillna(0)
1001
- # transition_df.reset_index(inplace=True, drop=True)
1002
- # transition_df[markov_field.ROUTE_LENGTH] = not_conn_cost * 1.0
1003
- #
1004
- # _ = transition_df[transition_df['cost'] > 0]
1005
- # adj_seq_path_dict = {(int(f_state), int(t_state)): node_path for f_state, t_state, node_path, c in
1006
- # zip(_[markov_field.FROM_STATE],
1007
- # _[markov_field.TO_STATE],
1008
- # _['path'],
1009
- # _['cost']) if c > 0}
1010
- # z = time.time()
1011
- # same_link_idx = transition_df[markov_field.FROM_STATE] == transition_df[markov_field.TO_STATE]
1012
- # transition_df.loc[same_link_idx, markov_field.ROUTE_LENGTH] = \
1013
- # np.abs(transition_df.loc[same_link_idx, :]['from_route_dis'].values.astype(float) -
1014
- # transition_df.loc[same_link_idx, :]['to_route_dis'].values.astype(float))
1015
- # transition_df['2nd_node'] = -1
1016
- # transition_df['-2nd_node'] = -1
1017
- # normal_path_idx_a = transition_df['cost'] > 0
1018
- # t2 = time.time()
1019
- # transition_df.loc[normal_path_idx_a, '2nd_node'] = transition_df.loc[normal_path_idx_a, :]['path'].apply(
1020
- # lambda x: x[1])
1021
- # transition_df.loc[normal_path_idx_a, '-2nd_node'] = transition_df.loc[normal_path_idx_a, :]['path'].apply(
1022
- # lambda x: x[-2])
1023
- # t3 = time.time()
1024
- # normal_path_idx_b = (normal_path_idx_a & \
1025
- # (transition_df['2nd_node'] == transition_df['from_link_t']) & \
1026
- # (transition_df['-2nd_node'] != transition_df['to_link_t'])) | \
1027
- # ((transition_df['from_link_f'] == transition_df['to_link_t']) &
1028
- # (transition_df['from_link_t'] == transition_df['to_link_f']))
1029
- #
1030
- # transition_df.loc[normal_path_idx_b, markov_field.ROUTE_LENGTH] = \
1031
- # np.abs(transition_df.loc[normal_path_idx_b, :]['cost'].values -
1032
- # transition_df.loc[normal_path_idx_b, :]['from_route_dis'].values.astype(float) +
1033
- # transition_df.loc[normal_path_idx_b, :]['to_route_dis'].values.astype(float))
1034
- # print(rf'cache_len: {len(done_stp_cost_df)}')
1035
- #
1036
- # transition_df = pd.merge(transition_df, gps_pre_next_dis_df, on=[gps_field.FROM_GPS_SEQ, gps_field.TO_GPS_SEQ],
1037
- # how='left')
1038
- #
1039
- # transition_df[markov_field.DIS_GAP] = np.abs(
1040
- # -transition_df[markov_field.ROUTE_LENGTH] + transition_df[gps_field.ADJ_DIS])
1041
- # t4 = time.time()
1042
- # # print(transition_df[markov_field.DIS_GAP])
1043
- # print(rf'向量化总时间: {t4 - z}')
1044
- # print(rf'apply: {t3 - t2}')
1045
- # print(rf'总计算: {t4 - t}')
1046
- #
1047
- # s2s_route_l = transition_df[[gps_field.FROM_GPS_SEQ, gps_field.TO_GPS_SEQ, markov_field.ROUTE_LENGTH,
1048
- # markov_field.FROM_STATE, markov_field.TO_STATE]].copy()
1049
- #
1050
- # transition_df['trans_values'] = \
1051
- # self.transition_probability(self.beta, transition_df[markov_field.DIS_GAP].values, self.dis_para)
1052
- #
1053
- # ft_transition_dict = {f_gps_seq: df[
1054
- # [markov_field.FROM_STATE, markov_field.TO_STATE, 'trans_values']].set_index(
1055
- # [markov_field.FROM_STATE, markov_field.TO_STATE]).unstack().values for (f_gps_seq, t_gps_seq), df in
1056
- # transition_df.groupby([gps_field.FROM_GPS_SEQ, gps_field.TO_GPS_SEQ])}
1057
- # print(rf'归并mat: {time.time() - t4}')
1058
- #
1059
- # return adj_seq_path_dict, ft_transition_dict, ft_idx_map, s2s_route_l, seq_k_candidate_info, done_stp_cost_df
1060
-
1061
-
1062
868
  if __name__ == '__main__':
1063
869
  pass
1064
- # a = LineString([(0, 0), (0, 1)])
1065
- # z = a.segmentize(1/3 + 0.1 * 1/ 3)
1066
- # print(z)
1067
-
1068
- # x = pd.DataFrame({'a': [1,2,3], 'b': [4,5,6]})
1069
- # print(x)
1070
- # x.loc[x['a'] >= 2, ['a', 'b']] = [[12, 11], [121,344]]
1071
- # print(x)
1072
- #
1073
- # x = datetime.datetime.now()
1074
- # time.sleep(2)
1075
- # x1 = datetime.datetime.now()
1076
- # print((x1 - x).total_seconds())
1077
870
 
1078
871
 
1079
872
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: gotrackit
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: A Python Package for Map Matching Algorithm Based on Hidden Markov Model
5
5
  Author-email: Kai Tang <794568794@qq.com>
6
6
  License: LICENCE
@@ -49,47 +49,50 @@ Developed by Tang Kai, Email: 794568794@qq.com & tangkai@zhechengdata.com
49
49
  更新命令:pip install --upgrade -i https://pypi.org/simple/ gotrackit
50
50
 
51
51
 
52
- - 效率优化, 相较于v0.2.2小幅度提升
52
+ - 地图匹配接口效率优化, 相较于v0.2.2小幅度提升
53
53
 
54
- - crs判断BUG修复、境外路网构建失败BUG修复
54
+ - 地图匹配接口报错机制优化
55
55
 
56
- - 报错机制优化
56
+ - 地图匹配接口移除html_fldr参数, 使用out_fldr替代
57
57
 
58
- - 输出文件目录指定参数html_fldr废除, 改为out_fldr
58
+ - 地图匹配接口增加即时输出开关instant_output, 打开后, 每匹配完一条轨迹马上进行结果存储
59
59
 
60
- - 增加环路处理功能
61
-
62
- - 增加匹配结果即时输出参数, 每匹配完一条轨迹可马上进行结果存储
60
+ - 路网构建: crs判断BUG修复、境外路网构建失败BUG修复
61
+
62
+ - 增加 环路 处理功能
63
+
64
+
65
+ **不要下载GitHub仓库上的代码来使用!!! 直接pip安装gotrackit为第三方库即可使用**
63
66
 
64
67
 
65
68
  <br>
66
69
 
67
70
  <div align=center>
68
- ~ v0.2.2效率将大幅度提升, 最高可以提升10倍的性能 !~
71
+ ~ v0.2.4(相较于0.2.1)效率将大幅度提升, 最高可以提升10倍的性能 !~
69
72
  </div>
70
73
 
71
74
  <br>
72
75
 
73
76
  与上一版本对比:
74
77
 
75
- | 样例数据 | 有效的GPS点数 | top_k(k邻近候选参数) | gps_buffer(临域半径) | 候选路段条数 | 状态转移次数 | v0.2.1版解算时间 | v0.2.2版解算时间 |
76
- |----------------|----------|----------------|------------------|---------|------------|-------------|-----------|
77
- | 1辆车,深圳稀疏轨迹点样例1 | 190 | 60 | 500m | 10615 | 629788次 | 28秒 | **3.3秒** |
78
- | 1辆车,深圳稀疏轨迹点样例2 | 400 | 20 | 120m | 5137 | 82006次 | 7.8秒 | **1.7秒** |
78
+ | 样例数据 | 有效的GPS点数 | top_k(k邻近候选参数) | gps_buffer(临域半径) | 候选路段条数 | 状态转移次数 | v0.2.1版解算时间 | v0.2.4版解算时间 |
79
+ |----------------|----------|----------------|------------------|---------|------------|-------------|-------------|
80
+ | 1辆车,深圳稀疏轨迹点样例1 | 190 | 60 | 500m | 10615 | 629788次 | 28秒 | **1.87秒** |
81
+ | 1辆车,深圳稀疏轨迹点样例2 | 400 | 20 | 120m | 5137 | 82006次 | 7.8秒 | **0.89秒** |
79
82
 
80
83
 
81
- v0.2.2多核效率对比:
84
+ v0.2.4多核效率对比:
82
85
 
83
- 基于上表深圳稀疏轨迹点样例2,我们将他复制150份,进行多核测试,可以看到到6核时, 效率已经不再提升,最快96s解算完150条轨迹,平均每条轨迹0.64s,相较于1.7s再次提升了60%,在车辆数较多时,多核的效率提升很明显。
86
+ 基于上表深圳稀疏轨迹点样例2,我们将他复制150份,进行多核测试,可以看到到6核时, 效率已经不再提升,最快89s解算完150条轨迹,平均每条轨迹0.59s,相较于0.89s再次提升了30%,在车辆数较多时,多核的效率提升很明显。
84
87
 
85
- | 样例数据 | 有效的GPS点数 | top_k | gps_buffer | 候选路段条数 | 状态转移次数 | v0.2.2解算时间 |
88
+ | 样例数据 | 有效的GPS点数 | top_k | gps_buffer | 候选路段条数 | 状态转移次数 | v0.2.4解算时间 |
86
89
  |-------------------------------------------|----------|----------------|------------------|-----|--------|------------|
87
- | 150辆车的GPS轨迹(单核串行,子图搜索,有构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 300.0秒 |
88
- | 150辆车的GPS轨迹(3核并行,子图搜索,有构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 139.6秒 |
89
- | 150辆车的GPS轨迹(3核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 120.3秒 |
90
- | 150辆车的GPS轨迹(4核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 104.9 |
91
- | 150辆车的GPS轨迹(5核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 96.4秒 |
92
- | 150辆车的GPS轨迹(6核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 97.5秒 |
90
+ | 150辆车的GPS轨迹(单核串行,子图搜索,有构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 290.0秒 |
91
+ | 150辆车的GPS轨迹(3核并行,子图搜索,有构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 130.6秒 |
92
+ | 150辆车的GPS轨迹(3核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 113.3秒 |
93
+ | 150辆车的GPS轨迹(4核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 97.3 |
94
+ | 150辆车的GPS轨迹(5核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 89.4秒 |
95
+ | 150辆车的GPS轨迹(6核并行,全图搜索,无构建子图的额外开销,提前预计算路径) | 6w | 20 | 120m | 75W | 1200W次 | 91.5秒 |
93
96
 
94
97
 
95
98
  <br>
File without changes
File without changes
File without changes