MapView not reloading annotations unless you zoom in or move map - iphone

I am using the following for loop to manage/find out the five nearest annotations to the user location, and then set them as the mapView's annotations.
for (int i = 0; i <= 5; i++) {
//NSLog(#"Stores Count For Loop: %i", [storesLessThan100KAway count]);
if ([storesLessThan100KAway count] > 5) {
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"distanceToTarget" ascending:YES];
NSArray *newArray = [storesLessThan100KAway sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptor]];
[mapView addAnnotation:[newArray objectAtIndex:i]];
if ([[mapView annotations] count] > 4) {
[descriptor release];
[dict release];
[currentlocation release];
[usrlocation release];
[annotation release];
[paul drain];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
return;
}
}
However the annotations added to the map will not be shown until the map is zoomed in or moved. Is there anyway that I could stop this?

MKMapView is a subclass of UIView -- You could try calling [mapView setNeedsDisplay]?
If that doesn't work:
// Force update of map view.
CLLocationCoordinate2D center = [mapView centerCoordinate];
[mapView setCenterCoordinate:center];

Try to put these lines in a Timer and stop it after you finish adding annotations
static float deltaX=.1;
CLLocation *location = [[[CLLocation alloc] initWithLatitude:self.mapView.centerCoordinate.latitude longitude:self.mapView.centerCoordinate.longitude] autorelease];
MKCoordinateRegion region;
region.center = location.coordinate;
MKCoordinateSpan span;
span.latitudeDelta = self.mapView.region.span.latitudeDelta+deltaX;
span.longitudeDelta = self.mapView.region.span.longitudeDelta+deltaX;
deltaX+=.1;
deltaX*=-1;
region.span = span; // Set the region's span to the new span.
[self.mapView setRegion:region animated:0];

Related

how to hide current Location annotation from mkmapview

