Logic Issue - MapKit - iphone

Following is my MapKitDisplayViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = 22.569722 ;
region.center.longitude = 88.369722;
[mapView setRegion:region animated:YES];
[mapView setDelegate:self];
DisplayMap *ann = [[DisplayMap alloc] init];
ann.title = [person name];
ann.subtitle = [person address];
ann.person = person;
ann.coordinate = region.center;
[mapView addAnnotation:ann];
}
-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:
(id <MKAnnotation>)annotation {
MKPinAnnotationView *pinView = nil;
if(annotation != mapView.userLocation)
{
static NSString *defaultPinID = #"com.invasivecode.pin";
pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil ) pinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
UIImageView *iconView = [[UIImageView alloc] initWithImage: [UIImage imageWithString:#?????????????????];
annotationView.leftCalloutAccessoryView = iconView;
pinView.pinColor = MKPinAnnotationColorRed;
pinView.canShowCallout = YES;
pinView.animatesDrop = YES;
}
return pinView;
}
You will see the line where it'll say ???????? I need to display an image there.
When the user clicks a pin point, then the popup will appear. Title, subtitle and the image is suppose to be displayed on the popup. I believe that the following line should display the image for that popup. But i am unable to pass the Person object's (or the pipoint which contains the person object) image URL to this method. Can you help me display the selected Image URL here.

It doesn't fail. I need to know how to pass the person object
selected by the user to viewForAnnotation method
Ahhh, I see know. I had a similar issue, and it can be a be tricky. I'm right in the middle of reworking my Annotation code, so you can see it since it doesn't work, but I you need to store something away that you can then later retrieve.
I made an object, MKAnnotation.
#interface FotoMapLocation : NSObject <MKAnnotation> {
So when I make an annotation, I create a FotoMapLocation object.
FotoMapLocation *annotation = [[FotoMapLocation alloc] initWithTitle:title
subtitle:subtitle
foto:aFoto
thumbnailImage:aFoto.thumbnailImage
];
[mapView addAnnotation:annotation];
Now, you can store anything here. So store your Person object in your subclass.
I know this is only halfway there, and very rambling. But I was right in the middle of ripping that code out, and then another fire came up, so it is currently in an in-between state. But I expect to return to it in a few days. I'll check back and if you don't have anything I'll update this answer.

This is what i did, in the viewForAnnotation method
DisplayMap *dm= (DisplayMap *)annotation;
NSString *url = [dm.person urlOfPerson];

Related

Regarding Map pin points that should display dynamically in iphone

hi everyone i have a mapview where i have to drop pins on the map based on latitude and longitude where i used to get that from a webservice can any one help me out how to get and plot it on the map and also if i have plotted any pin on the map that should be reflected in the web application through the web-services only.
Checklist for Adding an Annotation to the Map
The steps for implementing and using annotations in your map-based application are shown below. These steps assume that your application incorporates an MKMapView object somewhere in its interface.
1. Define an appropriate annotation object using one of the following options:
Use the MKPointAnnotation class to implement a simple annotation. This type of annotation contains properties for specifying the title and subtitle strings to display in the annotation’s onscreen callout bubble.
(OR)
Define a custom object that conforms to the MKAnnotation protocol, as described in “Defining a Custom Annotation Object” . This type of annotation can store any type of data you want.
2. Define an annotation view to present the data on screen. How you define your annotation view depends on your needs and may be one of the following:
If the annotation can be represented by a static image, create an instance of the MKAnnotationView class and assign the image to its image property; see “Using the Standard Annotation Views” .
(OR)
If you want to use a standard pin annotation, create an instance of the MKPinAnnotationView class; see “Using the Standard Annotation Views” .
If a static image is insufficient for representing your annotation, subclass MKAnnotationView and implement the custom drawing code needed to present it.
3. Implement the mapView:viewForAnnotation: method in your map view delegate.
Your implementation of this method should dequeue an existing annotation view if one exists or create a new one. If your application supports multiple types of annotations, you must include logic in this method to create a view of the appropriate type for the provided annotation object.
4. Add your annotation object to the map view using the addAnnotation: or addAnnotations: method.
REFER HERE FOR COMPLETE REFERENCE.
try this code:- in storeListArr store the value from web service
-(void)loadingMap
{
[self.mapView setMapType:MKMapTypeStandard];
[self.mapView setZoomEnabled:YES];
[self.mapView setScrollEnabled:YES];
NSLog(#"storeListArr = %#",storeListArr);
for(int i=0; i<[storeListArr count];i++)
{
MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = [[[storeListArr objectAtIndex:0] objectForKey:#"lat"] floatValue];
region.center.longitude = [[[storeListArr objectAtIndex:0] objectForKey:#"long"] floatValue];
region.span.longitudeDelta = .05f;
region.span.latitudeDelta = .05f;
[self.mapView setRegion: region animated:YES];
MyAnnotations *ann = [[MyAnnotations alloc] init];
NSString *str=[[storeListArr objectAtIndex:i] objectForKey:#"store_name"];
NSLog(#"Address %#",storeAddress);
ann.title = str;
ann.coordinate = region.center;
[self.mapView addAnnotation:ann];
}
[self.mapView setDelegate:self];
}
for call out
- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
NSLog(#"MKAnnotationView");
MKPinAnnotationView *pinView = nil;
if(annotation != mapView.userLocation)
{
static NSString *defaultPinID = #"com.invasivecode.pin";
pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil )
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
pinView.canShowCallout = YES;
UIImage *flagImage = [UIImage imageNamed:#"MapPin.png"];
pinView.image = flagImage;
pinView.opaque = NO;
UIButton *rightButton = [[UIButton alloc]initWithFrame:CGRectMake(0.0f,0.0f,28.0f,30.0f)];
[rightButton setImage:[UIImage imageNamed:#"MapArrow"] forState:UIControlStateNormal];
for (int i =0 ; i< [storeListArr count]; i++)
{
if ([[[storeListArr objectAtIndex:i] objectForKey:#"lat"] floatValue] == pinView.annotation.coordinate.latitude)
{
UIImageView *img = [[UIImageView alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 30.0f, 30.0f)];
if([[storeListArr objectAtIndex:i] objectForKey:#"imageUrl"])
{
[img setImage:[[storeListArr objectAtIndex:i] objectForKey:#"imageUrl"]];
}
pinView.leftCalloutAccessoryView =img;
[rightButton addTarget:self
action:#selector(showStoreDetail:)
forControlEvents:UIControlEventTouchUpInside];
pinView.rightCalloutAccessoryView = rightButton;
}
}
}
else
[mapView.userLocation setTitle:#"Current Location"];
return pinView;
}

How to pass sender tag in DetailView to get default Map application for direction?

I am opening the Detailview on annotation pin as well as on tableview. To get direction from detailview I have place following button click event.
Edited:: with -(IBAction)showDirectionUpdated; coding
-(IBAction)showDirectionUpdated;
{
NSIndexPath *selectedIndexPath = [self._tableView indexPathForSelectedRow];
if( selectedIndexPath == [self._tableView indexPathForSelectedRow])
{
marker *aMarker = (marker *)[appDelegate.markers objectAtIndex:selectedIndexPath.row];
NSString *EndLoc=[NSString stringWithFormat:#"%# %#", aMarker.address,aMarker.city];
NSString* addr = [NSString stringWithFormat:#"http://maps.google.com/maps?saddr=Current Location&daddr=%#",EndLoc];
NSURL* url = [[NSURL alloc] initWithString:[addr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[[UIApplication sharedApplication] openURL:url];
NSLog(#"%#",url);
[url release];
[self._tableView deselectRowAtIndexPath:selectedIndexPath animated:YES];
}
else
{
//here if I am opening the detailview from annotation callout button and calling
// direction in map default app. But respective address is not passing
//in default map app
NSInteger selectedIndex = [sender tag];
AddressAnnotation *selectedObject = [self.annobjs objectAtIndex:selectedIndex];
marker *aMarker = [appDelegate.markers objectAtIndex:selectedIndex];
NSString *EndLoc=[NSString stringWithFormat:#"%# %#", aMarker.address,aMarker.city];
NSString* addr = [NSString stringWithFormat:#"http://maps.google.com/maps?saddr=Current Location&daddr=%#",EndLoc];
NSURL* url = [[NSURL alloc] initWithString:[addr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[[UIApplication sharedApplication] openURL:url];
NSLog(#"%#",url);
[url release];
}
}
I want to pass some sender or id to call respective Direction from detailView which I get on pressing annotation. I am successful with getting direction default app from detailview which I get by selecting tableview(listview). Here some code of sender tag.
Edited 2=== with viewForAnnotation
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation
{ MKAnnotationView *annView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#""];
if (annView == nil)
{
annView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#""] autorelease];
annView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}
annView.image = [UIImage imageNamed:#"flag.png"];
annView.annotation = annotation;
[annView setEnabled:YES];
[annView setCanShowCallout:YES];
return annView;
}
-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
NSLog(#"calloutAccessoryControlTapped");
MKAnnotationView* annView = (MKAnnotationView*) view;
AddressAnnotation* annotation = (AddressAnnotation*)[annView annotation];
if(BcardView.hidden == YES)
{
SearchView.hidden = YES;
BcardView.hidden = NO;
BackButtontitle.text = #"Map View";
marker *aMarker = [[marker alloc]init];
ShowroomName.text = aMarker.name;
}}
Based on the code posted, here is my understanding:
marker is the top-level class that stores all the details about a location including address and city.
AddressAnnotation is the class that implements the MKAnnotation protocol currently containing just the coordinate, title, and subtitle for a location (it does not have the address and city). This is the class used to create objects that are passed to the map view's addAnnotation method.
What you would like to do is that when the callout button is pressed on an annotation, you would like to show some detail view or information that requires the address and city.
Instead of trying to keep track of array indexes using tags or searching for objects in arrays, I suggest adding a reference to the marker in AddressAnnotation. This way, when you have an AddressAnnotation object, you can get its related marker object using that reference (no searching or indexes needed).
In the AddressAnnotation class, add a retain property of type marker called parentMarker. When you create an AddressAnnotation object from a marker and before calling addAnnotation, set the parentMarker property to the current marker.
Then in calloutAccessoryControlTapped, cast view.annotation to an AddressAnnotation to get easy access to the parentMarker property. Now you can get the address and city from the marker. (By the way, in that method you don't need to cast view to MKAnnotationView since it already is one and you don't have to name it annView.)
I am not sure what BcardView is and why you're checking if it's hidden or not.
I'd also suggest a slight improvement to the viewForAnnotation method (use a non-blank re-use id and move the setting of the properties that don't change to inside the if):
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>) annotation
{
MKAnnotationView *annView = (MKAnnotationView *)[mapView
dequeueReusableAnnotationViewWithIdentifier:#"AddrAnnot"];
if (annView == nil)
{
annView = [[[MKAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:#"AddrAnnot"] autorelease];
annView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
annView.image = [UIImage imageNamed:#"flag.png"];
[annView setEnabled:YES];
[annView setCanShowCallout:YES];
}
annView.annotation = annotation;
return annView;
}

Custom callOut for A pin in a mkMapview of iphone!! .... Data miss match for default call out and custom call out

I am trying for a custom callout for a pin dropped in a mapView .. I am able to do this by hiding the default callout of pinView and showing my custom call out there. ().. everything is working fine ... But only prob is i am not able to assign the correct information for the call out ..I had shown the Default call out in which info is different than my custom call out. I ve attached the scrren shot .....
Here is my code
-(void)mapViewImplementaion
{
[mapview setMapType:MKMapTypeStandard];
mapview.showsUserLocation=YES;
for (int i =0;i<[allResultsArr count];i++)
{
List_Map_details *object=[allResultsArr objectAtIndex:i];
CLLocationCoordinate2D coordinat = {[object.lati floatValue], [object.longi floatValue]};
[mapview setRegion:MKCoordinateRegionMake(coordinat,
MKCoordinateSpanMake(0.027f, 0.027f))];
DisplayMapPark *ann = [[DisplayMapPark alloc] init];
ann.title =[NSString stringWithFormat:#"%#",object.forRetailerName];
ann.subtitle=[NSString stringWithFormat:#"%# %# %#",object.forAddress,object.forZipCode,object.forCityName];
ann.latitude=[object.lati floatValue];
ann.longitude=[object.longi floatValue];
ann.coordinate = coordinat;
[mapview addAnnotation:ann];
[ann release];
}
CalloutMapAnnotationView *calloutMapAnnotationView;
int m=1;
-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation {
MKAnnotationView *pinView = nil;
// here i wrote some code for my custom callout to generate(not shown)
if(annotation != mapview.userLocation)
{
//int i=0;
static NSString *defaultPinID = #"com.invasivecode.pin";
pinView = (MKAnnotationView *)[mapview dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil )
pinView = [[[MKAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
NSString *imagName = [NSString stringWithFormat:#"%d.png", m];
UIImage *image = [UIImage imageNamed:imagName];
[pinView setImage:image];
pinView.canShowCallout = NO;
// To show this in scrren Shot i set it to Yes;
[pinView setAnnotation:annotation];
pinView.tag=m;
UIButton *rightButton=[UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinView.rightCalloutAccessoryView=rightButton;
//pinView.rightCalloutAccessoryView.frame=CGRectMake(0, 0, 60, 60);
m++;
}
else
{
[mapview.userLocation setTitle:#"Ik ben hier"];
}
pinView.annotation = annotation;
[rightButton release];
return pinView;
}
Hi if any one is awre of this .. please help !!!!!
I solved this issue. It was the mistake by me. I was just not assigning the tags to the pins properly .. and when the user selects the pin i was reading some other pin's information.... Thanks all

Create overlay from user interaction on MKMapView?

I have two questions,
How to create an overlay on a MKMapkitView from user's touch down events? i.e. To keep it simple, the user touches down and it creates a MKCircle overlay
How does the Maps application implements the "dropped pin" on touch down? Anybody knows or have some code examples on how to accomplish something similar?
Any pointers would be greatly appreciated. I've been googling and reading lots of docs without much success as you can see.
Below is an example that creates a circle and drops a pin where the user touches and holds their finger for 1 second. It uses a UILongPressGestureRecognizer which is added to the mapView wherever the map is initialized (eg. viewDidLoad).
Make sure the mapView's delegate is set also.
// In viewDidLoad or where map is initialized...
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPress:)];
lpgr.minimumPressDuration = 1.0; //user must hold for 1 second
[mapView addGestureRecognizer:lpgr];
[lpgr release];
...
- (void)handleLongPress:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state != UIGestureRecognizerStateBegan)
return;
CGPoint touchPoint = [gestureRecognizer locationInView:mapView];
CLLocationCoordinate2D touchMapCoordinate = [mapView convertPoint:touchPoint toCoordinateFromView:mapView];
//add pin where user touched down...
MKPointAnnotation *pa = [[MKPointAnnotation alloc] init];
pa.coordinate = touchMapCoordinate;
pa.title = #"Hello";
[mapView addAnnotation:pa];
[pa release];
//add circle with 5km radius where user touched down...
MKCircle *circle = [MKCircle circleWithCenterCoordinate:touchMapCoordinate radius:5000];
[mapView addOverlay:circle];
}
-(MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id)overlay
{
MKCircleView* circleView = [[[MKCircleView alloc] initWithOverlay:overlay] autorelease];
circleView.fillColor = [UIColor redColor];
return circleView;
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString *AnnotationIdentifier = #"Annotation";
MKPinAnnotationView* pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if (!pinView)
{
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier] autorelease];
pinView.pinColor = MKPinAnnotationColorGreen;
pinView.animatesDrop = YES;
}
else
{
pinView.annotation = annotation;
}
return pinView;
}

Why can't I get mapkit to display a custom annotation pin image?

I figured that using my own custom pin image for annotations would be super easy.
But I have never been able to get it to work, and I have no idea why!
I am simply using:
Annotation *anno = [[[Annotation alloc] init] autorelease];
anno.coordinate = ridesMap.userLocation.location.coordinate;
anno.title = #"Current Location";
anno.subtitle = [NSString stringWithFormat:#"%f, %f", anno.coordinate.latitude, anno.coordinate.longitude];
static NSString *defaultPinID = #"LocationIdentifier";
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[ridesMap dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if (pinView == nil){
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:anno reuseIdentifier:defaultPinID] autorelease];
}
pinView.image = [UIImage imageNamed:#"custom_pin.png"];
pinView.opaque = NO;
pinView.canShowCallout = YES;
pinView.draggable = NO;
pinView.annotation = anno;
NSLog(#"Adding current location annotation");
return pinView;
I assumed that this should work, as a UIImage is what it is wanting, and I do have the custom_pin.png file in my project.
It never uses my image, but just the standard red pin. What am I doing wrong here?
From the docs:
The MKPinAnnotationView class provides a concrete annotation view that displays a pin icon like the ones found in the Maps application.
In other words, a MKPinAnnotationView will ignore the image property and always display a pin. Use a regular MKAnnotationView instead.