Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map kit Walking distance UI. #152

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
26 changes: 22 additions & 4 deletions Shared/Delegates/LocationManagerDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,34 @@
//
// Created by Gabriel Jacoby-Cooper on 9/11/20.
//

import CoreLocation
import CoreLocationUI

class LocationManagerDelegate: NSObject, CLLocationManagerDelegate {


class LocationManagerDelegate: NSObject,ObservableObject, CLLocationManagerDelegate {
let manager = CLLocationManager()

@Published var location: CLLocationCoordinate2D?
@Published var locationTEST: CLLocationCoordinate2D?


func requestLocation() {
manager.requestLocation()
}


func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard MapState.shared.travelState == .onBus else {



guard MapState.shared.travelState == .onBus else {
return
}
LocationUtilities.sendToServer(coordinate: locations.last!.coordinate)
}
//case on manager auth status to show the toast
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {

}

}
7 changes: 6 additions & 1 deletion Shared/State/MapState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ class MapState: ObservableObject {
@Published var stops = [Stop]()

@Published var routes = [Route]()



@Published var travelState = TravelState.notOnBus {
didSet {
switch self.travelState {
Expand All @@ -33,8 +34,12 @@ class MapState: ObservableObject {
self.mapView?.userLocation.title = self.oldUserLocationTitle
self.mapView?.showsUserLocation.toggle()
}

}
}




@Published var busID: Int?

Expand Down
266 changes: 196 additions & 70 deletions Shared/Views/PrimaryOverlay.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,48 @@

import SwiftUI
import StoreKit
import CoreLocation
import CoreLocationUI


extension Double {
var removeZero:String {
let nf = NumberFormatter()
nf.minimumFractionDigits = 1
nf.maximumFractionDigits = 2
return nf.string(from: self as NSNumber)!
}
}

func degreesToRadians(degrees: Double) -> Double { return degrees * .pi / 180.0 }
func radiansToDegrees(radians: Double) -> Double { return radians * 180.0 / .pi }
//takes in 2 CLLocations, and computes the bearing between those 2 points


func compute_direction (point1 : CLLocation, point2 : CLLocation) -> String {

let compassPoints = ["arrow.up", "arrow.up.right", "arrow.right", "arrow.down.right", "arrow.down", "arrow.down.backward", "arrow.left", "arrow.up.left", "arrow.up"]

let lat1 = degreesToRadians(degrees: point1.coordinate.latitude)
let lon1 = degreesToRadians(degrees: point1.coordinate.longitude)

let lat2 = degreesToRadians(degrees: point2.coordinate.latitude)
let lon2 = degreesToRadians(degrees: point2.coordinate.longitude)

let dLon = lon2 - lon1

let y = sin(dLon) * cos(lat2)
let x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon)
var radiansBearing = atan2(y, x)

radiansBearing = (radiansBearing + 2 * .pi).truncatingRemainder(dividingBy: 2 * .pi)

let degreesBearing = radiansToDegrees(radians: radiansBearing)
let index = Int((degreesBearing / 45.0) + 0.5) % compassPoints.count

return compassPoints[index]
}


struct PrimaryOverlay: View {

Expand All @@ -26,76 +68,170 @@ struct PrimaryOverlay: View {
}

@State private var isRefreshing = false

@EnvironmentObject private var mapState: MapState


@EnvironmentObject var mapState: MapState

@EnvironmentObject private var viewState: ViewState

@EnvironmentObject private var sheetStack: SheetStack


let defaultLocation = CLLocation(latitude: 37.7749, longitude: -122.4194)

@AppStorage("MaximumStopDistance") private var maximumStopDistance = 50

let conversionConstant = 0.000621371






var body: some View {

HStack {
Spacer()
if #available(iOS 15, *) {
VStack(alignment: .leading) {
Button {
switch self.mapState.travelState {
case .onBus:
self.mapState.busID = nil
self.mapState.locationID = nil
self.mapState.travelState = .notOnBus
self.viewState.statusText = .thanks
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
self.viewState.statusText = .mapRefresh

}
LocationUtilities.locationManager.stopUpdatingLocation()

// Remove any pending leave-bus notifications
UNUserNotificationCenter
.current()
.removeAllPendingNotificationRequests()

let windowScenes = UIApplication.shared.connectedScenes
.filter { (scene) in
return scene.activationState == .foregroundActive
}
.compactMap { (scene) in
return scene as? UIWindowScene
}
if let windowScene = windowScenes.first {
SKStoreReviewController.requestReview(in: windowScene)
}
case .notOnBus:
// TODO: Rename local `location` identifier to something more descriptive
guard let location = LocationUtilities.locationManager.location else {
break
}
let closestStopDistance = self.mapState.stops.reduce(into: Double.greatestFiniteMagnitude) { (distance, stop) in
let newDistance = stop.location.distance(from: location)
if newDistance < distance {
distance = newDistance
}
}
if closestStopDistance < Double(self.maximumStopDistance) {
self.mapState.locationID = UUID()
self.sheetStack.push(.busSelection)
if self.viewState.toastType == .boardBus {
self.viewState.toastType = nil
}
} else {
self.viewState.alertType = .noNearbyStop
}
}
} label: {
Text(self.buttonText)
.bold()
}
.buttonStyle(.block)
HStack {
Text(self.viewState.statusText.rawValue)
VStack(alignment: .leading) {
VStack{

HStack(spacing: 35){
Button {
switch self.mapState.travelState {
case .onBus:

self.mapState.busID = nil
self.mapState.locationID = nil
self.mapState.travelState = .notOnBus
self.viewState.statusText = .thanks
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
self.viewState.statusText = .mapRefresh

}
LocationUtilities.locationManager.stopUpdatingLocation()

// Remove any pending leave-bus notifications
UNUserNotificationCenter
.current()
.removeAllPendingNotificationRequests()

let windowScenes = UIApplication.shared.connectedScenes
.filter { (scene) in
return scene.activationState == .foregroundActive
}
.compactMap { (scene) in
return scene as? UIWindowScene
}
if let windowScene = windowScenes.first {
SKStoreReviewController.requestReview(in: windowScene)
}
case .notOnBus:
// TODO: Rename local `location` identifier to something more descriptive
guard let location = LocationUtilities.locationManager.location else {
break
}
let closestStopDistance = self.mapState.stops.reduce(into: Double.greatestFiniteMagnitude) { (distance, stop) in
let newDistance = stop.location.distance(from: location)
if newDistance < distance {
distance = newDistance
}
}
if closestStopDistance < Double(self.maximumStopDistance) {
self.mapState.locationID = UUID()
self.sheetStack.push(.busSelection)
if self.viewState.toastType == .boardBus {
self.viewState.toastType = nil
}
} else {
self.viewState.alertType = .noNearbyStop
}
}
} label: {
Text("Board Bus")
.bold()
}
.buttonStyle(.borderedProminent)

HStack{

if(LocationUtilities.locationManager.location == nil){

Button{

self.sheetStack.push(.permissions)


}label: {
Image(systemName: "exclamationmark.triangle.fill")
.foregroundColor(.yellow)
Text("Location Error!").lineLimit(1)
}


}else{


let location = LocationUtilities.locationManager.location
var stopLocation = LocationUtilities.locationManager.location

//we can force unwrap here as we are only here if location != nil
let closestStopDistance = self.mapState.stops.reduce(into: Double.greatestFiniteMagnitude) { (distance, stop) in
let newDistance = stop.location.distance(from: location!)
if newDistance < distance {
distance = newDistance
stopLocation = stop.location


}
}

Text("\((closestStopDistance * conversionConstant).removeZero) mi")
Image(systemName: compute_direction(point1: location!, point2: stopLocation!) )


Button(action: {

print("TO: \(stopLocation!.coordinate) FROM: \(LocationUtilities.locationManager.location!.coordinate)")
print(compute_direction(point1: location!, point2: stopLocation!))

let curr_Lattitude = LocationUtilities.locationManager.location!.coordinate.latitude
let currLongittude = LocationUtilities.locationManager.location!.coordinate.longitude

let destLattitude = stopLocation!.coordinate.latitude
let destLongitude = stopLocation!.coordinate.longitude

print(curr_Lattitude, currLongittude)

print(destLattitude, destLongitude)

let url = URL(string: "maps://?saddr=\(curr_Lattitude),\(currLongittude)&daddr=\(destLattitude),\(destLongitude)")


if UIApplication.shared.canOpenURL(url!) {
UIApplication.shared.open(url!, options: [:], completionHandler: nil)
}


}, label: {
HStack{

Image(systemName: "figure.walk")

}

})

}


}



}
}
HStack {
Text("Enroll in the shuttle tracker network today!" )
.layoutPriority(1)
Spacer()
Group {
Expand Down Expand Up @@ -260,13 +396,3 @@ struct PrimaryOverlay: View {
}

}

struct PrimaryOverlayPreviews: PreviewProvider {

static var previews: some View {
PrimaryOverlay()
.environmentObject(MapState.shared)
.environmentObject(ViewState.shared)
}

}
8 changes: 4 additions & 4 deletions Shuttle Tracker.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@
INFOPLIST_FILE = "$(SRCROOT)/App Clip/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = "Shuttle Tracker";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.navigation";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -781,7 +781,7 @@
INFOPLIST_FILE = "$(SRCROOT)/App Clip/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = "Shuttle Tracker";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.navigation";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -925,7 +925,7 @@
INFOPLIST_FILE = iOS/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Shuttle Tracker";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.navigation";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -954,7 +954,7 @@
INFOPLIST_FILE = iOS/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Shuttle Tracker";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.navigation";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down