简体   繁体   English

从地址获取纬度/经度

[英]Get latitude/longitude from address

如何使用iPhone SDK 3.x从用户输入的完整地址(街道,城市等)获取纬度和经度?

Here's an updated, more compact, version of unforgiven's code, which uses the latest v3 API: 这是一个更新,更紧凑的unforgiven代码版本,它使用最新的v3 API:

- (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 center;
    center.latitude = latitude;
    center.longitude = longitude;
    return center;
}

It makes the assumption that the coordinates for "location" come first, eg before those for "viewport", because it just takes the first coords it finds under the "lng" and "lat" keys. 它假设“位置”的坐标首先出现,例如在“视口”的坐标之前,因为它只取得它在“lng”和“lat”键下找到的第一个坐标。 Feel free to use a proper JSON scanner (eg SBJSON) if you are worried about this simple scanning technique used here. 如果您担心这里使用的简单扫描技术,请随意使用合适的JSON扫描仪(例如SBJSON)。

You can use Google Geocoding for this . 您可以使用谷歌地理编码 It is as simple as getting data through HTTP and parsing it (it can return JSON KML, XML, CSV). 它就像通过HTTP获取数据并解析它一样简单(它可以返回JSON KML,XML,CSV)。

Here's a similar solution for obtaining the latitude and longitude from Google. 以下是从Google获取经纬度的类似解决方案。 Note: This example uses the SBJson library, which you can find on github: 注意:此示例使用SBJson库,您可以在github上找到它:

+ (CLLocationCoordinate2D) geoCodeUsingAddress: (NSString *) address
{
    CLLocationCoordinate2D myLocation; 

// -- modified from the stackoverflow page - we use the SBJson parser instead of the string scanner --

        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"];   // get the results dictionary
    NSDictionary   *geometryDict = [   resultsDict valueForKey: @"geometry"];   // geometry dictionary within the  results dictionary
    NSDictionary   *locationDict = [  geometryDict valueForKey: @"location"];   // location dictionary within the geometry dictionary

// -- you should be able to strip the latitude & longitude from google's location information (while understanding what the json parser returns) --

    DLog (@"-- returning latitude & longitude from google --");

    NSArray *latArray = [locationDict valueForKey: @"lat"]; NSString *latString = [latArray lastObject];     // (one element) array entries provided by the json parser
    NSArray *lngArray = [locationDict valueForKey: @"lng"]; NSString *lngString = [lngArray lastObject];     // (one element) array entries provided by the json parser

     myLocation.latitude = [latString doubleValue];     // the json parser uses NSArrays which don't support "doubleValue"
    myLocation.longitude = [lngString doubleValue];

    return myLocation;
}

Update version, using iOS JSON: 使用iOS JSON更新版本:

