Getting coordinates based in direction in Google Maps/Apple Maps in Objective-C - iphone

Is it possible to get coordinates to be used in Google Maps/Apple Maps (depending on iOS versiĆ³n) based on a given direction? I've got the directoon (street and number), the post code and the country (in my case, the country will always be Spain)
Thank you

You need to use Geocoder for that, find a guide here:
Geocoding Location Data
You can find an example at the end of the document:
[geocoder geocodeAddressString:#"1 Infinite Loop"
completionHandler:^(NSArray* placemarks, NSError* error){
for (CLPlacemark* aPlacemark in placemarks)
{
// Process the placemark.
}
}];
As they say, the more info you provide, the more accurate will be.

Related

Get place names using CLGeocoder (not street names)

I want to develop my own maps app. I have been successful in getting a street address at the point of touch on my iPhone using CLGeocoder. Now my question is the following:
I know that you can get information about a place by using a URL like https://maps.google.com/?q=37.324599,-122.031844
If you click on the above URL, it will take you near a church in Cupertino. Now CLGeocoder will only give me its street address i.e. 10110 N De Anza Blvd Cupertino, CA 95014 (I get this). But how to get the actual name i.e. St Joseph of Cupertino Church and Parish?
We can see it on Google Maps that means they must have it stored somewhere right?
Is there any way to access those place names (Not just by CLGeoCoder, any way is fine).
The GeoCoding API in general is for converting between street addresses and coordinates. If you want place names you can probably use the Places API.
(I know this is more of a comment than an answer, but I think I don't have enough reputation points to comment on questions yet)
YOu need t odo like this way after getting lat long use this code by CLLocation manager class
{
CLGeocoder *reverseGeo = [[CLGeocoder alloc] init];
[reverseGeo reverseGeocodeLocation: loc completionHandler:
^(NSArray *placemarks, NSError *error) {
NSLog(#"%#",[placemarks objectAtIndex:0]);
for (CLPlacemark *placemark in placemarks) {
NSLog(#"~~~~~~~~%#",placemark.locality);
}
}];
}

CLGeocoder Only Returning One Placemark

I have a problem with CLGeocoder where when I call geocodeAddressString:withCompletionHandler I only ever get one result back, despite knowing that the inputted string should return more than one value. The class reference even states:
In the case of forward-geocoding requests, multiple placemark objects may be returned if the provided information yielded multiple possible locations.
However, my placemarks array only ever has one item in it:
[geocoderDestination geocodeAddressString:destination completionHandler:^(NSArray *placemarks, NSError *error){
NSLog(#"array count:%i", [placemarks count];}
Thank you for any help.
I have used strings such as "Piccadilly, UK", "Union Street, UK" which have only returned one result. Now that I think about it, putting UK on the end might be the contributing factor.
I dont know about CLGeocoder but if your requirement is a location search another way is to use google location search url http://maps.google.com/maps/geo?q=london which returns a json containing the matched location information.
Instead of UK use United Kingdom it will give you some related result.
Try to add some more info in your address.
One more thing UK is not a valid country code it's GB but it seems that putting GB instead of UK didn't solve the problem.
Moreover CLGeocoder is not as smart as Google Maps API right now because apple uses its own server to decode addresses so you can use Google services.

Geocoding address into coordinates in iPhone

I am trying to geocode address into coordinates using following code:
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:#"6138 Bollinger Road, San Jose, United States" completionHandler:^(NSArray* placemarks, NSError* error){
for (CLPlacemark* aPlacemark in placemarks)
{
// Process the placemark.
NSString *latDest1 = [NSString stringWithFormat:#"%.4f",aPlacemark.location.coordinate.latitude];
NSString *lngDest1 = [NSString stringWithFormat:#"%.4f",aPlacemark.location.coordinate.longitude];
lblDestinationLat.text = latDest1;
lblDestinationLng.text = lngDest1;
}
}];
I have tried it many times but the debugger never enters the block and I am not able to get the location. What can I try next?
All right I found my mistake.
The code is correct and works perfect. All the while I was working on it was through debugger and was trying to figure out why the debugger did not enter the block. But now I have found out debugger does not enter the block at that moment. It takes little in getting the location values. It is done asynchronously so I was not able to find it and I was getting crash because of no values just after the crash. I have moved my code post block to inside the block and everything works fine for me now.
I just ran that exact code and it worked as expected. Make sure that you have an active internet connection.
Try adding a NSLog on the strings and see if it gets called.
NSLog(#"lat: %#, lng: %#", latDest1, lngDest1);
Are you running it in the simulator or the device?
Blocks are new features to Objective C from iOS4.0 onwards. A block you can imagine as a delegate method working in same functional block. As for any delegate method it takes time to invoke, depending upon the condition, same way block executes the code inside it, when it completes its work of geocoding. You can read more about Block in apples documentation or read http://www.raywenderlich.com/9438/how-to-use-blocks-in-ios-5-tutorial-part-2.
You can also have look into my repository on GITHUB https://github.com/Mangesh20/geocoding

Use CurrentLocation for Continent iPhone

Is there a way to find out the users location Continent? I need to set an AWS entry point based on if they open the app in the US, or Europe. etc.
Is there a way to do this without taking GPS coordinates and making ranges out of them?
If you are in iOS5, you can use GLGeocoder to retrieve the information abotu a current location:
[self.CLGeocoder reverseGeocodeLocation: locationManager.location completionHandler:
^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
//placemark contains the address
}];
CLPlacemark reference:
https://developer.apple.com/library/ios/#DOCUMENTATION/CoreLocation/Reference/CLPlacemark_class/Reference/Reference.html
GLGeocoder reference:
https://developer.apple.com/library/ios/#DOCUMENTATION/CoreLocation/Reference/CLGeocoder_class/Reference/Reference.html
you can reverse geocode a location and get details of where the user is located in text. You use the reverseGeocodeLocation:completionHandler: method on the CLGeocoder class to do this
The completion handler in this method gets passed in an array of CLPlacemark objects, which contain the country code, which you can use to determine the users continent
Although a CLPlacemark object contains lots of useful information, its corresponding continent is not present on it.
I wrote a small category to add a -continent method that returns the corresponding string of the continent based on the -ISOCountryCode of a CLPlacemark.
https://github.com/Hecktorzr/Transcontinental

MKErrorDomain error 4 iPhone

I keep getting this randomly when I run my gps app I'm building. It doesn't happen everytime, and the coordinates passed in are always valid (i nslog them). Is there documentation for these somewhere?
EDIT:
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(locManager.location.coordinate.latitude, locManager.location.coordinate.longitude);
geocoder1 = [[MKReverseGeocoder alloc] initWithCoordinate:coord];
geocoder1.delegate = self;
[geocoder1 start];
and then about half the time it returns an error. I tried releasing and re-assigning the geocoder if there was an error, but that didn't help. Only thing that did was restarting the app.
In "MKTypes.h" in the MapKit framework, the following is defined:
Error constants for the Map Kit framework.
enum MKErrorCode {
MKErrorUnknown = 1,
MKErrorServerFailure,
MKErrorLoadingThrottled,
MKErrorPlacemarkNotFound,
};
...
MKErrorPlacemarkNotFound
The specified placemark could not be found.
This sounds like you are referencing some unknown placemark in your code? Or it could be that Google doesn't have a name for the position you are passing - however valid the coordinates may be.
I've met and solved this issue recently. In my case, when Apple Map cannot find any result for a query, it sometimes will just throw this this "MKErrorDomain = 4" error. So I ended up just treat this as "result not found".
It was painstaking to find this out, MapKit needs a better Error handling system.
I've been hitting this error repeatedly, and was unable to figure out how to make it stop; but I finally found an end-run around the whole issue that works quite well, and only takes a little more work: Don't use Apple's MKReverseGeocoder at all -- instead, directly call Google's reverse-geocoding API (this is apparently the same service that MKReverseGeocoder does behind the scenes). You can get back either JSON or XML (your preference), which you will then have to parse, but that isn't too hard.
For example, since my app is using ASIHTTPRequest, this is what it looks like (although this would also be easy to do with do with Apple's native APIs such as NSURLConnection):
#pragma mark -
#pragma mark CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
// Be careful: My code is passing sensor=true, because I got the lat/long
// from the iPhone's location services, but if you are passing in a lat/long
// that was obtained by some other means, you must pass sensor=false.
NSString* urlStr = [NSString stringWithFormat:
#"http://maps.googleapis.com/maps/api/geocode/xml?latlng=%f,%f&sensor=true",
newLocation.coordinate.latitude, newLocation.coordinate.longitude];
NSURL* url = [NSURL URLWithString:urlStr];
self.reverseGeocoderRequest = [ASIHTTPRequest requestWithURL:url];
self.reverseGeocoderRequest.delegate = self;
[self.reverseGeocoderRequest startAsynchronous];
}
By the way, Google's API has rules, just like Apple's does. Make sure you read the docs, especially regarding quotas.
I'm running into the same thing (the exact same code randomly fails sometimes) and I think I've found the answer. From Apple's developer docs: "Each Map Kit application has a limited amount of reverse geocoding capacity, so it is to your advantage to use reverse geocode requests sparingly."
So my theory is, we're getting rate-limited... since no other variables are changing (i.e. my code isn't changing, I'm running it on the simulator so the location of the device isn't changing, etc.) I think this must be the only remaining reason.
I just got done with a lot of research on this problem and it seems to be outside of our hands. I checked the developer forums as well as all around Stack and elsewhere and no one has a solution other than using a different service. There is a pretty good thread at https://devforums.apple.com/message/154126 on the subject.
Some people find the error after a certain time, I just find it to be out for a while and then comes back. I looked at the "Current Address" sample code and I couldn't see how I might have messed up. I ran the sample code and sure enough, it was NSLogging errors instead of returning a location.
This link has some code using Google's reverse geocoder: http://www.iphonedevsdk.com/forum/iphone-sdk-development/31883-pbrequestererrordomain-errors-reverse-geocoding.html#post155793
Actually, I am running into this problem as well. Code is extremely compact
//1. ask map for current coords
CLLocationCoordinate2D userLocation;
userLocation.latitude = [[_theMapView.userLocation location] coordinate].latitude;
userLocation.longitude = [[_theMapView.userLocation location] coordinate].longitude;
NSLog(#"%f, %f",userLocation.latitude,userLocation.longitude);
//2. reverse geocode coords
MKReverseGeocoder *reverseGeocoder = [[MKReverseGeocoder alloc]
initWithCoordinate:userLocation];
[reverseGeocoder setDelegate:self];
[reverseGeocoder start];
and later simply NSLog the error in the fail delegate method. It works the first time or two, then stops working