BLOG main image
분류 전체보기 (50)
아이폰 개발 이야기 (12)
스마트폰용 홈페이지 (3)
웹표준 개발 (8)
HTML5 (2)
Objective-C (2)
뉴미디어 기획 이야기 (10)
뉴미디어 뉴스 (12)
81,453 Visitors up to today!
Today 80 hit, Yesterday 88 hit
2010/06/29 10:56

아이폰 어플중에서 지도에 자기 좌표가 찍히고 주소가 나오는 어플들을 많이들 보셨을 텐데요.
오늘은 좌표값과 주소 구하는 방법에 대해서 알아보겠습니다.

이 기능은 참 많은 어플들을 통해서 활용이 가능할 것 같습니다. 
우선 작업목표를 정해보았습니다.

<좌표값으로 현재 주소를 검색하는 어플을 만들기 위한 순서>
1. 새 프로젝트 (Window-based Application)를 생성한다.
2. 새 프로젝트에 뷰를 하나 추가한다.
3. 추가한 뷰에 검색된 결과를 보여줄 화면(Label,Button등등)을 구성한다.
3. 현재 좌표값을 구한다.
4. 구해진 좌표값을 화면에 뿌린다.
5. 구해진 좌표값에 해당하는 주소를 구글맵에서 받아온다.
6. 받아온 결과를 화면에 뿌려준다.

막상 써 놓으니 음... 생각보단 간단하네요~!!
자~~ 이제 목표는 정해졌으니 하나씩 해보면 됩니다.ㅋ

이제 작업목표에서 정한 순서로  진행과정을 살펴보겠습니다..

시작해 볼까요~

1. 새 프로젝트를 생성합니다.
XCode에서 File->New Project->Window-based Application을 클릭하세요.
(아시는 분들도 많겠지만 혹시 모르는 분도 있을까 해서 아래 이미지 참조)



2. 새 프로젝트를 윈도우 베이스로 만들었지만 뭔가 보여줄 화면이 필요합니다.
화면용 파일을 하나 프로젝트에 추가합니다.
XCode화면의 Groups&Files 영역에서 마우스 오른쪽 클릭해서 Add->New File을 합니다.



3. 이제 화면도 만들었습니다.
Command+R 키로 그냥 한번 실행해봅니다. 아무것도 없습니다..
화면에 뭔가 만들어주어야 합니다. 다른 것을 사용해도 되겠지만 이번 작업에서는 단순하게 Label로 모두 처리하도록 합니다.

아래화면 참고해서 같이 만들어보죠.



참고로 화면에 구성된 Label들은 소스파일의 IBOutlet로 선언된 변수들과 연결해주어야 합니다.

4. Label과 아웃렛과의 연결 하셨다면 이제 좌표값을 구해보겠습니다.
좌표값을 구하기 위해서는 CoreLocation.framework을 현재 프로젝트에 추가해주어야 합니다.
추가했나요? 이젠 좌표구하는 부분 소스를 보겠습니다.

=============================================================================================

/*
viewDidLoad  이벤트에 CLLocationManager를 생성해서 실행줍니다.
그러면  #pragma mark - 이하 부분이 자동적으로 실행됩니다.
핵심 소스가 여기입니다.
*/

- (void)viewDidLoad {
 self.locationManager = [[CLLocationManager alloc] init];
 [locationManager startUpdatingLocation];
 locationManager.delegate = self;
 locationManager.distanceFilter = kCLDistanceFilterNone;
 locationManager.desiredAccuracy = kCLLocationAccuracyBest;
}

#pragma mark -
#pragma mark CLLocationManagerDelegate Methods
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
 
 if (startingPoint == nil)
  self.startingPoint = newLocation;
 
 NSString *latitudeString = [[NSString alloc] initWithFormat:@"위도 : %g°", newLocation.coordinate.latitude];
 latitudeLabel.text = latitudeString;
 [latitudeString release];
 
 NSString *longitudeString = [[NSString alloc] initWithFormat:@"경도 : %g°", newLocation.coordinate.longitude];
 longitudeLabel.text = longitudeString;
 [longitudeString release];

}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
 
 NSString *errorType = (error.code == kCLErrorDenied) ? @"Access Denied" : @"Unknown Error";
 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error gettingg location from Core Location" message:errorType delegate:nil cancelButtonTitle:@"Okay" otherButtonTitles:nil];
 [alert show];
 [alert release];
 
}
==============================================================================================


 
5. 좌표값을 받아서 구글맵에서 주소를 조회하는 부분을 보겠습니다.
1) 구글맵에 주소 조회 쿼리를 보내서 결과(XML)를 받아오는 기능을 구현합니다.
2) 받아온 결과(XML)을 파싱하는 기능을 구현합니다.

위에 1), 2)는 유기적으로 함께 구동됩니다.

==================구글맵에 주소 조회 쿼리 보내기=========================

-(IBAction)loadXMLData{
 self.xmlUrl = @"
http://maps.google.com/maps/api/geocode/xml?latlng=37.630478,127.090199&language=kr&sensor=true";
 xmlConnection = [[NSURLConnection alloc]
      initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:xmlUrl]]
      delegate:self];
 
 if (xmlConnection == nil)
  NSLog(@"Connect error");
 else
  [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
 
 xmlParseData = [[NSMutableArray alloc] init];
 xmlValue = [[NSMutableString alloc] init];
 currectItem = [[NSMutableDictionary alloc] init];
 receiveData = [[NSMutableData alloc] init];
}

