I'd like to add annotation manually (when user touch in to the particular place in map view) and to get the details of that location (latitude,longitude,address)..
as #iPrabu directed to similar post, with very good and correct answer for your problem... for second part i.e. to get details about that location..you can do something like this
-(void)getAddressFromCurruntLocation:(CLLocation *)location{
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error)
{
if(placemarks && placemarks.count > 0)
{
CLPlacemark *placemark= [placemarks objectAtIndex:0];
NSString *address = [NSString stringWithFormat:#"%# %#",[placemark country],[placemark administrativeArea]];
// you may also get locality,sublocality,subadministrativeare etc
NSLog(#"The Address Is:%#",address);
}
}];
}
Happy Coding :)
Related
In my application I want the exact lattitude and longitude of given address using forward geocoding in IOS in Objective-C.
I had used forward geocoding in my application but it is not giving the exact address. this is my code of forward geocoding
-(void)detectlocation:(NSString*)address
{
CLGeocoder *geocoder=[[CLGeocoder alloc]init];
[geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error)
{
if(!error)
{
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSLog(#"%f",placemark.location.coordinate.latitude);
NSLog(#"%f",placemark.location.coordinate.longitude);
self.latitude4=placemark.location.coordinate.latitude;
self.longitude4=placemark.location.coordinate.longitude;
NSLog(#"%#",[NSString stringWithFormat:#"%#",[placemark description]]);
}
}];
}
Thanks In Advance
You can access placemark properties for a more accurate location.
This is swift, but the same is for objective-c
Declare and initiate your CLLocationMager* inside the viewDidLoad method.
I recommend to use:
#property YourCustomLocation* foundedLocation;
in order to "save" data of the place that has been found.
Then try this inside your method:
[self.geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
//if 1+ "places" have been found:
if ([placemarks count] > 0) {
//save the first place that has been found
CLPlacemark *placemark = [placemarks objectAtIndex:0];
//save location from the placemark
CLLocation *location = placemark.location;
//save coordinates from location
CLLocationCoordinate2D coordinate = location.coordinate;
//Do more stuffs...like:
self->_foundedLocation = [[YouCustomLocation alloc]initLocationWithLatitude:coordinate.latitude Longitude:coordinate.longitude];}
}];
Remember that forward-geocoding works with blocks, so unless you use __block directive near the variable you won't be able to "save the location" on a variable declared outside the block.
I have an array of coordinates that I step through with a for loop. I would like to place annotations on a map for each location and have the subtitle for the callout be the address of the coordinate, found by using reverseGeocodeLocation In the for loop, I call the reverseGeocodeLocation method, and inside the completion block I create the annotation and display it on the map. However, when I run the app, only one annotation shows up. I went in the debugger, and the completion block is only getting called once (for two calls to the reverseGeocodeLocation method). Any suggestions to fix this?
My for loop:
for(int i = 0; i < [locations count]; i++)
{
CLLocation *location = [locations objectAtIndex:i];
__block NSString *info;
NSLog(#"Resolving the Address");
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error)
{
NSLog(#"Found placemarks: %#, error: %#", placemarks, error);
if (error == nil && [placemarks count] > 0)
{
placemark = [placemarks lastObject];
info = [NSString stringWithFormat:#"%# %# %# %#, %#",
placemark.subThoroughfare, placemark.thoroughfare,
placemark.postalCode, placemark.locality,
placemark.administrativeArea];
[self remainderOfMethod:location withAddress:info atIndex:i];
}
else
{
NSLog(#"%#", error.debugDescription);
}
} ];
}
And the method called at the completion block:
- (void) remainderOfMethod: (CLLocation *)location withAddress:(NSString *)info atIndex: (int)i
{
MKPointAnnotation* annotation = [[MKPointAnnotation alloc] init];
if (location != nil)
{
[annotation setSubtitle:[NSString stringWithFormat:#"%#", info]];
annotation.coordinate = location.coordinate;
[self.mapView addAnnotation:annotation];
}
}
Thanks!
From the official Apple documentation:
After initiating a reverse-geocoding request, do not attempt to
initiate another reverse- or forward-geocoding request
You can find the docs here: https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLGeocoder_class/Reference/Reference.html#//apple_ref/occ/instm/CLGeocoder/reverseGeocodeLocation:completionHandler:
One way to solve it is to do only one request at a time in a recursive method that pops a location from a stack (or array) on each iteration.
Even in that case, consider what Apple has to say about it:
Geocoding requests are rate-limited for each app, so making too many
requests in a short period of time may cause some of the requests to
fail
So you may want to request geocoding on demand, for example when a user taps on an annotation.
I got the user location, now I want to, somehow, identify the nearest intersection/cross.
For example: I'm at 5th Av. between the 44 & 45. The Mapkit will give me the 5th av as the current address but I can't find a way to detect the two intersections.
Is this possible?
I'm not stuck to the map kit, and the only thing I want is a method or class to return the name of the streets. So if there is another service or kit to determine that, it will be perfect.
CLLocation *currentLocation = [locations lastObject];
[_geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
if (error == nil && [placemarks count] > 0)
{
_currentPlaceMark = [placemarks lastObject];
_posicaoAtual.text = [NSString stringWithFormat:#"%# | %#-%#",
[_currentPlaceMark valueForKey:#"thoroughfare"],
[_currentPlaceMark valueForKey:#"locality"],
[_currentPlaceMark valueForKey:#"administrativeArea"]];
}
} ];
I have some problem with CLGeocoder, it doesn't return any value for Polish street name:
"Suwalska 3 Wrocław"
I use this method to download coordinate:
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:#"Suwalska 3 Wrocław" completionHandler:^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
}];
Why for example string geocoder does not return anything? I found also other example streets when geocoder won't work. Why google maps/emaps/ can show "Suwalska 3 Wrocław" on map by geocoder does not return anything. Should I use google API for ios insted? So even if apple does not support such big street in Poland why people should use geocoder. I think this is some kind of missunderstanding from Apple.
Thanks for any suggestions.
By default on a map view we can show the user's location. On tapping the annotation pin, it will show "Current Location". But I want to show the address of the user as street, city and country. How can I do it by using CLGeoCoder class?
Do something like this:
CLGeocoder *gc = [[[CLGeocoder alloc] init] autorelease];
[gc reverseGeocodeLocation:locationObject completionHandler:^(NSArray *placemark, NSError *error) {
CLPlacemark *pm = [placemark objectAtIndex:0];
NSDictionary *address = pm.addressDictionary;
// do something with the address, see keys in the remark below
}];
And the relevant docs here:
http://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLPlacemark_class/Reference/Reference.html#//apple_ref/occ/instp/CLPlacemark/addressDictionary