I am trying to show multiple pins on a map using latitude and longitude from an array of dictionaries. The problem is it is only showing the pin for the last dictionary in the plist always.
Here is the method I have:
- (void)loadMapPins
{
MapAnnotation *annotation = [[MapAnnotation alloc] init];
for (int i=0; i<self.dataDictionary.count; i++){
NSDictionary *dictionary = [NSDictionary dictionaryWithDictionary:[self.dataDictionary objectAtIndex:i]];
double latitude = [[dictionary objectForKey:#"Latitude"] doubleValue];
double longitude = [[dictionary objectForKey:#"Longitude"] doubleValue];
CLLocationCoordinate2D coord = {.latitude =
latitude, .longitude = longitude};
MKCoordinateRegion region = {coord};
annotation.title = [dictionary objectForKey:#"Name"];
annotation.subtitle = [dictionary objectForKey:#"Center Type"];
annotation.coordinate = region.center;
[mapView addAnnotation:annotation];
}
}
I need it to go through the loop and drop the pins on the map accordingly. Any help/examples are appreciated.
I think you want to move your annotation creation into your loop. From the looks of things you only created one, then in the loop you mutate it over and over again. When the loop completes, the last modification to your annotation variable reflects the last item in self.dataDictionary that you are iterating.
The code below creates a new annotation object each loop iteration.
- (void)loadMapPins
{
for (int i=0; i<self.dataDictionary.count; i++){
NSDictionary *dictionary = [NSDictionary dictionaryWithDictionary:[self.dataDictionary objectAtIndex:i]];
double latitude = [[dictionary objectForKey:#"Latitude"] doubleValue];
double longitude = [[dictionary objectForKey:#"Longitude"] doubleValue];
CLLocationCoordinate2D coord = {.latitude =
latitude, .longitude = longitude};
MKCoordinateRegion region = {coord};
MapAnnotation *annotation = [[MapAnnotation alloc] init];
annotation.title = [dictionary objectForKey:#"Name"];
annotation.subtitle = [dictionary objectForKey:#"Center Type"];
annotation.coordinate = region.center;
[mapView addAnnotation:annotation];
}
}
Hope this helps,
Scott H
Related
i want to add latitude and longitude in plist and want to show the location on map view.
I am unable to load latitude and longitude in plist.
NSString *path = [[NSBundle mainBundle] pathForResource:#"map" ofType:#"plist"];
NSArray *anns = [NSArray arrayWithContentsOfFile:path];
NSLog(#"anns=%#",anns);
for(NSMutableDictionary *note in anns) {
float realLatitude = [[note objectForKey:#"latitude"] floatValue];
float realLongitude = [[note objectForKey:#"logitude"] floatValue];
WHLocationAnnotation* myAnnotation = [[WHLocationAnnotation alloc] init];
CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = realLatitude;
theCoordinate.longitude = realLongitude;
NSLog(#"...abc...%f",[[note objectForKey:#"latitude"] floatValue]);
myAnnotation.title = [note objectForKey:#"Title"];
myAnnotation.subtitle = [note objectForKey:#"subtitle"];
[mapViewForAnnotation setDelegate:self];
[mapViewForAnnotation addAnnotation:myAnnotation];
}
}
I have done this in viewdidload. I am getting latitude longitude with nslog but location is not correct on mapview.
I want to load map on MKMapView.
Basically what i want to do is,
I want to load Particular Venue in my MapView.
My Database contains lot of Venues, according to requirement, i am fetching Venue and i want to load that Venue in my mapView.
for eg: I got this as Venue: #"100 Oxford Street, London, W1D 1LL, 020 7636 0933" from Database, then i want to load this location in my mapView
Thanks in advance.
EDIT:
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
NSString *venue= #"100 Oxford Street, London, W1D 1LL, 020 7636 0933";
[geocoder geocodeAddressString:venue completionHandler:^(NSArray *placemarks, NSError *error)
{
if ([placemarks count] > 0)
{
CLPlacemark *placemark = [placemarks objectAtIndex:0];
CLLocation *loc = placemark.location;
CLLocationCoordinate2D _venue = loc.coordinate;
NSLog(#"_venue:=%f",loc.coordinate);
MKPointAnnotation *venueAnnotation = [[MKPointAnnotation alloc]init];
[venueAnnotation setCoordinate:_venue];
[venueAnnotation setTitle:#"Venue"];
[MapVw addAnnotation:venueAnnotation];
}
}
];
- (IBAction)BtnClick:(id)sender {
NSLog(#"Map ");
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:#"100 Oxford Street, London, W1D 1LL, 020 7636 0933"
completionHandler:^(NSArray* placemarks, NSError* error)
{
if (placemarks && placemarks.count > 0)
{
CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
[self.MapView addAnnotation:placemark];
CLLocationCoordinate2D _venue = placemark.coordinate;
[self.MapView setCenterCoordinate:_venue];
MKCoordinateRegion region = self.MapView.region;
region.span.longitudeDelta = 1.0;
region.span.latitudeDelta = 1.0;
[self.MapView setRegion:region animated:YES];
}
}
];
}
Steps:
1. Import CoreLocation.framework and MapKit.framework.
2. Use CoreLocation class Geocoder's method :
geoCodeAddressString:completionHandler:
NSString *venue= #"100 Oxford Street, London, W1D 1LL, 020 7636 0933";
[_geoCoder geocodeAddressString:venue completionHandler:^(NSArray *placemarks, NSError *error)
{
if ([placemarks count] > 0)
{
CLPlacemark *placemark = [placemarks objectAtIndex:0];
CLLocation *loc = placemark.location;
CLLocationCoordinate2D _venue = loc.coordinate;
}
});
]
[self performSelector:#selector(createVenueAnnotation) withObject:nil afterDelay:5];
UIActivityIndicatorView *activity = [[UIActivityIndicatorView alloc]init];
[_mapView addSubview:activity];
[activity startAnimating];
Step 3. If you want to place a MKPointAnnotation on the venue point.
- (void)createVenueAnnotation{
[activity stopAnimating];
[activity removeFromSuperview];
MKPointAnnotation *venueAnnotation = [[MKPointAnnotation alloc]init];
[venueAnnotation setCoordinate:_venue];
[venueAnnotation setTitle:#"Venue"];
[_mapView addAnnotation:venueAnnotation];
}
Step 4: Center your map around the venue.
// you need to call this function
- (void)centerMapAroundVenue
{
MKMapRect rect = MKMapRectNull;
MKMapPoint venuePoint = MKMapPointForCoordinate(_venue);
rect = MKMapRectUnion(rect, MKMapRectMake(venuePoint .x, venuePoint .y, 0, 0));
MKCoordinateRegion region = MKCoordinateRegionForMapRect(rect);
[_mapView setRegion:region animated:YES];
}
Here is simple scenario :
Get the Co-ordinates of the Address using GeoCoder
Using the Co-ordinatation ,Add the Annotation to the MapView.
Do something Like this to get the CLlocationCoordinate :
- (CLLocationCoordinate2D) geoCodeUsingAddress:(NSString *)address
{
double latitude = 0, longitude = 0;
NSString *esc_addr = [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *req = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", esc_addr];
NSString *result = [NSString stringWithContentsOfURL:[NSURL URLWithString:req] encoding:NSUTF8StringEncoding error:NULL];
if (result) {
NSScanner *scanner = [NSScanner scannerWithString:result];
if ([scanner scanUpToString:#"\"lat\" :" intoString:nil] && [scanner scanString:#"\"lat\" :" intoString:nil]) {
[scanner scanDouble:&latitude];
if ([scanner scanUpToString:#"\"lng\" :" intoString:nil] && [scanner scanString:#"\"lng\" :" intoString:nil]) {
[scanner scanDouble:&longitude];
}
}
}
CLLocationCoordinate2D center;
center.latitude = latitude;
center.longitude = longitude;
return center;
}
Using the Center just add the annotation to the MapView.
[self.mapView addAnnotation:<annotationName>];
Plz go through this link For more info.
Hope this helps.
Hi my array is filled with three objects and only 1 annotation is showing on the map. Any ideas? If i NSLog certain elements it is filled. Just cant get the 3 annotations to show.
NSMutableArray *currentBranch = [xmlParser branch];
int counter=[currentBranch count];
NSMutableArray *new = [[NSMutableArray alloc] init];
CLLocationCoordinate2D coordinates;
Mapdets * myAnn;
myAnn = [[Mapdets alloc] init];
[mapview setMapType:MKMapTypeStandard];
[mapview setZoomEnabled:YES];
[mapview setScrollEnabled:YES];
MKCoordinateRegion region = {{0.0, 0.0}, {0.0,0.0 }};
region.center.latitude = -33.86434888;
region.center.longitude = 151.2090236;
region.span.longitudeDelta = 55.80f;
region.span.latitudeDelta = 55.80f;
[mapview setRegion:region animated:YES];
for(int i=0;i<counter;i++)
{
Mapdets *currentBranch = [[xmlParser branch] objectAtIndex:i];
NSString *title = currentBranch.title;
NSString *subtitle = currentBranch.subtitle;
NSString *lat = currentBranch.lat;
NSString *lng = currentBranch.lng;
coordinates.latitude = [lat doubleValue];
coordinates.longitude = [lng doubleValue];
myAnn.coordinate = coordinates;
myAnn.title = title;
myAnn.subtitle = subtitle;
NSLog(#"%#", title);
[new addObject:myAnn];
}
[mapview addAnnotations:new];
Thanks for the help!
Just initialise myAnn in for loop..
for(int i=0;i<counter;i++)
{
Mapdets * myAnn;
myAnn = [[Mapdets alloc] init];
Mapdets *currentBranch = [[xmlParser branch] objectAtIndex:i];
NSString *title = currentBranch.title;
NSString *subtitle = currentBranch.subtitle;
NSString *lat = currentBranch.lat;
NSString *lng = currentBranch.lng;
coordinates.latitude = [lat doubleValue];
coordinates.longitude = [lng doubleValue];
myAnn.coordinate = coordinates;
myAnn.title = title;
myAnn.subtitle = subtitle;
NSLog(#"%#", title);
[new addObject:myAnn];
}
I have looked at other questions in stackoverflow that are closely related to my question however my issue is a bit different. Here, the code works fine on iPad but not my iPhone. My iPad will load all 300+ annotations correctly but my iPhone will only load only 80 of them. I'm not sure if this is due to the amount of memory on the iPhone because it does the same thing when I test on the simulator. Below you will find my sample code.
#interface MOVmapViewController ()
#end
#define VA_LATITUDE 37.413754;
#define VA_LONGITUDE -79.142246;
//Span
#define THE_SPAN 5.50f;
#implementation MOVmapViewController
#synthesize myMapView;
-(IBAction)findmylocation:(id)sender {
myMapView.showsUserLocation = YES;
myMapView.delegate = MKMapTypeStandard;
[myMapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
}
-(IBAction)setmaptype:(id)sender {
switch (((UISegmentedControl *)sender).selectedSegmentIndex) {
case 0:
myMapView.mapType = MKMapTypeStandard;
break;
case 1:
myMapView.mapType = MKMapTypeSatellite;
break;
case 2:
myMapView.mapType = MKMapTypeHybrid;
break;
default:
myMapView.mapType = MKMapTypeStandard;
break;
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typiclly from a nib.
//Create the region
MKCoordinateRegion myRegion;
//Center
CLLocationCoordinate2D center;
center.latitude = VA_LATITUDE;
center.longitude = VA_LONGITUDE;
//Span
MKCoordinateSpan span;
span.latitudeDelta = THE_SPAN;
span.longitudeDelta = THE_SPAN;
myRegion.center = center;
myRegion.span = span;
//Set our mapView
[myMapView setRegion:myRegion animated:YES];
//Annotations
//Abingdon Lodge No. 48
NSString *abingdon = #"325 W Main Street Abingdon, Virginia 24210";
CLGeocoder *abingdongeo = [[CLGeocoder alloc] init];
[abingdongeo geocodeAddressString:abingdon completionHandler:^(NSArray* placemarks, NSError* error){
if (placemarks && placemarks.count > 0) {CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = placemark.coordinate;
point.title = #"Abingdon Lodge No. 48";
point.subtitle = #"Abingdon, VA";
[self.myMapView addAnnotation:point]; }}];
//York Lodge No. 12
NSString *york = #"14411 Black Hollow Road Abingdon, Virginia 24210";
CLGeocoder *yorkgeo = [[CLGeocoder alloc] init];
[yorkgeo geocodeAddressString:york completionHandler:^(NSArray* placemarks, NSError* error){
if (placemarks && placemarks.count > 0) {CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = placemark.coordinate;
point.title = #"York Lodge No. 12";
point.subtitle = #"Abingdon, VA";
[self.myMapView addAnnotation:point]; }}];
//Alberene Lodge No. 277
NSString *alberene = #"2722 Plank Road Alberene, Virginia 22959";
CLGeocoder *alberenegeo = [[CLGeocoder alloc] init];
[alberenegeo geocodeAddressString:alberene completionHandler:^(NSArray* placemarks, NSError* error){
if (placemarks && placemarks.count > 0) {CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = placemark.coordinate;
point.title = #"Alberene Lodge No. 277";
point.subtitle = #"Alberene, VA";
[self.myMapView addAnnotation:point]; }}];
//A. Douglas Smith, Jr. Lodge of Research No. 1949
NSString *douglas = #"101 Callahan Drive Alexandria, Virginia 22301";
CLGeocoder *douglasgeo = [[CLGeocoder alloc] init];
[douglasgeo geocodeAddressString:douglas completionHandler:^(NSArray* placemarks, NSError* error){
if (placemarks && placemarks.count > 0) {CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = placemark.coordinate;
point.title = #"A. Douglas Smith, Jr. Lodge of Research No. 1949";
point.subtitle = #"Alexandria, VA";
[self.myMapView addAnnotation:point]; }}];
//Alexandria-Washington Lodge No. 22 same location as above use lat/long
CLLocationCoordinate2D washington;
washington.latitude = 38.806758;
washington.longitude = -77.065251;
Annotation *alexandriawashingtonlodge = [Annotation alloc];
alexandriawashingtonlodge.coordinate = washington;
alexandriawashingtonlodge.title = #"Alexandria-Washington Lodge No. 22";
alexandriawashingtonlodge.subtitle = #"Alexandria, VA";
[self.myMapView addAnnotation:alexandriawashingtonlodge];
This list continues for a total of about 310 lodge locations.
Use like this,
NSString *abingdon = #"325 W Main Street Abingdon, Virginia 24210";
CLGeocoder *abingdongeo = [[CLGeocoder alloc] init];
[abingdongeo geocodeAddressString:abingdon completionHandler:^(NSArray* placemarks, NSError* error){
if (placemarks && placemarks.count > 0) {
CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = placemark.coordinate;
point.title = #"Abingdon Lodge No. 48";
point.subtitle = #"Abingdon, VA";
// 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]; }}];
The reason that some of my annotations are not showing up is because I'm calling on CLGeocoder to many times. Here is how I fixed the issue.
//Columbia Lodge No. 285
CLLocationCoordinate2D columbia;
columbia.latitude = 38.895746;
columbia.longitude = -77.106511;
Annotation *columbialodge = [[Annotation alloc] init];
columbialodge.coordinate = columbia;
columbialodge.title = #"Columbia Lodge No. 285";
columbialodge.subtitle = #"Arlington, VA";
[self.myMapView addAnnotation:columbialodge];
I'v converted all my of address to Lat long. Which has cut down on memory usage as well.
As much as I enjoyed just putting in the address it looks like CLGeocoder is just taking up to many resources.
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;
}