i have a map and i want to set the user location ( blue dot ) when i open it.i tried lot of things and didn't work.please help me
MKCoordinateRegion region;
region.center.latitude=BG_LATITUDE;
region.center.longitude=BG_LONGITUDE;
region.span.latitudeDelta=SPAN_VALUE;
region.span.longitudeDelta=SPAN_VALUE;
[self.mapView setRegion:region animated:YES];
NSMutableArray *annotations =[[NSMutableArray alloc]init];
//coordinate (for the annotation)
CLLocationCoordinate2D location;
mapAnnotation *ann;
location.latitude=MaB_LATITUDE;
location.longitude=MaB_LONGITUDE;
//annotation
ann = [[mapAnnotation alloc]init];
[ann setCoordinate:location];
ann.title=#"Main Branch";
[annotations addObject:ann];
you dont need to write so much lines of code to show the blue dot , MKMapView itself contains a property called "showUserLocation" which has to be set as true in order to show blue dot on to the Map .
self.mapView.showsUserLocation = TRUE;
It also automatically tracks the Device's Location . Hope it will help you .
Use this if you want show user location on map
self.mapView.showsUserLocation = YES;
Related
I am trying to Shown the marker and it's info window together in ios when I tapped on map but didn't work for me here is my sample of code
- (void) mapView: (GMSMapView *) mapView
didTapAtCoordinate: (CLLocationCoordinate2D) coordinate{
CLLocation *destination_lat_long = [[CLLocation alloc]initWithLatitude:coordinate.latitude longitude:coordinate.longitude];
GMSMarker *marker_test = [[GMSMarker alloc] init];
marker_test.position = coordinate;
marker_test.title = #"Location selected";
marker_test.snippet = #"Testing";
marker_test.map = self.MyMapView;
//Show info window on map
[self.MyMapView setSelectedMarker:marker];
}
I don't understand why it's not working?
I want to populate the info window on marker set.
Related to comments:
Sure you can but I think without making custom Markers and InfoWindows it is only possible for one marker:
GMSMarkerOptions *myLocationOptions = [GMSMarkerOptions options];
myLocationOptions.title = #"Your title goes here";
myLocationOptions.snippet = #"Snippet goes here";
self.MapView.selectedMarker = [self.MapView addMarkerWithOptions: locationOptions];
But if you want to show more markers with their infoWindows you'll have to make a custom solution.
I'm implementing search in my MKMapView and I've faced two problems:
When I perform search, location appears in the result and map moves to the found location only after I start to move to the destination. This happens, when the search results are out of the view bounds. If they are inside of the map view bounds or near them it's fine.
It "hops" all the time from one search result to another or to the user's location. I don't expect such behaviour from it.
I've tried several things and I suppose, that the problem is in: didAddAnnotationViews:
[self.locationManager stopUpdatingLocation];
MKAnnotationView *annotationView = [views objectAtIndex:0];
NSLog(#"_Here_ %#", [views description]);
id<MKAnnotation> mp = [annotationView annotation];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance([mp coordinate], 250, 250);
[mv setRegion:region animated:YES];
[self.mapView selectAnnotation:mp animated:YES];
Though, I also thought that the problem is in didUpdateToLocation, so I disable updating after the first pin is drop (by search or by tap):
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
double miles = 0.3;
double scalingFactor =
ABS( cos(2 * M_PI * newLocation.coordinate.latitude /360.0) );
MKCoordinateSpan span;
span.latitudeDelta = miles/69.0;
span.longitudeDelta = miles/( scalingFactor*69.0 );
MKCoordinateRegion region;
region.span = span;
region.center = newLocation.coordinate;
[self.mapView setRegion:region animated:YES];
self.mapView.showsUserLocation = YES;
}
Finally, search method:
-(void)searchBarSearchButtonClicked:(UISearchBar *)theSearchBar
{
MKLocalSearchRequest *searchRequest = [[MKLocalSearchRequest alloc] init];
[searchRequest setNaturalLanguageQuery:theSearchBar.text];
searchRequest.region = MKCoordinateRegionMakeWithDistance(self.mapView.userLocation.coordinate, 1000, 1000);
MKLocalSearch *localSearch = [[MKLocalSearch alloc] initWithRequest:searchRequest];
[localSearch startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {
if (!error) {
NSMutableArray *annotations = [NSMutableArray array];
[response.mapItems enumerateObjectsUsingBlock:^(MKMapItem *item, NSUInteger idx, BOOL *stop) {
for (id<MKAnnotation>annotation in self.mapView.annotations)
{
if (annotation.coordinate.latitude == item.placemark.coordinate.latitude &&
annotation.coordinate.longitude == item.placemark.coordinate.longitude)
{
return;
}
}
MKPointAnnotation *addAnnotation = [[MKPointAnnotation alloc] init];
addAnnotation.title = [item.placemark.addressDictionary objectForKey:#"Street"];
addAnnotation.coordinate = item.placemark.coordinate;
[annotations addObject:addAnnotation];
}];
for (id<MKAnnotation>annotation in self.mapView.annotations) {
[self.mapView removeAnnotation:annotation];
}
[self.mapView addAnnotations:annotations];
} else {
NSLog(#"Search Request Error: %#", [error localizedDescription]);
}
}];
//Hide the keyboard.
[self.searchBar resignFirstResponder];
}
My aim is to create a MapView, where user can pin the location by tap or via search and, obviously, see the search result.
For the first problem:
When I perform search, location appears in the result and map moves to
the found location only after I start to move to the destination. This
happens, when the search results are out of the view bounds. If they
are inside of the map view bounds or near them it's fine.
This happens because you are moving the map to the annotations found (at least the first one) in the didAddAnnotationViews delegate method.
But that delegate method is only called when an annotation is in the visible area. If an annotation is added to the map but it's not in the visible area (yet), viewForAnnotation won't get called and therefore didAddAnnotationViews won't get called.
Then, when you manually move the map, the annotations that were added start coming into the visible area and then the delegate method gets called and suddenly the map jumps to one of those annotations.
Don't call setRegion inside the didAddAnnotationViews delegate method.
Sometimes, doing so can also cause an endless cycle of viewForAnnotation and didAddAnnotationViews calls because when the region is changed, it causes other annotations to come into view that weren't previously, so viewForAnnotation gets called and then didAddAnnotationViews gets called, and so on.
Instead, set the region right after you call addAnnotations: (or better, just call showAnnotations:) in the searchBarSearchButtonClicked: method.
I would also remove the call to stopUpdatingLocation from didAddAnnotationViews. You probably don't even need the location manager at all if you set the map's showsUserLocation to YES.
For the second problem:
It "hops" all the time from one search result to another or to the
user's location. I don't expect such behaviour from it.
This is also partly due to calling setRegion in didAddAnnotationViews but also because setRegion is called in didUpdateToLocation.
So for the reason described for the first problem, the two delegate methods and the user's manual movements are fighting with each other and the map ends up hopping around.
Don't call setRegion in the didUpdateToLocation method (or, call it once by keeping track in a BOOL whether you've already zoomed to the user location or not).
Not affecting the behavior, but setting showsUserLocation to YES in the didUpdateToLocation doesn't make sense. Why not set this in viewDidLoad or turn it on in the storyboard/xib?
Also, there's no need to calculate the region span manually like that (it's better to let the MapKit do that work for you). Just convert the miles to meters and call MKCoordinateRegionMakeWithDistance.
Im trying to load annotation point into mapview in which i have the seperate array for latitude and a seperate array for longitude here is my code
- (void)viewDidLoad
{
[super viewDidLoad];
delegate=[[UIApplication sharedApplication]delegate];
delegate.arrForLat=[[NSMutablearray alloc]initwithobjects:#"33.930216",#"33.939788",#"33.9272",#"33.902237"];
delegate.arrForLon=[[NSMutablearray alloc]initwithobjects:#"-118.050392",#"-118.076549",#"-118.065817",#"-118.081733"];
for (int i=0 ; i< delegate.arrForLat.count;i++)
{
annotationCoord.latitude = [[delegate.arrForLat objectAtIndex:i] doubleValue];
annotationCoord.longitude = [[delegate.arrForLng objectAtIndex:i] doubleValue];
MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init];
annotationPoint.coordinate = annotationCoord;
[MapView addAnnotation:annotationPoint];
}
}
Now i get only 1 annotation point in mapview but i have 4 coordinates.I don't know what mistake i have done.
Ah, I think I see it. You only have one annotationCoord. On the first trip through the loop you set its lat and long to (33.930216,-118.050392) and create a new object called annotationPoint point its coordinate attribute to your annotationCoord. Then on the next time through the loop you edit annotationCoord by giving it new coordinates. But it's still the same annotationCoord and the annotation you added to the map is still using it, now with the new coordinates.
So the solution is to make a new CLLocationCoordinate2D each time through the loop.
When a user selects a menu option I currently have the location name sent to my map view via "stringToDisplay" and a pin drops on the map as expected, however, it does not center the pin or zoom on the location on the first attempt. Every attempt after the first is flawless. How can I make the map zoom to my location(s) on the first attempt? Your input is greatly appreciated.
I have multiple IF statements contained in my viewWillAppear, but see below for one example of a location which experiences this problem:
-(void)viewWillAppear:(BOOL)animated
{
CLLocationCoordinate2D location;
NSLog(#"self.stringToDisplay = %#", self.stringToDisplay);
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=0.1;
span.longitudeDelta=0.1;
region.span=span;
region.center=location;
[mapView setRegion:region animated:TRUE];
[mapView regionThatFits:region];
if ([self.stringToDisplay isEqualToString: #"August First Bakery & Café"])
{
location.latitude = (double) 44.475486;
location.longitude = (double) -73.2172641;
MapViewAnnotation *newAnnotation = [[MapViewAnnotation alloc] initWithTitle:#"August First Bakery & Café" andCoordinate:location];
[self.mapView addAnnotation:newAnnotation];
[mapView setCenterCoordinate:location animated:YES];
}
}
Set a breakpoint in the viewWillAppear. Check to see if mapView is nil when you're doing the setRegion/regionThatFits. If it is you may need to move the code to viewDidAppear. - compliments of Phlibbo
I have a tab on the RootViewController.m. The tab has 2 buttons. The first button upon click will go to CorpViewcontroller which has the mapView on it. When I click on the first button on the first try, the map is blank with google label on the bottom. I have to click back then click on the button again then the map show up. Is it possible to always show the map on the first button click?
My rootViewController.m to go to the second screen:
[self.navigationController pushViewController:self.corpController animated:YES];
The second screen called corpViewController has the following code:
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Set Remote Location";
self.jsonData = [[NSMutableData alloc] init];
mapView.showsUserLocation = YES;
//Setup the double tap gesture for getting the remote location..
UITapGestureRecognizer *tgr = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleGesture:)];
tgr.numberOfTapsRequired = 2;
tgr.numberOfTouchesRequired = 1;
[mapView addGestureRecognizer:tgr];
mapView.delegate = self;
NSLog(#"viewDidLoad done");
}
- (void)viewWillAppear:(BOOL)animated {
NSLog(#"viewWillAppear");
appDelegate = (NBSAppDelegate *)[[UIApplication sharedApplication] delegate];
double curLat = [appDelegate.curLat doubleValue];
MKUserLocation *userLocation = mapView.userLocation;
double miles = 10.0;
double scalingFactor = ABS( (cos(2 * M_PI * curLat / 360.0) ));
MKCoordinateSpan span;
span.latitudeDelta = miles/69.0;
span.longitudeDelta = miles/(scalingFactor * 69.0);
MKCoordinateRegion region2;
region2.span = span;
region2.center = userLocation.coordinate;
[mapView setRegion:region2 animated:YES];
NSLog(#"viewWillAppear done..");
}
Please Advise.
Thank you
Are you initializing the MapView in the viewDidLoad method in your view controller?
If so, try moving it to the viewDidAppear method. That worked for me.
In viewDidLoad you are setting showsUserLocation to YES and in viewWillAppear, you are zooming into the mapView.userLocation coordinate.
The userLocation property isn't usually ready with a valid coordinate immediately after setting showsUserLocation to YES.
The first time you show the view controller, it's still invalid and you are zooming into the coordinate 0,0.
By the time you show the view controller a second time, the user location has been obtained and the coordinate is valid.
Instead of zooming into the user location in viewWillAppear, do it in the delegate method mapView:didUpdateUserLocation: which the map view calls when it gets a user location update.
In addition, you also probably want to move the mapView.showsUserLocation = YES; to viewWillAppear and in viewWillDisappear, set it to NO. This way, the map view will zoom in to the user location every time the view controller is shown instead of just the first time.
An unrelated point is that to zoom in to a specific distance, it's much easier to use the MKCoordinateRegionMakeWithDistance function instead of trying to convert miles to degrees yourself.
Here's an example of the changes suggested in corpViewController:
- (void)viewWillAppear:(BOOL)animated
{
//move this from viewDidLoad to here...
mapView.showsUserLocation = YES;
}
-(void)viewWillDisappear:(BOOL)animated
{
mapView.showsUserLocation = NO;
}
-(void)mapView:(MKMapView *)mv didUpdateUserLocation:(MKUserLocation *)userLocation
//Changed the **internal** parameter name from mapView to mv
//to avoid a compiler warning about it hiding instance var with same name.
//It's better to use the passed parameter variable anyway.
{
NSLog(#"didUpdateUserLocation");
double miles = 10.0;
//Instead of manually calculating span from miles to degrees,
//use MKCoordinateRegionMakeWithDistance function...
//Just need to convert miles to meters.
CLLocationDistance meters = miles * 1609.344;
MKCoordinateRegion region2 = MKCoordinateRegionMakeWithDistance
(userLocation.coordinate, meters, meters);
[mv setRegion:region2 animated:YES];
}