it-swarm.com.de

iPhone - Ermitteln Sie den Namen der Stadt aus Breite und Länge

Ich möchte meinen aktuellen Städtenamen in meiner iPhone App erhalten.

Momentan bekomme ich mit CLLocationManager die Längen- und Breitengrade und gebe meine Koordinaten an CLGeocoder weiter.

    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];
        }  
    }];

Dies funktioniert gut in iOS 5.0, aber nicht in iOS 4.3.

Als Alternative begann ich, den Google-Webdienst zu verwenden 

-(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];
        }
    }
}

Aber die Antwort, die ich bekomme, ist zu lang, bedeutet, dass ich immer noch nicht in der Lage bin, den Namen der Stadt zu erhalten, da dieser Webservice in einigen Fällen alle anderen Informationen bezüglich der Koordinaten mit dem Namen der Stadt erwarten lässt.

Kann mir einer bitte helfen?

16
Muhammad Saqib

Laut Dokumentation CLGeocoder funktioniert nicht unter iOS5. Sie müssen einen anderen Weg nehmen, um sowohl iOS4 als auch iOS5 zu unterstützen.

Sie können nach MKReverseGeocoder suchen, es ist jedoch in iOS5 veraltet, wird aber dennoch den Zweck erfüllen. Zur Bestätigung können Sie so genannte Frage prüfen.

+(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];
}

Sie können diese Funktion verwenden, um die Adresse von Breitengrad und Längengrad zu erhalten. Sie können je nach Anforderung ändern. Wir setzen dies als Klassenmethode, damit wir es direkt als verwenden können

NSString *strAddressFromLatLong = [CLassName getAddressFromLatLon:37.484848 withLongitude:74.48489];

EDIT

Hören Sie auf, die oben genannte Funktion zu verwenden, da sie nicht mehr in Kommentaren angezeigt wird (nicht von mir getestet). Ich empfehle die Verwendung von SVGeocoder

23
Janak Nirmal

Ich verwende das und erhalte die Postleitzahl und den Namen der Stadt. Die von Janak hinzugefügte Methode wurde geändert. 

- (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);

    }];

}
13
Ram G.

Für mich geht das :) 

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);
 }];
8
Ahmed Mh
//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 für mein schlechtes Englisch hoffe es wird dir helfen

5
superGokuN

Versuchen Sie es mit dieser Anfrage. Hier finden Sie alle Daten zum aktuellen Standort, Namen der Straße/Stadt/Region sowie der Hausnummer. Für Ihre Anfrage fügen Sie dies einfach ein.

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"];
3

Das ist gut für mich gearbeitet.

Ich bekomme die Längen- und Breitengrade mit CLLocationManager und gebe meine Koordinaten an CLGeocoder weiter.

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;
}
2
Shangari C

Ich habe @Constantin Saulenco großartige Antwort verbessert. Die Json-Ergebnisse werden nicht immer in derselben Reihenfolge geordnet. Die Stadt befindet sich also nicht immer im gleichen Index. Diese Funktion sucht nach dem richtigen. Land hinzugefügt auch.

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];
1
DaNLtR
- (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)];
    }
}];
}
1
iKushal

Ich habe diesen Code gefunden und für mich funktioniert: https://Gist.github.com/flyworld/4222448 .

Ändern Sie einfach placemark.ISOcountryCode in placemark.locality.

0
Carlos Ancona

Bitte überprüfen Sie die unten genannte Funktion

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
        })
    }
}
0
Urvish Modi