wip: support saferide shuttle
This commit is contained in:
parent
3f0342b6cb
commit
7b6a276c21
|
@ -0,0 +1,61 @@
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_map/flutter_map.dart';
|
||||||
|
import 'package:furman_now/src/widgets/map/route_marker.dart';
|
||||||
|
import 'package:latlong2/latlong.dart';
|
||||||
|
|
||||||
|
class TransportationRoute {
|
||||||
|
final Polyline route;
|
||||||
|
final List<Stop> stops;
|
||||||
|
|
||||||
|
TransportationRoute({
|
||||||
|
required this.route,
|
||||||
|
required this.stops,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory TransportationRoute.fromPoints({
|
||||||
|
required List<LatLng> points,
|
||||||
|
required Color color,
|
||||||
|
required List<Stop> stops,
|
||||||
|
}) {
|
||||||
|
var route = Polyline(
|
||||||
|
points: points,
|
||||||
|
color: color,
|
||||||
|
strokeWidth: 4,
|
||||||
|
);
|
||||||
|
return TransportationRoute(
|
||||||
|
route: route,
|
||||||
|
stops: stops,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Stop {
|
||||||
|
int id;
|
||||||
|
String name;
|
||||||
|
LatLng location;
|
||||||
|
|
||||||
|
Stop({
|
||||||
|
required this.id,
|
||||||
|
required this.name,
|
||||||
|
required this.location,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Stop.fromLiveSafeJson(Map<String, dynamic> json) {
|
||||||
|
return Stop(
|
||||||
|
id: json["AddressID"],
|
||||||
|
name: json["Description"],
|
||||||
|
location: LatLng(json["Latitude"], json["Longitude"]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Marker toMarker({required Color color}) {
|
||||||
|
return Marker(
|
||||||
|
point: location,
|
||||||
|
height: 100,
|
||||||
|
width: 100,
|
||||||
|
builder: (context) => RouteMarker(color: color),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,48 @@
|
||||||
class TransportationSafeRideShuttleService {
|
import 'dart:convert';
|
||||||
|
|
||||||
}
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:furman_now/src/utils/decode_polyline.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
|
import 'route.dart';
|
||||||
|
|
||||||
|
class TransportationSafeRideShuttleService {
|
||||||
|
static const service =
|
||||||
|
"https://furmansaferide.ridesystems.net/Services/JSONPRelay.svc";
|
||||||
|
|
||||||
|
static const apiKey = "8882812681";
|
||||||
|
|
||||||
|
static Future<http.Response> _serviceRequest(
|
||||||
|
String endpoint, Map<String, dynamic>? queryParameters) async {
|
||||||
|
Uri serviceUri = Uri.https(
|
||||||
|
'furmansaferide.ridesystems.net',
|
||||||
|
"/Services/JSONPRelay.svc/$endpoint",
|
||||||
|
{...?queryParameters, 'apiKey': apiKey});
|
||||||
|
return http.get(serviceUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<TransportationRoute> fetchShuttleRoute() async {
|
||||||
|
final response = await _serviceRequest(
|
||||||
|
'GetRoutesForMapWithScheduleWithEncodedLine', {'isDispatch': 'false'});
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
// If the server did return a 200 OK response,
|
||||||
|
// then parse the JSON.
|
||||||
|
final json = jsonDecode(response.body);
|
||||||
|
String encodedPolyline = json[0]["EncodedPolyline"];
|
||||||
|
final points = decodeEncodedPolyline(encodedPolyline);
|
||||||
|
var stops = (json[0]["Stops"] as List<dynamic>)
|
||||||
|
.map((e) => Stop.fromLiveSafeJson(e))
|
||||||
|
.toList();
|
||||||
|
return TransportationRoute.fromPoints(
|
||||||
|
points: points,
|
||||||
|
color: Colors.red.shade300,
|
||||||
|
stops: stops,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// If the server did not return a 200 OK response,
|
||||||
|
// then throw an exception.
|
||||||
|
throw Exception('Failed to load SafeRide shuttle route.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
abstract class TransportationVehicle {
|
||||||
|
// name of the vehicle
|
||||||
|
String get name;
|
||||||
|
|
||||||
|
// is the vehicle currently running?
|
||||||
|
VehicleStatus get status;
|
||||||
|
|
||||||
|
// name of vehicle's next stop
|
||||||
|
String get nextStop;
|
||||||
|
|
||||||
|
// vehicle icon
|
||||||
|
IconData get icon;
|
||||||
|
|
||||||
|
// vehicle route
|
||||||
|
TransitionRoute get route;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum VehicleStatus { running, stopped }
|
|
@ -0,0 +1,34 @@
|
||||||
|
import 'package:latlong2/latlong.dart';
|
||||||
|
|
||||||
|
/// Decodes the an encoded polyline using the Encoded Polyline Algorithm Format
|
||||||
|
/// for more info about the algorithm check
|
||||||
|
/// https://developers.google.com/maps/documentation/utilities/polylinealgorithm
|
||||||
|
List<LatLng> decodeEncodedPolyline(String encoded) {
|
||||||
|
List<LatLng> poly = [];
|
||||||
|
int index = 0, len = encoded.length;
|
||||||
|
int lat = 0, lng = 0;
|
||||||
|
|
||||||
|
while (index < len) {
|
||||||
|
int b, shift = 0, result = 0;
|
||||||
|
do {
|
||||||
|
b = encoded.codeUnitAt(index++) - 63;
|
||||||
|
result |= (b & 0x1f) << shift;
|
||||||
|
shift += 5;
|
||||||
|
} while (b >= 0x20);
|
||||||
|
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
|
||||||
|
lat += dlat;
|
||||||
|
|
||||||
|
shift = 0;
|
||||||
|
result = 0;
|
||||||
|
do {
|
||||||
|
b = encoded.codeUnitAt(index++) - 63;
|
||||||
|
result |= (b & 0x1f) << shift;
|
||||||
|
shift += 5;
|
||||||
|
} while (b >= 0x20);
|
||||||
|
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
|
||||||
|
lng += dlng;
|
||||||
|
LatLng p = LatLng((lat / 1E5).toDouble(), (lng / 1E5).toDouble());
|
||||||
|
poly.add(p);
|
||||||
|
}
|
||||||
|
return poly;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
import "package:furman_now/src/services/transportation/saferide_shuttle.dart";
|
||||||
|
import "package:test/test.dart";
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
test("shuttle status is fetched successfully", () async {
|
||||||
|
var route = await TransportationSafeRideShuttleService.fetchShuttleRoute();
|
||||||
|
|
||||||
|
// ensure polyline has points
|
||||||
|
expect(route.route.points.length, isNonZero);
|
||||||
|
// ensure stops are listed
|
||||||
|
expect(route.stops.length, isNonZero);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("shuttle route is fetched successfully", () async {
|
||||||
|
var route = await TransportationSafeRideShuttleService.fetchShuttleRoute();
|
||||||
|
|
||||||
|
// ensure polyline has points
|
||||||
|
expect(route.route.points.length, isNonZero);
|
||||||
|
// ensure stops are listed
|
||||||
|
expect(route.stops.length, isNonZero);
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue