Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Improve this question
I'm getting the wrong annotation location on Mapview. I have tried so many things, but with no luck.
I'm getting the right coordinate but it's displayed at the wrong location on mapview. Does anyone know why?
for(WatchEntityLocation *watchEntityLocation in watchEntityLocationList)
{
locationArray=watchEntityLocation.locationList;
NSLog(#"location count:%i",[locationArray count]);
Location *location=[locationArray objectAtIndex:0];
NSLog(#"watcher latlong:%g,%g",location.latitude,location.longitude);
CLLocationCoordinate2D coordinate= CLLocationCoordinate2DMake(location.latitude,location.longitude);
if (CLLocationCoordinate2DIsValid(coordinate)) {
NSLog(#"valid Cordinate!");
} else {
NSLog(#"Invalid Cordinate!");
}
NSLog(#"latitude is::%g" , coordinate.latitude);
NSLog(#"longitude is: :%g" , coordinate.longitude);
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(coordinate, 0.5*METERS_PER_MILE, 0.5*METERS_PER_MILE);
MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion];
NSLog(#"adjustedRegion latitude is::%g" , adjustedRegion.center.latitude);
NSLog(#"adjustedRegion longitude is: :%g" ,adjustedRegion.center.longitude);
if ((adjustedRegion.center.latitude >= -90) && (adjustedRegion.center.latitude <= 90) && (adjustedRegion.center.longitude >= -180) && (adjustedRegion.center.longitude <= 180)){
NSLog(#"valid region!");
[mapView setRegion:adjustedRegion animated:YES];
mapView.showsUserLocation = NO;
}else{
NSLog(#"Invalid region!");
}
[self addAnnotation:adjustedRegion.center tlocation:watchEntityLocation.watchEntity.name];}
-(void)addAnnotation:(CLLocationCoordinate2D)lcordinate tlocation:(NSString *)name
{
MyAnnotation *annotation =
[[MyAnnotation alloc] initWithCoordinates:lcordinate
title:name
subTitle:#""];
annotation.pinColor = MKPinAnnotationColorGreen;
[mapView addAnnotation:annotation];
[annotationArray addObject:annotation];
}
- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views
{
for (MKAnnotationView *av in views) {
id <MKAnnotation> mp = [av annotation];
if (![mp isKindOfClass:[MKUserLocation class]])
{
[mv selectAnnotation:mp animated:YES];
break;
}
}
}
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
if(annotation != map.userLocation)
{
MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"MyPin"];
annView.animatesDrop=TRUE;
annView.canShowCallout = YES;
[annView setSelected:YES];
annView.pinColor = MKPinAnnotationColorRed;
annView.calloutOffset = CGPointMake(15, 15);
return annView;
}
I think check your lat-long datatype and its value.
Related
I have a MKMapView that is having a very strange problem which is kind of hard to explain.
I have an MKOverlay that is saved between sessions by saving the points of the overlay to a file and loading the overlay in viewDidLoad. So here's the problem:
Steps
I add an MKOverlay to the MKMapView
On the second or third run after adding the MKOverlay to the map
everything on the map gets overlayed by an overlay of the same color
as the one I added. Everything on the map with the exception of the
view of the map that you can see when the view loaded.
Other weird things:
This problem only occurs when mapView.showsUserLocation is set to
true
This problem only occurs on iOS5. Everything works fine on iOS6.
If you zoom out the colored overlay re sizes the visible portion of
the map to fill the map at the new level at which you zoomed out to.
This guy is having the same problem, although his solution did not work for me.
Trouble with overlay using MKPolyline & MKPolylineView
Here is some of my code:
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
MKPinAnnotationView *pinView = nil; //switch this to MKAnnotationView and use .image property if pins need to be images
if(annotation == self.startingPin || annotation == self.endingPin){
static NSString *defaultPinID = #"com.MagnusDevelopment.pin";
pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if (pinView == nil)pinView = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:defaultPinID];
pinView.canShowCallout = YES;
pinView.animatesDrop = TRUE;
if(annotation == self.startingPin){
//starting pin
pinView.pinColor = MKPinAnnotationColorGreen;
}else{
//ending pin
pinView.pinColor = MKPinAnnotationColorRed;
}
}
return pinView;
}
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
MKPolylineView *aView = [[MKPolylineView alloc] initWithPolyline:(MKPolyline *)overlay];
aView.lineWidth = 7.0;
aView.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.6];
return aView;
}
Code called when the view loads, I have logged the coordinates that are being added to the polyline array right before they are added, and everything is fine and dandy!
NSInteger numberOfSteps = pointsArray.count;
NSLog(#"number of steps: %i",numberOfSteps);
CLLocationCoordinate2D coordinates[numberOfSteps];
for (NSInteger index = 0; index < numberOfSteps; index++) {
CLLocation *location = [pointsArray objectAtIndex:index];
CLLocationCoordinate2D coordinate = location.coordinate;
coordinates[index] = coordinate;
}
MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:coordinates count:numberOfSteps];
[self.mainMap addOverlay:polyLine];
Here is a picture of what happens when the overlay appears and the user pans to the side on the map:
Any ideas about what the problem is?
You're using dequeueReusableAnnotationViewWithIdentifier, but you're only assigning an annotation to pinView if the result of dequeueReusableAnnotationViewWithIdentifier was nil.
As that method will often return an existing MKPinAnnotationView instance, this should instead be:
MKPinAnnotationView *pin = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if (pin == nil) {
pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID];
} else {
pin.annotation = annotation;
}
This might be the problem: When the mapview tries to access the view for user's current location, you are passing your customized view.
Try adding this with your existing implementation.
- (MKAnnotationView *) mapView:(MKMapView *) mapView viewForAnnotation:(id ) annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]]) {
return nil;
}
return yourView;
}
PS: This may not be an issue of overlay view.
Best Regards.
I am new with MapKit and all its functionalities and therefore, stuck at trying to display a pin. I followed an online video tutorial on how to find user current location and drop a pin there. But when I typed the method for the pin, I do not get it at all. I would like to know where did I go wrong for this.
- (void)viewDidLoad{
[super viewDidLoad];
self.title = #"Location";
mapView.showsUserLocation = YES;
self.locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
[locationManager startUpdatingHeading];
}
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
NSLog(#"Annotation view run");
MKPinAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"currentloc"];
pin.animatesDrop = YES;
return pin;
}
-(void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
// once location is determined, center to that location.
location = newLocation.coordinate;
MKCoordinateRegion region;
region.center = location;
MKCoordinateSpan span;
span.latitudeDelta = 0.003;
span.longitudeDelta = 0.003;
region.span = span;
[mapView setRegion:region animated:FALSE];
}
Any advice of where I done wrong would be great!
As your method is never got invoked, you should do:
- (void)mapView:(MKMapView *)aMapView regionDidChangeAnimated:(BOOL)animated {
[aMapView removeAnnotation:[self point]];
mkShape.coordinate = aMapView.centerCoordinate;
[aMapView addAnnotation:mkShape];
}
And you should create your MKAnnotationView properly.
You need create two properties in .h file first (for performance reason):
MKPointAnnotation *mkShape;
MKAnnotationView *annotationView;
then use the code below to create your MKPointAnnotation
- (void)createShape
{
if (!mkShape) {
mkShape = [[MKPointAnnotation alloc] init];
mkShape.title = nil;
mkShape.subtitle = #"test description";
}
}
- (id <MKAnnotation>)point
{
[self createShape];
// Make sure to check if this is an MKPointAnnotation. MKOverlays also
// conform to MKAnnotation, so it isn't sufficient to just check to
// conformance to MKAnnotation.
if ([mkShape isKindOfClass:[MKPointAnnotation class]])
return (id <MKAnnotation>)mkShape;
return nil;
}
- (MKAnnotationView *)annotationView
{
if (!annotationView) {
id <MKAnnotation> annotation = [self point];
if (annotation) {
MKPinAnnotationView *pin =
[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil];
pin.canShowCallout = YES;
pin.animatesDrop = YES;
pin.draggable = NO;
annotationView = pin;
}
}
return annotationView;
}
- (MKAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isEqual:mkShape]) {
return [self annotationView];
}
return nil;
}
At the end, don't forget to release your properties.
- (void)dealloc
{
[annotationView release];
[mkShape release];
[super dealloc];
}
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
I'm developing an app to show the stores available in a particular zipcode. I start with the current location. I'm getting a blue pulsating dot for my current location. when I enter a zipcode I'm able to show the annotations in the mapview. I have a button "current location" which can to go back to the current location again. However the second time I'm not getting the blue dot? How do I get it, this is the code:
- (void)showCurrentLocation
{
self.mapView.showsUserLocation = YES;
GPSAnnotation *annotation = [[GPSAnnotation alloc] initWithCoordinate:self.mapView.userLocation.coordinate];
annotation.title = #"Location";
[self.mapView addAnnotation:annotation];
[annotation release];
MKCoordinateRegion zoomIn;
zoomIn.center.latitude = self.mapView.userLocation.coordinate.latitude;
zoomIn.center.longitude=self.mapView.userLocation.coordinate.longitude;
zoomIn.span.latitudeDelta = .1f;
zoomIn.span.longitudeDelta =.1f;
self.mapView.showsUserLocation = YES;
[self.mapView setRegion:zoomIn animated:TRUE];
}
// annotation view
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(GPSAnnotation *)annotation
{
if ([[annotation title] isEqualToString:#"Location"])
{
MKAnnotationView *annotationView=[[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil] autorelease];
annotationView = [self.mapView dequeueReusableAnnotationViewWithIdentifier:#"blueDot"];
annotationView.annotation = annotation;
return annotationView;
}
else if ([annotation isKindOfClass:[MKUserLocation class]])
{
return nil;
}
}
Do you make somewhere a [self.mapView removeAnnotations:self.mapView.annotations] to empty the map? Thats a common error because you also remove the userlocation by doing that.
i have got the Latitude and Longitude from XML Parsing how can i show MapAnnotation(pin) on the Map,Please help me....
Create a new class that implements the MKAnnotation protocol. This will hold the lat/long, and will also have a title and description which will be displayed if you select the annotation after it has been rendered on your map.
The controller for the view that will display the map will need to implement the - - (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation; method of the MKMapViewDelegate protocol. The code in this method will look something like the code at the bottom (apologies for the poor formatting, I couldn't get right in here or at the bottom).
Then at some point in your controller code you will need to call something along the lines of [self.mapView addAnnotation: annotation]; where annotation is an instance of your custom annotation class created in step 1, with the lat/long set etc.
Finally, so that the viewForAnnotation method gets called correctly, and is something that is easy to miss, in interface builder, make sure that you set the delegate outlet of the MKMapView to be your controller (that implements the MKMapViewDelegate protocol.
-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation {
static NSString *AnnotationViewIdentifier = #"annotationViewIdentifier";
MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier: AnnotationViewIdentifier];
if (annotationView == nil) {
annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier: AnnotationViewIdentifier] autorelease];
// This is all optional and depends on your requirements
annotationView.animatesDrop = NO;
annotationView.canShowCallout = YES;
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
annotationView.enabled = YES;
annotationView.pinColor = MKPinAnnotationColorGreen;
}
return annotationView;
}
First you want to create MKAnnotation Protocol class (Here MyAnnotation class implements the MKAnnotation Protocol).This class should be includes lat, long, title, subtitle and also whatever you want.
Second, In your view controller, where you want to display the pin and you will implement this code,
AnnObj = [[MyAnnotation alloc] init];
AnnObj.latitude = [[latitude objectAtIndex:storyIndex] floatValue];
AnnObj.longitude = [[longitude objectAtIndex:storyIndex] floatValue];
MKCoordinateRegion region;
region.center = location;
MKCoordinateSpan span;
region.center.latitude = [[latitude objectAtIndex:storyIndex] floatValue];
region.center.longitude = [[longitude objectAtIndex:storyIndex] floatValue];
span.latitudeDelta = 0.0005;
span.longitudeDelta = 0.0005;
region.span = span;
[mapview setRegion:region animated:TRUE];
AnnObj.title = titleString;
AnnObj.subTitle = subTitleString;
NSString * titleString = [[buildingNames objectAtIndex:storyIndex] stringByReplacingOccurrencesOfString:#"\n\t" withString:#""];
[eventPoints addObject:AnnObj];
[mapview addAnnotations:eventPoints];
Third, Implement the MKAnnotation delegate method,
- (MKAnnotationView *)mapView: (MKMapView *)lmapView viewForAnnotation:(id <MKAnnotation>) annotation {
if (lmapView.userLocation == annotation){
return nil;
}
MKAnnotationView* myCusAnn = (MKAnnotationView*)[lmapView dequeueReusableAnnotationViewWithIdentifier:#"eventview"];
if(myCusAnn == nil)
{
myCusAnn = [[[ MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"eventview"] autorelease];
}
myCusAnn.canShowCallout = YES;
[myCusAnn setEnabled:YES];
return myCusAnn;
}
I hope it will help you.