How can i show Multiple pins on the map? - iphone

i want to show multiple pins on my MapView all with Animation of Dropping pin so how it is possible if any body have sample code then please send send link.i am new in this field.Thanks in Advance.

There are few code samples on developer.apple.com
This
is a simple map example with two pins

Just as you show single pin.. keep the code for single pin in Loop and pass different longitude latitude in loop.. You will get the pins at different location

if([points retainCount] > 0)
{
[points release];
points = nil;
}
if([annotationAry retainCount] > 0)
{
[annotationAry release];
annotationAry = nil;
}
points = [[NSMutableArray alloc]init];
annotationAry = [[NSMutableArray alloc]init];
for(int i=0;i<[longitudeary count];i++)
{
CLLocation* currentLocation1 = [[CLLocation alloc] initWithLatitude:[[latitudeary objectAtIndex:i]doubleValue] longitude:[[longitudeary objectAtIndex:i]doubleValue]];
[points addObject:currentLocation1];
}
for(int i=0;i<[points count];i++)
{
// CREATE THE ANNOTATIONS AND ADD THEM TO THE MAP
CSMapAnnotation* annotation = nil;
// create the start annotation and add it to the array
annotation = [[[CSMapAnnotation alloc] initWithCoordinate:[[points objectAtIndex:i] coordinate]
annotationType:CSMapAnnotationTypeImage
title:#"123456..."
shID:[shIDary objectAtIndex:i]
catID:[catIDary objectAtIndex:i]
ciggUse:[ciggaretteUSEary objectAtIndex:i]
wifiUse:[wifiUSEary objectAtIndex:i]
controller:self]autorelease];
[annotationAry addObject:annotation];
}
[mapViewmy addAnnotations:[NSArray arrayWithArray:annotationAry]];

Related

Create multiple MKOverlays of polyline from locations coming via web-service

