IPhoneアプリで現在の都市名を取得したい。
現在、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];
}
}];
これはiOS5.0では正常に機能しますが、iOS4.3では機能しません。
別の方法として、私はGoogleWebサービスを使い始めました
-(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];
}
}
}
しかし、私が得ている応答が長すぎるということは、このWebサービスが座標に関する他のすべての情報を提供するため、都市名を取得できないことを意味します。
誰か助けてくれませんか?
ドキュメントによると CLGeocoder iOS5以下では機能しません。 iOS4とiOS5の両方をサポートするには、別のルートを使用する必要があります。
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];
}
この関数を使用して、緯度、経度から住所を取得できます。要件に応じて変更できます。これをClassメソッドとして配置し、直接使用できるようにします。
NSString *strAddressFromLatLong = [CLassName getAddressFromLatLon:37.484848 withLongitude:74.48489];
[〜#〜]編集[〜#〜]
コメントで報告されているように、上記の機能の使用を停止してください(私はテストしていません)。 SVGeocoder の使用を開始することをお勧めします
私はこれを使用して、郵便番号と都市名を取得しています。 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);
}];
}
わたしにはできる :)
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);
}];
//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
私の悪い英語でごめんなさいそれがあなたを助けることを願っています
ここでこのリクエストを試してみてください。現在の場所、通り/都市/地域名、家番号に関するすべてのデータが見つかりますが、リクエストにはこれを貼り付けるだけです。
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"];
これは大丈夫です、私のために働きました。
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;
}
- (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)];
}
}];
}
私は@ConstantinSaulencoのすばらしい答えを改善しました-jsonの結果は常に同じ順序であるとは限りません-したがって、都市は常に同じインデックスにあるとは限りません-この関数は正しいものを検索します。国も追加しました。
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];
私はこのコードを見つけました、そしてそれは私のために働きました: https://Gist.github.com/flyworld/4222448 。
placemark.ISOcountryCode
をplacemark.locality
に変更するだけです。
ベローズ機能をご確認ください
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
})
}
}