gotrackit 0.1.0__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 TangKai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,88 @@
1
+ Metadata-Version: 2.1
2
+ Name: gotrackit
3
+ Version: 0.1.0
4
+ Summary: A Python Package for Map Matching Algorithm Based on Hidden Markov Model
5
+ Author-email: Kai Tang <794568794@qq.com>
6
+ License: LICENCE
7
+ Project-URL: Homepage, https://github.com/zdsjjtTLG/TrackIt
8
+ Keywords: HMM,MapMatching,Net,Link,Node,Hidden Markov Model,Algorithm
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.8
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: geopandas>=0.14.1
16
+ Requires-Dist: shapely
17
+ Requires-Dist: networkx
18
+ Requires-Dist: pandas
19
+ Requires-Dist: numpy
20
+ Requires-Dist: keplergl
21
+
22
+ # GoTrackIt
23
+
24
+ 作者: 唐铠, 794568794@qq.com, tangkai@zhechengdata.com
25
+
26
+ ## 1. 简介
27
+ gotrackit是一个地图匹配包, 基于隐马尔可夫模型(Hidden Markov Model)实现
28
+
29
+ ### 1.1. 如何安装gotrackit
30
+
31
+ #### __所需前置依赖__
32
+
33
+ - geopandas(0.14.1)
34
+ - gdal(3.4.3)
35
+ - networkx(3.2.1)
36
+ - shapely(2.0.2)
37
+ - pandas(2.0.3)
38
+ - numpy(1.26.2)
39
+ - pyproj(3.6.1)
40
+ - keplergl(0.3.2)
41
+
42
+ 括号中为作者使用版本(基于python3.11), 仅供参考
43
+
44
+ geopandas为最新版本, 如果不是最新版本可能会报错(有个函数旧版本没有)
45
+
46
+ #### __使用pip安装__
47
+
48
+ ``` shell
49
+ pip install -i https://test.pypi.org/simple/ gotrackit==0.0.2
50
+ ```
51
+
52
+ ### 1.2 用户手册
53
+
54
+ 链接:https://gotrackitdocs.readthedocs.io/en/latest/
55
+
56
+
57
+ ## 2. 地图匹配问题
58
+
59
+ ![car_gps.png](./doc/docs/source/images/car_gps.png)
60
+
61
+ ![where_car.png](./doc/docs/source/images/whereIsCar.png)
62
+
63
+ __如何依据GPS数据推算车辆的实际路径?__
64
+
65
+ ## 3. 地图匹配算法动画演示
66
+
67
+ 想了解算法过程的可以参考B站视频:
68
+
69
+ https://www.bilibili.com/video/BV1gQ4y1w7dC/?vd_source=7389960e7356c27a5d1849f7ee9ae6f2
70
+
71
+ ![main.png](./doc/docs/source/images/single_p.png)
72
+
73
+ ![main.png](./doc/docs/source/images/transition.png)
74
+
75
+ ![main.png](./doc/docs/source/images/viterbi.png)
76
+
77
+ ![main.png](./doc/docs/source/images/trace.png)
78
+
79
+
80
+ ## 4. 匹配结果可视化
81
+
82
+ 中高频GPS匹配效果:
83
+
84
+ ![main.png](./doc/docs/source/images/m_h_f.gif)
85
+
86
+ 低频GPS匹配效果:
87
+
88
+ ![main.png](./doc/docs/source/images/l_f.gif)
@@ -0,0 +1,67 @@
1
+ # GoTrackIt
2
+
3
+ 作者: 唐铠, 794568794@qq.com, tangkai@zhechengdata.com
4
+
5
+ ## 1. 简介
6
+ gotrackit是一个地图匹配包, 基于隐马尔可夫模型(Hidden Markov Model)实现
7
+
8
+ ### 1.1. 如何安装gotrackit
9
+
10
+ #### __所需前置依赖__
11
+
12
+ - geopandas(0.14.1)
13
+ - gdal(3.4.3)
14
+ - networkx(3.2.1)
15
+ - shapely(2.0.2)
16
+ - pandas(2.0.3)
17
+ - numpy(1.26.2)
18
+ - pyproj(3.6.1)
19
+ - keplergl(0.3.2)
20
+
21
+ 括号中为作者使用版本(基于python3.11), 仅供参考
22
+
23
+ geopandas为最新版本, 如果不是最新版本可能会报错(有个函数旧版本没有)
24
+
25
+ #### __使用pip安装__
26
+
27
+ ``` shell
28
+ pip install -i https://test.pypi.org/simple/ gotrackit==0.0.2
29
+ ```
30
+
31
+ ### 1.2 用户手册
32
+
33
+ 链接:https://gotrackitdocs.readthedocs.io/en/latest/
34
+
35
+
36
+ ## 2. 地图匹配问题
37
+
38
+ ![car_gps.png](./doc/docs/source/images/car_gps.png)
39
+
40
+ ![where_car.png](./doc/docs/source/images/whereIsCar.png)
41
+
42
+ __如何依据GPS数据推算车辆的实际路径?__
43
+
44
+ ## 3. 地图匹配算法动画演示
45
+
46
+ 想了解算法过程的可以参考B站视频:
47
+
48
+ https://www.bilibili.com/video/BV1gQ4y1w7dC/?vd_source=7389960e7356c27a5d1849f7ee9ae6f2
49
+
50
+ ![main.png](./doc/docs/source/images/single_p.png)
51
+
52
+ ![main.png](./doc/docs/source/images/transition.png)
53
+
54
+ ![main.png](./doc/docs/source/images/viterbi.png)
55
+
56
+ ![main.png](./doc/docs/source/images/trace.png)
57
+
58
+
59
+ ## 4. 匹配结果可视化
60
+
61
+ 中高频GPS匹配效果:
62
+
63
+ ![main.png](./doc/docs/source/images/m_h_f.gif)
64
+
65
+ 低频GPS匹配效果:
66
+
67
+ ![main.png](./doc/docs/source/images/l_f.gif)
@@ -0,0 +1,24 @@
1
+ [build-system]
2
+ requires = ["setuptools >= 61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "gotrackit"
7
+ version = "0.1.0"
8
+ dependencies = ["geopandas>=0.14.1", "shapely", "networkx", "pandas", "numpy", "keplergl"]
9
+ requires-python = ">=3.8"
10
+ authors = [
11
+ { name="Kai Tang", email="794568794@qq.com" },
12
+ ]
13
+ description = "A Python Package for Map Matching Algorithm Based on Hidden Markov Model"
14
+ readme = "README.md"
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Operating System :: OS Independent",
19
+ ]
20
+ license = {text = "LICENCE"}
21
+ keywords = ["HMM", "MapMatching", "Net", "Link", "Node", "Hidden Markov Model", "Algorithm"]
22
+
23
+ [project.urls]
24
+ Homepage = "https://github.com/zdsjjtTLG/TrackIt"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,4 @@
1
+ # -- coding: utf-8 --
2
+ # @Time : 2023/12/9 8:01
3
+ # @Author : TangKai
4
+ # @Team : ZheChengData
@@ -0,0 +1,366 @@
1
+ # -- coding: utf-8 --
2
+ # @Time : 2023/12/10 20:14
3
+ # @Author : TangKai
4
+ # @Team : ZheChengData
5
+
6
+ """字段名称常量"""
7
+ import copy
8
+
9
+
10
+ class NetField(object):
11
+ """路网字段"""
12
+ def __init__(self):
13
+ self.LINK_ID_FIELD = 'link_id'
14
+ self.SINGLE_LINK_ID_FIELD = 'single_link_id'
15
+ self.DIRECTION_FIELD = 'dir'
16
+ self.FROM_NODE_FIELD = 'from_node'
17
+ self.TO_NODE_FIELD = 'to_node'
18
+ self.LENGTH_FIELD = 'length'
19
+ self.GEOMETRY_FIELD = 'geometry'
20
+ self.NODE_ID_FIELD = 'node_id'
21
+ self.NODE_PATH_FIELD = 'node_path'
22
+ self.COST_FIELD = 'cost'
23
+
24
+ class GpsField(object):
25
+ """gps数据字段"""
26
+ def __init__(self):
27
+ self.POINT_SEQ_FIELD = 'seq'
28
+ self.SUB_SEQ_FIELD = 'sub_seq'
29
+ self.ORIGIN_POINT_SEQ_FIELD = 'origin_seq'
30
+ self.TIME_FIELD = 'time'
31
+ self.LNG_FIELD = 'lng'
32
+ self.LAT_FIELD = 'lat'
33
+ self.HEADING_FIELD = 'heading'
34
+ self.AGENT_ID_FIELD = 'agent_id'
35
+ self.TYPE_FIELD = 'type'
36
+ self.NEXT_LINK_FIELD = 'next_link'
37
+ self.GEOMETRY_FIELD = 'geometry'
38
+
39
+
40
+ class MarkovField(object):
41
+ """HMM模型字段"""
42
+ def __init__(self):
43
+ self.FROM_STATE = 'from_state'
44
+ self.TO_STATE = 'to_state'
45
+ self.ROUTE_LENGTH = 'route_l'
46
+ self.ROUTE_ITEM = 'route_item'
47
+ self.STRAIGHT_LENGTH = 'straight_l'
48
+ self.DIS_GAP = 'dis_gap'
49
+ self.PRJ_L = 'prj_dis'
50
+
51
+
52
+ class KeplerConfig(object):
53
+ def __init__(self):
54
+ self.__BASE_CONFIG = {
55
+ 'version': 'v1',
56
+ 'config': {
57
+ 'visState': {
58
+ 'filters': [
59
+ {
60
+ 'dataId': [
61
+ 'mix'
62
+ ],
63
+ 'id': 'fd18q2cbg',
64
+ 'name': [
65
+ 'time'
66
+ ],
67
+ 'type': 'timeRange',
68
+ 'value': [
69
+ 1652372040.0,
70
+ 1652373265.0
71
+ ],
72
+ 'enlarged': False,
73
+ 'plotType': 'histogram',
74
+ 'animationWindow': 'incremental',
75
+ 'yAxis': None,
76
+ 'speed': 0.2
77
+ }
78
+ ],
79
+ 'layers': [
80
+ {
81
+ 'id': 'kb29zg',
82
+ 'type': 'geojson',
83
+ 'config': {
84
+ 'dataId': 'mix',
85
+ 'label': 'mix',
86
+ 'color': [
87
+ 18,
88
+ 147,
89
+ 154
90
+ ],
91
+ 'highlightColor': [
92
+ 252,
93
+ 242,
94
+ 26,
95
+ 255
96
+ ],
97
+ 'columns': {
98
+ 'geojson': 'geometry'
99
+ },
100
+ 'isVisible': True,
101
+ 'visConfig': {
102
+ 'opacity': 0.8,
103
+ 'strokeOpacity': 0.8,
104
+ 'thickness': 0.1,
105
+ 'strokeColor': [
106
+ 221,
107
+ 178,
108
+ 124
109
+ ],
110
+ 'colorRange': {
111
+ 'name': 'Custom Palette',
112
+ 'type': 'custom',
113
+ 'category': 'Custom',
114
+ 'colors': [
115
+ '#FFC300',
116
+ '#438ecd'
117
+ ],
118
+ 'reversed': True
119
+ },
120
+ 'strokeColorRange': {
121
+ 'name': 'Global Warming',
122
+ 'type': 'sequential',
123
+ 'category': 'Uber',
124
+ 'colors': [
125
+ '#5A1846',
126
+ '#900C3F',
127
+ '#C70039',
128
+ '#E3611C',
129
+ '#F1920E',
130
+ '#FFC300'
131
+ ]
132
+ },
133
+ 'radius': 10,
134
+ 'sizeRange': [
135
+ 0,
136
+ 10
137
+ ],
138
+ 'radiusRange': [
139
+ 0,
140
+ 50
141
+ ],
142
+ 'heightRange': [
143
+ 0,
144
+ 500
145
+ ],
146
+ 'elevationScale': 5,
147
+ 'enableElevationZoomFactor': True,
148
+ 'stroked': False,
149
+ 'filled': True,
150
+ 'enable3d': False,
151
+ 'wireframe': False
152
+ },
153
+ 'hidden': False,
154
+ 'textLabel': [
155
+ {
156
+ 'field': None,
157
+ 'color': [
158
+ 255,
159
+ 255,
160
+ 255
161
+ ],
162
+ 'size': 18,
163
+ 'offset': [
164
+ 0,
165
+ 0
166
+ ],
167
+ 'anchor': 'start',
168
+ 'alignment': 'center'
169
+ }
170
+ ]
171
+ },
172
+ 'visualChannels': {
173
+ 'colorField': {
174
+ 'name': 'type',
175
+ 'type': 'string'
176
+ },
177
+ 'colorScale': 'ordinal',
178
+ 'strokeColorField': None,
179
+ 'strokeColorScale': 'quantile',
180
+ 'sizeField': None,
181
+ 'sizeScale': 'linear',
182
+ 'heightField': None,
183
+ 'heightScale': 'linear',
184
+ 'radiusField': None,
185
+ 'radiusScale': 'linear'
186
+ }
187
+ },
188
+ ],
189
+ 'interactionConfig': {
190
+ 'tooltip': {
191
+ 'fieldsToShow': {
192
+ 'mix': [
193
+ {
194
+ 'name': 'agent_id',
195
+ 'format': None
196
+ },
197
+ {
198
+ 'name': 'time',
199
+ 'format': None
200
+ },
201
+ {
202
+ 'name': 'seq',
203
+ 'format': None
204
+ },
205
+ {
206
+ 'name': 'sub_seq',
207
+ 'format': None
208
+ },
209
+ {
210
+ 'name': 'link_id',
211
+ 'format': None
212
+ },
213
+ {
214
+ 'name': 'from_node',
215
+ 'format': None
216
+ },
217
+ {
218
+ 'name': 'to_node',
219
+ 'format': None
220
+ }
221
+ ]
222
+ },
223
+ 'compareMode': False,
224
+ 'compareType': 'absolute',
225
+ 'enabled': True
226
+ },
227
+ 'brush': {
228
+ 'size': 2.7,
229
+ 'enabled': False
230
+ },
231
+ 'geocoder': {
232
+ 'enabled': False
233
+ },
234
+ 'coordinate': {
235
+ 'enabled': True
236
+ }
237
+ },
238
+ 'layerBlending': 'normal',
239
+ 'splitMaps': [],
240
+ 'animationConfig': {
241
+ 'currentTime': None,
242
+ 'speed': 0.5
243
+ }
244
+ },
245
+ 'mapState': {
246
+ 'bearing': 24,
247
+ 'dragRotate': True,
248
+ 'latitude': 34.23188690328708,
249
+ 'longitude': 108.94371457924842,
250
+ 'pitch': 50,
251
+ 'zoom': 15,
252
+ 'isSplit': False
253
+ },
254
+ 'mapStyle': {
255
+ 'styleType': 'dark',
256
+ 'topLayerGroups': {},
257
+ 'visibleLayerGroups': {
258
+ 'label': True,
259
+ 'road': False,
260
+ 'border': False,
261
+ 'building': True,
262
+ 'water': True,
263
+ 'land': True,
264
+ '3d building': False
265
+ },
266
+ 'threeDBuildingColor': [
267
+ 9.665468314072013,
268
+ 17.18305478057247,
269
+ 31.1442867897876
270
+ ],
271
+ 'mapStyles': {}
272
+ }
273
+ }
274
+ }
275
+
276
+ self.__POLYGON_CONFIG = {
277
+ "id": 'layer_id',
278
+ "type": "geojson",
279
+ "config": {
280
+ "dataId": 'layer_id',
281
+ "label": 'layer_id',
282
+ "color": [65, 72, 88],
283
+ "highlightColor": [
284
+ 252,
285
+ 242,
286
+ 26,
287
+ 255
288
+ ],
289
+ "columns": {
290
+ "geojson": "geometry"
291
+ },
292
+ "isVisible": True,
293
+ "visConfig": {
294
+ "opacity": 0.8,
295
+ "strokeOpacity": 0.8,
296
+ "thickness": 0.1,
297
+ "strokeColor": [
298
+ 221,
299
+ 178,
300
+ 124
301
+ ],
302
+ "radius": 10,
303
+ "sizeRange": [
304
+ 0,
305
+ 10
306
+ ],
307
+ "radiusRange": [
308
+ 0,
309
+ 50
310
+ ],
311
+ "heightRange": [
312
+ 0,
313
+ 500
314
+ ],
315
+ "elevationScale": 5,
316
+ "enableElevationZoomFactor": True,
317
+ "stroked": False,
318
+ "filled": True,
319
+ "enable3d": False,
320
+ "wireframe": False
321
+ },
322
+ "hidden": False,
323
+ "textLabel": [
324
+ {
325
+ "field": None,
326
+ "color": [
327
+ 255,
328
+ 255,
329
+ 255
330
+ ],
331
+ "size": 18,
332
+ "offset": [
333
+ 0,
334
+ 0
335
+ ],
336
+ "anchor": "start",
337
+ "alignment": "center"
338
+ }
339
+ ]
340
+ },
341
+ "visualChannels": {
342
+ "colorField": {
343
+ "name": "type",
344
+ "type": "string"
345
+ },
346
+ "colorScale": "ordinal",
347
+ "strokeColorField": None,
348
+ "strokeColorScale": "quantile",
349
+ "sizeField": None,
350
+ "sizeScale": "linear",
351
+ "heightField": None,
352
+ "heightScale": "linear",
353
+ "radiusField": None,
354
+ "radiusScale": "linear"
355
+ }
356
+ }
357
+
358
+ self.BASE_LINK_NAME = 'base_link'
359
+ self.BASE_NODE_NAME = 'base_node'
360
+ self.MIX_NAME = 'mix'
361
+ def get_base_config(self):
362
+ return copy.deepcopy(self.__BASE_CONFIG)
363
+
364
+ def get_polygon_config(self):
365
+ return copy.deepcopy(self.__POLYGON_CONFIG)
366
+
@@ -0,0 +1,28 @@
1
+ # -- coding: utf-8 --
2
+ # @Time : 2023/12/31 21:16
3
+ # @Author : TangKai
4
+ # @Team : ZheChengData
5
+
6
+ import time
7
+
8
+
9
+ def function_time_cost(f):
10
+ def inner(*args, **kwargs):
11
+ # time.time获取函数执行的时间
12
+ s = time.time() # func开始的时间
13
+ res = f(*args, **kwargs)
14
+ e = time.time() # func结束的时间
15
+ print(f"{f.__name__} costs :{e - s} seconds!")
16
+ return res
17
+ return inner
18
+
19
+
20
+ @function_time_cost
21
+ def aaa(a: int = None, b: int = None):
22
+ print(a + b)
23
+ time.sleep(12)
24
+ return a + b
25
+
26
+
27
+ if __name__ == '__main__':
28
+ aaa(13, 122)
@@ -0,0 +1,4 @@
1
+ # -- coding: utf-8 --
2
+ # @Time : 2024/1/18 11:51
3
+ # @Author : TangKai
4
+ # @Team : ZheChengData