My app is real-time tracker, where multiple users are logged in and updating their location by sending their co-ordinates to our web service which is then called back let's after every 2 minutes to show all the users on my MapView.
Every time I get the locations of users from web service in connectionDidFinishLoading method, I am parsing, creating polyline through pointsArray and adding them to overlay:
-(void) connectionDidFinishLoading: (NSURLConnection *) connection
{
userLatitudeArray = [[NSMutableArray alloc]init];
userLongitudeArray = [[NSMutableArray alloc]init];
userIdArray = [[NSMutableArray alloc]init];
userNameArray = [[NSMutableArray alloc]init];
userProfilePicArray = [[NSMutableArray alloc]init];
profilePicURLStringArray = [[NSMutableArray alloc]init];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSArray *trackingDict = [NSJSONSerialization JSONObjectWithData:empJsonData options:kNilOptions error:nil];
if ([trackingDict count] >= 2) {
for (trackUsersCount = 0; trackUsersCount< trackingDict.count; trackUsersCount++) {
NSLog(#"trackUsersCount %i", trackUsersCount);
NSMutableArray *latlongArray = [[NSMutableArray alloc]init];
latlongArray = [[trackingDict objectAtIndex:trackUsersCount]objectForKey:#"latlong"];
[userLongitudeArray removeAllObjects];
[userLatitudeArray removeAllObjects];
for (int i = 0; i<latlongArray.count; i++) {
[userLatitudeArray addObject:[[latlongArray objectAtIndex:i]objectForKey:#"lat"]];
[userLongitudeArray addObject:[[latlongArray objectAtIndex:i]objectForKey:#"long"]];
}
NSString *name = [[trackingDict objectAtIndex:trackUsersCount]objectForKey:#"user_firstName"];
// ProfilePIC URL
profilePicURLString = [[trackingDict objectAtIndex:trackUsersCount]objectForKey:#"user_profilePicture"];
[userNameArray addObject:name];
[profilePicURLStringArray addObject:profilePicURLString];
int i;
if (userLatitudeArray.count>1) {
for (i = 0; i<userLatitudeArray.count; i++) {
CLLocationCoordinate2D userLocation;
userLocation.latitude = [[userLatitudeArray objectAtIndex:i]doubleValue];
userLocation.longitude = [[userLongitudeArray objectAtIndex:i] doubleValue];
MKMapPoint * pointsArray = malloc(sizeof(CLLocationCoordinate2D)*userLongitudeArray.count);
pointsArray[i] = MKMapPointForCoordinate(userLocation);
polyline = [MKPolyline polylineWithPoints:pointsArray count:i];
free(pointsArray);
}
polyline.title = name;
[mapView addOverlay:polyline];
}
}
}
}
What I want to do is to have control on each polyline created for each user, so I can change the color of it and hide/show them on click of a button (one to show/hide my track and the other for all other users), this is why I am adding title to it.
I can see now that I am adding polyline to the same overlay, which is wrong I believe. But I don't know how many users will be there in web-service so can add multiple overlays of them.
Initially I thought I am able to remove a particular polyline with title but then I realised it is removing all as polyline.title property gets updated.
Any help would be much appreciated!
You could collect an array of those tracks that relate to other users, and keep a single track for the current user. If you clean the array at the start of the connectionDidFinishLoading function and populate it where you are currently adding the overlays to the map, then you move the addOverlay to a new function that you call at the end.
- (void) resetMap
{
if (showOtherTracks)
{
[mapView addOverlays:otherUserTracks];
} else {
[mapView removeOverlays:otherUserTracks];
}
if (showMyTrack)
{
[mapView addOverlay:myTrack];
} else {
[mapView removeOverlay:myTrack];
}
}
You can also call this when ever the button is pressed and the state changes.

crash application when scrolling map only when displaying annotaion

My application is crashing when I scrolling map with displaying one or more annotation. Without display annotation map is working fine.
Now I can't understand what is problem here. Please Help Me.
Following is code that I used to display All annotation.
-(void)displayAllAnnotation
{
NSLog(#"%d",[reminderTitle count]);
for (int i=0 ; i<[reminderTitle count]; i++)
{
double templati=[[reminderLatitude objectAtIndex:i]doubleValue];
double templongi=[[reminderLongitude objectAtIndex:i]doubleValue];
CLLocationCoordinate2D coord;
coord.latitude=(CLLocationDegrees)templati;
coord.longitude=(CLLocationDegrees)templongi;
DDAnnotation *ann = [[[DDAnnotation alloc] initWithCoordinate:coord addressDictionary:nil] autorelease];
ann.title = [reminderTitle objectAtIndex:i];
[self.mapView addAnnotation:ann];
[ann release];
}
}
You release ann object two times so your application is crashing.
remove autorelease. just write like this:
DDAnnotation *ann = [[DDAnnotation alloc] initWithCoordinate:coord addressDictionary:nil];

Maximum number of annotations (MKAnnotation) that can be drawn on MKMapView?

I want to add a number of annotations(arround 500) on a mapview but the maximum it seems to display is 100. If I go beyond 100, viewForAnnotation delegate method is not called. However it works perfectly for annotations below 100.
here is the code: (works only when count of annotationArray array is less than 101)
_allPoints = [[NSMutableArray alloc] init];
NSString* responseFile = [[NSBundle mainBundle] pathForResource:#"Datafile" ofType:#"txt"];
NSData *sampleData = [NSData dataWithContentsOfFile:responseFile];
if (sampleData) {
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:sampleData
options:kNilOptions
error:&error];
NSArray* response = [json objectForKey:#"response"];
for (NSDictionary *lineDict in response) {
if ([[lineDict objectForKey:#"data"] isKindOfClass:[NSArray class]]) {
SinglePoint *singlePoint = [[SinglePoint alloc] initWithDictionary:lineDict];
[_allPoints addObject:singlePoint];
}
else {
NSLog(#"Error");
}
}
}
_mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[_mapView setDelegate:self];
[self.view addSubview:_mapView];
NSMutableArray *annotationArray = [[NSMutableArray alloc] init];
for (int i=0; i<[_allPoints count]; i++) {
SinglePoint *singlePoint = [_allPoints objectAtIndex:i];
NVPolylineAnnotation *annotation = [[NVPolylineAnnotation alloc] initWithPoint:singlePoint mapView:_mapView];
[annotationArray addObject:annotation];
}
[_mapView addAnnotations:(NSArray *)annotationArray];
CLLocationCoordinate2D centerCoord = { 28.632747, 77.219982 };
[_mapView setCenterCoordinate:centerCoord zoomLevel:12 animated:NO];
The delegate method is:
EDIT: As per comments, started reusing the view but with no luck :(
if ([annotation isKindOfClass:[NVPolylineAnnotation class]]) {
static NSString *viewIdentifier = #"annotationView";
NVPolylineAnnotationView *annotationView = (NVPolylineAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:viewIdentifier];
if (annotationView == nil) {
annotationView = [[NVPolylineAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:viewIdentifier mapView:_mapView];
}
return annotationView;
}
return nil;
I could not find any restriction in the documentation or anywhere else. Could it be memory issue?
The MKMapView has not Limit for annotationViews. But it gets quite laggy and unusable above a certain number of views (+1000).
I believe, that the reason for this is that you handle the annotationView management totally wrong. You shouldn't create a unique view for every single annotation, even if you are using ARC. Your rather should reuse every unused View like the cell of a UITableView.
There are a couple of good tutorials for this like Introduction to MapKit on iOS - Ray Wenderlich.
If this won't resolve your problem, you should try to debug your annotation classes. (NVPolylineAnnotation and NVPolylineAnnotationView). Maybe there's something wrong.
Did you also checked your points array for equal coordinates?
Finally was able to track down the problem. Solved it by setting the center of mapView first and then adding annotations later. I still dont know why 100 annotations were shown earlier (and why the no 100 only). Thank you all for your suggestions and time on this.
This is the code I changed:-
_mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[_mapView setDelegate:self];
[self.view addSubview:_mapView];
CLLocationCoordinate2D centerCoord = { 28.632747, 77.219982 };
[_mapView setCenterCoordinate:centerCoord zoomLevel:12 animated:NO];
NSMutableArray *annotationArray = [[NSMutableArray alloc] init];
for (int i=0; i<[_allPoints count]; i++) {
SinglePoint *singlePoint = [_allPoints objectAtIndex:i];
NVPolylineAnnotation *annotation = [[NVPolylineAnnotation alloc] initWithPoint:singlePoint mapView:_mapView];
[annotationArray addObject:annotation];
}
[_mapView addAnnotations:(NSArray *)annotationArray];
You can add as many annotations as you like. However, the views for each annotation will not be created until that annotation's coordinate property intersects with the visible portion of your map view. MapKit will not create a view just because you added an annotation to the map.

Adding annotation on Map by parser latitude & longitude values

I have the following code:
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=0.0005;
span.longitudeDelta=0.0005;
CLLocationCoordinate2D location = mapView.userLocation.coordinate;
for (int i = 0; i < [appDelegate.markers count]; i++) {
marker *aMarker = [appDelegate.markers objectAtIndex:i];
location.latitude = [[aMarker.lat objectAtIndex:i] floatValue];
location.longitude =[[aMarker.lng objectAtIndex:i] floatValue];
region.span=span;
region.center=location;
if(addAnnotation != nil)
{
[mapView removeAnnotation:addAnnotation];
[addAnnotation release];
addAnnotation = nil;
}
addAnnotation = [[AddressAnnotation alloc] initWithCoordinate:location];
[mapView addAnnotation:addAnnotation];
}
I have parsed latitude and longitude in my XMLparser class. Now I want to add annotation on buttonclick event on Map. Can someone correct my code?
The warning NSString may not respond to -objectAtIndex means lat and lng are NSString objects (which don't have an objectAtIndex method).
You don't need to call objectAtIndex on lat and lng--they are the values in the specific marker object you just retrieved from the array.
(By the way, you get the warning when you compile the code--not when you "run" it like in your comment. Secondly, don't ignore compiler warnings. In this case, when you run the code you will get an exception: NSInvalidArgumentException - unrecognized selector.)
The other problem is the loop removes the previously added annotation before adding the current one. If you want to add all the markers to the map, this doesn't make sense. Currently, it would end up adding only the last marker to the map. If you really want to add only the last marker then you don't need to loop through the array (just grab the last marker from the array directly and create an annotation from it).
If instead you do want to add all the markers to the map, the loop should look like this:
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 *addrAnnot = [[AddressAnnotation alloc] initWithCoordinate:location];
[mapView addAnnotation:addrAnnot];
[addrAnnot release];
}
It's not clear what you're doing with region. If you're trying to set the region so that the map view shows all the annotations, look at the answers to this question: iOS MKMapView zoom to show all markers.

How to get a description for each pin, in Google Maps for the iPhone

I have a problem with MKPointAnnotation. I want to create my iPhone application like this:
Show a pin in Google Maps
Show a description on each pin, pulling that description from a NSMutableArray.
So, My question is, how do I show a description on each pin?
This is my code:
NSMutableArray *points = [[NSMutableArray alloc] init];
for(int i=0; i < [dataTable count]; i++) {
MKPointAnnotation *point =[[MKPointAnnotation alloc] init];
CLLocationCoordinate2D coordinate;
coordinate.latitude = [[[dataTable objectAtIndex:i] objectForKey:#"latitude"] floatValue];
coordinate.longitude = [[[dataTable objectAtIndex:i] objectForKey:#"longitude"] floatValue];
[point setCoordinate:coordinate];
[point setTitle:[[dataTable objectAtIndex:i] objectForKey:#"name"]]; //-- name of pin
[points addObject:point];
}
[map addAnnotations:points];
I would adopt the MKAnnotation protocol in my own class and simply override the
- (NSString) title
and implement
- (CLLocationCoordinate2D) coordinate {
CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = self.latitude;
theCoordinate.longitude = self.longitude;
return theCoordinate;
}
My class would also have an initialiser that takes all the data it needs (from the array you mentioned)
- (id) initWithTitle:(NSString *)title_ andLatitude:(CLLocationDegrees)latitude_ andLongitude:(CLLocationDegrees)longitude_;
When iterating I would create my own objects and then add them to the collection of annotations.
Cheers...