How do you centre the map as user changes location - ios

How do you center the google map as user is moving, like driving? The code I have does not center the user, and the user just goes toward the border and disapper. How do you keep user in center all the time?
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = manager.location {
if (firstLoad) {
firstLoad = false
recentCoordinate = location.coordinate
mapView.camera = GMSCameraPosition(target: location.coordinate, zoom: Constants.MapView.Zoom, bearing: 0, viewingAngle: Constants.MapView.ViewingAngle)
}
else {
// This line of code suppose to center the user as user moves along while keeping the zoom and angle state user has chosen
mapView.camera = GMSCameraPosition(target: location.coordinate, zoom: mapView.camera.zoom, bearing: 0, viewingAngle: mapView.camera.viewingAngle)
}
// Filter out noise. Currently not working
let age = 0 - location.timestamp.timeIntervalSinceNow
if (age > 120) {
return; // ignore old (cached) updates
}
if (location.horizontalAccuracy < 0) {
return; // ignore invalid updates
}
if (location.horizontalAccuracy <= 10){
// this is a valid update
// Draw route as user moves along
path.addCoordinate(CLLocationCoordinate2D(latitude: location.coordinate.latitude,
longitude: location.coordinate.longitude))
let polyline = GMSPolyline(path: path)
polyline.strokeColor = UIColor.redColor()
polyline.strokeWidth = 3
polyline.map = mapView
// Save the coordinates to array
coordinateArray.append([location.coordinate.latitude, location.coordinate.longitude])
}
}

There are couple other ways you can try.
let update = GMSCameraUpdate.setTarget(location.coordinate)
mapView.moveCamera(update)
or
mapView.camera = GMSCameraPosition.camera(target: location.coordinate, zoom: 15.0)
or
let update = GMSCameraUpdate.setTarget(location.coordinate)
mapView.animate(with: update)

If anybody looking for swift 2.3 solution like myself, here is the solution :
mapView.animateToLocation(CLLocationCoordinate2D(latitude: location.coordinate.latitude,longitude: location.coordinate.longitude))

Related

How to check if a marker is outside geofence region

I was wondering if was possible to check if a marker is outside of the region.
I can check if the user left the region, but I want to also check if any marker on the map to the same thing as well, I want to check the geofence region between to markers.
func setUpGeofence() {
let geofenceRegionCenter = CLLocationCoordinate2DMake(getLatitude(),getLongitude());
let geofenceRegion = CLCircularRegion(center: geofenceRegionCenter, radius: 400, identifier: "Geofence");
geofenceRegion.notifyOnExit = true;
geofenceRegion.notifyOnEntry = true;
self.locationManager.startMonitoring(for: geofenceRegion)
}
}
You can use CLLocation.distance(from:) to calculate each marker's distance from your geofence center.
let center = CLLocation(latitude: getLatitude(), longitude: getLongitude())
for marker in markers {
if marker.location.distance(from: center) > radius {
// outside
} else {
// inside
}
}

Ios Google maps keep current location course(angle) always north like google Navigation

I'm using google maps to track
func ShowcurrentMarker()
{
currentlocationCoordinate = CLLocationCoordinate2DMake(LatestLocation.coordinate.latitude, LatestLocation.coordinate.longitude)
if(CurrentLocationMarker == nil)
{
CurrentLocationMarker = GMSMarker(position:currentlocationCoordinate)
CurrentLocationMarker.map = self.mapView
CurrentLocationMarker.icon = UIImage.init(named:"car_icon")
mapView.camera = GMSCameraPosition.camera(withTarget: CLLocationCoordinate2DMake(LatestLocation.coordinate.latitude, LatestLocation.coordinate.longitude), zoom: 15.0)
}
else
{
CATransaction.begin()
CATransaction.setAnimationDuration(2)
CurrentLocationMarker.position = currentlocationCoordinate
CurrentLocationMarker.rotation = CLLocationDirection.abs(LatestLocation.course)
mapView.camera = GMSCameraPosition.camera(withTarget: CLLocationCoordinate2DMake(LatestLocation.coordinate.latitude, LatestLocation.coordinate.longitude), zoom:mapView.camera.zoom)
CATransaction.commit()
}
}
Here is my working code. Now I want my car always to keep on north facing like navigation app.
How can I do that ?

