@fleetbase/fleetops-engine 0.4.19 → 0.4.21
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.
- package/addon/components/activity-event-selector.js +1 -1
- package/addon/components/activity-form-panel.js +2 -2
- package/addon/components/activity-logic-builder.js +1 -1
- package/addon/components/admin/navigator-app.hbs +77 -1
- package/addon/components/admin/navigator-app.js +65 -12
- package/addon/components/contact-form-panel.js +2 -2
- package/addon/components/contact-panel.js +2 -2
- package/addon/components/custom-field-form-panel.js +2 -2
- package/addon/components/driver-form-panel.js +2 -2
- package/addon/components/driver-panel.js +2 -2
- package/addon/components/edit-order-route-panel.js +2 -2
- package/addon/components/fleet-form-panel.js +2 -2
- package/addon/components/fleet-panel/driver-listing.js +1 -1
- package/addon/components/fleet-panel/vehicle-listing.js +1 -1
- package/addon/components/fleet-panel.js +2 -2
- package/addon/components/fuel-report-form-panel.js +2 -2
- package/addon/components/fuel-report-panel.js +2 -2
- package/addon/components/issue-form-panel.js +2 -2
- package/addon/components/issue-panel.js +2 -2
- package/addon/components/live-map-drawer.js +2 -2
- package/addon/components/order-config-manager/activity-flow.js +1 -1
- package/addon/components/order-config-manager/custom-fields.js +1 -1
- package/addon/components/order-config-manager/entities.js +1 -1
- package/addon/components/order-config-manager-overlay.js +1 -1
- package/addon/components/order-config-manager.js +2 -2
- package/addon/components/place-form-panel.js +2 -2
- package/addon/components/place-panel.js +2 -2
- package/addon/components/vehicle-form-panel.js +2 -2
- package/addon/components/vehicle-panel.js +2 -2
- package/addon/components/vendor-form-panel/create-form.js +1 -1
- package/addon/components/vendor-form-panel.js +2 -2
- package/addon/components/vendor-panel.js +2 -2
- package/composer.json +2 -2
- package/extension.json +1 -1
- package/package.json +2 -2
- package/server/config/fleetops.php +19 -0
- package/server/src/Console/Commands/DispatchAdhocOrders.php +44 -30
- package/server/src/Console/Commands/DispatchOrders.php +27 -21
- package/server/src/Console/Commands/FixInvalidPolymorphicRelationTypeNamespaces.php +96 -0
- package/server/src/Console/Commands/TrackOrderDistanceAndTime.php +30 -15
- package/server/src/Http/Controllers/Api/v1/DriverController.php +0 -1
- package/server/src/Http/Controllers/Api/v1/OrderController.php +49 -2
- package/server/src/Http/Controllers/Internal/v1/SettingController.php +20 -0
- package/server/src/Http/Filter/ContactFilter.php +5 -0
- package/server/src/Http/Filter/DriverFilter.php +5 -0
- package/server/src/Http/Filter/EntityFilter.php +18 -0
- package/server/src/Http/Filter/FleetFilter.php +5 -0
- package/server/src/Http/Filter/FuelReportFilter.php +5 -0
- package/server/src/Http/Filter/IssueFilter.php +5 -0
- package/server/src/Http/Filter/OrderConfigFilter.php +5 -0
- package/server/src/Http/Filter/OrderFilter.php +5 -0
- package/server/src/Http/Filter/PayloadFilter.php +18 -0
- package/server/src/Http/Filter/PlaceFilter.php +5 -0
- package/server/src/Http/Filter/PurchaseRateFilter.php +18 -0
- package/server/src/Http/Filter/ServiceAreaFilter.php +5 -0
- package/server/src/Http/Filter/ServiceQuoteFilter.php +5 -0
- package/server/src/Http/Filter/ServiceRateFilter.php +5 -0
- package/server/src/Http/Filter/TrackingNumberFilter.php +18 -0
- package/server/src/Http/Filter/TrackingStatusFilter.php +5 -0
- package/server/src/Http/Filter/VehicleFilter.php +5 -0
- package/server/src/Http/Filter/VendorFilter.php +5 -0
- package/server/src/Http/Filter/ZoneFilter.php +5 -0
- package/server/src/Http/Resources/v1/Order.php +1 -0
- package/server/src/Models/Driver.php +1 -1
- package/server/src/Models/Order.php +2 -4
- package/server/src/Providers/FleetOpsServiceProvider.php +4 -3
- package/server/src/Support/Algo.php +0 -24
- package/server/src/Support/DistanceMatrix.php +9 -1
- package/server/src/Support/OSRM.php +7 -0
- package/server/src/Support/Utils.php +216 -169
- package/server/src/routes.php +3 -3
- package/translations/en-us.yaml +3 -0
- package/addon/utils/apply-context-component-arguments.js +0 -33
- package/addon/utils/context-component-callback.js +0 -16
- package/app/utils/apply-context-component-arguments.js +0 -1
- package/app/utils/context-component-callback.js +0 -1
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
namespace Fleetbase\FleetOps\Support;
|
|
4
4
|
|
|
5
5
|
use Fleetbase\FleetOps\Flow\Activity;
|
|
6
|
+
use Fleetbase\LaravelMysqlSpatial\Types\Point;
|
|
6
7
|
use Fleetbase\Support\Utils as FleetbaseUtils;
|
|
7
8
|
use Illuminate\Support\Arr;
|
|
8
9
|
use Illuminate\Support\Facades\DB;
|
|
@@ -95,11 +96,11 @@ class Utils extends FleetbaseUtils
|
|
|
95
96
|
/**
|
|
96
97
|
* Unpacks a mysql POINT column from binary to array.
|
|
97
98
|
*/
|
|
98
|
-
public static function mysqlPointAsGeometry(string $rawPoint):
|
|
99
|
+
public static function mysqlPointAsGeometry(string $rawPoint): Point
|
|
99
100
|
{
|
|
100
101
|
$coordinates = static::unpackPoint($rawPoint);
|
|
101
102
|
|
|
102
|
-
return new
|
|
103
|
+
return new Point($coordinates['lon'], $coordinates['lat']);
|
|
103
104
|
}
|
|
104
105
|
|
|
105
106
|
/**
|
|
@@ -162,7 +163,7 @@ class Utils extends FleetbaseUtils
|
|
|
162
163
|
public static function isCoordinates($coordinates): bool
|
|
163
164
|
{
|
|
164
165
|
try {
|
|
165
|
-
return static::getPointFromMixed($coordinates) instanceof
|
|
166
|
+
return static::getPointFromMixed($coordinates) instanceof Point;
|
|
166
167
|
} catch (\Throwable $e) {
|
|
167
168
|
return false;
|
|
168
169
|
}
|
|
@@ -175,9 +176,9 @@ class Utils extends FleetbaseUtils
|
|
|
175
176
|
*
|
|
176
177
|
* @param mixed $coordinates the coordinates input value to extract a coordinate from
|
|
177
178
|
*
|
|
178
|
-
* @return
|
|
179
|
+
* @return Point the extracted Point object
|
|
179
180
|
*/
|
|
180
|
-
public static function getPointFromMixed($coordinates):
|
|
181
|
+
public static function getPointFromMixed($coordinates): ?Point
|
|
181
182
|
{
|
|
182
183
|
$latitude = null;
|
|
183
184
|
$longitude = null;
|
|
@@ -199,7 +200,7 @@ class Utils extends FleetbaseUtils
|
|
|
199
200
|
$coordinates = $coordinates->getSpatialValue();
|
|
200
201
|
}
|
|
201
202
|
|
|
202
|
-
if ($coordinates instanceof
|
|
203
|
+
if ($coordinates instanceof Point) {
|
|
203
204
|
$latitude = $coordinates->getLat();
|
|
204
205
|
$longitude = $coordinates->getLng();
|
|
205
206
|
} elseif (static::isGeoJson($coordinates)) {
|
|
@@ -216,7 +217,7 @@ class Utils extends FleetbaseUtils
|
|
|
216
217
|
|
|
217
218
|
if (static::isJson($coordinatesJson)) {
|
|
218
219
|
try {
|
|
219
|
-
$coordinates =
|
|
220
|
+
$coordinates = Point::fromJson($coordinatesJson);
|
|
220
221
|
} catch (\Throwable $e) {
|
|
221
222
|
if ($coordinatesInGeoJson) {
|
|
222
223
|
return static::getPointFromMixed($coordinatesInGeoJson);
|
|
@@ -312,7 +313,7 @@ class Utils extends FleetbaseUtils
|
|
|
312
313
|
$longitude = $coords[1];
|
|
313
314
|
}
|
|
314
315
|
|
|
315
|
-
if ($coordinates instanceof
|
|
316
|
+
if ($coordinates instanceof Point) {
|
|
316
317
|
return $coordinates;
|
|
317
318
|
}
|
|
318
319
|
|
|
@@ -321,7 +322,7 @@ class Utils extends FleetbaseUtils
|
|
|
321
322
|
throw new \Exception('Attempted to resolve Point from invalid location.');
|
|
322
323
|
}
|
|
323
324
|
|
|
324
|
-
return new
|
|
325
|
+
return new Point((float) $latitude, (float) $longitude);
|
|
325
326
|
}
|
|
326
327
|
|
|
327
328
|
/**
|
|
@@ -334,7 +335,7 @@ class Utils extends FleetbaseUtils
|
|
|
334
335
|
*/
|
|
335
336
|
public static function isCoordinatesStrict($coordinates)
|
|
336
337
|
{
|
|
337
|
-
return static::getPointFromCoordinatesStrict($coordinates) instanceof
|
|
338
|
+
return static::getPointFromCoordinatesStrict($coordinates) instanceof Point;
|
|
338
339
|
}
|
|
339
340
|
|
|
340
341
|
/**
|
|
@@ -343,15 +344,15 @@ class Utils extends FleetbaseUtils
|
|
|
343
344
|
*
|
|
344
345
|
* @param mixed $coordinates the coordinates, which can be an array, object, or string
|
|
345
346
|
*
|
|
346
|
-
* @return
|
|
347
|
+
* @return Point Returns the Point instance
|
|
347
348
|
*/
|
|
348
|
-
public static function getPointFromCoordinatesStrict($coordinates):
|
|
349
|
+
public static function getPointFromCoordinatesStrict($coordinates): ?Point
|
|
349
350
|
{
|
|
350
351
|
if ($coordinates instanceof \Fleetbase\LaravelMysqlSpatial\Eloquent\SpatialExpression) {
|
|
351
352
|
$coordinates = $coordinates->getSpatialValue();
|
|
352
353
|
}
|
|
353
354
|
|
|
354
|
-
if ($coordinates instanceof
|
|
355
|
+
if ($coordinates instanceof Point) {
|
|
355
356
|
return $coordinates;
|
|
356
357
|
}
|
|
357
358
|
|
|
@@ -363,7 +364,7 @@ class Utils extends FleetbaseUtils
|
|
|
363
364
|
}
|
|
364
365
|
|
|
365
366
|
if (static::isJson($coordinatesJson)) {
|
|
366
|
-
$coordinates =
|
|
367
|
+
$coordinates = Point::fromJson($coordinatesJson);
|
|
367
368
|
}
|
|
368
369
|
}
|
|
369
370
|
|
|
@@ -372,7 +373,7 @@ class Utils extends FleetbaseUtils
|
|
|
372
373
|
$longitude = static::or($coordinates, ['lon', '_lon', 'long', 'lng', '_lng', '_longitude', 'longitude', 'y', '1']);
|
|
373
374
|
|
|
374
375
|
if (is_numeric($latitude) && is_numeric($longitude)) {
|
|
375
|
-
$coordinates = new
|
|
376
|
+
$coordinates = new Point((float) $latitude, (float) $longitude);
|
|
376
377
|
}
|
|
377
378
|
}
|
|
378
379
|
|
|
@@ -412,11 +413,11 @@ class Utils extends FleetbaseUtils
|
|
|
412
413
|
$longitude = $coords[1];
|
|
413
414
|
|
|
414
415
|
if (is_numeric($latitude) && is_numeric($longitude)) {
|
|
415
|
-
$coordinates = new
|
|
416
|
+
$coordinates = new Point((float) $latitude, (float) $longitude);
|
|
416
417
|
}
|
|
417
418
|
}
|
|
418
419
|
|
|
419
|
-
if ($coordinates instanceof
|
|
420
|
+
if ($coordinates instanceof Point) {
|
|
420
421
|
return $coordinates;
|
|
421
422
|
}
|
|
422
423
|
|
|
@@ -444,7 +445,7 @@ class Utils extends FleetbaseUtils
|
|
|
444
445
|
$coordinates = $coordinates->location;
|
|
445
446
|
}
|
|
446
447
|
|
|
447
|
-
if ($coordinates instanceof
|
|
448
|
+
if ($coordinates instanceof Point) {
|
|
448
449
|
$latitude = $coordinates->getLat();
|
|
449
450
|
$longitude = $coordinates->getLng();
|
|
450
451
|
} elseif (is_array($coordinates) || is_object($coordinates)) {
|
|
@@ -534,22 +535,22 @@ class Utils extends FleetbaseUtils
|
|
|
534
535
|
*
|
|
535
536
|
* @param mixed $coordinates the input value representing a location or set of coordinates
|
|
536
537
|
*
|
|
537
|
-
* @return
|
|
538
|
+
* @return Point the extracted point value
|
|
538
539
|
*/
|
|
539
|
-
public static function getPointFromCoordinates($coordinates):
|
|
540
|
+
public static function getPointFromCoordinates($coordinates): Point
|
|
540
541
|
{
|
|
541
|
-
if ($coordinates instanceof
|
|
542
|
+
if ($coordinates instanceof Point) {
|
|
542
543
|
return $coordinates;
|
|
543
544
|
}
|
|
544
545
|
|
|
545
546
|
if (is_null($coordinates) || !static::isCoordinates($coordinates)) {
|
|
546
|
-
return new
|
|
547
|
+
return new Point(0, 0);
|
|
547
548
|
}
|
|
548
549
|
|
|
549
550
|
$latitude = static::getLatitudeFromCoordinates($coordinates);
|
|
550
551
|
$longitude = static::getLongitudeFromCoordinates($coordinates);
|
|
551
552
|
|
|
552
|
-
return new
|
|
553
|
+
return new Point($latitude, $longitude);
|
|
553
554
|
}
|
|
554
555
|
|
|
555
556
|
/**
|
|
@@ -563,19 +564,19 @@ class Utils extends FleetbaseUtils
|
|
|
563
564
|
{
|
|
564
565
|
$wkt = 'POINT(0 0)';
|
|
565
566
|
|
|
566
|
-
if ($point instanceof
|
|
567
|
+
if ($point instanceof Point) {
|
|
567
568
|
$wkt = $point->toWKT();
|
|
568
569
|
}
|
|
569
570
|
|
|
570
571
|
if (is_array($point)) {
|
|
571
572
|
$json = json_encode($point);
|
|
572
|
-
$p =
|
|
573
|
+
$p = Point::fromJson($json);
|
|
573
574
|
|
|
574
575
|
$wkt = $p->toWkt();
|
|
575
576
|
}
|
|
576
577
|
|
|
577
578
|
if (is_string($point)) {
|
|
578
|
-
$p =
|
|
579
|
+
$p = Point::fromString($point);
|
|
579
580
|
|
|
580
581
|
$wkt = $p->toWKT();
|
|
581
582
|
}
|
|
@@ -605,107 +606,75 @@ class Utils extends FleetbaseUtils
|
|
|
605
606
|
*
|
|
606
607
|
* @param string $data the binary string representing the point
|
|
607
608
|
*
|
|
608
|
-
* @return
|
|
609
|
+
* @return Point the Laravel MySQL Spatial Point instance
|
|
609
610
|
*/
|
|
610
|
-
public static function rawPointToPoint(string $data):
|
|
611
|
+
public static function rawPointToPoint(string $data): Point
|
|
611
612
|
{
|
|
612
613
|
// Use the `unpack` function to extract the X, Y, and SRID values from the binary string.
|
|
613
614
|
$res = unpack('lSRID/CByteOrder/lTypeInfo/dX/dY', $data);
|
|
614
615
|
|
|
615
616
|
// Return a new Laravel MySQL Spatial Point instance with the X, Y, and SRID values.
|
|
616
|
-
return new
|
|
617
|
+
return new Point($res['X'], $res['Y'], $res['SRID']);
|
|
617
618
|
}
|
|
618
619
|
|
|
619
620
|
/**
|
|
620
|
-
* Calculates driving distance and time
|
|
621
|
-
* Returns distance in meters and time in seconds.
|
|
621
|
+
* Calculates the driving distance and time between two points.
|
|
622
622
|
*
|
|
623
|
-
*
|
|
624
|
-
*
|
|
623
|
+
* This function attempts to find the driving distance and time from the origin to the destination
|
|
624
|
+
* using various map APIs. It first attempts to resolve the origin and destination from various input types
|
|
625
|
+
* into geographical coordinates. Then, based on the provider specified in the options or defaulting to configured provider,
|
|
626
|
+
* it queries the respective service for the driving distance and time. The result is returned as a DistanceMatrix
|
|
627
|
+
* object with the distance in meters and the time in seconds.
|
|
628
|
+
*
|
|
629
|
+
* @param mixed $origin The origin of the journey. Can be a Place model, a string, or an array with latitude and longitude.
|
|
630
|
+
* @param mixed $destination The destination of the journey. Similar to the origin, it accepts multiple input types.
|
|
631
|
+
*
|
|
632
|
+
* @return DistanceMatrix an object containing the distance and time of the journey
|
|
633
|
+
*
|
|
634
|
+
* @throws \Throwable throws any exception encountered during the resolution of points or API calls
|
|
625
635
|
*/
|
|
626
|
-
public static function getDrivingDistanceAndTime($origin, $destination): DistanceMatrix
|
|
636
|
+
public static function getDrivingDistanceAndTime($origin, $destination, $options = []): DistanceMatrix
|
|
627
637
|
{
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
'longitude' => $destination->location->getLng(),
|
|
650
|
-
]
|
|
651
|
-
);
|
|
652
|
-
} else {
|
|
653
|
-
$point = static::getPointFromMixed($destination);
|
|
654
|
-
$destination = static::createObject(
|
|
655
|
-
[
|
|
656
|
-
'latitude' => $point->getLat(),
|
|
657
|
-
'longitude' => $point->getLng(),
|
|
658
|
-
]
|
|
659
|
-
);
|
|
638
|
+
$origin = static::getPointFromMixed($origin);
|
|
639
|
+
$destination = static::getPointFromMixed($destination);
|
|
640
|
+
$origins = $origin->getLat() . ',' . $origin->getLng();
|
|
641
|
+
$destinations = $destination->getLat() . ',' . $destination->getLng();
|
|
642
|
+
|
|
643
|
+
// Create empty distance matric
|
|
644
|
+
$distanceMatrix = new DistanceMatrix(0, 0);
|
|
645
|
+
$provider = data_get($options, 'provider', config('fleetops.distance_matrix.provider'));
|
|
646
|
+
switch ($provider) {
|
|
647
|
+
case 'calculate':
|
|
648
|
+
$distanceMatrix = static::calculateDrivingDistanceAndTime($origins, $destinations);
|
|
649
|
+
break;
|
|
650
|
+
|
|
651
|
+
case 'osrm':
|
|
652
|
+
$distanceMatrix = static::getDistanceMatrixFromOSRM($origins, $destinations);
|
|
653
|
+
break;
|
|
654
|
+
|
|
655
|
+
case 'google':
|
|
656
|
+
default:
|
|
657
|
+
$distanceMatrix = static::getDistanceMatrixFromGoogle($origins, $destinations);
|
|
658
|
+
break;
|
|
660
659
|
}
|
|
661
660
|
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
// check cache for results
|
|
665
|
-
$cachedResult = Redis::get($cacheKey);
|
|
666
|
-
|
|
667
|
-
if ($cachedResult) {
|
|
668
|
-
$json = json_decode($cachedResult);
|
|
669
|
-
|
|
670
|
-
if (!empty($json->distance) && !empty($json->time)) {
|
|
671
|
-
return new DistanceMatrix($json->distance, $json->time);
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
$response = Http::get(
|
|
676
|
-
'https://maps.googleapis.com/maps/api/distancematrix/json',
|
|
677
|
-
[
|
|
678
|
-
'origins' => $origin->latitude . ',' . $origin->longitude,
|
|
679
|
-
'destinations' => $destination->latitude . ',' . $destination->longitude,
|
|
680
|
-
'mode' => 'driving',
|
|
681
|
-
'key' => env('GOOGLE_MAPS_API_KEY'),
|
|
682
|
-
]
|
|
683
|
-
)->json();
|
|
684
|
-
|
|
685
|
-
$distance = data_get($response, 'rows.0.elements.0.distance.value');
|
|
686
|
-
$time = data_get($response, 'rows.0.elements.0.duration.value');
|
|
687
|
-
|
|
688
|
-
$result = static::createObject(
|
|
689
|
-
[
|
|
690
|
-
'distance' => $distance,
|
|
691
|
-
'time' => $time,
|
|
692
|
-
]
|
|
693
|
-
);
|
|
694
|
-
|
|
695
|
-
// cache result
|
|
696
|
-
Redis::set($cacheKey, json_encode($result));
|
|
697
|
-
|
|
698
|
-
return new DistanceMatrix($distance, $time);
|
|
661
|
+
return $distanceMatrix;
|
|
699
662
|
}
|
|
700
663
|
|
|
701
664
|
/**
|
|
702
|
-
*
|
|
703
|
-
* Returns distance in meters and time in seconds.
|
|
665
|
+
* Computes a distance matrix for multiple origins and destinations.
|
|
704
666
|
*
|
|
705
|
-
*
|
|
706
|
-
*
|
|
667
|
+
* This function is designed to handle arrays of origins and destinations to calculate a distance matrix.
|
|
668
|
+
* It converts the input arrays into a string format suitable for the map API request. The provider specified
|
|
669
|
+
* in the options (default is Google) determines which map service API is used for the calculations.
|
|
670
|
+
*
|
|
671
|
+
* @param array|\Illuminate\Support\Collection $origins array or collection of origin points
|
|
672
|
+
* @param array|\Illuminate\Support\Collection $destinations array or collection of destination points
|
|
673
|
+
* @param array $options options for API calls, like the provider and mode of transport
|
|
674
|
+
*
|
|
675
|
+
* @return DistanceMatrix an object representing the distance and time between the furthest origins and destinations
|
|
707
676
|
*/
|
|
708
|
-
public static function distanceMatrix($origins = [], $destinations = []): DistanceMatrix
|
|
677
|
+
public static function distanceMatrix($origins = [], $destinations = [], $options = []): DistanceMatrix
|
|
709
678
|
{
|
|
710
679
|
if ($origins instanceof \Illuminate\Support\Collection) {
|
|
711
680
|
$origins = $origins->all();
|
|
@@ -715,57 +684,83 @@ class Utils extends FleetbaseUtils
|
|
|
715
684
|
$destinations = $destinations->all();
|
|
716
685
|
}
|
|
717
686
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
687
|
+
// Convert origins and destinatinos to string
|
|
688
|
+
$origins = static::createCoordinateStringFromPlacesArray($origins);
|
|
689
|
+
$destinations = static::createCoordinateStringFromPlacesArray($destinations);
|
|
690
|
+
|
|
691
|
+
// Create empty distance matric
|
|
692
|
+
$distanceMatrix = new DistanceMatrix(0, 0);
|
|
693
|
+
$provider = data_get($options, 'provider', config('fleetops.distance_matrix.provider'));
|
|
694
|
+
switch ($provider) {
|
|
695
|
+
case 'calculate':
|
|
696
|
+
$distanceMatrix = static::calculateDrivingDistanceAndTime($origins, $destinations);
|
|
697
|
+
break;
|
|
698
|
+
|
|
699
|
+
case 'osrm':
|
|
700
|
+
$distanceMatrix = static::getDistanceMatrixFromOSRM($origins, $destinations);
|
|
701
|
+
break;
|
|
702
|
+
|
|
703
|
+
case 'google':
|
|
704
|
+
default:
|
|
705
|
+
$distanceMatrix = static::getDistanceMatrixFromGoogle($origins, $destinations);
|
|
706
|
+
break;
|
|
707
|
+
}
|
|
732
708
|
|
|
733
|
-
$
|
|
734
|
-
|
|
735
|
-
$point = static::getPointFromMixed($destination);
|
|
736
|
-
$destination = static::createObject(
|
|
737
|
-
[
|
|
738
|
-
'latitude' => $point->getLat(),
|
|
739
|
-
'longitude' => $point->getLng(),
|
|
740
|
-
]
|
|
741
|
-
);
|
|
742
|
-
|
|
743
|
-
return $destination;
|
|
744
|
-
},
|
|
745
|
-
$destinations
|
|
746
|
-
);
|
|
709
|
+
return $distanceMatrix;
|
|
710
|
+
}
|
|
747
711
|
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
712
|
+
/**
|
|
713
|
+
* Converts an array of places into a coordinate string.
|
|
714
|
+
*
|
|
715
|
+
* Accepts an array of places (or any type that can be converted into geographical points)
|
|
716
|
+
* and converts each into a 'latitude,longitude' format. These coordinates are then concatenated into a single string,
|
|
717
|
+
* separated by the specified separator. The function gracefully handles any errors in the conversion process.
|
|
718
|
+
*
|
|
719
|
+
* @param array $places array of places to be converted into coordinates
|
|
720
|
+
* @param string $separator separator used to concatenate the coordinates into a single string
|
|
721
|
+
*
|
|
722
|
+
* @return string a concatenated string of coordinates
|
|
723
|
+
*/
|
|
724
|
+
public static function createCoordinateStringFromPlacesArray(array $places = [], $separator = '|'): string
|
|
725
|
+
{
|
|
726
|
+
$coordinates = array_map(
|
|
727
|
+
function ($place) {
|
|
728
|
+
try {
|
|
729
|
+
$point = static::getPointFromMixed($place);
|
|
730
|
+
} catch (\Throwable $e) {
|
|
731
|
+
$point = new Point(0, 0);
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
return $point;
|
|
752
735
|
},
|
|
753
|
-
$
|
|
754
|
-
)
|
|
736
|
+
$places
|
|
737
|
+
);
|
|
755
738
|
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
return $destination->latitude . ',' . $destination->longitude;
|
|
739
|
+
return implode($separator, array_map(
|
|
740
|
+
function ($point) {
|
|
741
|
+
return $point->getLat() . ',' . $point->getLng();
|
|
760
742
|
},
|
|
761
|
-
$
|
|
743
|
+
$coordinates
|
|
762
744
|
));
|
|
745
|
+
}
|
|
763
746
|
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
747
|
+
/**
|
|
748
|
+
* Retrieves a distance matrix using the Google Distance Matrix API.
|
|
749
|
+
*
|
|
750
|
+
* This function calculates the distance and time between origins and destinations using the Google API.
|
|
751
|
+
* It first checks if there is a cached result in Redis and, if not, performs an API call to Google.
|
|
752
|
+
* The results are then cached in Redis and returned as a DistanceMatrix object.
|
|
753
|
+
*
|
|
754
|
+
* @param string $origins a string of origins in 'latitude,longitude' format, separated by a specified delimiter
|
|
755
|
+
* @param string $destinations a string of destinations in a similar format to origins
|
|
756
|
+
* @param array $options additional options for the API call, like the mode of transport
|
|
757
|
+
*
|
|
758
|
+
* @return DistanceMatrix the distance and time between the given origins and destinations
|
|
759
|
+
*/
|
|
760
|
+
public static function getDistanceMatrixFromGoogle(string $origins, string $destinations, $options = []): DistanceMatrix
|
|
761
|
+
{
|
|
762
|
+
$cacheKey = md5($origins . '_' . $destinations);
|
|
767
763
|
$cachedResult = Redis::get($cacheKey);
|
|
768
|
-
|
|
769
764
|
if ($cachedResult) {
|
|
770
765
|
$json = json_decode($cachedResult);
|
|
771
766
|
|
|
@@ -777,9 +772,9 @@ class Utils extends FleetbaseUtils
|
|
|
777
772
|
$response = Http::withOptions(['verify' => false])->get(
|
|
778
773
|
'https://maps.googleapis.com/maps/api/distancematrix/json',
|
|
779
774
|
[
|
|
780
|
-
'origins' => $
|
|
781
|
-
'destinations' => $
|
|
782
|
-
'mode' => 'driving',
|
|
775
|
+
'origins' => $origins,
|
|
776
|
+
'destinations' => $destinations,
|
|
777
|
+
'mode' => data_get($options, 'mode', 'driving'),
|
|
783
778
|
'key' => env('GOOGLE_MAPS_API_KEY'),
|
|
784
779
|
]
|
|
785
780
|
)->json();
|
|
@@ -787,17 +782,69 @@ class Utils extends FleetbaseUtils
|
|
|
787
782
|
$distance = (float) data_get($response, 'rows.0.elements.0.distance.value', 0);
|
|
788
783
|
$time = (float) data_get($response, 'rows.0.elements.0.duration.value', 0);
|
|
789
784
|
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
'distance' => $distance,
|
|
793
|
-
'time' => $time,
|
|
794
|
-
]
|
|
795
|
-
);
|
|
785
|
+
// Create distance matrix
|
|
786
|
+
$distanceMatrix = new DistanceMatrix($distance, $time);
|
|
796
787
|
|
|
797
|
-
//
|
|
798
|
-
Redis::set($cacheKey, json_encode($
|
|
788
|
+
// Cache distance matrix
|
|
789
|
+
Redis::set($cacheKey, json_encode($distanceMatrix));
|
|
799
790
|
|
|
800
|
-
return
|
|
791
|
+
return $distanceMatrix;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* Calculates distance and time between points using the OSRM API.
|
|
796
|
+
*
|
|
797
|
+
* Similar to the Google Distance Matrix function, this uses the OSRM (Open Source Routing Machine) API.
|
|
798
|
+
* It first checks for cached results before making a new API request. The origins and destinations are
|
|
799
|
+
* reformatted to the OSRM API requirement and the response is parsed into a DistanceMatrix object.
|
|
800
|
+
*
|
|
801
|
+
* @param string $origins comma-separated string of origin coordinates
|
|
802
|
+
* @param string $destinations comma-separated string of destination coordinates
|
|
803
|
+
*
|
|
804
|
+
* @return DistanceMatrix an object containing the distance and time for the specified journey
|
|
805
|
+
*/
|
|
806
|
+
public static function getDistanceMatrixFromOSRM(string $origins, string $destinations): DistanceMatrix
|
|
807
|
+
{
|
|
808
|
+
$cacheKey = md5($origins . '_' . $destinations);
|
|
809
|
+
$cachedResult = Redis::get($cacheKey);
|
|
810
|
+
if ($cachedResult) {
|
|
811
|
+
$json = json_decode($cachedResult);
|
|
812
|
+
|
|
813
|
+
if (!empty($json->distance) && !empty($json->time)) {
|
|
814
|
+
return new DistanceMatrix($json->distance, $json->time);
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
// OSRM uses semi-colon to delimit coordinates so replace any `|` as we typically use with `;`
|
|
819
|
+
$origins = Str::replace('|', ';', $origins);
|
|
820
|
+
$destinations = Str::replace('|', ';', $destinations);
|
|
821
|
+
$coordinatesString = $origins . ';' . $destinations;
|
|
822
|
+
// Split the string into individual coordinates
|
|
823
|
+
$coordinatesArray = explode(';', $coordinatesString);
|
|
824
|
+
|
|
825
|
+
// Reverse the latitude and longitude in each coordinate
|
|
826
|
+
$reversedCoordinates = array_map(function ($coordinate) {
|
|
827
|
+
$parts = explode(',', $coordinate);
|
|
828
|
+
if (count($parts) == 2) {
|
|
829
|
+
return $parts[1] . ',' . $parts[0]; // Swap latitude and longitude
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
return $coordinate; // Return original if it's not a valid coordinate
|
|
833
|
+
}, $coordinatesArray);
|
|
834
|
+
|
|
835
|
+
// Join the reversed coordinates back into a string
|
|
836
|
+
$reversedCoordinatesString = implode(';', $reversedCoordinates);
|
|
837
|
+
$response = OSRM::getRouteFromCoordinatesString($reversedCoordinatesString);
|
|
838
|
+
$distance = (float) data_get($response, 'routes.0.distance', 0);
|
|
839
|
+
$time = (float) data_get($response, 'routes.0.duration', 0);
|
|
840
|
+
|
|
841
|
+
// Create distance matrix
|
|
842
|
+
$distanceMatrix = new DistanceMatrix($distance, $time);
|
|
843
|
+
|
|
844
|
+
// Cache distance matrix
|
|
845
|
+
Redis::set($cacheKey, json_encode($distanceMatrix));
|
|
846
|
+
|
|
847
|
+
return $distanceMatrix;
|
|
801
848
|
}
|
|
802
849
|
|
|
803
850
|
/**
|
|
@@ -857,13 +904,13 @@ class Utils extends FleetbaseUtils
|
|
|
857
904
|
* https://en.wikipedia.org/wiki/Great-circle_distance#Formulas
|
|
858
905
|
* https://en.wikipedia.org/wiki/Antipodal_point
|
|
859
906
|
*
|
|
860
|
-
* @param
|
|
861
|
-
* @param
|
|
907
|
+
* @param Point Starting point
|
|
908
|
+
* @param Point Ending point
|
|
862
909
|
* @param float $earthRadius Mean earth radius in [m]
|
|
863
910
|
*
|
|
864
911
|
* @return float Distance between points in [m] (same as earthRadius)
|
|
865
912
|
*/
|
|
866
|
-
public static function vincentyGreatCircleDistance(
|
|
913
|
+
public static function vincentyGreatCircleDistance(Point $from, Point $to, float $earthRadius = 6371000): float
|
|
867
914
|
{
|
|
868
915
|
// convert from degrees to radians
|
|
869
916
|
$latFrom = deg2rad($from->getLat());
|
|
@@ -884,7 +931,7 @@ class Utils extends FleetbaseUtils
|
|
|
884
931
|
/**
|
|
885
932
|
* Finds the nearest timezone for a given coordinate point.
|
|
886
933
|
*/
|
|
887
|
-
public static function getNearestTimezone(
|
|
934
|
+
public static function getNearestTimezone(Point $location, string $countryCode = ''): string
|
|
888
935
|
{
|
|
889
936
|
$timezoneIds = \DateTimeZone::listIdentifiers(\DateTimeZone::PER_COUNTRY, $countryCode);
|
|
890
937
|
$lat = $location->getLat();
|
|
@@ -984,7 +1031,7 @@ class Utils extends FleetbaseUtils
|
|
|
984
1031
|
|
|
985
1032
|
public static function isPoint($point): bool
|
|
986
1033
|
{
|
|
987
|
-
return $point instanceof
|
|
1034
|
+
return $point instanceof Point;
|
|
988
1035
|
}
|
|
989
1036
|
|
|
990
1037
|
/**
|
|
@@ -1249,7 +1296,7 @@ class Utils extends FleetbaseUtils
|
|
|
1249
1296
|
*
|
|
1250
1297
|
* @return float the heading in degrees from the starting point to the ending point
|
|
1251
1298
|
*/
|
|
1252
|
-
public static function calculateHeading(
|
|
1299
|
+
public static function calculateHeading(Point $point1, Point $point2): float
|
|
1253
1300
|
{
|
|
1254
1301
|
// Extract latitude and longitude from Point objects
|
|
1255
1302
|
$lat1 = $point1->getLat();
|
package/server/src/routes.php
CHANGED
|
@@ -12,9 +12,6 @@ use Illuminate\Support\Facades\Route;
|
|
|
12
12
|
| is assigned the "api" middleware group. Enjoy building your API!
|
|
13
13
|
|
|
|
14
14
|
*/
|
|
15
|
-
|
|
16
|
-
Route::get('fleet-ops-test', 'Fleetbase\FleetOps\Http\Controllers\Controller@test');
|
|
17
|
-
|
|
18
15
|
Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase\FleetOps\Http\Controllers')->group(
|
|
19
16
|
function ($router) {
|
|
20
17
|
/*
|
|
@@ -84,6 +81,7 @@ Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase
|
|
|
84
81
|
$router->post('{id}/capture-photo/{subjectId?}', 'OrderController@capturePhoto');
|
|
85
82
|
$router->put('{id}', 'OrderController@update');
|
|
86
83
|
$router->delete('{id}', 'OrderController@delete');
|
|
84
|
+
$router->get('{id}/editable-entity-fields', 'OrderController@getEditableEntityFields');
|
|
87
85
|
});
|
|
88
86
|
// entities routes
|
|
89
87
|
$router->group(['prefix' => 'entities'], function () use ($router) {
|
|
@@ -435,6 +433,8 @@ Route::prefix(config('fleetops.api.routing.prefix', null))->namespace('Fleetbase
|
|
|
435
433
|
function ($router) {
|
|
436
434
|
$router->get('visibility', 'SettingController@getVisibilitySettings');
|
|
437
435
|
$router->post('visibility', 'SettingController@saveVisibilitySettings');
|
|
436
|
+
$router->get('entity-editing-settings', 'SettingController@getEntityEditingSettings');
|
|
437
|
+
$router->post('entity-editing-settings', 'SettingController@saveEntityEditingSettings');
|
|
438
438
|
}
|
|
439
439
|
);
|
|
440
440
|
$router->group(
|
package/translations/en-us.yaml
CHANGED
|
@@ -236,6 +236,9 @@ fleet-ops:
|
|
|
236
236
|
title: Navigator App
|
|
237
237
|
name: Instance Linking URL
|
|
238
238
|
message: Use this URL to link the official Navigator app to this {companyName} instance. Opening this URL on a mobile device will open the Navigator app and update it's configuration and branding.
|
|
239
|
+
settings: Entity Settings
|
|
240
|
+
select-input: Allow driver to update entity details
|
|
241
|
+
|
|
239
242
|
visibility-controls:
|
|
240
243
|
title: Visibility Controls
|
|
241
244
|
message: Visibility controls allow you to disable sections of Fleet-Ops. Toggle the checkbox to enable or disable sections to hide in Fleet-ops.
|