1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the Ivory Google Map package. |
5
|
|
|
* |
6
|
|
|
* (c) Eric GELOEN <[email protected]> |
7
|
|
|
* |
8
|
|
|
* For the full copyright and license information, please read the LICENSE |
9
|
|
|
* file that was distributed with this source code. |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace Ivory\GoogleMap\Service\Directions; |
13
|
|
|
|
14
|
|
|
use Http\Client\HttpClient; |
15
|
|
|
use Http\Message\MessageFactory; |
16
|
|
|
use Ivory\GoogleMap\Base\Bound; |
17
|
|
|
use Ivory\GoogleMap\Base\Coordinate; |
18
|
|
|
use Ivory\GoogleMap\Overlay\EncodedPolyline; |
19
|
|
|
use Ivory\GoogleMap\Service\AbstractService; |
20
|
|
|
use Ivory\GoogleMap\Service\Base\Distance; |
21
|
|
|
use Ivory\GoogleMap\Service\Base\Duration; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* @author GeLo <[email protected]> |
25
|
|
|
*/ |
26
|
|
|
class Directions extends AbstractService |
27
|
|
|
{ |
28
|
|
|
/** |
29
|
|
|
* @param HttpClient $client |
30
|
|
|
* @param MessageFactory $messageFactory |
31
|
|
|
*/ |
32
|
|
|
public function __construct(HttpClient $client, MessageFactory $messageFactory) |
33
|
|
|
{ |
34
|
|
|
parent::__construct($client, $messageFactory, 'http://maps.googleapis.com/maps/api/directions'); |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* @param DirectionsRequest $request |
39
|
|
|
* |
40
|
|
|
* @return DirectionsResponse |
41
|
|
|
*/ |
42
|
|
View Code Duplication |
public function route(DirectionsRequest $request) |
|
|
|
|
43
|
|
|
{ |
44
|
|
|
$response = $this->getClient()->sendRequest($this->createRequest($request->buildQuery())); |
45
|
|
|
$data = $this->parse((string) $response->getBody()); |
46
|
|
|
|
47
|
|
|
return $this->buildResponse($data); |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* @param string $data |
52
|
|
|
* |
53
|
|
|
* @return mixed[] |
54
|
|
|
*/ |
55
|
|
|
private function parse($data) |
56
|
|
|
{ |
57
|
|
|
if ($this->getFormat() === self::FORMAT_JSON) { |
58
|
|
|
return json_decode($data, true); |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
return $this->getXmlParser()->parse($data, [ |
62
|
|
|
'leg' => 'legs', |
63
|
|
|
'route' => 'routes', |
64
|
|
|
'step' => 'steps', |
65
|
|
|
'waypoint_index' => 'waypoint_order', |
66
|
|
|
]); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* @param mixed[] $data |
71
|
|
|
* |
72
|
|
|
* @return DirectionsResponse |
73
|
|
|
*/ |
74
|
|
|
private function buildResponse(array $data) |
75
|
|
|
{ |
76
|
|
|
$response = new DirectionsResponse(); |
77
|
|
|
$response->setStatus($data['status']); |
78
|
|
|
$response->setRoutes(isset($data['routes']) ? $this->buildRoutes($data['routes']) : []); |
79
|
|
|
$response->setGeocodedWaypoints( |
80
|
|
|
isset($data['geocoded_waypoints']) ? $this->buildGeocodedWaypoints($data['geocoded_waypoints']) : [] |
81
|
|
|
); |
82
|
|
|
|
83
|
|
|
return $response; |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* @param mixed[] $data |
88
|
|
|
* |
89
|
|
|
* @return DirectionsRoute[] |
90
|
|
|
*/ |
91
|
|
|
private function buildRoutes(array $data) |
92
|
|
|
{ |
93
|
|
|
$routes = []; |
94
|
|
|
foreach ($data as $item) { |
95
|
|
|
$routes[] = $this->buildRoute($item); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
return $routes; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* @param mixed[] $data |
103
|
|
|
* |
104
|
|
|
* @return DirectionsRoute |
105
|
|
|
*/ |
106
|
|
|
private function buildRoute(array $data) |
107
|
|
|
{ |
108
|
|
|
$route = new DirectionsRoute(); |
109
|
|
|
$route->setCopyrights(isset($data['copyrights']) ? $data['copyrights'] : null); |
110
|
|
|
$route->setLegs($this->buildLegs($data['legs'])); |
111
|
|
|
$route->setOverviewPolyline(new EncodedPolyline($data['overview_polyline']['points'])); |
112
|
|
|
$route->setSummary(isset($data['summary']) ? $data['summary'] : null); |
113
|
|
|
$route->setFare(isset($data['fare']) ? $this->buildFare($data['fare']) : null); |
114
|
|
|
$route->setWarnings(isset($data['warnings']) ? $data['warnings'] : []); |
115
|
|
|
$route->setWaypointOrders(isset($data['waypoint_order']) ? $data['waypoint_order'] : []); |
116
|
|
|
|
117
|
|
|
$route->setBound(new Bound( |
118
|
|
|
new Coordinate( |
119
|
|
|
$data['bounds']['southwest']['lat'], |
120
|
|
|
$data['bounds']['southwest']['lng'] |
121
|
|
|
), |
122
|
|
|
new Coordinate( |
123
|
|
|
$data['bounds']['northeast']['lat'], |
124
|
|
|
$data['bounds']['northeast']['lng'] |
125
|
|
|
) |
126
|
|
|
)); |
127
|
|
|
|
128
|
|
|
return $route; |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* @param mixed[] $data |
133
|
|
|
* |
134
|
|
|
* @return DirectionsGeocoded[] |
135
|
|
|
*/ |
136
|
|
|
private function buildGeocodedWaypoints(array $data) |
137
|
|
|
{ |
138
|
|
|
$geocodedWaypoints = []; |
139
|
|
|
foreach ($data as $item) { |
140
|
|
|
$geocodedWaypoints[] = $this->buildGeocodedWaypoint($item); |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
return $geocodedWaypoints; |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* @param mixed[] $data |
148
|
|
|
* |
149
|
|
|
* @return DirectionsGeocoded |
150
|
|
|
*/ |
151
|
|
|
private function buildGeocodedWaypoint(array $data) |
152
|
|
|
{ |
153
|
|
|
$geocodedWaypoint = new DirectionsGeocoded(); |
154
|
|
|
$geocodedWaypoint->setStatus($data['geocoder_status']); |
155
|
|
|
$geocodedWaypoint->setPartialMatch(isset($data['partial_match']) ? $data['partial_match'] : null); |
156
|
|
|
$geocodedWaypoint->setPlaceId(isset($data['place_id']) ? $data['place_id'] : null); |
157
|
|
|
$geocodedWaypoint->setTypes($data['types']); |
158
|
|
|
|
159
|
|
|
return $geocodedWaypoint; |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
/** |
163
|
|
|
* @param mixed[] $data |
164
|
|
|
* |
165
|
|
|
* @return DirectionsLeg[] |
166
|
|
|
*/ |
167
|
|
|
private function buildLegs(array $data) |
168
|
|
|
{ |
169
|
|
|
$legs = []; |
170
|
|
|
foreach ($data as $item) { |
171
|
|
|
$legs[] = $this->buildLeg($item); |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
return $legs; |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* @param mixed[] $data |
179
|
|
|
* |
180
|
|
|
* @return DirectionsLeg |
181
|
|
|
*/ |
182
|
|
|
private function buildLeg(array $data) |
183
|
|
|
{ |
184
|
|
|
$leg = new DirectionsLeg(); |
185
|
|
|
$leg->setDistance(new Distance($data['distance']['text'], $data['distance']['value'])); |
186
|
|
|
$leg->setDuration(new Duration($data['duration']['text'], $data['duration']['value'])); |
187
|
|
|
$leg->setEndAddress($data['end_address']); |
188
|
|
|
$leg->setEndLocation(new Coordinate($data['end_location']['lat'], $data['end_location']['lng'])); |
189
|
|
|
$leg->setStartAddress($data['start_address']); |
190
|
|
|
$leg->setStartLocation(new Coordinate($data['start_location']['lat'], $data['start_location']['lng'])); |
191
|
|
|
$leg->setSteps($this->buildSteps($data['steps'])); |
192
|
|
|
$leg->setViaWaypoints(isset($data['via_waypoint']) ? $data['via_waypoint'] : []); |
193
|
|
|
|
194
|
|
|
return $leg; |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* @codeCoverageIgnore |
199
|
|
|
* |
200
|
|
|
* @param mixed[] $data |
201
|
|
|
* |
202
|
|
|
* @return DirectionsFare |
203
|
|
|
*/ |
204
|
|
|
private function buildFare(array $data) |
205
|
|
|
{ |
206
|
|
|
$fare = new DirectionsFare(); |
207
|
|
|
$fare->setCurrency($data['currency']); |
208
|
|
|
$fare->setValue($data['value']); |
209
|
|
|
$fare->setText($data['text']); |
210
|
|
|
|
211
|
|
|
return $fare; |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
/** |
215
|
|
|
* @param mixed[] $data |
216
|
|
|
* |
217
|
|
|
* @return DirectionsStep[] |
218
|
|
|
*/ |
219
|
|
|
private function buildSteps(array $data) |
220
|
|
|
{ |
221
|
|
|
$steps = []; |
222
|
|
|
foreach ($data as $item) { |
223
|
|
|
$steps[] = $this->buildStep($item); |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
return $steps; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
/** |
230
|
|
|
* @param mixed[] $data |
231
|
|
|
* |
232
|
|
|
* @return DirectionsStep |
233
|
|
|
*/ |
234
|
|
|
private function buildStep(array $data) |
235
|
|
|
{ |
236
|
|
|
$step = new DirectionsStep(); |
237
|
|
|
$step->setDistance(new Distance($data['distance']['text'], $data['distance']['value'])); |
238
|
|
|
$step->setDuration(new Duration($data['duration']['text'], $data['duration']['value'])); |
239
|
|
|
$step->setEndLocation(new Coordinate($data['end_location']['lat'], $data['end_location']['lng'])); |
240
|
|
|
$step->setInstructions($data['html_instructions']); |
241
|
|
|
$step->setEncodedPolyline(new EncodedPolyline($data['polyline']['points'])); |
242
|
|
|
$step->setStartLocation(new Coordinate($data['start_location']['lat'], $data['start_location']['lng'])); |
243
|
|
|
$step->setTravelMode($data['travel_mode']); |
244
|
|
|
|
245
|
|
|
return $step; |
246
|
|
|
} |
247
|
|
|
} |
248
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.