i am working on a map kit that shows all the data extracted from an xml web service .this web service contains 3 variables longitude (lon),latitude(lat), the name of the atm (atmName).the for loop is extracting the data from the Aatm array but the pins are not showing on the map .also my pins are all from the same region thats why i used a default center from the Aatm array with a default value. here is my code
thank you for helping me in advance :
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Aatm = [[NSMutableArray alloc] init];
pinArray = [[NSMutableArray alloc] init];
NSString *url=#"http://192.168.83.1:8080/jeeRestApp-1.0/rest/Atm";
NSXMLParser *parser;
parser=[[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
parser.delegate=self;
if ([parser parse]==FALSE){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Erreur" message:#"erreur de connection!" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:nil, nil];
[alert show];
}
//Setting the approximate region
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.mapview setShowsUserLocation:YES];
MKCoordinateRegion Myregion;
CLLocationCoordinate2D center1;
//replace by variable -----------------------------------
atm=[Aatm objectAtIndex:1];
center1.latitude=[atm.lat doubleValue];
center1.longitude=[atm.lon doubleValue];
NSLog(#"la latitude (defaut) est: %#",atm.lat);
MKCoordinateSpan span1;
span1.longitudeDelta = 0.01f;
span1.latitudeDelta = 0.01f;
Myregion.center=center1;
Myregion.span=span1;
[mapview setRegion:Myregion animated:YES];
for(int i = 0; i<=[Aatm count] - 1;i++)
{
//CLLocationCoordinate2D newCoord = { atm.lat, atm.lon};
atm=[Aatm objectAtIndex:i];
CLLocationCoordinate2D pinLocaton;
pinLocaton.latitude=[atm.lat doubleValue];
NSLog(#"latitude est de :%#",atm.lat);
pinLocaton.longitude=[atm.lon doubleValue];
NSLog(#"longitude est de :%#",atm.lon);
MKPointAnnotation *annotation=[MKPointAnnotation alloc];
annotation.title=atm.atmName;
NSLog(#"latitude est de :%#",atm.atmName);
annotation.coordinate=pinLocaton;
MKPinAnnotationView *newAnnotation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"annotation1"];
newAnnotation.pinColor = MKPinAnnotationColorGreen;
newAnnotation.animatesDrop = YES;
newAnnotation.canShowCallout = NO;
[newAnnotation setSelected:YES animated:YES];
[mapview addAnnotation:annotation];
NSLog(#"annotation added");
}
You need to implement mapView:viewForAnnotation: something like:
-(MKAnnotationView*)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if([annotation isKindOfClass:[MKPointAnnotation class]])
{
MKPinAnnotationView* view = (MKPinAnnotationView*) [mapView dequeueReusableAnnotationViewWithIdentifier:#"pin"];
if(!view)
{
view = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"pin"];
}
else
{
view.annotation = annotation;
}
view.pinColor = MKPinAnnotationColorGreen;
view.animatesDrop = YES;
view.canShowCallout = NO;
return view;
}
else
{
return nil;
}
}
Related
I'm a newbie to ios dev. I tried to add pin annotations on map using mapkit. However, after tried the most basic methods, it still didn't show up, either that's a simple pin, or a custom annotationview. There is no error message, it's just the pin won't show up in the map.
Here's my code:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.mapView.delegate = self;
NSLog(#"Custom Annotations start.");
// Custom Annotations.
CLLocationCoordinate2D bryanParkCoordinates = CLLocationCoordinate2DMake(37.785834, -122.406417);
MyCustomAnnotation *bryanParkAnnotation = [[MyCustomAnnotation alloc]initWithTitle:#"Bryant Park" Location:bryanParkCoordinates];
[self.mapView addAnnotation:bryanParkAnnotation];
// Simple pin.
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
[annotation setCoordinate:bryanParkCoordinates];
[annotation setTitle:#"Title"];
[self.mapView addAnnotation:annotation];
// Another try.
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(37.330713, -121.894348);
MKCoordinateSpan span = MKCoordinateSpanMake(0.1, 0.1);
MKCoordinateRegion region = {coord, span};
MKPointAnnotation *newannotation = [[MKPointAnnotation alloc] init];
[newannotation setCoordinate:coord];
[self.mapView setRegion:region];
[self.mapView addAnnotation:annotation];
// On your location.
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = bryanParkCoordinates;
point.title = #"Where am I?";
point.subtitle = #"I'm here!!!";
[self.mapView addAnnotation:point];
}
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if([annotation isKindOfClass:[MyCustomAnnotation class]])
{
MyCustomAnnotation *myLocation = (MyCustomAnnotation *)annotation;
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:#"MyCustomAnnotation"];
if(annotationView == nil)
annotationView = myLocation.annotationView;
else
annotationView.annotation = annotation;
return annotationView;
}
else{
MKPinAnnotationView *pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"DETAILPIN_ID"];
[pinView setAnimatesDrop:YES];
[pinView setCanShowCallout:NO];
return pinView;
}
}
If I just want a simple pin on map, just adding those lines
// Simple pin.
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
[annotation setCoordinate:bryanParkCoordinates];
[annotation setTitle:#"Title"];
[self.mapView addAnnotation:annotation];
should be enough? Is there other things that I could have missed? Like adding other delegate or something else other than adding those simple codes in 'viewDidLoad'? Thanks so much!
Managing Annotation Views
You should implement this delegate method and create a view for the annotation and return it.
basically when you add an annotation this delegates method will get called and you have to create the view for that annotation within this delegate method
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.mapView.delegate = self;
NSLog(#"Custom Annotations start.");
// Custom Annotations.
CLLocationCoordinate2D bryanParkCoordinates = CLLocationCoordinate2DMake(37.785834, -122.406417);
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(37.330713, -121.894348);
MKCoordinateSpan span = MKCoordinateSpanMake(0.1, 0.1);
MKCoordinateRegion region = {coord, span};
[self.mapView setRegion:region];
[self.mapView addAnnotation:annotation];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = bryanParkCoordinates;
point.title = #"Where am I?";
point.subtitle = #"I'm here!!!";
[self.mapView addAnnotation:point];
}
Try the following code:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if (annotation == mapView.userLocation) return nil;
static NSString* Identifier = #"PinAnnotationIdentifier";
MKPinAnnotationView* pinView;
pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:Identifier];
if (pinView == nil) {
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:Identifier];
pinView.canShowCallout = YES;
return pinView;
}
pinView.annotation = annotation;
return pinView;
}
Don't forget to add <MKMapViewDelegate> to your #interface section.
#interface YourViewController () <MKMapViewDelegate>
I'm having issues getting annotations to show up on a map in an iOS application.
I have followed the conventions in the documentation. From debugging it seems that viewForAnnotation is never being called for the annotation point.
The code for the View Controller is:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super
// Do any additional setup after loading the view, typically from a nib.
self.mapView.delegate = self;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
[self.locationManager requestAlwaysAuthorization];
[self.locationManager startUpdatingLocation];
self.mapView.showsUserLocation = YES;
[self.mapView setMapType:MKMapTypeStandard];
[self.mapView setZoomEnabled:YES];
[self.mapView setScrollEnabled:YES];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
//View Area
MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = self.locationManager.location.coordinate.latitude;
region.center.longitude = self.locationManager.location.coordinate.longitude;
region.span.longitudeDelta = 0.005f;
region.span.longitudeDelta = 0.005f;
[self.mapView setRegion:region animated:YES];
[self.mapView addAnnotations:[self createAnnotations]];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:YES];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
NSLog(#"viewForAnnotation");
if([annotation isKindOfClass:[MKUserLocation class]]) {
return nil;
}
MKPinAnnotationView *pinView = [[MKPinAnnotationView alloc] init];
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"foo"];
[pinView setPinColor:MKPinAnnotationColorGreen];
pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
return pinView;
}
- (NSMutableArray *)createAnnotations
{
NSMutableArray *annotations = [[NSMutableArray alloc] init];
CLLocationCoordinate2D coord;
coord.latitude = 37.4;
coord.longitude = -122.2;
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
[annotations addObject:annotation];
return annotations;
}
#end
One obvious problem is here in the createAnnotations method:
CLLocationCoordinate2D coord;
coord.latitude = 37.4;
coord.longitude = -122.2;
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
[annotations addObject:annotation];
The coordinate property of the annotation is never set.
Set it after creating the annotation:
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
annotation.coordinate = coord; // <-- add this line
[annotations addObject:annotation];
I have a problem when trying to add a polyline on the map.
I get directions from MKDirections, and create a RMPolylineAnnotation, but it does not appear on the map.
As I can see, the following method is called just once when the map appears:
- (RMMapLayer *)mapView:(RMMapView *)mapView layerForAnnotation:(RMAnnotation *)annotation
Here is the code I am using:
- (void)getRoute {
CLLocation *source = [[CLLocation alloc] initWithLatitude:self.mapView.userLocation.coordinate.latitude longitude:self.mapView.userLocation.coordinate.longitude];
CLLocation *destination = [[CLLocation alloc] initWithLatitude:self.mapView.selectedAnnotation.coordinate.latitude longitude:self.mapView.selectedAnnotation.coordinate.longitude];
[AppleDirectionManager getDirectionsFromPoint:source toPoint:destination transportType:MKDirectionsTransportTypeAutomobile withCompletion:^(MKDirectionsResponse *result) {
self.routeStepsArray = [[result.routes firstObject] steps];
for (MKRoute *route in result.routes) {
NSMutableArray *points = [NSMutableArray array];
for (int i = 0; i < route.polyline.pointCount; i++) {
MKMapPoint point = route.polyline.points[i];
CLLocation *location = [[CLLocation alloc] initWithLatitude:point.x longitude:point.y];
[points addObject:location];
}
dispatch_async(dispatch_get_main_queue(), ^{
NSArray *arr = [points copy];
RMPolylineAnnotation *polyline = [[RMPolylineAnnotation alloc] initWithMapView:self.mapView points:arr];
[self.mapView addAnnotation:polyline];
});
}
}];
}
- (RMMapLayer *)mapView:(RMMapView *)mapView layerForAnnotation:(RMAnnotation *)annotation {
if (annotation.isUserLocationAnnotation)
return nil;
RMMarker *marker = [[RMMarker alloc] initWithUIImage:[UIImage imageNamed:#"blabla.png"]];
[marker setCanShowCallout:YES];
[marker setName:#"blabla"];
return marker;
}
Also I can not show a custom callout for a RMPointAnnotation.
For RMPointAnnotation it's easily.
_polylineAnnotation = [[RMPolylineAnnotation alloc] initWithMapView:_mapView points:#[Location,Location]];
_polylineAnnotation.lineColor = [UIColor redColor];
_polylineAnnotation.lineWidth = 10.0f;
[_mapView addAnnotation:_polylineAnnotation];
How do I add a button to my placemarks and then get it to push onto a view controller?
- (void)viewDidLoad
{
[super viewDidLoad];
// Set "More" logo in navigation bar
self.navigationItem.titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Navigation"]];
appDelegate=[[UIApplication sharedApplication] delegate];
// Set longatude and latitude to tyne and wear
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(54.995184, -1.566699);
// Set span to cover area
MKCoordinateSpan span = MKCoordinateSpanMake(0.5, 0.5);
// Set region
MKCoordinateRegion regionToDisplay = MKCoordinateRegionMake(center, span);
[self.nearbyMapView setRegion: regionToDisplay];
for (int i = 0; i < [[appDelegate offersFeeds] count]; i++)
{
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
NSString *plotAddress = [[[appDelegate offersFeeds] objectAtIndex:i] valueForKey:#"addressline"];
NSString *plotTitle = [[[appDelegate offersFeeds] objectAtIndex:i] valueForKey:#"title"];
[geocoder geocodeAddressString:plotAddress completionHandler:^(NSArray *placemarks, NSError *error) {
if (placemarks && placemarks.count > 0)
{
CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc]initWithPlacemark:topResult];
// Set title
MKPointAnnotation *pa = [[MKPointAnnotation alloc] init];
pa.coordinate = placemark.location.coordinate;
pa.title = plotTitle;
// Add placemark to map
[self.nearbyMapView addAnnotation:pa];
}
}];
}
}
I've had a look at MKAnotationView but struggling to understand how to get this working with CLPlacemark.
Add this before you add mapview to self.view
-(void)viewDidLoad
{
MKPointAnnotation *annotation = [[MKPointAnnotation alloc]init];
annotation.coordinate = yourCoordinate;
annotation.title = #"Title";
annotation.subtitle = #"SubTitle";
[mapView1 addAnnotation:annotation];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKAnnotationView *pinView = nil;
static NSString *defaultPinID = #"identifier";
pinView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil )
{
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID];
annotationView.enabled = YES;
pinView.canShowCallout = YES;
UIButton *btn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
//Accessoryview for the annotation view in ios.
pinView.rightCalloutAccessoryView = btn;
}
else
{
pinView.annotation = annotation;
}
pinView.annotation = annotation;
return pinView;
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
//Put your button stuff here...
}
I hope it is useful to you
First of all I am running a Map page that just only show pins on map for every store. I was running only one pin on the map and it was fast after I put more than 25 pins it push very slow to the map page. What it is doing now at that process the app just load all data of the pin location (as I see in the target output) and then it push to the next screen. So please where would be my problem?
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"";
self.navigationItem.title = #"Mek";
response = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://kalkatawi.com/mapLocation.php"]];
if(response!=nil) {
NSError *parseError = nil;
jsonArray = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingAllowFragments error:&parseError];
jsonArray1 = [[NSMutableArray alloc] init];
jsonArray2 = [[NSMutableArray alloc] init];
jsonArray3 = [[NSMutableArray alloc] init];
for(int i=0;i<[jsonArray count];i++)
{
name = [[jsonArray objectAtIndex:i] objectForKey:#"name"];
longitude = [[jsonArray objectAtIndex:i] objectForKey:#"longitude"];
latitude = [[jsonArray objectAtIndex:i] objectForKey:#"latitude"];
[jsonArray1 addObject:name];
[jsonArray2 addObject:longitude];
[jsonArray3 addObject:latitude];
self.locationMap.delegate = self; //set delegate before adding annotations
CLLocationCoordinate2D annotationCoord;
for (int i=0; i < [jsonArray count]; i++)
{
NSDictionary *annotationDictionary = [jsonArray objectAtIndex:i];
name = [annotationDictionary objectForKey:#"name"];
annotationCoord.latitude
= [[annotationDictionary objectForKey:#"longitude"] doubleValue];
annotationCoord.longitude
= [[annotationDictionary objectForKey:#"latitude"] doubleValue];
MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init];
annotationPoint.coordinate = annotationCoord;
annotationPoint.title = name;
annotationPoint.subtitle = [NSString stringWithFormat:#"%f %f", annotationPoint.coordinate.latitude, annotationPoint.coordinate.longitude];
[self.locationMap addAnnotation:annotationPoint];
//------------------------//
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(annotationPoint.coordinate, 50000, 50000);
[self.locationMap setRegion:[self.locationMap regionThatFits:region] animated:YES];
locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
[locationManager startUpdatingLocation];
lat = locationManager.location.coordinate.latitude;
lon = locationManager.location.coordinate.longitude;
}
}
}
else {
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"You are not connected to internet" message:#"Please check the internet connection" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}
- (MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation
{
MKAnnotationView *pinView = nil;
if(annotation != locationMap.userLocation)
{
static NSString *defaultPinID = #"myPin";
pinView = (MKAnnotationView *)[locationMap dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil )
pinView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
pinView.image = [UIImage imageNamed:#"pinpinpin.png"];
pinView.canShowCallout = YES;
pinView.enabled = YES;
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinView.rightCalloutAccessoryView = infoButton;
}
return pinView;
}
SImple way is load data in background thread, and then when data is fully load display it on the map. You can do this in any of view controller, means you can do it in parent view controller and when you got response then update on map view controller.
Or on view did load method load data in background and update it when its load. This approach will not hold your UI. You can use blocks like this
dispatch_async(queue, ^{
//load data from server
dispatch_async(dispatch_get_main_queue(), ^{
//Update map
});
});