It is convenient to use "– reverseGeocodeLocation:completionHandler:" method to Reverse Geocoding a Location. But how to obtain all locations in a region.
ps. If there are several places in a region. How could I use the region information to find out all the places? Such as reverse geocoding a location, given a coordinate, return a location. Here I wanna give a region, return all locations in the region.
There is a google Geocoder API which returns JSON , It is just a kind of a web service which uses GET method
And This is the Google Gecoder API and This is the link for that web service and in this link i have given the region name as london.
Note: You need to include SBJson library to your code.
At the end of that link i have appended address, if you append address- you need to give the region name (or) if you append latitude and longitude, you need to give coordinates and it will return the results accordingly.
And the code for calling google api will be like this
//Call the Google API
NSString *req = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", esc_addr];
NSLog(#"The get address is %#", req);
//Pass the string to the NSURL
NSString *result = [NSString stringWithContentsOfURL:[NSURL URLWithString:req] encoding:NSUTF8StringEncoding error:NULL];
NSLog(#"The result is %#", result);
//Initialize the SBJSON Class
SBJSON *parser = [[SBJSON alloc] init];
NSError *error = nil;
//Get the resullts and stored in the address array
addressArray = [parser objectWithString:result error:&error];
//Get the latitude values for the given address
NSDictionary *dict = [[[addressArray valueForKey:#"results"] valueForKey:#"geometry"] valueForKey:#"location"];
self.latitudeValue = [[dict valueForKey:#"lat"] objectAtIndex:0];
self.longitudeValue = [[dict valueForKey:#"lng"] objectAtIndex:0];
NSLog(#"LAT : %#",self.latitudeValue);
NSLog(#"LONG : %#",self.longitudeValue);
Related
I have an array of addresses that I need to convert to Lat/Long using Google's Geocode api. I am feeding an address and the city into the Google Geocode URL, which forms a correct connection url.
Basically I want to be able to use a for loop to create multiple NSURLConnection requests, returning multiple responses.
-(void)setString{
for (int i = 0; i < [businessArray count]; i ++)
{
NSString *address = [addressArray objectAtIndex:0];
NSString *city = [locationDict valueForKey:#"city"];
NSString *geocodeURL = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/geocode/json?address=%#,+%#,&sensor=true", address, city];
geocodeURL = [geocodeURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:geocodeURL]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10];
NSLog(#"%#", request);
geoCodeConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
if (geoCodeConnection)
{
responseData = [NSMutableData data];
connectionIsActive = YES;
NSLog(#"connection active");
} else {
NSLog(#"connection failed");
connectionIsActive = NO;
}
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSError *jsonError = nil;
SBJsonParser *json = [[SBJsonParser alloc] init];
NSDictionary *parsedJSON = [json objectWithString:responseString error:&jsonError];
NSString *lat= [[[[parsedJSON valueForKey:#"results"] valueForKey:#"geometry"] valueForKey:#"location"] valueForKey:#"lat"];
NSString *lng= [[[[parsedJSON valueForKey:#"results"] valueForKey:#"geometry"] valueForKey:#"location"] valueForKey:#"lng"];
NSLog(#"lat = %# long= %#", lat, lng);
connectionIsActive = NO;
[geoCodeLatArray addObject:lat];
[geoCodeLngArray addObject:lng];
NSLog(#"geoCodeArrayLat: %#", geoCodeLatArray);
}
Right now the code returns only the last address' lat and long. How can I send multiply requests and return multiply responses with JSON?
Try this I am using this,
for(int i=0;i< businessArray.count;i++)
{
NSString *address = [addressArray objectAtIndex:i];
NSString *city = [locationDict valueForKey:#"city"];
NSString *address = [NSString stringWithFormat:#"%#,%#", address, city];
CLLocationCoordinate2D location = [self geoCodeUsingAddress:address];
// then here store the location.latitude in lat array and location.longitude in long array.
}
- (CLLocationCoordinate2D) geoCodeUsingAddress:(NSString *)address
{
NSString *esc_addr = [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *req = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", esc_addr];
NSDictionary *googleResponse = [[NSString stringWithContentsOfURL: [NSURL URLWithString: req] encoding: NSUTF8StringEncoding error: NULL] JSONValue];
NSDictionary *resultsDict = [googleResponse valueForKey: #"results"];
NSDictionary *geometryDict = [resultsDict valueForKey: #"geometry"];
NSDictionary *locationDict = [geometryDict valueForKey: #"location"];
NSArray *latArray = [locationDict valueForKey: #"lat"];
NSString *latString = [latArray lastObject];
NSArray *lngArray = [locationDict valueForKey: #"lng"];
NSString *lngString = [lngArray lastObject];
CLLocationCoordinate2D location;
location.latitude = [latString doubleValue];
location.longitude = [lngString doubleValue];
return location;
}
Update to the above function:
- (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 location;
location.latitude = latitude;
location.longitude = longitude;
return location;
}
This worked for me.
You might approach the problem using an asynchronous method that performs the request and has a completion block which will be called when the result is available. This completion block provides a parameter result which is the result of the connection request.
This method may be declared as follows:
typedef void (^completion_block_t) (id result);
- (void) fetchGeoCoordinateForAddress:(NSString*)address
completionHandler:(completion_block_t)completionHandler;
Say, if the request succeeds the parameter result in the block is a JSON representation of the response data. Otherwise, result is an NSError object indicating the error. But the exact details depend on how you implement the method fetchGeoCoordinateForAddress:completionHandler:.
Now you can setup the loop as follows:
for (NSString* address in addresses)
{
[self fetchGeoCoordinateForAddress:address completionHandler:^(id result) {
if (![result isKindOfError:[NSError class]]) // check if result is an error
{
// Note: result is not nil and is a NSDictionary representation of JSON.
// Retrieve the "location" from the response:
NSDictionary* location = result[#"results"][#"geometry"][#"location"];
// Multiple request can occur at the same time! Thus, we need to
// synchronize access to the result array "myLocations" through
// accessing it *exclusively and everywhere* on the main thread:
dispatch_async(dispatch_get_main_queue(), ^{
[self.myLocations addObject:location];
});
}
else {
// got error
DebugLog(#"ERROR: %#", result);
}
}
}
Note: your actual code may differ slightly depending on the actual JSON and other details.
Regarding the implementation of method fetchGeoCoordinateForAddress:completionHandler: you have a few options:
Use a third party library and implement a simple convenience wrapper fetchGeoCoordinateForAddress:completionHandler:.
Create your own "MyHTTPConnectionOperation" class that encapsulates a NSURLConnection and the response data and couple of other useful state info in a dedicated class. This class executes the request asynchronously via start method and has a completion handler. Basically, all third party network libraries will use this approach. Then implement the wrapper.
Use NSURLConnection's asynchronous convenient method if it is sufficient and works in your context. This is the fastest to implement, but least flexible approach and may not work in all cases and may also work only suboptimal.
Edit:
A couple of hints:
If possible, use NSJSONSerialization for parsing JSON and creating a Foundation representation. Other third party libraries only offer a slight advantage if you have special requirements, e.g. you need "chunked parsing with NSData objects" - which is useful when you want to download and parse simultaneously. Or you need to create other representations than Foundation - say a C++ container or you want directly create a Model with SAX style parsing. Or, you need better performance and lower memory food print since you are receiving ultra large strings which you want to save to disk. NSJSONSerialization became quite fast recently, so "performance" alone shouldn't be an argument today.
The timeout for the request shall be not that low as 10 seconds. In a cellular connection, this is too less. Leave it at the default.
If you plan to implement your own "HTTPConnectionOperation" class, I've put a very limited sample on gist here which can give you a jump start.
I think you have to start with AFNetworking
AFNetworking1
AFNetworking2
because AFNetworking gives a lot of power and flexibility in terms of scheduling and queueing requests as well as pausing and cancelling requests.
I am using the following code to get the user's city and country in Iphone.
CLLocation *location = // Some location
[[[CLGeocoder alloc] init] reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {}];
It works but the problem is that it returns the values in a specified language. For example, if the user's current country is UAE and City Dubai then it gives me values as دبي and لإمارات . I want to get these values in English, for example, Dubai and United Arab Emirates.
use this code to get detail.
#define REVERSE_GEO_CODING_URL #"https://maps.googleapis.com/maps/api/geocode/json?"
NSString *urlStr = [NSString stringWithFormat:#"%#latlng=%#,%#&sensor=true",REVERSE_GEO_CODING_URL,latitude,longitude];
DLog(#"%#",urlStr);
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
NSString *json = [BKAPIClient handleConnection:request];
[request release];
if (json)
return (NSMutableDictionary *)[json JSONValue];
I have tested this using saudi arabia's latlong and it return english address in return.
see this link its gives address of somewhere in Saudi arabia .
In my iPhone app I am using Google API. One thing I have to do is I have a drop down of countries and when I select any country, i need to fetch all the cities of that country. Is it possible with Google API or I have to use any other. Please suggest!
Thanks-
The google Geocoder API returns JSON , It is just a kind of a web service which uses GET method
And This is the Google Gecoder API and This is the link for that web service and in this link i have given the region name as london. you can give you country name
Note: You need to include SBJson library to your code.
At the end of that link i have appended address, if you append address- you need to give the region name (or) if you append latitude and longitude, you need to give coordinates and it will return the results accordingly.
And the code for calling google api will be like this
//Call the Google API
NSString *req = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", esc_addr];
NSLog(#"The get address is %#", req);
//Pass the string to the NSURL
NSString *result = [NSString stringWithContentsOfURL:[NSURL URLWithString:req] encoding:NSUTF8StringEncoding error:NULL];
NSLog(#"The result is %#", result);
//Initialize the SBJSON Class
SBJSON *parser = [[SBJSON alloc] init];
NSError *error = nil;
//Get the resullts and stored in the address array
addressArray = [parser objectWithString:result error:&error];
//Get the latitude values for the given address
NSDictionary *dict = [[[addressArray valueForKey:#"results"] valueForKey:#"geometry"] valueForKey:#"location"];
self.latitudeValue = [[dict valueForKey:#"lat"] objectAtIndex:0];
self.longitudeValue = [[dict valueForKey:#"lng"] objectAtIndex:0];
NSLog(#"LAT : %#",self.latitudeValue);
NSLog(#"LONG : %#",self.longitudeValue);
I have just given an idea, you can get all the names in form of Short name, Long name etc in the JSON Response there
I was trying to show the address in google map in my iphone app.
I tried to use
NSString * theAddressString =......;
NSString * query = [NSString stringWithFormat:#"http://maps.google.com/maps?q=%#",theAddressString];
NSString * urlString = [query stringByAddingPercetntEscapesUsingEncoding:NSUTF8StringEncoding];
[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString];
Google map can not find some addresses we provided.(Some Japanese or Chinese addresses) But if I saved the address to iPhone contacts. And then pressed
the contact's address link. It will jump to google maps,though google map first alerted that "can not locate the address", after I confirmed the alert message, another view would display the location in the google map or show the address in the nearby.
So iPhone's "Contact" app may use other apis to filter the address string to locate the address or using some king of "fuzzy search".
Does anybody know how do they achieve it?
I really appreciate your help.
Try out the following one and let me about the status of solution.
NSString * theAddressString =......;
NSString *latlong = [[myLatitude stringByAppendingString:#","]stringByAppendingString:myLongitude];
NSString * query = [NSString stringWithFormat:#"http://maps.google.com/maps?q=%##%#",[theAddressString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], [latlong stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
//NSString * urlString = [query stringByAddingPercetntEscapesUsingEncoding:NSUTF8StringEncoding];
[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString];
New Code with give address:
NSString *theAddressString = #"東村山市野口町1-3-49 アマドムス 102, 東京都, 日本";
NSString *urlString=[NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%#&output=csv",[theAddressString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString]];
NSArray *listItems = [locationString componentsSeparatedByString:#","];
float latitude=0.0;
float longitude=0.0;
if([listItems count] >=4 && [ [listItems objectAtIndex:0] isEqualToString:#"200"]){
latitude = [[listItems objectAtIndex:2] doubleValue];
longitude = [[listItems objectAtIndex:3] doubleValue];
}
else{
NSLog(#"Error");
}
NSString *myLatitude = [NSString stringWithFormat:#"%f",latitude];
NSString *myLongitude = [NSString stringWithFormat:#"%f",longitude];
NSString *latlong = [[myLatitude stringByAppendingString:#","]stringByAppendingString:myLongitude];
NSString * query = [NSString stringWithFormat:#"http://maps.google.com/maps?q=%##%#",[theAddressString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], [latlong stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:query]];
I have checked the query string with google map and it is showing me the pin in Google map.
I am trying to develop an travel application.I would like to submit the Airport code and get back the Country,City, along with the weather of that particular space.Is there an API out in the market that will help me in doing that???Or is there some other way I can do that?
Here's one for the city/country: http://airportcode.riobard.com/about
and this question has good info about weather: Weather API - Provides "About to..." Information?
Here's a sample piece of code that accepts the text from 'inputTextField' and outputs the location to 'outputLabel'
-(IBAction)getCity{
NSString *urlString = [NSString stringWithFormat:#"http://airportcode.riobard.com/airport/%#?fmt=json",self.inputTextField.text];
NSURL *url = [NSURL URLWithString:urlString];
NSString *response = [[NSString alloc] initWithContentsOfURL:url];
const char *convert = [response UTF8String];
NSString *responseString = [NSString stringWithUTF8String:convert];
NSDictionary *airport = [responseString JSONValue];
self.outputLabel.text=[airport objectForKey:#"location"];
}