- (CLLocationCoordinate2D)getLocation:(NSString *)address {

    CLLocationCoordinate2D center;
    NSString *esc_addr =  [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSString *req = [NSString stringWithFormat:@"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%@", esc_addr];
    NSData *responseData = [[NSData alloc] initWithContentsOfURL:
                        [NSURL URLWithString:req]];    NSError *error;
    NSMutableDictionary *responseDictionary = [NSJSONSerialization
                                               JSONObjectWithData:responseData
                                               options:nil
                                               error:&error];
    if( error )
    {
        NSLog(@"%@", [error localizedDescription]);
        center.latitude = 0;
        center.longitude = 0;
        return center;
    }
    else {
        NSArray *results = (NSArray *) responseDictionary[@"results"];
        NSDictionary *firstItem = (NSDictionary *) [results objectAtIndex:0];
        NSDictionary *geometry = (NSDictionary *) [firstItem objectForKey:@"geometry"];
        NSDictionary *location = (NSDictionary *) [geometry objectForKey:@"location"];
        NSNumber *lat = (NSNumber *) [location objectForKey:@"lat"];
        NSNumber *lng = (NSNumber *) [location objectForKey:@"lng"];

        center.latitude = [lat doubleValue];
        center.longitude = [lng doubleValue];
        return center;
    }
}

The following method does what you asked for. 您要求的是以下方法。 You need to insert your Google maps key for this to work correctly. 您需要插入Google地图密钥才能正常使用。

- (CLLocationCoordinate2D) geoCodeUsingAddress:(NSString *)address{

    int code = -1;
    int accuracy = -1;
    float latitude = 0.0f;
    float longitude = 0.0f;
    CLLocationCoordinate2D center;

    // setup maps api key
    NSString * MAPS_API_KEY = @"YOUR GOOGLE MAPS KEY HERE";

    NSString *escaped_address =  [address stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
    // Contact Google and make a geocoding request
    NSString *requestString = [NSString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@&output=csv&oe=utf8&key=%@&sensor=false&gl=it", escaped_address, MAPS_API_KEY];
    NSURL *url = [NSURL URLWithString:requestString];

    NSString *result = [NSString stringWithContentsOfURL: url encoding: NSUTF8StringEncoding error:NULL];
        if(result){
            // we got a result from the server, now parse it
            NSScanner *scanner = [NSScanner scannerWithString:result];
            [scanner scanInt:&code];
            if(code == 200){
                // everything went off smoothly
                [scanner scanString:@"," intoString:nil];
                [scanner scanInt:&accuracy];

                //NSLog(@"Accuracy: %d", accuracy);

                [scanner scanString:@"," intoString:nil];
                [scanner scanFloat:&latitude];
                [scanner scanString:@"," intoString:nil];
                [scanner scanFloat:&longitude];


                center.latitude = latitude;
                center.longitude = longitude;

                return center;


            }
            else{
                // the server answer was not the one we expected
                UIAlertView *alert = [[[UIAlertView alloc] 
                                       initWithTitle: @"Warning" 
                                       message:@"Connection to Google Maps failed"
                                       delegate:nil
                                       cancelButtonTitle:nil 
                                       otherButtonTitles:@"OK", nil] autorelease];

                [alert show];

                center.latitude = 0.0f;
                center.longitude = 0.0f;

                return center;


            }

        }
        else{
            // no result back from the server
            UIAlertView *alert = [[[UIAlertView alloc] 
                                   initWithTitle: @"Warning" 
                                   message:@"Connection to Google Maps failed"
                                   delegate:nil
                                   cancelButtonTitle:nil 
                                   otherButtonTitles:@"OK", nil] autorelease];

            [alert show];

            center.latitude = 0.0f;
            center.longitude = 0.0f;

            return center;
        }

    }

        center.latitude = 0.0f;
        center.longitude = 0.0f;

        return center;

}

There's also CoreGeoLocation, which wraps up the functionality in a framework (Mac) or static library (iPhone). 还有CoreGeoLocation,它包含了框架(Mac)或静态库(iPhone)中的功能。 Supports lookups through Google or Yahoo, if you have a preference for one over the other. 支持通过谷歌或雅虎进行查询,如果你有一个优先于另一个。

https://github.com/thekarladam/CoreGeoLocation https://github.com/thekarladam/CoreGeoLocation

For the google map key solution, as described by unforgiven above, doesn't one has to make the app free? 对于google地图密钥解决方案,如上面的unforgiven所描述的,没有人必须免费提供应用程序? As per google terms & conditions: 9.1 Free, Public Accessibility to Your Maps API Implementation. 根据Google条款和条件:9.1免费,公开访问您的Maps API实施。 Your Maps API Implementation must be generally accessible to users without charge. 您的Maps API实施必须经常为用户免费提供。

With map kit in sdk 3.0 this is easily done using the SDK. 使用sdk 3.0中的地图工具包,可以使用SDK轻松完成。 See apple's manuals or follow: https://developer.apple.com/documentation/mapkit 请参阅Apple的手册或关注: https//developer.apple.com/documentation/mapkit

- (void)viewDidLoad
{
    app=(AppDelegate *)[[UIApplication sharedApplication] delegate];
    NSLog(@"%@", app.str_address);


    NSLog(@"internet connect");

    NSString *Str_address=_txt_zipcode.text;

    double latitude1 = 0, longitude1 = 0;
    NSString *esc_addr =  [ Str_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:&latitude1];
            if ([scanner scanUpToString:@"\"lng\" :" intoString:nil] && [scanner scanString:@"\"lng\" :" intoString:nil])
            {
                [scanner scanDouble:&longitude1];
            }
        }
    }


    //in #.hfile
   // CLLocationCoordinate2D lat;
   // CLLocationCoordinate2D lon;
   // float address_latitude;
   // float address_longitude;


    lat.latitude=latitude1;
    lon.longitude=longitude1;

    address_latitude=lat.latitude;
    address_longitude=lon.longitude;

}
func geoCodeUsingAddress(address: NSString) -> CLLocationCoordinate2D {
    var latitude: Double = 0
    var longitude: Double = 0
    let addressstr : NSString = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=\(address)" as NSString
    let urlStr  = addressstr.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
    let searchURL: NSURL = NSURL(string: urlStr! as String)!
    do {
        let newdata = try Data(contentsOf: searchURL as URL)
        if let responseDictionary = try JSONSerialization.jsonObject(with: newdata, options: []) as? NSDictionary {
            print(responseDictionary)
            let array = responseDictionary.object(forKey: "results") as! NSArray
            let dic = array[0] as! NSDictionary
            let locationDic = (dic.object(forKey: "geometry") as! NSDictionary).object(forKey: "location") as! NSDictionary
            latitude = locationDic.object(forKey: "lat") as! Double
            longitude = locationDic.object(forKey: "lng") as! Double
        }} catch {
    }
    var center = CLLocationCoordinate2D()
    center.latitude = latitude
    center.longitude = longitude
    return center
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM