I am working on app the like Ola cabs. When the user drags map the a view transparent view appears with marker moving and when the user stops dragging the we have to centre
Use delegates of GMSMapView
- (void) mapView:(GMSMapView *)mapView didDragMarker:(GMSMarker *)marker;
- (void) mapView:(GMSMapView *)mapView didBeginDraggingMarker:(GMSMarker *)marker;
- (void) mapView:(GMSMapView *)mapView didEndDraggingMarker:(GMSMarker *)marker;
I have achieved this kind of things in two apps which are related with live tracking of vahicle.
There are some requirements that I have used:
Most important thing is that Driver latitude and longitude should with correct for showing car movement on the map. gmsMarker location consider as old value and newLocation value is current location.
let preLoc = CLLocation.init(latitude: self.gmsMarker.position.latitude, longitude: self.gmsMarker.position.longitude)
let curLoc = CLLocation.init(latitude: newLocation.latitude, longitude: newLocation.longitude)
let changeInLocation = preLoc.distance(from: curLoc)
if changeInLocation > 5{
let degree = self.DegreeBearing(preLoc, curLoc)
if degree > 5{
self.gmsMarker.rotation = degree
}
}
Below four function will calculate your travel direction and based on that car will show correct on road with moving.
func DegreeBearing(_ A:CLLocation,_ B:CLLocation)-> Double{
var dlon = self.ToRad(degrees: B.coordinate.longitude - A.coordinate.longitude)
let dPhi = log(tan(self.ToRad(degrees: B.coordinate.latitude) / 2 + M_PI / 4) / tan(self.ToRad(degrees: A.coordinate.latitude) / 2 + M_PI / 4))
if abs(dlon) > M_PI{
dlon = (dlon > 0) ? (dlon - 2*M_PI) : (2*M_PI + dlon)
}
return self.ToBearing(radians: atan2(dlon, dPhi))
}
func ToRad(degrees:Double) -> Double{
return degrees*(M_PI/180)
}
func ToBearing(radians:Double)-> Double{
return (ToDegrees(radians: radians) + 360).truncatingRemainder(dividingBy: 360)
}
func ToDegrees(radians:Double)->Double{
return radians * 180 / M_PI
}
For Customer side, just show marker with whatever data you received from Driver side as self.gmsMarker.rotation
value.
@interface ViewController () <CLLocationManagerDelegate, GMSMapViewDelegate> {
GMSMarker *marker2;
}
In viewDidLoad
marker2 = [[GMSMarker alloc] init];
// Create a GMSCameraPosition that tells the map to display the
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:latitude
longitude:longitude
zoom:18];
// Create GMSMapView
GMSMapView *mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
// Available map types: kGMSTypeNormal, kGMSTypeSatellite, kGMSTypeHybrid,
// kGMSTypeTerrain, kGMSTypeNone
// Set the mapType to Satellite
mapView.mapType = kGMSTypeSatellite;
mapView.myLocationEnabled = YES;
self.view = mapView;
// Creates a marker in the center of the map.
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(latitude, longitude);
marker.map = mapView;
mapView.delegate = self;
After that call delegate functions
- (void)mapView:(GMSMapView *)mapView willMove:(BOOL)gesture {
// NSLog(@"willMove");
}
- (void) mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position {
// NSLog(@"didChangeCameraPosition");
// Creates a marker in the center of the map.
// NSLog(@"%@", position);
marker2.position = CLLocationCoordinate2DMake(mapView.camera.target.latitude, mapView.camera.target.longitude);
marker2.map = mapView;
// marker2.draggable = YES;
marker2.icon = [GMSMarker markerImageWithColor:[UIColor blueColor]];
}