ARKit navigation in iOS Swift? - ios

I would like to do ar navigation using arkit 2.0. I tried using github sample projects https://github.com/chriswang101/AR-Navigation but dont know how to pass static data of user current location and destination lat long.
From github link user search destination and then goes to ar navigation, But in my case user directly goes to ar navigation screen by using lat long of source and destination .
How can i do that. Here is what i tried so far:
let l1 = CLLocationCoordinate2D(latitude: 34.0987346, longitude: -117.7123592)
let l2 = CLLocationCoordinate2D(latitude: 34.0990761, longitude: -117.7099627)
let l3 = CLLocationCoordinate2D(latitude: 34.0972554, longitude: -117.7093386)
let l4 = CLLocationCoordinate2D(latitude: 34.0986692, longitude: -117.7136621)
let l5 = CLLocationCoordinate2D(latitude: 34.0996506, longitude: -117.7143718)
let l6 = CLLocationCoordinate2D(latitude: 34.1001445, longitude: -117.7129978)
let sc = CLLocationCoordinate2D(latitude: 34.0195564, longitude: -118.2889155)
override func viewDidLoad() {
super.viewDidLoad()
print("route:::\(routeCoordinates)")
routeCoordinates = [CLLocationCoordinate2D(latitude: 12.873058, longitude: 80.226391)]
//Set to true to display an arrow which points north.
//Checkout the comments in the property description and on the readme on this.
// sceneLocationView.orientToTrueNorth = false
// sceneLocationView.locationEstimateMethod = .coreLocationDataOnly
sceneLocationView.showAxesNode = true
sceneLocationView.locationDelegate = self
if displayDebugging {
sceneLocationView.showFeaturePoints = true
}
self.plotARRoute()
view.addSubview(sceneLocationView)
if showMapView {
mapView.delegate = self
mapView.showsUserLocation = true
mapView.alpha = 0.8
view.addSubview(mapView)
updateUserLocationTimer = Timer.scheduledTimer(
timeInterval: 0.5,
target: self,
selector: #selector(ViewController.updateUserLocation),
userInfo: nil,
repeats: true)
}
}

Related

draw polyline in parallel with animation marker in google maps

I am using google maps in my application wherein I have to draw the polyline parallel along with the animation marker.Both should move simultaneous.,
Right now, my solution works like this ., First polyline is drawn with new coordinates, then animation marker is moved after.
I have tried few links in the stack overflow.. wherein the solution wasn't there.
This is the solution i'm looking for in swift iOS... the below link is for android.. which works perfectly
How to move marker along polyline using google map
Thanks if you can help me out in these..`
#objc func pocDrawPolyline() {
if poclastShownIndex < (vehicleLocationArray.count) {
let dict = vehicleLocationArray[poclastShownIndex]
if let lati = dict["latitude"], let logi = dict["longitude"] {
let lat = Double(lati as! String)
let log = Double(logi as! String)
let location = dict["location"] as? String
pocCreateVehicleMarkerWith(address: location ?? "School Bus", latitude: lat!, and: log!)
pocPath.add(CLLocationCoordinate2DMake(lat!, log!))
}
polyline.path = pocPath
polyline.strokeWidth = 3.0
polyline.strokeColor = UIColor.red
polyline.map = googleMapView
poclastShownIndex += 1
} else {
//No update from "NOW" API call
}
}
func pocCreateVehicleMarkerWith(address: String, latitude: Double, and Longitude: Double) {
// Creates a marker for Vehicle.
if vechicleMarker.map == nil {
vechicleMarker.position = CLLocationCoordinate2D(latitude: latitude, longitude: Longitude)
vechicleMarker.title = address
vechicleMarker.icon = UIImage(named: "bus1")
vechicleMarker.map = googleMapView
} else {
CATransaction.begin()
CATransaction.setAnimationDuration(0.5)
vechicleMarker.position = CLLocationCoordinate2D(latitude: latitude, longitude: Longitude)
vechicleMarker.title = address
vechicleMarker.icon = UIImage(named: "bus1")
CATransaction.commit()
if poclastShownIndex > 0 {
if let oldLatitude = vehicleLocationArray[poclastShownIndex-1]["latitude"],
let oldLongitude = vehicleLocationArray[poclastShownIndex-1]["longitude"],
let newLatitude = vehicleLocationArray[poclastShownIndex]["latitude"],
let newLongitude = vehicleLocationArray[poclastShownIndex]["longitude"] {
let oldLat = Double(oldLatitude as! String)
let oldLon = Double(oldLongitude as! String)
let newLat = Double(newLatitude as! String)
let newLon = Double(newLongitude as! String)
let oldloc = CLLocationCoordinate2D(latitude: oldLat!, longitude: oldLon!)
let newloc = CLLocationCoordinate2D(latitude: newLat!, longitude: newLon!)
let distanceInMeters = distance(from: oldloc, to: newloc)
if distanceInMeters > 0 {
print("Rotation Degree ------ \(CLLocationDegrees(getHeadingForDirection(fromCoordinate: oldloc, toCoordinate: newloc)))")
vechicleMarker.groundAnchor = CGPoint(x: CGFloat(0.5), y: CGFloat(0.5))
vechicleMarker.rotation = CLLocationDegrees(getHeadingForDirection(fromCoordinate: oldloc, toCoordinate: newloc))
googleMapView.animate(toLocation: newloc)
}
}
}
}
}func timerMethod() {
pocTimer = Timer.scheduledTimer(timeInterval: 10.0, target: self, selector: #selector(pocDrawPolyline), userInfo: nil, repeats: true)
}`

