ios iPhone - 从纬度和经度获取城市名称
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10515639/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iPhone - Get City name from Latitude and Longtiude
提问by Muhammad Saqib
I want get my Current City name in my iPhone App.
我想在我的 iPhone 应用程序中获取我当前的城市名称。
I'm currently getting the latitude and longitude using CLLocationManager and than i am passing my coordinates into CLGeocoder.
我目前正在使用 CLLocationManager 获取纬度和经度,然后将坐标传递给 CLGeocoder。
CLGeocoder * geoCoder = [[CLGeocoder alloc] init];
[geoCoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
for (CLPlacemark * placemark in placemarks) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Current City" message:[NSString stringWithFormat:@"Your Current City:%@",[placemark locality]] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil];
[alert show];
}
}];
This is working fine in iOS 5.0 but not working in iOS 4.3.
这在 iOS 5.0 中运行良好,但在 iOS 4.3 中不起作用。
As an alternative, I started using the Google Web service
作为替代方案,我开始使用 Google Web 服务
-(void)findLocationFor:(NSString *)latitudeStr
andLontitude:(NSString *)longtitudeStr{
if ([self connectedToWiFi]){
float latitude = [latitudeStr floatValue];
float longitude = [longtitudeStr floatValue];
NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[NSString stringWithFormat:@"%f,%f", latitude, longitude], @"latlng", nil];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://maps.googleapis.com/maps/api/geocode/json"]];
[parameters setValue:@"true" forKey:@"sensor"];
[parameters setValue:[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode] forKey:@"language"];
NSMutableArray *paramStringsArray = [NSMutableArray arrayWithCapacity:[[parameters allKeys] count]];
for(NSString *key in [parameters allKeys]) {
NSObject *paramValue = [parameters valueForKey:key];
[paramStringsArray addObject:[NSString stringWithFormat:@"%@=%@", key, paramValue]];
}
NSString *paramsString = [paramStringsArray componentsJoinedByString:@"&"];
NSString *baseAddress = request.URL.absoluteString;
baseAddress = [baseAddress stringByAppendingFormat:@"?%@", paramsString];
[request setURL:[NSURL URLWithString:baseAddress]];
NSError *error = nil;
NSURLResponse *response = nil;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (response == nil) {
if (error != nil) {
}
}
else {
NSDictionary *responseDict = [returnData objectFromJSONData];
NSArray *resultsArray = [responseDict valueForKey:@"results"];
NSMutableArray *placemarksArray = [NSMutableArray arrayWithCapacity:[resultsArray count]];
for(NSDictionary *placemarkDict in resultsArray){
NSDictionary *coordinateDict = [[placemarkDict valueForKey:@"geometry"] valueForKey:@"location"];
float lat = [[coordinateDict valueForKey:@"lat"] floatValue];
float lng = [[coordinateDict valueForKey:@"lng"] floatValue];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:[NSString stringWithFormat:@"%.f",lat] forKey:@"latitude"];
[dict setObject:[NSString stringWithFormat:@"%.f",lng] forKey:@"longitude"];
[dict setObject:[placemarkDict objectForKey:@"formatted_address"] forKey:@"address"];
[placemarksArray addObject:dict];
[dict release];
}
NSDictionary *placemark = [placemarksArray objectAtIndex:0];
}
}
}
But the response which i am getting is too long , means i am still unable to get the city name because in some case this web service give all other information regarding coordinates expect City Name.
但是我得到的响应太长,意味着我仍然无法获得城市名称,因为在某些情况下,此 Web 服务会提供有关坐标的所有其他信息(除了城市名称)。
Can any one help me please?
任何一个可以帮助我吗?
回答by Janak Nirmal
As per documentation CLGeocoderdoes not work below iOS5. You need to take another route to support iOS4 and iOS5 both.
根据文档,CLGeocoder在 iOS5 下不起作用。您需要采取另一条路线来同时支持 iOS4 和 iOS5。
You can look at MKReverseGeocoder, however it is deprecated in iOS5 but still will serve the purpose. For confirmation you can check so called question
您可以查看MKReverseGeocoder,但它在 iOS5 中已被弃用,但仍可达到目的。为了确认,您可以检查所谓的问题
+(NSString *)getAddressFromLatLon:(double)pdblLatitude withLongitude:(double)pdblLongitude
{
NSString *urlString = [NSString stringWithFormat:@"http://maps.google.com/maps/geo?q=%f,%f&output=csv",pdblLatitude, pdblLongitude];
NSError* error;
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString] encoding:NSASCIIStringEncoding error:&error];
locationString = [locationString stringByReplacingOccurrencesOfString:@"\"" withString:@""];
return [locationString substringFromIndex:6];
}
You can use this function for getting address from latitude, longitude. You can change according to requirement. We put this as Class method so we can directly use it as
您可以使用此功能从纬度、经度获取地址。您可以根据需要进行更改。我们把它作为类方法,所以我们可以直接使用它作为
NSString *strAddressFromLatLong = [CLassName getAddressFromLatLon:37.484848 withLongitude:74.48489];
EDIT
编辑
Please stop using above function as it has stopped working reported in comments (Not tested by me). I recommend to start using SVGeocoder
请停止使用上述功能,因为它已在评论中报告停止工作(未经我测试)。我建议开始使用SVGeocoder
回答by Ram G.
I am using this and getting the ZIP code and City Name. Modified the method added by Janak.
我正在使用它并获取邮政编码和城市名称。修改了 Janak 添加的方法。
- (void) getAddressFromLatLon:(CLLocation *)bestLocation
{
NSLog(@"%f %f", bestLocation.coordinate.latitude, bestLocation.coordinate.longitude);
CLGeocoder *geocoder = [[CLGeocoder alloc] init] ;
[geocoder reverseGeocodeLocation:bestLocation
completionHandler:^(NSArray *placemarks, NSError *error)
{
if (error){
NSLog(@"Geocode failed with error: %@", error);
return;
}
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSLog(@"placemark.ISOcountryCode %@",placemark.ISOcountryCode);
NSLog(@"locality %@",placemark.locality);
NSLog(@"postalCode %@",placemark.postalCode);
}];
}
回答by Ahmed Mh
It works for me :)
这个对我有用 :)
CLGeocoder *ceo = [[CLGeocoder alloc]init];
CLLocation *loc = [[CLLocation alloc]initWithLatitude:26.93611 longitude:26.93611];
[ceo reverseGeocodeLocation: loc completionHandler:
^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSLog(@"placemark %@",placemark);
//String to hold address
NSString *locatedAt = [[placemark.addressDictionary valueForKey:@"FormattedAddressLines"] componentsJoinedByString:@", "];
NSLog(@"addressDictionary %@", placemark.addressDictionary);
NSLog(@"placemark %@",placemark.region);
NSLog(@"placemark %@",placemark.country); // Give Country Name
NSLog(@"placemark %@",placemark.locality); // Extract the city name
NSLog(@"location %@",placemark.name);
NSLog(@"location %@",placemark.ocean);
NSLog(@"location %@",placemark.postalCode);
NSLog(@"location %@",placemark.subLocality);
NSLog(@"location %@",placemark.location);
//Print the location to console
NSLog(@"I am currently at %@",locatedAt);
}];
回答by superGokuN
//Place below parser code where you are reading latlng and place your latlng in the url
NSXMLParser *parser = [[NSXMLParser alloc]initWithContentsOfURL:[NSURL URLWithString:@"http://maps.googleapis.com/maps/api/geocode/xml?latlng=40.714224,-73.961452&sensor=false"]];
[parser setDelegate:self];
[parser parse];
// Below are the delegates which will get you the exact address easyly
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:@"formatted_address"]){
got = YES; //got is a BOOL
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if(got){
NSLog(@"the address is = %@",string);
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
}
//what we are doing is using xmlparser to parse the data which we get through the google map api copy above link and use in browser you will see the xml data brought
Sorry for my bad english hope it willhelp you
对不起,我的英语不好希望它会帮助你
回答by Constantin Saulenco
Try this request here you will find all data about the current location, street/city/region name, house number but for your request just paste this.
在此处尝试此请求,您将找到有关当前位置、街道/城市/地区名称、门牌号的所有数据,但对于您的请求,只需粘贴此内容即可。
NSString *urlString = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&sensor=false",pdblLatitude, pdblLongitude];
NSError* error;
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString] encoding:NSASCIIStringEncoding error:&error];
NSData *data = [locationString dataUsingEncoding:NSUTF8StringEncoding];
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSDictionary *dic = [[json objectForKey:kResults] objectAtIndex:0];
NSString *cityName = [[[dic objectForKey:@"address_components"] objectAtIndex:1] objectForKey:@"long_name"];
回答by Shangari C
This is fine, worked for me.
这很好,对我有用。
I'm getting the latitude and longitude using CLLocationManager and than i am passing my coordinates into CLGeocoder.
我使用 CLLocationManager 获取纬度和经度,然后将坐标传递给 CLGeocoder。
import @corelocation and for getting city,country #import <AddressBook/AddressBook.h>
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *location=[locations lastObject];
CLGeocoder *geocoder=[[CLGeocoder alloc]init];
CLLocationCoordinate2D coord;
coord.longitude = location.coordinate.longitude;
coord.latitude = location.coordinate.latitude;
// or a one shot fill
coord = [location coordinate];
NSLog(@"longitude value%f", coord.longitude);
NSLog(@"latitude value%f", coord.latitude);
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = placemarks[0];
NSDictionary *addressDictionary = [placemark addressDictionary];
city = addressDictionary[(NSString *)kABPersonAddressCityKey];
stateloc = addressDictionary[(NSString *)kABPersonAddressStateKey];
country = placemark.country;
NSLog(@"city%@/state%@/country%@",city,stateloc,country);
[self getImagesFromServer:city];
}];
[self stopSignificantChangesUpdates];
}
- (void)stopSignificantChangesUpdates
{
[self.locationManager stopUpdatingLocation];
self.locationManager = nil;
}
回答by iKushal
- (void)reverseGeocode:(CLLocation *)location {
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(@"Finding address");
if (error) {
NSLog(@"Error %@", error.description);
} else {
CLPlacemark *placemark = [placemarks lastObject];
self.myAddress.text = [NSString stringWithFormat:@"%@", ABCreateStringWithAddressDictionary(placemark.addressDictionary, NO)];
}
}];
}
回答by DaNLtR
I improved @Constantin Saulenco great answer- the json results in not always ordered in same order - so city is not always at the same index - this func will search for the right one. Added country as well.
我改进了@Constantin Saulenco 很好的答案 - json 结果并不总是以相同的顺序排序 - 所以城市并不总是处于相同的索引 - 这个 func 将搜索正确的。还添加了国家。
NSString *urlString = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&sensor=false",location.coordinate.latitude, location.coordinate.longitude];
NSError* error;
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString] encoding:NSASCIIStringEncoding error:&error];
NSData *data = [locationString dataUsingEncoding:NSUTF8StringEncoding];
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSDictionary *dic = [[json objectForKey:@"results"] objectAtIndex:0];
NSArray* arr = [dic objectForKey:@"address_components"];
//Iterate each result of address components - find locality and country
NSString *cityName;
NSString *countryName;
for (NSDictionary* d in arr)
{
NSArray* typesArr = [d objectForKey:@"types"];
NSString* firstType = [typesArr objectAtIndex:0];
if([firstType isEqualToString:@"locality"])
cityName = [d objectForKey:@"long_name"];
if([firstType isEqualToString:@"country"])
countryName = [d objectForKey:@"long_name"];
}
NSString* locationFinal = [NSString stringWithFormat:@"%@,%@",cityName,countryName];
回答by Carlos Ancona
I found this code and it worked for me: https://gist.github.com/flyworld/4222448.
我找到了这段代码,它对我有用:https: //gist.github.com/flyworld/4222448。
Just change placemark.ISOcountryCode
to placemark.locality
.
只需更改placemark.ISOcountryCode
为placemark.locality
.
回答by Urvish Modi
Please check the bellow function
请检查波纹管功能
func getDataCity(tmpLat:Double,tmpLong:Double) {
let tmpCLGeocoder = CLGeocoder.init()
if tmpLat > 0 , tmpLong > 0
{
let tmpDataLoc = CLLocation.init(latitude: tmpLat, longitude: tmpLong)
tmpCLGeocoder.reverseGeocodeLocation(tmpDataLoc, completionHandler: {(placemarks,error) in
guard let tmpPlacemarks = placemarks else{
return
}
let placeMark = tmpPlacemarks[0] as CLPlacemark
guard let strLocality = placeMark.locality else{
return
}
// strLocality is your city
guard let strSubLocality = placeMark.subLocality else{
return
}
// strSubLocality is your are of city
})
}
}