Hi am using this method to get the coordinates and add a pin to the map view for one post code
-(void)myMapview
{
//sitePC is an Array with the Post code location
NSString *addressString = [self.sitePC valueForKey:#"sitePC"];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:addressString completionHandler:^(NSArray *placemarks, NSError *anError)
{ for(CLPlacemark *placemark in placemarks) {
NSLog(#"Placemark: %#",placemark);
MKPointAnnotation *pa = [[MKPointAnnotation alloc] init];
pa.coordinate = placemark.location.coordinate;
pa.title = [self.sitePC valueForKey:#"siteName"];
[self.mapview addAnnotation:pa];
} if(anError)
{ NSLog(#"Error: %#",[anError description]); }
}];
}
but now the sitePC array hold 10 post codes to process, I read the Documents for CLGeocoder and I know I can only send one request at the time.
my question is how do I send only one request at the time , for each postcode ?
You can make an Array for annotations and Add that annotation array on MapView . Hope following changes in code will help you.
NSString *addressString = [self.sitePC valueForKey:#"sitePC"];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:addressString completionHandler:^(NSArray *placemarks, NSError *anError)
{
NSMutableArray *pointsArray = [[NSMutableArray alloc]init]
for(CLPlacemark *placemark in placemarks) {
NSLog(#"Placemark: %#",placemark);
MKPointAnnotation *pa = [[MKPointAnnotation alloc] init];
pa.coordinate = placemark.location.coordinate;
pa.title = [self.sitePC valueForKey:#"siteName"];
[pointsArray addObject:pa];
}
[self.mapview addAnnotations:pointsArray];
if(anError)
{ NSLog(#"Error: %#",[anError description]); }
}];
Related
I'm using the below code to display addresses from an array (responseObject) as annotations on my mapview. It works, and the pin is dropped successfully from my location string, however it only shows a pin for the most recent address added to the array. How can I change my code so that it shows pins on the map for all addresses in my array instead of just the most recent one? Apologies if this is a newb question. Thanks!
viewcontroller.m
NSMutableDictionary *viewParams = [NSMutableDictionary new];
[viewParams setValue:#"u000" forKey:#"view_name"];
[DIOSView viewGet:viewParams success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.addressData = [responseObject mutableCopy];
NSString *location = self.addressData[0][#"address"];
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];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = placemark.coordinate;
point.title = self.addressData[0][#"users_name"];
point.subtitle = self.addressData[0][#"userbio"];
[self.mapView addAnnotation:point];
You are accessing only one object ?
NSString *location = self.addressData[0][#"address"];
Edited
I think you should handle your data, separated with your view. i.e. implement geocoder related code in the mapView:viewForAnnotation: method in your map view delegate. Then you should be able to create the annotations one by one and use [self.mapView addAnnotations] for all of them
For your code, which I believe is inspired by this answer, you should be able to iterate through all location addresses by something like
for (NSMutableDictionary *loc in self.addressData) {
NSString *loc = location[#"address"];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
......
}
Forgive me if the syntax is wrong for Objective C.
I want to search for a destination using the name in MapKit and get back the longitude and latitude (CLLocationCoordinate2D).
Currently I'm using the hardcoded value to set the destination.
// Make a directions request
MKDirectionsRequest *directionsRequest = [MKDirectionsRequest new];
// Start at our current location
MKMapItem *source = [MKMapItem mapItemForCurrentLocation];
[directionsRequest setSource:source];
// Make the destination --> I WANT TO GET THIS COORDINATE USING NAME
CLLocationCoordinate2D destinationCoords = CLLocationCoordinate2DMake(45.545824, 9.327515);
MKPlacemark *destinationPlacemark = [[MKPlacemark alloc] initWithCoordinate:destinationCoords addressDictionary:nil];
MKMapItem *destination = [[MKMapItem alloc] initWithPlacemark:destinationPlacemark];
[directionsRequest setDestination:destination];
You have to use CLGeocoder to forward-geocode using an address:
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:#"New York City" completionHandler:^(NSArray *placemarks, NSError *error) {
if (error) {
NSLog(#"%#", error);
} else {
CLPlacemark *placemark = [placemarks lastObject];
MKCoordinateRegion region;
region.center.latitude = placemark.location.coordinate.latitude;
region.center.longitude = placemark.location.coordinate.longitude;
[self.mapView setRegion:region animated:YES];
}
}];
This will set the map's region to the location returned, using the latitude and longitude as it's centre.
There must be an easy way to do this or somewhere I am going wrong but I can't seem to save my current location as a global variable and then add it to my array to populate my UITableView.
Basically, at the moment I have an empty UITableView that is used to populate results from a local search, via a search bar. This part works great. BUT, what I want is to always have the 1st row as the users current location, like in maps, google maps, reminders etc. I figured this would be a simple task but I cant get it to work. Can someone help me please.
I use the following code to get my current location, reverse geocode it, and plot it on the map when the app starts:
self.locationManager = [[CLLocationManager alloc]init];
if ([CLLocationManager locationServicesEnabled]) {
self.locationManager.delegate = self;
self.locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
}
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = _locationManager.location.coordinate.latitude;
zoomLocation.longitude= _locationManager.location.coordinate.longitude;
currentCoord.latitude = _locationManager.location.coordinate.latitude;
currentCoord.longitude= _locationManager.location.coordinate.longitude;
//reverse geocoder
CLLocation *currentLocation = [[CLLocation alloc] initWithLatitude:zoomLocation.latitude longitude:zoomLocation.longitude];
CLGeocoder *geoCoder = [[CLGeocoder alloc] init];
[geoCoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
for (CLPlacemark *placemark in placemarks) {
MKPointAnnotation *annotation =
[[MKPointAnnotation alloc]init];
annotation.coordinate = zoomLocation;
annotation.title = #"Current Location";
annotation.subtitle = placemark.name;
// 2
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 0.5*METERS_PER_MILE, 0.5*METERS_PER_MILE);
// 3
[_mapView setRegion:viewRegion animated:YES];
[_mapView addAnnotation:annotation];
}
}];
When I run my local search I use the following code to populate my array to load the table with:
MKLocalSearchRequest *request =
[[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = _searchBar.text;
request.region = _mapView.region;
MKLocalSearch *search =
[[MKLocalSearch alloc]initWithRequest:request];
[search startWithCompletionHandler:^(MKLocalSearchResponse
*response, NSError *error) {
if (response.mapItems.count == 0)
NSLog(#"No Matches");
else
for (MKMapItem *item in response.mapItems)
{
[tableData addObject:item];
MKPointAnnotation *annotation =
[[MKPointAnnotation alloc]init];
annotation.coordinate = item.placemark.coordinate;
annotation.title = item.placemark.name;
annotation.subtitle = item.placemark.title;
[annotations addObject:annotation];
[_tableResults reloadData];
}
}];
I really can't figure this out. How would I add my current location? Would really appreciate some advise. Thanks in advance guys!
Try this,
[search startWithCompletionHandler:^(MKLocalSearchResponse
*response, NSError *error) {
if (response.mapItems.count == 0)
NSLog(#"No Matches");
else
for (MKMapItem *item in response.mapItems)
{
[tableData addObject:item];
[annotations addObject:[self annotationFromMapItem:item]];
}
double latitude = self.locationManager.location.coordinate.latitude;
double longitude = self.locationManager.location.coordinate.longitude;
MKPlacemark *placemark = [[[MKPlacemark alloc] initWithCoordinate:CLLocationCoordinate2DMake(latitude, longitude) addressDictionary:nil] autorelease];
MKMapItem *mapItem = [[[MKMapItem alloc] initWithPlacemark:placemark] autorelease];
[mapItem setName:Current Location];
[tableData insertObject:mapItem atIndex:0];
[annotations insertObject:[self annotationFromMapItem:mapItem] atIndex:0];
[_tableResults reloadData];
}];
- (MKPointAnnotation) annotationFromMapItem:(MKMapItem *)item {
MKPointAnnotation *annotation =
[[MKPointAnnotation alloc]init];
annotation.coordinate = item.placemark.coordinate;
annotation.title = item.placemark.name;
annotation.subtitle = item.placemark.title;
return annotation;
}
This question already has answers here:
Easiest way of getting reverse geocoded current location from iOS
(4 answers)
Closed 9 years ago.
I need to find the name of the user's location using latitude and longitude. The following code I have used to pin the point in location using annotation.
//MAP VIEW Point
MKCoordinateRegion myRegion;
//Center
CLLocationCoordinate2D center;
center.latitude=latitude;
center.longitude=longitude;
//Span
MKCoordinateSpan span;
span.latitudeDelta=THE_SPAN;
span.longitudeDelta=THE_SPAN;
myRegion.center=center;
myRegion.span=span;
//Set our mapView
[MapViewC setRegion:myRegion animated:YES];
//Annotation
//1.create coordinate for use with the annotation
CLLocationCoordinate2D wimbLocation;
wimbLocation.latitude=latitude;
wimbLocation.longitude=longitude;
Annotation * myAnnotation= [Annotation alloc];
myAnnotation.coordinate=wimbLocation;
This could be the simplest way
- (void)reverseGeocodeLocation {
CLLocation *someLocation=[[CLLocation alloc]initWithLatitude:20.256456 longitude:68.545656]
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:someLocation completionHandler:^(NSArray *placemarks, NSError *error) {
if(placemarks.count){
NSDictionary *dictionary = [[placemarks objectAtIndex:0] addressDictionary];
[self.addressOutlet setText:[dictionary valueForKey:#"Street"]];
[self.cityOutlet setText:[dictionary valueForKey:#"City"]];
[self.stateOutlet setText:[dictionary valueForKey:#"State"]];
[self.zipOutlet setText:[dictionary valueForKey:#"ZIP"]];
}
}];
}
First You need to import the AddressBook/AddressBook.h
Then include the below method
-(NSString*)locationFromCoordinate:(CLLocationCoordinate2D)coordinate
{
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
CLLocation *loc = [[CLLocation alloc]initWithLatitude:coordinate.latitude
longitude:coordinate.longitude];
NSString *address;
[geocoder reverseGeocodeLocation:loc
completionHandler:^(NSArray *placemarks, NSError *error) {
if (error) {
NSLog(#"Failed with error: %#", error);
return;
}
if (placemarks.count > 0)
{
CLPlacemark *placemark = placemarks[0];
NSDictionary *addressDictionary =
placemark.addressDictionary;
address = [addressDictionary
objectForKey:(NSString *)kABPersonAddressStreetKey];
}
return address;
}
At the moment, I have a place dictionary that contains values for all the different parts of a typical address, that I then pass through a geocoder. It looks like this:
[self.placeDictionary setValue:#"166 Bovet Rd" forKey:#"Street"];
[self.placeDictionary setValue:#"San Mateo" forKey:#"City"];
[self.placeDictionary setValue:#"CA" forKey:#"State"];
[self.placeDictionary setValue:#"94402" forKey:#"ZIP"];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressDictionary:self.placeDictionary completionHandler:^(NSArray *placemarks, NSError *error) {
if([placemarks count]) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
CLLocation *location = placemark.location;
CLLocationCoordinate2D coordinate = location.coordinate;
PFGeoPoint* userLocation = [PFGeoPoint geoPointWithLatitude:coordinate.latitude longitude:coordinate.longitude];
NSLog(#"%f,%f", userLocation.latitude, userLocation.longitude);
} else {
NSLog(#"location error");
return;
}
}];
Instead of having a separate dictionary entry for each individual part of the address, could I merge them into one string to pass through the geocoder? Something of this effect:
[self.placeDictionary setValue:#"166 Bovet Rd San Mateo CA 94402" forKey:#"Address"];
The reason I want to do this is I have a search bar in which a user is supposed to enter a location into for geocoding, and I can't divide it and extract each individual part of the address, so is there a way that I can pass the entire address like so, for geocoding?
edit: I've tried the following code and the terminal prints "location error":
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
[self.placeDictionary setValue:#"166 Bovet Rd San Mateo CA 94402" forKey:#"Address"];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressDictionary:self.placeDictionary completionHandler:^(NSArray *placemarks, NSError *error) {
if([placemarks count]) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
CLLocation *location = placemark.location;
CLLocationCoordinate2D coordinate = location.coordinate;
PFGeoPoint* userLocation = [PFGeoPoint geoPointWithLatitude:coordinate.latitude longitude:coordinate.longitude];
NSLog(#"%f,%f", userLocation.latitude, userLocation.longitude);
} else {
NSLog(#"location error");
return;
}
}];
[self.view endEditing:YES];
}
After taking four values for keys Street, City, State & Zip you can create an additional key manually and store complete address in it otherwise you can store all these four values in four different strings and then save them collectively for any key in dictionary.
I figured it out. I simply used the method geocodeAddressString instead.
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
NSString* address = [NSString stringWithFormat:#"166 Bovet Road San Mateo CA 94402"];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
if([placemarks count]) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
CLLocation *location = placemark.location;
CLLocationCoordinate2D coordinate = location.coordinate;
PFGeoPoint* userLocation = [PFGeoPoint geoPointWithLatitude:coordinate.latitude longitude:coordinate.longitude];
NSLog(#"%f,%f", userLocation.latitude, userLocation.longitude);
} else {
NSLog(#"location error");
return;
}
}];
[self.view endEditing:YES];
}