I want to move added annotation to newlocation, below is the code and in else part i want to do that :
In previous code, new annotation is added and previous annotation is removed, but its get affected in degree of direction. So, i want to move annotation with out adding new annotation.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
if (newLocation.horizontalAccuracy < 0)
return;
if (!newLocation)
return;
static BOOL annotationAdded = NO;
self.currentLocation = newLocation;
self.previousLocation = oldLocation;
if(self.currentLocation != nil)
{
CLLocationCoordinate2D location = CLLocationCoordinate2DMake(self.currentLocation.coordinate.latitude, self.currentLocation.coordinate.longitude);
myAnnotation = [[MyAnnotation alloc] initWithCoordinates:location title:#"Current Location" subTitle:nil];
if (!annotationAdded)
{
annotationAdded = YES;
[self.myMapView addAnnotation:myAnnotation];
}
else
{
// Here i want to move added annotation to newlocation coordinates
}
}
}
The way it works, is that you feed the map with annotations and then it fires the function that plot the annotations on the screen. Once it's on the screen, that is no way basically to move the annotation but to delete it and add a new one with new coordinates.
Related
I am working on a navigation app that will give turn by turn navigation.
I am using google directions API to plot best route between points. Apart from source and destination user can add up to 8 waypoints. I have stored all the coordinates in an array and in didUpdateLocations method i am checking the distance between current location and coordinates stored in array. If the distance is less than 5 meters then the user is going in the right direction
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation *myLocation = [locations lastObject];
BOOL goingWrongWay = YES;
//Searching Current Location in Coordinates Array
for(int i=0;i<self.decodedArray.count;i++)
{
CLLocation *tempLoc = [self.decodedArray objectAtIndex:i];
//NSLog(#"distance=%f", [myLocation distanceFromLocation:tempLoc]);
if([myLocation distanceFromLocation:tempLoc]<=5)
{
goingWrongWay = NO;
break;
}
}
if(goingWrongWay)
self.title = #"Wrong Way";
else
self.title = #"On Track";
NSLog(#"YES");
if(isShowingRoute)
{
NSLog(#"YES");
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:myLocation.coordinate.latitude
longitude:myLocation.coordinate.longitude
zoom:19.0];
[mapView animateToCameraPosition:camera];
}
}
Is there any other way to detect whether the user is going in the right direction or not as i have to Re-route user. BTW i am using google maps SDK for ios
I am developing an iPhone Application in which i have provide Pin Annotation button on tool bar. When user click on button then pin will drop on center of map view. Now i want that user move that pin and place at their desired place and i will get latitude and longitude of that point. So how i define all these event with my map view? How do that? I get this code for add annotation.
- (void)addPinAnnotation:(id)sender {
UICRouteAnnotation *pinAnnotation = [[[UICRouteAnnotation alloc] initWithCoordinate:[routeMapView centerCoordinate]
title:nil
annotationType:UICRouteAnnotationTypeWayPoint] autorelease];
[routeMapView addAnnotation:pinAnnotation];
}
How get latitude and longitude of that point?
Thanks in advance....
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
// Add annotation to map
MKCoordinateRegion reg;
CLLocationCoordinate2D location = newLocation.coordinate ;
reg.center = location;
MKCoordinateSpan span;
span.latitudeDelta = 1.5;
span.longitudeDelta = 1.5;
reg.span = span;
reg.center=newLocation.coordinate;
[self.mapView setRegion:reg animated:TRUE];
annotation = [[myAnnotation alloc] initWithCoordinate:newLocation.coordinate title:#"Click > to set or drag to move"];
[self.mapView addAnnotation:annotation];
[self.mapView selectAnnotation:annotation animated:YES];
[manager stopUpdatingLocation];
[loading stopAnimating];
}
I am attempting to set a map annotation to the user's current location. I am trying to set the pin in the viewDidLoad method, however because the method
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
Has not been called yet, the lat and long are 0.000000. Is there a way to call this method in my viewDidLoad or any other solution that will make a pin appear at my beginning location when the application loads?
UPDATE, Added Annotation Code
CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = (_currentLocation.latitude);
theCoordinate.longitude = (_currentLocation.longitude);
NSLog(#"The Coordinate Value:");
NSLog(#"%f, %f",theCoordinate.latitude,theCoordinate.longitude);
DDAnnotation *annotation = [[[DDAnnotation alloc] initWithCoordinate:theCoordinate addressDictionary:nil] autorelease];
annotation.title = #"Drag to Move Pin";
annotation.subtitle = [NSString stringWithFormat:#"%f %f", annotation.coordinate.latitude, annotation.coordinate.longitude];
[self.mapView addAnnotation:annotation];
UPDATE 2
Still not working, code is in the didUpdateLocation Method
static BOOL annotationAdded = NO;
if (!annotationAdded) {
annotationAdded = YES;
CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = _currentLocation.latitude;
theCoordinate.longitude = _currentLocation.longitude;
//Sets Initial Point to Africa Because Method to obtain current Location
//Hasen't Fired when View Loads
theCoordinate.latitude = (mapView.userLocation.coordinate.latitude);
theCoordinate.longitude = (mapView.userLocation.coordinate.longitude);
NSLog(#"The Coordinate Value:");
NSLog(#"%f, %f",theCoordinate.latitude,theCoordinate.longitude);
DDAnnotation *annotation = [[[DDAnnotation alloc] initWithCoordinate:theCoordinate addressDictionary:nil] autorelease];
annotation.title = #"Drag to Move Pin";
annotation.subtitle = [NSString stringWithFormat:#"%f %f", annotation.coordinate.latitude, annotation.coordinate.longitude];
[self.mapView addAnnotation:annotation];
}
MKMapView automatically places an annotation of class MKUserLocation when you set mapView.showsUserLocation = YES.
You can replace the default view for this annotation to whatever default annotation view you want by doing this in mapView:viewForAnnotation::
- (MKAnnotationView *) mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation {
if ([annotation isKindOfClass:[MKUserLocation class]]) {
// replace the following with code to generate and return custom user position annotation view
return customAnnotationView;
}
//*** other code ***//
}
Update:
If all you want to do is set a pin initially (once) at the user's location when the view loads, then you will have to wait until the phone can grab the data you need since that takes some time. Add your annotation in mapView:didUpdateUserLocation the first time it is called, and that should do the trick:
- (void) mapView:(MKMapView *)theMapView didUpdateUserLocation:(MKUserLocation *)userLocation {
static BOOL annotationAdded = NO;
if (!annotationAdded) {
annotationAdded = YES;
//*** add annotation to mapView ***//
}
}
Final Comment:
I would generally avoid setting a static pin at a users location the first time this method is called, however, and instead opt to just using the default standard blue dot. That is because the location services in the phone take time to find an accurate reading on the user's location, but in the interest of time it will send you location updates as soon as possible. This means that the first location update may not be very accurate, but subsequent updates may be much more accurate. That is why the standard blue dot sometimes changes position frequently within the first few moments of showing up on the map.
Just a caveat. Obviously what you choose to do depends on what the purpose of your app is.
I've never found a way to manually call that method. I believe it's a delegate method that's completely passive. Sorry.
It takes some time for the device to determine the location -- you can't speed up the process by calling -locationManager:didUpdateToLocation: yourself. You'll need to either use #Matt's suggestion to let the map draw the user's location, or else wait for -...didUpdateToLocation: to be called and take action then.
I have an application where I have to check that whether user's mobile location has changed or for 30 consecutive seconds or not?If it has not changed in 30 seconds then user will be navigated to the other view and if it has changed then user will have a message that your mobile location's coordinates have changed in these 30 seconds.
I am using these code but it does nothing ...
-(void)time
{
for(int i = 0; i<= timeremaining ;i++)
{
if (new1 == old)
{
if(timeremaining == 1)
{
Timer90 *timerview = [[Timer90 alloc] initWithNibName:#"Timer90" bundle:nil];
[self.navigationController pushViewController:timerview animated:YES];
}
}
else
{
[NSTimer cancelPreviousPerformRequestsWithTarget:self selector:#selector(time) object:nil];
}
timeleft.text = [NSString stringWithFormat:#"%d",timeremaining];
}
timeremaining--;
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
new1 = newLocation;
old=oldLocation;
latitude = [[NSString alloc]initWithFormat:#"%g",newLocation.coordinate.latitude];
longitude = [[NSString alloc]initWithFormat:#"%g",newLocation.coordinate.longitude];
accuracy = [[NSString alloc] initWithFormat:#"%g",newLocation.horizontalAccuracy];
if(oldLocation == NULL)
{
oldLocation == newLocation;
}
}
here timer90 is name of my view.Please help me out friends...Any help will be appreciated.
You could possibly do something like this (after adding counter and initialLocation to your properties) it will compare location after 30 seconds following the first update, but I think it would be helpful if you added an age check to the entire method so that you aren't comparing to some very old data point.
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
if(self.counter==0){
self.intialLocation=newLocation;
self.counter=1;
}
NSTimeInterval age = [initialLocation.timestamp timeIntervalSinceNow];
if(age>30)
{
self.counter=0;
if(newLocation.latitude==initialLocation.latitude&&newLocation.longitude==initialLocation.longitude){
Timer90 *timerview = [[Timer90 alloc] initWithNibName:#"Timer90" bundle:nil];
[self.navigationController pushViewController:timerview animated:YES];
}
}
}
Two things that I notice. May be the whole issue, or only part of it.
Number 1.
if(oldLocation == NULL)
{
oldLocation == newLocation;
}
oldLocation == newLocation will not set the two equal to each other (you need one equals sign) and your are assigning the parameter pointers to the same object, not your member pointers. For example, if oldLocation points to Object A and newLocation points to Object B at the start of didUpdateToLocation:fromLocation:, then:
new1 is set to point at Object B
old is set to point at Object A
if(Object A is NULL)
oldLocation and newLocation both point at Object B
The values of new1 and old are not set to the same object in the NULL case. Which is what you are checking for in time
Number 2.
In time you are checking if new1 and old are pointing at the same object. No necessarily if the two objects represent the same location. In the case where oldLocation is null and they are set together, this check may pass...however, it is more likely that CoreLocation will call the update method a few times while accuracy gets better, and you will have two separate objects that represent the same lat/long location.
You should compare these two locations for proximity using the CLLocation getDistanceFromLocation: method.
Hope that Helps!
I need to track user current location with realtime refreshrate
I have one function with two solutions for that.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
# ifdef Variant_1
if(m_currentLocation)
[m_Map removeAnnotation:m_currentLocation];
else
m_currentLocation = [MKPlacemark alloc];
[m_currentLocation initWithCoordinate:newLocation.coordinate addressDictionary:nil];
[m_Map addAnnotation:m_currentLocation];
[m_Map setCenterCoordinate:m_currentLocation.coordinate animated:YES];
# else //Variant_2
if(m_currentLocation == nil)
{
m_currentLocation = [MKPlacemark alloc];
[m_currentLocation initWithCoordinate:newLocation.coordinate addressDictionary:nil];
[m_Map addAnnotation:m_currentLocation];
}else
{
[m_currentLocation initWithCoordinate:newLocation.coordinate addressDictionary:nil];
//[m_currentLocation setCoordinate:newLocation.coordinate];
}
[m_Map setCenterCoordinate:m_currentLocation.coordinate animated:YES];
# endif
}
Variant_1 works good but when you move fast the location sing on the map blinks.
Variant_2 does not blink but does not move location sing however moves map.
Where is the problem?
In Variant_1, it probably blinks because you're doing a removeAnnotation and then an addAnnotation instead of just modifying the coordinates of the existing annotation.
In Variant_2, initWithCoordinate returns a new MKPlacemark object with those coordinates. It doesn't update the properties of the object you are calling the method on.
What happens if you run the setCoordinate line instead?
A separate question is why not use the MKMapView's built-in ability to show the current user location? Just do m_Map.showsUserLocation = YES; at the start. You don't need CLLocationManager to get the user's current location if you are using the MKMapView anyway.
I think you'll still need to center the map on the user's current location using one of the map view delegate methods:
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
[mapView setCenterCoordinate:userLocation.location.coordinate animated:YES];
}