Compare commits

..

3 Commits

11 changed files with 424 additions and 261 deletions

View File

@@ -14,8 +14,9 @@ PODS:
- geolocator_apple (1.2.0):
- Flutter
- OrderedSet (5.0.0)
- path_provider_ios (0.0.1):
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- url_launcher_ios (0.0.1):
- Flutter
@@ -25,7 +26,7 @@ DEPENDENCIES:
- flutter_compass (from `.symlinks/plugins/flutter_compass/ios`)
- flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`)
- geolocator_apple (from `.symlinks/plugins/geolocator_apple/ios`)
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
SPEC REPOS:
@@ -43,8 +44,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_inappwebview/ios"
geolocator_apple:
:path: ".symlinks/plugins/geolocator_apple/ios"
path_provider_ios:
:path: ".symlinks/plugins/path_provider_ios/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios"
@@ -55,9 +56,9 @@ SPEC CHECKSUMS:
flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721
geolocator_apple: cc556e6844d508c95df1e87e3ea6fa4e58c50401
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4
PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
COCOAPODS: 1.11.3
COCOAPODS: 1.12.1

View File

@@ -156,7 +156,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1300;
LastUpgradeCheck = 1430;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
@@ -205,6 +205,7 @@
files = (
);
inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
LastUpgradeVersion = "1430"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -122,7 +122,10 @@ class _HomeScreenState extends State<HomeScreen> {
alignment: Alignment.bottomCenter,
child: Container(
height: overscrollBottomAmount + 30,
color: Colors.grey.shade50,
decoration: BoxDecoration(
color: Colors.grey.shade50,
border: Border.all(width: 0, color: Colors.white),
),
),
),
Consumer<HomePageState>(

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

File diff suppressed because it is too large Load Diff

View File

@@ -35,7 +35,7 @@ dependencies:
cupertino_icons: ^1.0.2
english_words: ^4.0.0
intl: ^0.17.0
google_fonts: ^3.0.1
google_fonts: ^4.0.4
http: ^0.13.5
convert: ^3.0.2
crypto: ^3.0.2

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