Google Maps zoom out to GPS and markers

I am trying to show three things on map :
GPS (the current location) , Marker 1 , Marker 2, but I am not sure I am doing it right or not ! Here is my code :
self.startMarker.position = CLLocationCoordinate2D(latitude: self.startLatitude, longitude: self.startLongitude)
self.startMarker.icon = #imageLiteral(resourceName: "Pin Start")
self.startMarker.map = self.mapView
self.endMarker.position = CLLocationCoordinate2D(latitude: self.endLatitude, longitude: self.endLongitude)
self.endMarker.icon = #imageLiteral(resourceName: "Pin End")
self.endMarker.map = self.mapView
let southWest = CLLocationCoordinate2DMake(self.startLatitude,self.startLongitude)
let northEast = CLLocationCoordinate2DMake(self.endLatitude,self.endLongitude)
let bounds = GMSCoordinateBounds(coordinate: northEast, coordinate: southWest)
let camera = self.mapView.camera(for: bounds, insets:.zero)
self.mapView.camera = camera!
More Code :
// MARK: - Google Map
private func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
if status == CLAuthorizationStatus.authorizedWhenInUse {
mapView.isMyLocationEnabled = true
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let newLocation = locations.last
mapView.camera = GMSCameraPosition.camera(withTarget: newLocation!.coordinate, zoom: 14)
mapView.isMyLocationEnabled = true
}
The result is like this :
What I need :
EDITED
if let myLocation = self.mapView.myLocation {
let path = GMSMutablePath()
path.add(myLocation.coordinate)
path.add(self.startMarker.position)
path.add(self.endMarker.position)
let bounds = GMSCoordinateBounds(path: path)
self.mapView.animate(with: GMSCameraUpdate.fit(bounds, withPadding: 40))
}
Showing All Markers with screen bound:
Here I am trying to provide you one simple example, hope this will help you.
Using this, you can show any number of markers on screen.
Example:
let path = GMSMutablePath()
for var i in 0 ..< array.count //Here take your "array" which contains lat and long.
{
let marker = GMSMarker()
let lat = Double(array.objectAtIndex(i).valueForKey(lattitude) as! String)
let long = Double(arrayr.objectAtIndex(i).valueForKey(longitude) as! String)
marker.position = CLLocationCoordinate2DMake(lat!,long!)
path.addCoordinate(marker.position)
marker.map = self.mapView
}
let bounds = GMSCoordinateBounds(path: path)
self.mapView!.animateWithCameraUpdate(GMSCameraUpdate.fitBounds(bounds, withPadding: 30.0))
Can you try the below code, this is converted from ObjC code here is the documentation of includingCoordinate
let bounds = GMSCoordinateBounds()
bounds.includingCoordinate(self.startMarker.position)
bounds.includingCoordinate(self.endMarker.position)
bounds.includingCoordinate(yourCurrentLocationPosition)
self.mapView.animateWithCameraUpdate(GMSCameraUpdate(fitBounds:bounds, padding:20.0f))
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
showMarkers(locations)
//stop updating location when you find suitable
}
func showMarkers(userLocation: [CLLocation]){
let location1: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: self.startLatitude, longitude: self.startLongitude)
let location2: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: self.endLatitude, longitude: self.endLongitude)
let location3: CLLocationCoordinate2D = userLocation[0].coordinate
var locationArray = []
locationArray.append(location1)
locationArray.append(location2)
locationArray.append(location3)
var bounds = GMSCoordinateBounds()
for location in locationArray
{
let latitude = location.valueForKey("latitude")
let longitude = location.valueForKey("longitude")
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
marker.map = self.mapView
bounds = bounds.includingCoordinate(marker.position)
}
let update = GMSCameraUpdate.fitBounds(bounds, withPadding: 100)
mapView.animateWithCameraUpdate(update)
}
Note:
locationArray contains three locations ie. Marker 1, Marker 2, user location.
For someone who is looking for solution with Objective-C, This might help
//Locations
CLLocationCoordinate2D source = CLLocationCoordinate2DMake(19.2880, 72.1587);
CLLocationCoordinate2D userLocation = CLLocationCoordinate2DMake(19.1780, 72.9577);
CLLocationCoordinate2D destination = CLLocationCoordinate2DMake(19.0760, 72.8777);
//Create a GMSMutablePath
GMSMutablePath *path = [GMSMutablePath new];
[path addCoordinate:source];
[path addCoordinate:userLocation];
[path addCoordinate:destination];
//Create bounds
GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc]initWithPath:path];
//Update the camera position
[mapview animateWithCameraUpdate:[GMSCameraUpdate fitBounds:bounds]];

