Completed
Push — master ( 492b3e...b38f26 )
by Yannick
29:43
created

MapMatching::FAMMapMatching()   B

Complexity

Conditions 6
Paths 10

Size

Total Lines 26
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 21
nc 10
nop 1
dl 0
loc 26
rs 8.439
c 0
b 0
f 0
1
<?php
2
/**
3
 * This class is part of FlightAirmap. It's used to do Map Matching.
4
 *
5
 * Copyright (c) Ycarus (Yannick Chabanois) at Zugaina <[email protected]>
6
 * Licensed under AGPL license.
7
 * For more information see: https://www.flightairmap.com/
8
*/
9
require_once(dirname(__FILE__).'/class.Common.php');
10
11
class MapMatching {
12
	/*
13
	 * Return results from map matching engine set by $globalMapMatchingSource
14
	 * @param Array $spotter_history_array Array with latitude, longitude, altitude and date
15
	 * @return Array Modified data with new map matching coordinates
16
	*/
17
	public function match($spotter_history_array) {
18
		global $globalMapMatchingSource;
19
		if ($globalMapMatchingSource == 'mapbox') {
20
			return $this->mapbox($spotter_history_array);
21
		} elseif ($globalMapMatchingSource == 'graphhopper') {
22
			return $this->GraphHopper($spotter_history_array);
23
		} elseif ($globalMapMatchingSource == 'osmr') {
24
			return $this->osmr($spotter_history_array);
25
		} elseif ($globalMapMatchingSource == 'fam') {
26
			return $this->FAMMapMatching($spotter_history_array);
27
		/*
28
		} elseif ($globalMapMatchingSource == 'trackmatching') {
29
			return $this->TrackMatching($spotter_history_array);
30
		*/
31
		} else {
32
			return $spotter_history_array;
33
		}
34
	}
35
36
	/*
37
	* Create simple GPX file
38
	* @param Array $spotter_history_array Array with latitude, longitude, altitude and date
39
	* @return String The GPX file
40
	*/
41
	public function create_gpx($spotter_history_array) {
42
		date_default_timezone_set('UTC');
43
		$gpx = '<?xml version="1.0" encoding="UTF-8"?>';
44
		$gpx .= '<gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:gpsies="http://www.gpsies.com/GPX/1/0" creator="GPSies http://www.gpsies.com - Sendl.-O&amp;apos;sch-heim" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.gpsies.com/GPX/1/0 http://www.gpsies.com/gpsies.xsd">';
45
		$gpx .= '<trk>';
46
		$gpx .= '<trkseg>';
47
		foreach($spotter_history_array as $spotter_data) {
48
			$gpx .= '<trkpt lat="'.sprintf("%.8f",$spotter_data['latitude']).'" lon="'.sprintf("%.8f",$spotter_data['longitude']).'">';
49
			$gpx .= '<ele>'.sprintf("%.6f",$spotter_data['altitude']).'</ele>';
50
			$gpx .= '<time>'.date("Y-m-d\TH:i:s\Z",strtotime($spotter_data['date'])).'</time>';
51
			$gpx .= '</trkpt>';
52
		}
53
		$gpx .= '</trkseg>';
54
		$gpx .= '</trk>';
55
		$gpx .= '</gpx>';
56
		return $gpx;
57
	}
58
/*
59
	public function Mapzen($spotter_history_array) {
60
		global $globalMapMatchingMaxPts, $globalMapzenKey;
61
		if (!isset($globalMapMatchingMaxPts)) $globalMapMatchingMaxPts = 500;
62
		if (count($spotter_history_array) < 2) return $spotter_history_array;
63
		if (count($spotter_history_array) > $globalMapMatchingMaxPts) $spotter_history_array = array_slice($spotter_history_array,-$globalMapMatchingMaxPts);
64
		$data = $this->create_gpx($spotter_history_array);
65
		$url = 'https://valhalla.mapzen.com/trace_route?api_key='.$globalMapzenKey;
66
		$Common = new Common();
67
		$matching = $Common->getData($url,'post',$data,array('Content-Type: application/gpx+xml'));
68
		$matching = json_decode($matching,true);
69
		//print_r($matching);
70
		
71
		if (isset($matching['paths'][0]['points']['coordinates'])) {
72
			$spotter_history_array = array();
73
			foreach ($matching['paths'][0]['points']['coordinates'] as $match) {
74
				$coord = $match;
75
				$spotter_history_array[] = array('longitude' => $coord[0],'latitude' => $coord[1]);
76
			}
77
		}
78
		return $spotter_history_array;
79
		
80
	}
81
  */
82
83
	public function TrackMatching($spotter_history_array) {
84
		global $globalMapMatchingMaxPts, $globalTrackMatchingAppKey, $globalTrackMatchingAppId;
85
		if (!isset($globalMapMatchingMaxPts)) $globalMapMatchingMaxPts = 100;
86
		if (count($spotter_history_array) < 2) return $spotter_history_array;
87
		if (count($spotter_history_array) > $globalMapMatchingMaxPts) $spotter_history_array = array_slice($spotter_history_array,-$globalMapMatchingMaxPts);
88
		$data = $this->create_gpx($spotter_history_array);
89
		$url = 'https://test.roadmatching.com/rest/mapmatch/?app_id='.$globalTrackMatchingAppId.'&app_key='.$globalTrackMatchingAppKey.'&output.waypoints=true';
90
		$Common = new Common();
91
		$matching = $Common->getData($url,'post',$data,array('Content-Type: application/gpx+xml','Accept: application/json'));
92
		$matching = json_decode($matching,true);
93
		if (isset($matching['diary']['entries'][0]['route']['links'])) {
94
			$spotter_history_array = array();
95
			foreach ($matching['diary']['entries'][0]['route']['links'] as $match) {
96
				if (isset($match['wpts'])) {
97
					foreach ($match['wpts'] as $coord) {
98
						$spotter_history_array[] = array('longitude' => $coord['x'],'latitude' => $coord['y']);
99
					}
100
				}
101
			}
102
		}
103
		$spotter_history_array[0]['mapmatching_engine'] = 'trackmatching';
104
		return $spotter_history_array;
105
	}
106
107
	/*
108
	* Use https://www.graphhopper.com/ as map matching engine
109
	* @param Array $spotter_history_array Array with latitude, longitude, altitude and date
110
	* @return Array Modified data with new map matching coordinates
111
	*/
112
	public function GraphHopper($spotter_history_array) {
113
		global $globalMapMatchingMaxPts, $globalGraphHopperKey;
114
		if (!isset($globalMapMatchingMaxPts)) $globalMapMatchingMaxPts = 100;
115
		if (count($spotter_history_array) < 2) return $spotter_history_array;
116
		$spotter_history_initial_array = array();
117
		if (count($spotter_history_array) > $globalMapMatchingMaxPts) {
118
			$spotter_history_array = array_slice($spotter_history_array,-$globalMapMatchingMaxPts);
119
			$spotter_history_initial_array = array_slice($spotter_history_array,0,count($spotter_history_array)-$globalMapMatchingMaxPts);
120
		}
121
		$data = $this->create_gpx($spotter_history_array);
122
		$url = 'https://graphhopper.com/api/1/match?vehicle=car&points_encoded=0&instructions=false&key='.$globalGraphHopperKey;
123
		$Common = new Common();
124
		$matching = $Common->getData($url,'post',$data,array('Content-Type: application/gpx+xml'));
125
		$matching = json_decode($matching,true);
126
		if (isset($matching['paths'][0]['points']['coordinates'])) {
127
			$spotter_history_array = array();
128
			foreach ($matching['paths'][0]['points']['coordinates'] as $match) {
129
				$coord = $match;
130
				$spotter_history_array[] = array('longitude' => $coord[0],'latitude' => $coord[1]);
131
			}
132
		}
133
		$spotter_history_array = array_merge($spotter_history_initial_array,$spotter_history_array);
134
		$spotter_history_array[0]['mapmatching_engine'] = 'graphhopper';
135
		return $spotter_history_array;
136
	}
137
138
	/*
139
	* Use https://mapmatching.flightairmap.com/ as map matching engine
140
	* @param Array $spotter_history_array Array with latitude, longitude, altitude and date
141
	* @return Array Modified data with new map matching coordinates
142
	*/
143
	public function FAMMapMatching($spotter_history_array) {
144
		global $globalMapMatchingMaxPts, $globalGraphHopperKey;
145
		if (!isset($globalMapMatchingMaxPts)) $globalMapMatchingMaxPts = 100;
146
		if (count($spotter_history_array) < 2) return $spotter_history_array;
147
		$spotter_history_initial_array = array();
148
		if (count($spotter_history_array) > $globalMapMatchingMaxPts) {
149
			$spotter_history_array = array_slice($spotter_history_array,-$globalMapMatchingMaxPts);
150
			$spotter_history_initial_array = array_slice($spotter_history_array,0,count($spotter_history_array)-$globalMapMatchingMaxPts);
151
		}
152
		$data = $this->create_gpx($spotter_history_array);
153
		$url = 'https://mapmatching.flightairmap.com/api/1/match?vehicle=car&points_encoded=0&instructions=false';
154
		//$url = 'https://mapmatching.flightairmap.com/api/1/match?vehicle=car&points_encoded=0';
155
		$Common = new Common();
156
		$matching = $Common->getData($url,'post',$data,array('Content-Type: application/gpx+xml'));
157
		$matching = json_decode($matching,true);
158
		if (isset($matching['paths'][0]['points']['coordinates'])) {
159
			$spotter_history_array = array();
160
			foreach ($matching['paths'][0]['points']['coordinates'] as $match) {
161
				$coord = $match;
162
				$spotter_history_array[] = array('longitude' => $coord[0],'latitude' => $coord[1]);
163
			}
164
		}
165
		$spotter_history_array = array_merge($spotter_history_initial_array,$spotter_history_array);
166
		$spotter_history_array[0]['mapmatching_engine'] = 'fam';
167
		return $spotter_history_array;
168
	}
169
170
	/*
171
	* Use https://www.project-osrm.org/ as map matching engine
172
	* @param Array $spotter_history_array Array with latitude, longitude, altitude and date
173
	* @return Array Modified data with new map matching coordinates
174
	*/
175
	public function osmr($spotter_history_array) {
176
		global $globalMapMatchingMaxPts;
177
		if (!isset($globalMapMatchingMaxPts)) $globalMapMatchingMaxPts = 50;
178
		if (count($spotter_history_array) < 2) return $spotter_history_array;
179
		$spotter_history_initial_array = array();
180
		if (count($spotter_history_array) > $globalMapMatchingMaxPts) {
181
			$spotter_history_array = array_slice($spotter_history_array,-$globalMapMatchingMaxPts);
182
			$spotter_history_initial_array = array_slice($spotter_history_array,0,count($spotter_history_array)-$globalMapMatchingMaxPts);
183
		}
184
		$coord = '';
185
		$ts = '';
186
		$rd = '';
187
		foreach ($spotter_history_array as $spotter_data) {
188
			if ($coord != '') $coord .= ';';
189
			$coord .= $spotter_data['longitude'].','.$spotter_data['latitude'];
190
			if ($ts != '') $ts .= ';';
191
			$ts .= strtotime($spotter_data['date']);
192
			if ($rd != '') $rd .= ';';
193
			$rd .= '20';
194
		}
195
		$url = 'https://router.project-osrm.org/match/v1/driving/'.$coord.'?timestamps='.$ts.'&overview=full&geometries=geojson&tidy=true&gaps=ignore';
196
		$Common = new Common();
197
		$matching = $Common->getData($url);
198
		$matching  = json_decode($matching,true);
199
		if (isset($matching['matchings'][0]['geometry']['coordinates'])) {
200
			$spotter_history_array = array();
201
			foreach ($matching['matchings'][0]['geometry']['coordinates'] as $match) {
202
				$coord = $match;
203
				$spotter_history_array[] = array('longitude' => $coord[0],'latitude' => $coord[1]);
204
			}
205
		}
206
		$spotter_history_array = array_merge($spotter_history_initial_array,$spotter_history_array);
207
		$spotter_history_array[0]['mapmatching_engine'] = 'osmr';
208
		return $spotter_history_array;
209
	}
210
211
	/*
212
	* Use https://www.mapbox.com/ as map matching engine
213
	* @param Array $spotter_history_array Array with latitude, longitude, altitude and date
214
	* @return Array Modified data with new map matching coordinates
215
	*/
216
	public function mapbox($spotter_history_array) {
217
		global $globalMapMatchingMaxPts, $globalMapboxToken;
218
		if (!isset($globalMapMatchingMaxPts)) $globalMapMatchingMaxPts = 60;
219
		if (count($spotter_history_array) < 2) return $spotter_history_array;
220
		$spotter_history_initial_array = array();
221
		if (count($spotter_history_array) > $globalMapMatchingMaxPts) {
222
			$spotter_history_array = array_slice($spotter_history_array,-$globalMapMatchingMaxPts);
223
			$spotter_history_initial_array = array_slice($spotter_history_array,0,count($spotter_history_array)-$globalMapMatchingMaxPts);
224
		}
225
		$coord = '';
226
		$ts = '';
227
		$rd = '';
228
		foreach ($spotter_history_array as $spotter_data) {
229
			if ($coord != '') $coord .= ';';
230
			$coord .= $spotter_data['longitude'].','.$spotter_data['latitude'];
231
			if ($ts != '') $ts .= ';';
232
			$ts .= strtotime($spotter_data['date']);
233
			if ($rd != '') $rd .= ';';
234
			$rd .= '20';
235
		}
236
		//$url = 'https://api.mapbox.com/matching/v5/mapbox/driving/'.$coord.'?access_token='.$globalMapboxToken.'&timestamps='.$ts.'&overview=full&tidy=true&geometries=geojson&radiuses='.$rd;
237
		$url = 'https://api.mapbox.com/matching/v5/mapbox/driving/'.$coord.'?access_token='.$globalMapboxToken.'&timestamps='.$ts.'&overview=full&tidy=true&geometries=geojson';
238
		$Common = new Common();
239
		$matching = $Common->getData($url);
240
		$matching  = json_decode($matching,true);
241
		if (isset($matching['matchings'][0]['geometry']['coordinates'])) {
242
			$spotter_history_array = array();
243
			foreach ($matching['matchings'][0]['geometry']['coordinates'] as $match) {
244
				$coord = $match;
245
				$spotter_history_array[] = array('longitude' => $coord[0],'latitude' => $coord[1]);
246
			}
247
		}
248
		$spotter_history_array = array_merge($spotter_history_initial_array,$spotter_history_array);
249
		$spotter_history_array[0]['mapmatching_engine'] = 'mapbox';
250
		return $spotter_history_array;
251
	}
252
253
}
254
?>