Move Multiple marker with their live location at my end

I am building an application where I have to move multiple marker. These markers will be visible at my end according to the multiple user's live locations. I am able to update only a single marker. but the rest are not updating. I stored these data in firebase and I am getting their data from there.
override func viewDidLoad() {
super.viewDidLoad()
Database.database().reference().child("users").observe(.childChanged, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject]
{
self.hideHUD()
self.latitudeFloatValue = (dictionary["lat"] as! Double)
self.longitudeFloatValue = (dictionary["long"] as! Double)
self.moveMent.delegate = self
//set old coordinate
self.oldCoordinate = CLLocationCoordinate2DMake(self.latitudeFloatValue, self.longitudeFloatValue)
print(self.oldCoordinate)
// Create a GMSCameraPosition that tells the map to display the marker
let camera = GMSCameraPosition.camera(withLatitude: self.latitudeFloatValue, longitude: self.longitudeFloatValue , zoom: 14)
self.mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
self.mapView.isMyLocationEnabled = true
self.mapView.delegate = self
self.view = self.mapView
// Creates a marker in the center of the map.
self.driverMarker = GMSMarker()
self.driverMarker.position = self.oldCoordinate!
self.driverMarker.icon = UIImage(named: "car")
self.driverMarker.map = self.mapView
self.copyCordinates = self.cordinates
print(self.copyCordinates)
print(self.cordinates)
self.cordinates = ["lattitude":self.latitudeFloatValue,"longitude":self.longitudeFloatValue]
print("self.cordinates",self.cordinates)
print(self.oldCordinates)
print(self.newCordinates)
if(self.oldCordinates["lattitude"] == nil)
{
self.oldCordinates = self.cordinates
self.newCordinates = self.cordinates
}
self.newCordinates = self.cordinates
self.oldCordinates = self.copyCordinates
print("oldCordinates",self.oldCordinates)
print("newCordinates",self.newCordinates)
self.movinfMarker()
}
}, withCancel: nil)
//for use in background
self.locman.requestAlwaysAuthorization()
locman.requestWhenInUseAuthorization()
if (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedWhenInUse || CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedAlways){
guard let currentLocation = locman.location else {
return
}
stringLatitude = currentLocation.coordinate.latitude
stringLongitude = currentLocation.coordinate.longitude
print(currentLocation.coordinate.latitude)
print(currentLocation.coordinate.longitude)
}
// Create a GMSCameraPosition that tells the map to display the marker
let camera = GMSCameraPosition.camera(withLatitude: stringLatitude, longitude: stringLongitude , zoom: 7)
self.mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
self.mapView.isMyLocationEnabled = true
self.mapView.delegate = self
self.view = self.mapView
Database.database().reference().child("users").observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject]
{
self.latitudeFloatValue = (dictionary["lat"] as! Double)
self.longitudeFloatValue = (dictionary["long"] as! Double)
self.titleMarker = (dictionary["username"] as! String)
self.uuidValue = (dictionary["uuid"] as! String)
self.states = [
State(name: self.titleMarker, uuid: self.uuidValue, long: self.longitudeFloatValue, lat: self.latitudeFloatValue),
]
}
for state in self.states {
// Creates a marker in the center of the map.
let state_marker = GMSMarker()
state_marker.position = CLLocationCoordinate2D(latitude: state.lat, longitude: state.long)
state_marker.icon = UIImage(named: "car")
state_marker.title = state.name
state_marker.userData = state.uuid//zIndex = Int32(state.uuid)!
state_marker.snippet = "Hey, this is \(state.name)"
state_marker.map = self.mapView
self.markerDict[state.name] = state_marker
}
}, withCancel: nil)
}
func movinfMarker(){
driverMarker.map = nil
let oldCoodinate: CLLocationCoordinate2D? = CLLocationCoordinate2D(latitude: self.oldCordinates["lattitude"] ?? 0.0 , longitude: self.oldCordinates["longitude"] ?? 0.0)
let newCoodinate: CLLocationCoordinate2D? = CLLocationCoordinate2D(latitude: self.newCordinates["lattitude"] ?? 0.0 , longitude: self.newCordinates["longitude"] ?? 0.0)
print("oldCordinatesNewWala",oldCoodinate as Any)
print("newCordinatesNewWala",newCoodinate as Any)
driverMarker.icon = UIImage(named: "car")
mapView.camera = GMSCameraPosition.camera(withTarget: newCoodinate!, zoom: 17)
driverMarker.groundAnchor = CGPoint(x: CGFloat(0.5), y: CGFloat(0.5))
driverMarker.position = oldCoodinate ?? CLLocationCoordinate2D(latitude: 0.0,longitude: 0.0)
//this can be old position to make car movement to new position
driverMarker.map = mapView
//marker movement animation
CATransaction.begin()
CATransaction.setValue(Int(2.0), forKey: kCATransactionAnimationDuration)
CATransaction.setCompletionBlock({() -> Void in
self.driverMarker.groundAnchor = CGPoint(x: CGFloat(0.5), y: CGFloat(0.5))
//New bearing value from backend after car movement is done
})
driverMarker.position = newCoodinate ?? CLLocationCoordinate2D(latitude: 0.0,longitude: 0.0)
//this can be new position after car moved from old position to new position with animation
driverMarker.map = mapView
driverMarker.groundAnchor = CGPoint(x: CGFloat(0.5), y: CGFloat(0.5))
//found bearing value by calculation
CATransaction.commit()
}