In my application i have used the MKmapview,I want to hide the user current location annotation point,Here my code
- (void)viewDidLoad
{
[super viewDidLoad];
appDel=(AppDelegate *)[UIApplication sharedApplication].delegate;
DatabaseController *dbObj=[[DatabaseController alloc] init];
NSString *query=[NSString stringWithFormat:#"select * from petBoundarySettings where petId=%#",self.petID];
NSMutableArray *alertSettingArray=[dbObj getPetAlertSerrings:query :[appDel getDBPath]];
if([alertSettingArray count]>0){
distance=[[[alertSettingArray objectAtIndex:0] objectForKey:#"distance"] integerValue];
address=[[alertSettingArray objectAtIndex:0] objectForKey:#"address"];
lat2=[[alertSettingArray objectAtIndex:0] objectForKey:#"lat"] ;
lon2=[[alertSettingArray objectAtIndex:0] objectForKey:#"lang"] ;
}
UIImageView *imageNav = [[UIImageView alloc] initWithImage: [UIImage imageNamed: #"sml-cat_03.png"]];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:imageNav];
[imageNav release];
[dbObj release];
MKCoordinateSpan span;
span.latitudeDelta=.01;
span.longitudeDelta=.01;
MKCoordinateRegion region;
//distance=appDel.alertDistance;
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = nil;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
currentAnnotation=[[MyAnnotations alloc]init];
NSLog(#"GL%f",appDel.getlat);
NSLog(#"GN%f",appDel.getlon);
regionCoordinate.latitude =[lat2 floatValue];
regionCoordinate.longitude = [lon2 floatValue];
currentAnnotation.coordinate=regionCoordinate;
currentAnnotation.title=#"Boundary Location";
currentAnnotation.subtitle=appDel.address;
region.center=CLLocationCoordinate2DMake(regionCoordinate.latitude,regionCoordinate.longitude);
region.span=span;
[_myMapView setRegion:region animated:YES];
[_myMapView regionThatFits:region];
region1=region;
petAnnotation=[[MyAnnotations alloc]init];
petCoordinate.latitude = +11.028549739;
petCoordinate.longitude = +76.89644586;
petAnnotation.coordinate=petCoordinate;
petAnnotation.title=#"My Pet Location";
petAnnotation.subtitle=#"Vadavalli";
MKCircle *circle = [MKCircle circleWithCenterCoordinate:regionCoordinate radius:distance];
[_myMapView addOverlay:circle];
CLLocation *whereIAm = [locationManager location];
NSLog(#"MI%#",whereIAm);
[_myMapView addAnnotation:currentAnnotation];
MKMapPoint p1 = MKMapPointForCoordinate(regionCoordinate);
MKMapPoint p2 = MKMapPointForCoordinate(petCoordinate);
CLLocationDistance dist = MKMetersBetweenMapPoints(p1, p2);
i=0;
[self getPetData];
timer= [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:#selector(getPetData) userInfo:nil repeats:YES];
if(appDel.checkGPS==NO)
{
[self getPetDataFromGPS];
}
}
How to hide the current location from mkmapview,Please help me to sort out.
MKMapView has a property named showsUserLocation that you can set to determine whether the user's location can be displayed. However, I see that you're not setting it in code, and the default value is NO.
If you're using a Xib or Storyboard, check the MKMapView in there, as there is a checkbox for this behaviour in the attributes inspector. (Shows User Location)

Set up my MapView; how do I add more than one annotation?

I've created a MapView in my app that zooms into the user's current location, and it works perfectly. See my code below:
.h file
#interface MapViewController : UIViewController <MKMapViewDelegate>
#property (nonatomic, strong) IBOutlet MKMapView *mapView;
#end
.m file
- (void)viewDidLoad {
[super viewDidUnload];
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
self.mapView.delegate = self;
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = userLocation.coordinate;
point.title = #"You Are Here";
point.subtitle = #"Your current location";
[self.mapView addAnnotation:point];
}
This code places an annotation where the user's current location is. However from here, I want to add multiple annotations (so that users can see key locations around them). What code do I need to add/change in order to do this?
Thanks.
This can be done many, many different ways. It depends on your data source and needs
Here's a way to add two
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = userLocation.coordinate;
point.title = #"You Are Here";
point.subtitle = #"Your current location";
[self.mapView addAnnotation:point];
MKPointAnnotation *point2 = [[MKPointAnnotation alloc] init];
point2.coordinate = aDifferentCoordinate;
point2.title = #"You Are Here";
point2.subtitle = #"Your current location";
[self.mapView addAnnotation:point2];
Here's a way to add a thousand at the same point
int i;
for(i = 0; i < 1000; i++)
{
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = userLocation.coordinate;
point.title = #"You Are Here";
point.subtitle = #"Your current location";
[self.mapView addAnnotation:point];
}

Can you create an annotation in Mapview from an address?

I have "googled" this question a few times today with no luck. I would like to know if it is possible to create an annotation in Mapview from an address rather than using the lat/Long method. My current code is below.
//1. Create a coordinate for use with the annotation
CLLocationCoordinate2D Sharon;
Sharon.latitude = 38.952223;
Sharon.longitude = -77.193646;
Annotation *myAnnotation = [Annotation alloc];
myAnnotation.coordinate = Sharon;
myAnnotation.title = #"Sharon Lodge #327";
myAnnotation.subtitle = #"McLean, VA";
Try like this,
NSString *location = "some address, state, and zip";
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:location
completionHandler:^(NSArray* placemarks, NSError* error){
if (placemarks && placemarks.count > 0) {
CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
MKCoordinateRegion region = self.mapView.region;
region.center = placemark.region.center;
region.span.longitudeDelta /= 8.0;
region.span.latitudeDelta /= 8.0;
[self.mapView setRegion:region animated:YES];
[self.mapView addAnnotation:placemark];
}
];
for annotation title and subtitle,
CLPlacemark *topResult = [placemarks objectAtIndex:0];
// Create an MLPlacemark
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
// Create an editable PointAnnotation, using placemark's coordinates, and set your own title/subtitle
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = placemark.coordinate;
point.title = #"Sample Location";
point.subtitle = #"Sample Subtitle";
// Set your region using placemark (not point)
MKCoordinateRegion region = self.mapView.region;
region.center = placemark.region.center;
region.span.longitudeDelta /= 8.0;
region.span.latitudeDelta /= 8.0;
// Add point (not placemark) to the mapView
[self.mapView setRegion:region animated:YES];
[self.mapView addAnnotation:point];
// Select the PointAnnotation programatically
[self.mapView selectAnnotation:point animated:NO];
You can get lat long from an address using google api or CLGeocoder
google api
Link 1 Link 2
CLGeocoder
-(id)getAnnotationAryFromAddress
{
CLGeocoder *geocoder2 = [[CLGeocoder alloc] init];
NSString *addressString = "string contain address, city, state and zip";
[geocoder2 geocodeAddressString:addressString
completionHandler:^(NSArray *placemarks, NSError *error) {
if (error) {
//NSLog(#"Geocode failed with error: %#", error);
return;
}
if (placemarks && placemarks.count > 0)
{
CLPlacemark *placemark = [placemarks objectAtIndex:0];
CLLocation *location = placemark.location;
RegionAnnotation *annotation = [[RegionAnnotation alloc] init];
CLLocationCoordinate2D theCoordinate1;
theCoordinate1 = location.coordinate;
annotation.title = #"Title";
annotation.subtitle = #"SubTitle";
annotation.tag = i;
annotation.coordinate = theCoordinate1;
[self.mapView addAnnotation:annotation];
}
}];
}
return self;
}

Current Location in the Simulator

Im doing an app in which i have to find the current location of the user.can i get the current location of the user in the iOS 5 simulator by using CLLocationmanager?
xcode - Edit Scheme - Run you.app - Option
check Allow Location Simulation, then select "Default Location"
Add GPX File to Project
the format like this
In Xcode, you can select the location to simulate using a small button above the console.
- (void)viewDidLoad{
[super viewDidLoad];
self.title = #"MapView";
self.navigationController.navigationBarHidden = NO;
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation];
}
- (void) loadPin {
iCodeBlogAnnotation *appleStore1;
CLLocationCoordinate2D workingCoordinate;
workingCoordinate.latitude = [latitude doubleValue];
workingCoordinate.longitude = [longitude doubleValue];
appleStore1 = [[iCodeBlogAnnotation alloc] initWithCoordinate:workingCoordinate];
[appleStore1 setTitle:[NSString stringWithFormat:#"Default Point"]];
//[appleStore1 setSubtitle:[NSString stringWithFormat:#"Distance %.2f Miles",miles]];
[appleStore1 setAnnotationType:iCodeBlogAnnotationTypeEDU];
[mapView addAnnotation:appleStore1];
[(MKMapView*)self.mapView selectAnnotation:appleStore1 animated:NO];
MKCoordinateRegion region;
region.center.latitude = [latitude doubleValue];
region.center.longitude = [longitude doubleValue];
region.span.latitudeDelta = .5;
region.span.longitudeDelta = .5;
[mapView setRegion:region animated:YES];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
latitude = [[NSString alloc] initWithFormat:#"%f", newLocation.coordinate.latitude];
longitude = [[NSString alloc] initWithFormat:#"%f", newLocation.coordinate.longitude];
[locationManager stopUpdatingLocation];
if (latitude > 0) {
[self loadPin];
}
}

Current location query on click event

I am Showing Australia continent when my Map application launch. I have one button on which I want to set coding for current location and zoom in to that location after pressing butoon. I am getting current latitude & longitude and able to pass in Web-service url. I did following coding
- (void)viewDidLoad
{
//to set the australia region
CLLocationCoordinate2D AusLoc = {-19.048230,133.685730};
MKCoordinateSpan AusSpan = MKCoordinateSpanMake(45, 45);
MKCoordinateRegion AusRegion = MKCoordinateRegionMake(AusLoc, AusSpan);
mapView.region = AusRegion;
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation]; }
and
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
if((fabs(newLocation.coordinate.latitude) > 0.001) || (fabs(newLocation.coordinate.longitude) > 0.001)) {
NSLog(#"Got location %f,%f", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
if (currentLocation != nil) {
[currentLocation release];
}
currentLocation = newLocation;
[currentLocation retain];
}
NSString *lati=[NSString stringWithFormat:#"%f", newLocation.coordinate.latitude];
NSString *longi=[NSString stringWithFormat:#"%f", newLocation.coordinate.longitude];
}
on Search button(web service calling)
NSString *url = [NSString stringWithFormat:#"http://.....url...../hespdirectory/phpsqlsearch_genxml.php?lat=%f&lng=%f&radius=%f",locationManager.location.coordinate.latitude,locationManager.location.coordinate.longitude,radius];
Updated with coding:
- (IBAction) showAddress {
if (locationManager.location == nil)
{
NSLog(#"user location not found yet or service disabled/denied");
}
else
{
// Change map region using span (degrees)...
MKCoordinateSpan span = MKCoordinateSpanMake(0.001, 0.001);
MKCoordinateRegion region = MKCoordinateRegionMake
(locationManager.location.coordinate, span);
[mapView setRegion:region animated:YES];
}
}
When I set mapView.showUserLocation = YES; it shows current location when map application launch that is before tapping button. I am confused with previous answer. So What code should I put under button click event to show current location and also suggest If there is any change to pass current Lati and longi in web service url after giving coding for click event. Thanks in advance
Edited:-
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation
{
MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#""];
annView.pinColor = MKPinAnnotationColorGreen;
//annView.animatesDrop=TRUE;
annView.canShowCallout = YES;
annView.calloutOffset = CGPointMake(-5, 5);
annView.enabled = YES;
annView.image = [UIImage imageNamed:#"flagg.png"];
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self
action:#selector(showDetails:)
forControlEvents:UIControlEventTouchUpInside];
annView.rightCalloutAccessoryView = rightButton;
NSLog(#"Created annotation at: %f %f", ((CustomPlacemark*)annotation).coordinate.latitude, ((CustomPlacemark*)annotation).coordinate.longitude);
[annView addObserver:self
forKeyPath:#"selected"
options:NSKeyValueObservingOptionNew
context:#"GMAP_ANNOTATION_SELECTED"];
[annView autorelease];
return annView;
}
//return nil;
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context{
NSString *action = (NSString*)context;
// We only want to zoom to location when the annotation is actaully selected. This will trigger also for when it's deselected
if([[change valueForKey:#"new"] intValue] == 1 && [action isEqualToString:#"GMAP_ANNOTATION_SELECTED"])
{
if([((MKAnnotationView*) object).annotation isKindOfClass:[CustomPlacemark class]])
{
CustomPlacemark *place = ((MKAnnotationView*) object).annotation;
// Zoom into the location
[mapView setRegion:place.coordinateRegion animated:TRUE];
NSLog(#"annotation selected: %f %f", ((MKAnnotationView*) object).annotation.coordinate.latitude, ((MKAnnotationView*) object).annotation.coordinate.longitude);
}
}
}
In Search button(calling webservice)
CLLocationCoordinate2D location;
//currentLocation = newLocation;
float radius = [[arrayNo objectAtIndex:[pickerView selectedRowInComponent:0]] floatValue];
//NSURL *url = [[NSURL alloc] initWithString:#"http://www.hettich.com.au/hespdirectory/phpsqlsearch_genxml.php?lat=-33.853468&lng=150.94042160000004&radius=5"];
NSString *url = [NSString stringWithFormat:#"http://www.hettich.com.au/hespdirectory/phpsqlsearch_genxml.php?lat=%f&lng=%f&radius=%f",locationManager.location.coordinate.latitude,locationManager.location.coordinate.longitude,radius];
//NSLog(#"NSString *url");
NSLog(#"%#", url);
NSURL *URL = [NSURL URLWithString:url];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:URL];
//Initialize the delegate.
XMLParser *parser = [[XMLParser alloc] initXMLParser];
//Set delegate
[xmlParser setDelegate:parser];
//Start parsing the XML file.
BOOL success = [xmlParser parse];
if(success)
{ resultButton.userInteractionEnabled = YES;
// NSMutableArray* annotations = [[NSMutableArray alloc] init];
for (int i = 0; i < [appDelegate.markers count]; i++)
{
marker *aMarker = [appDelegate.markers objectAtIndex:i];
location.latitude = [aMarker.lat floatValue];
location.longitude =[aMarker.lng floatValue];
AddressAnnotation *annob = [[AddressAnnotation alloc] initWithCoordinate:location];
annob.title = aMarker.name;
annob.subTitle = aMarker.address;
[mapView addAnnotation:annob];
[annob release];
CLLocationCoordinate2D ausLoc = {location.latitude,location.longitude}; //for zoom in the showroom results region
MKCoordinateSpan ausSpan = MKCoordinateSpanMake(0.108889, 0.169922);
MKCoordinateRegion ausRegion = MKCoordinateRegionMake(ausLoc, ausSpan);
NSLog(#"No Errors");
mapView.region = ausRegion;
}
}
In your button tapped method, you should first check if the location manager has obtained a location and then set the map's center or region to the user's location:
if (locationManager.location == nil)
{
NSLog(#"user location not found yet or service disabled/denied");
}
else
{
// Change map center (preserving current zoom level)...
[mapView setCenterCoordinate:locationManager.location.coordinate animated:YES];
// --OR--
// Change map region using distance (meters)...
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance
(locationManager.location.coordinate, 1000, 1000);
[mapView setRegion:region animated:YES];
// --OR--
// Change map region using span (degrees)...
MKCoordinateSpan span = MKCoordinateSpanMake(0.001, 0.001);
MKCoordinateRegion region = MKCoordinateRegionMake
(locationManager.location.coordinate, span);
[mapView setRegion:region animated:YES];
}
In the didUpdateToLocation method, you are setting a "currentLocation" variable but I don't see a need for it. The locationManager already has a location property.
In any case, only considering absolute latitudes or longitudes greater than 0.001 as "valid" is incorrect because a) it excludes locations near the equator or prime meridian (even though you're only interested in Australia this logic is the wrong way to go), and b) it's better instead to check if newLocation itself is nil.