Drawing a clean polyline on the map

I'm working on iOS app that draw polyline on the map to highlight the route user has taken. I can draw the poly line with no problem. But, the line is not a clean line that you see on Googlemap. It's a bit squiggly like handdrawn as you can see in the pic. Apology for big images as I don't know how to resize them in SO.
How can I acheive the result like this one in the picture :
This is my code that is responsible for drawing poly line :
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = manager.location {
if (firstLoad) {
firstLoad = false
recentCoordinate = location.coordinate
mapView.camera = GMSCameraPosition(target: location.coordinate, zoom: Constants.MapView.Zoom, bearing: 0, viewingAngle: Constants.MapView.ViewingAngle)
}
else {
mapView.animateToLocation(CLLocationCoordinate2D(latitude: location.coordinate.latitude,longitude: location.coordinate.longitude))
}
// this is suppose to filter out noise. I don't think it's working
let age = 0 - location.timestamp.timeIntervalSinceNow
if (age > 120) {
return; // ignore old (cached) updates
}
if (location.horizontalAccuracy < 0) {
return; // ignore invalid updates
}
if (location.horizontalAccuracy <= 10){
// this is a valid update
// Draw route as user moves along
path.addCoordinate(CLLocationCoordinate2D(latitude: location.coordinate.latitude,
longitude: location.coordinate.longitude))
let polyline = GMSPolyline(path: path)
polyline.strokeColor = UIColor.redColor()
polyline.strokeWidth = 3
polyline.map = mapView
// Save the coordinates to array
coordinateArray.append([location.coordinate.latitude, location.coordinate.longitude])
}
}
}

Swift CLLocationDistance error

I am building a learning app where i want to create pins and show the distance between current location and the pin but i get a really weird output
func createPin(){
var coord = CLLocationCoordinate2D(latitude: 51.50, longitude: -0.13)
var coord2 = CLLocation(latitude: coord.latitude, longitude: coord.longitude)
var kilometers:CLLocationDistance = coord2.distanceFromLocation(locNow)
var str = NSString(format: "%.2f", kilometers)
let pin = Annotation(coordinate: coord, title: "LocationAlfa", subtitle: "distance : \(str)" + " meters", dist: kilometers)
map.addAnnotation(pin)
println("\(kilometers)")
}
this is my create pin method and here i get my location distance
func locationManager(manager: CLLocationManager!, didUpdateToLocation newLocation: CLLocation!, fromLocation oldLocation: CLLocation!){
let location = newLocation
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
var region: () = centerMapOnLocation(location)
// self.map.setRegion(region, animated: true)
println("Latitude = \(newLocation.coordinate.latitude)")
println("Longitude = \(newLocation.coordinate.longitude)")
locNow = newLocation
}
and this is the shown distance in meters on the map : 5718215.17 (when the pin is made next to the pointed location on the map as the device location)

Resources