wip: support saferide shuttle

This commit is contained in:
Michael Thomas 2023-08-31 09:39:24 -04:00
parent 3f0342b6cb
commit 7b6a276c21
5 changed files with 184 additions and 2 deletions

View File

@ -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),
);
}
}

View File

@ -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.');
}
}
}

View File

@ -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 }

View File

@ -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;
}

View File

@ -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);
});
}