Redraw direction paths in didUpdateLocations

I want to redraw my direction path and move my marker to the current location. I am currently doing this inside didUpdateLocations function but it gets glitchy because it draws multiple markers and path at the same time.
Here is my code:
let location = locations.last
let destination = CLLocation(latitude: order!.user_coord![0], longitude: order!.user_coord![1])
let origin = CLLocation(latitude: (location?.coordinate.latitude)!, longitude: (location?.coordinate.longitude)!)
self.drawPath(startLocation: origin, endLocation: destination)
self.createMarker(titleMarker: order!.store_name!, iconMarker: UIImage(named: "icons8-user_filled")!, latitude: order!.user_coord![0], longitude: order!.user_coord![1])
self.createMarker(titleMarker: "User", iconMarker: UIImage(named: "icons8-mountain_biking")!, latitude: (location?.coordinate.latitude)!, longitude: (location?.coordinate.longitude)!)
let camera = GMSCameraPosition.camera(withLatitude: (location?.coordinate.latitude)!, longitude: (location?.coordinate.longitude)!, zoom: 17.0)
self.map.animate(to: camera)
locationManager.stopUpdatingLocation()
Declare a variable
var drawFinished:Bool!
in viewDidLoad
drawFinished = false
in didUpdate
if(!drawFinished)
{
drawFinished = true
let location = locations.last
let destination = CLLocation(latitude: order!.user_coord![0], longitude: order!.user_coord![1])
let origin = CLLocation(latitude: (location?.coordinate.latitude)!, longitude: (location?.coordinate.longitude)!)
self.drawPath(startLocation: origin, endLocation: destination)
self.createMarker(titleMarker: order!.store_name!, iconMarker: UIImage(named: "icons8-user_filled")!, latitude: order!.user_coord![0], longitude: order!.user_coord![1])
self.createMarker(titleMarker: "User", iconMarker: UIImage(named: "icons8-mountain_biking")!, latitude: (location?.coordinate.latitude)!, longitude: (location?.coordinate.longitude)!)
let camera = GMSCameraPosition.camera(withLatitude: (location?.coordinate.latitude)!, longitude: (location?.coordinate.longitude)!, zoom: 17.0)
self.map.animate(to: camera)
locationManager.stopUpdatingLocation()
}
when you want to update set
drawFinished = false
and clear paths and annotations like this
func clearMapOverlays()
{
for dl in self.myMapView.overlays
{
if(dl is GMSPolyline )
{
self.myMapView.remove(dl)
}
}
self.myMapView.setNeedsDisplay()
for name in self.myMapView.annotations
{
self.myMapView.removeAnnotation(anno)
}
}

Google Maps not zooming to my current location

I have to plot multiple pins in a Google Map view, and then zoom to the user's current location. Pins are plotted successfully but not zoomed to current location. Any help would be appreciated
override func viewDidAppear(_ animated: Bool) {
if (self.googleMapsView == nil) {
self.googleMapsView = GMSMapView(frame: self.mapViewContainer.frame)
self.view.addSubview(self.googleMapsView)
print(AppDelegate.getAppDelegate().mapArray)
googleMapsView.clear()
for i in 0...AppDelegate.getAppDelegate().mapArray.count - 1 {
let lon = Double ((AppDelegate.getAppDelegate().mapArray[i]["lon"] as? String)!)
let lat = Double ((AppDelegate.getAppDelegate().mapArray[i]["lat"] as? String)!)
let tit = AppDelegate.getAppDelegate().mapArray[i]["location"] as? String
locateWithLongitude(lon: lon!,andLatitude: lat! ,andTitle: tit!)
}
let marker = GMSMarker(position: AppDelegate.getAppDelegate().myLocation)
let camera = GMSCameraPosition.camera(withLatitude: AppDelegate.getAppDelegate().myLocation.latitude, longitude: AppDelegate.getAppDelegate().myLocation.longitude, zoom: 11)
self.googleMapsView.camera = camera
marker.title = AppDelegate.getAppDelegate().sublocality
marker.map = self.googleMapsView
self.googleMapsView.animate(to: camera)
}
}
func locateWithLongitude(lon: Double, andLatitude lat: Double, andTitle title: String) {
DispatchQueue.main.async() { () -> Void in
let position = CLLocationCoordinate2DMake(lat, lon)
let marker = GMSMarker(position: position)
let camera = GMSCameraPosition.camera(withLatitude: lat, longitude: lon, zoom: 0)
self.googleMapsView.camera = camera
marker.title = title
marker.map = self.googleMapsView
}
}
Your zoom is set to 0, increase it to 15/16 like bellow.
let camera = GMSCameraPosition.camera(withLatitude: lat, longitude: lon, zoom: 16)

Create multiple markers using Google iOS SDK

I am a newbie in Swift. I was ale to get 2 markers on Google Maps:
import UIKit
import GoogleMaps
class ViewController: UIViewController {
// You don't need to modify the default init(nibName:bundle:) method.
override func loadView() {
let camera = GMSCameraPosition.cameraWithLatitude(37.0902, longitude: -95.7129, zoom: 3.0)
let mapView = GMSMapView.mapWithFrame(CGRect.zero, camera: camera)
mapView.myLocationEnabled = true
view = mapView
let state_marker = GMSMarker()
state_marker.position = CLLocationCoordinate2D(latitude: 61.370716, longitude: -152.404419)
state_marker.title = "Alaska"
state_marker.snippet = "Hey, this is Alaska"
state_marker.map = mapView
let state_marker1 = GMSMarker()
state_marker1.position = CLLocationCoordinate2D(latitude: 32.806671, longitude: -86.791130)
state_marker1.title = "Alabama"
state_marker1.snippet = "Hey, this is Alabama"
state_marker1.map = mapView
}
}
I need to add 51 more markers to different latitude and longitude for each state with different title and snippet.
I can probably just copy this block 51 times but is there a way to optimize this code?
You should create a struct like this:
struct State {
let name: String
let long: CLLocationDegrees
let lat: CLLocationDegrees
}
Then create an array of this struct in your VC:
let states = [
State(name: "Alaska", long: -152.404419, lat: 61.370716),
State(name: "Alabama", long: -86.791130, lat: 32.806671),
// the other 51 states here...
]
Now you can just loop through the array, adding markers in each iteration:
for state in states {
let state_marker = GMSMarker()
state_marker.position = CLLocationCoordinate2D(latitude: state.lat, longitude: state.long)
state_marker.title = state.name
state_marker.snippet = "Hey, this is \(state.name)"
state_marker.map = mapView
}
You might also want to add a dictionary that stores the names of the states as keys and the corresponding GMSMarker as value. This way, you can modify the markers later.
var markerDict: [String: GMSMarker] = [:]
override func loadView() {
for state in states {
let state_marker = GMSMarker()
state_marker.position = CLLocationCoordinate2D(latitude: state.lat, longitude: state.long)
state_marker.title = state.name
state_marker.snippet = "Hey, this is \(state.name)"
state_marker.map = mapView
markerDict[state.name] = state_marker
}
}

Resources