#pragma mark URLConnection delegate methods

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
 NSLog(@"Receive: %@, %@, %d",
    [response URL],
    [response MIMEType],
    [response expectedContentLength]);
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
 NSLog(@"%@", [error localizedDescription]);
 [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
 //NSString *str = [[NSString alloc] initWithData:data encoding:0x80000000 + kCFStringEncodingDOSKorean];
    //NSData *data1 = [str dataUsingEncoding:NSUTF8StringEncoding];

 [receiveData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
 
 //NSString *str = [[NSString alloc] initWithData:receiveData encoding:0x80000000 + kCFStringEncodingDOSKorean];
    //NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
 //NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];

 NSXMLParser *parser = [[NSXMLParser alloc] initWithData:receiveData];

    [parser setDelegate:self];
 
    [parser parse];
 
 
 [parser release];
 
 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
 
 [xmlConnection release];
 [receiveData release];
}


================================조회 결과 XML을 파싱하여 화면에 보여주기================================

#pragma mark XMLParse delegate methods
//#pragma mark NSXMLParser delegate methods

- (void)parserDidEndDocument:(NSXMLParser *)parser {
 self.clickBtn;
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
 if ([elementName isEqualToString:@"address_component"])
  elementType = etItem;

 [xmlValue setString:@""];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
 
 if (elementType != etItem)
  return;
 
 if ([elementName isEqualToString:@"long_name"]) {
  [currectItem setValue:[NSString stringWithString:xmlValue] forKey:elementName]; 
 } else if ([elementName isEqualToString:@"short_name"]) {
  [currectItem setValue:[NSString stringWithString:xmlValue] forKey:elementName];
 
 } else if ([elementName isEqualToString:@"address_component"]) {
  [xmlParseData addObject:[NSDictionary dictionaryWithDictionary:currectItem]];
 }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
 if (elementType == etItem) {
  [xmlValue appendString:string];
 }
}

좀 부족했지만 위 설명을 잘 수행한다면 다음과 같은 화면이 나오게 됩니다...(제가 사는곳입니다. ㅎㅎㅎ)



부족한 부분은 첨부된 소스 보면 이해가 될겁니다. 파일첨부합니다~!! 화이팅하세요~




 

 

저작자 표시 비영리 동일 조건 변경 허락
Trackback Address :: http://web2log.com/trackback/56 관련글 쓰기
angellake | 2010/07/27 01:32 | PERMALINK | EDIT/DEL | REPLY
감사합니다. 많은 도움이 되었구요....만약 반대로 주소값으로 좌표를 구하려면 어떻게 해야되나요??
현재 위치가 아닌 특정지역의 주소명을 가지고 반대로 좌표값을 구하는 방법이 있으면 좀 가르쳐 주세용~~
심정우 | 2010/07/28 00:43 | PERMALINK | EDIT/DEL | REPLY
특정 주소지에 대한 좌표값을 구하는 것은 역으로 생각하시면 됩니다.
좌표값을 보내서 주소를 받아왔던 것처럼 주소를 보내서 좌표를 받아오는 것이지요..^^
개념적으로는 같구요.. 단지 주소를 받아서 좌표를 리턴해주는 (구글,네이버,다음 등등) 서비스를 하는 곳에다가
원하는 주소값을 보내서 리턴받으시면 됩니다.. 소스가 오히려 더 많이 공유되고 있더라구요..^^
angellake | 2010/07/28 16:27 | PERMALINK | EDIT/DEL | REPLY
네~ 감사합니다...그러면 구글에서는 그런 서비스를 안해주고 구글 네이버 다음등의 api에서 하는건가요??
심정우 | 2010/07/28 23:27 | PERMALINK | EDIT/DEL | REPLY
구글에서 가능한걸로 알고 있지만 저도 테스트는 못해봤습니다..
그래서 한번 검색해봤는데.. 어떤 분이 잘 설명을 해두셨네요... 물론 XCode로 구현한 것은 아니고 PHP로 하셨네요..
참고하시면 좋을듯 싶습니다..

http://blog.naver.com/songws72?Redirect=Log&logNo=50077099849

^^ 별거아닌 포스트에 관심주시니 감사합니다.. 저도 아는게 짧아서 답변이 좀 어설픈 점 양해부탁드립니다..
우와 | 2010/08/03 04:24 | PERMALINK | EDIT/DEL | REPLY
멋져요~~ 퍼가고 싶은데 어떻게 퍼가는지 몰라서 즐겨찾기 등록해둘께요

삭제하지마세요 자주 놀러올께요
acid | 2010/09/08 21:07 | PERMALINK | EDIT/DEL | REPLY
http://maps.google.com/maps/api/geocode/xml?latlng=37.630478,127.090199&language=kr&sensor=true

이 주소에서 보여지는 xml 데이터는 저는 영어로 뜨는데...어떻게 한글로 받아오신건지 궁금합니다..ㅠㅠ

url에서도 보여지다시피 language=kr 이란 부분이 있긴 하나 ...저는 영어로 보입니다...ㅠㅠ
| 2010/11/10 11:31 | PERMALINK | EDIT/DEL | REPLY
비밀댓글입니다
Name
Password
Homepage
Secret
prev"" #1 ... #5 #6 #7 #8 #9 #10 #11 #12 #13 ... #50 next