Skip to content

Commit 268c3fe

Browse files
author
UQ Times
committed
CLGeocoderを利用したサンプルを公開。MKReverseGeocoderは別プロジェクトとした。
1 parent 0c217c5 commit 268c3fe

File tree

7 files changed

+6001
-39
lines changed

7 files changed

+6001
-39
lines changed

CoreLocationSample-Geocoding/CoreLocationSample-Geocoding.xcodeproj/project.pbxproj

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
CE4AA8431571CE690083848A /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CE4AA8421571CE690083848A /* ViewController.m */; };
1717
CE4AA8461571CE690083848A /* ViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE4AA8441571CE690083848A /* ViewController_iPhone.xib */; };
1818
CE4AA8491571CE690083848A /* ViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE4AA8471571CE690083848A /* ViewController_iPad.xib */; };
19+
CEDABEDD1571E2D800A62E43 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEDABEDC1571E2D800A62E43 /* CoreLocation.framework */; };
1920
/* End PBXBuildFile section */
2021

2122
/* Begin PBXFileReference section */
23+
CE46E804157366000027AFE2 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.md; sourceTree = "<group>"; };
2224
CE4AA82B1571CE690083848A /* CoreLocationSample-Geocoding.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "CoreLocationSample-Geocoding.app"; sourceTree = BUILT_PRODUCTS_DIR; };
2325
CE4AA82F1571CE690083848A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
2426
CE4AA8311571CE690083848A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
@@ -33,13 +35,15 @@
3335
CE4AA8421571CE690083848A /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
3436
CE4AA8451571CE690083848A /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPhone.xib; sourceTree = "<group>"; };
3537
CE4AA8481571CE690083848A /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPad.xib; sourceTree = "<group>"; };
38+
CEDABEDC1571E2D800A62E43 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
3639
/* End PBXFileReference section */
3740

3841
/* Begin PBXFrameworksBuildPhase section */
3942
CE4AA8281571CE690083848A /* Frameworks */ = {
4043
isa = PBXFrameworksBuildPhase;
4144
buildActionMask = 2147483647;
4245
files = (
46+
CEDABEDD1571E2D800A62E43 /* CoreLocation.framework in Frameworks */,
4347
CE4AA8301571CE690083848A /* UIKit.framework in Frameworks */,
4448
CE4AA8321571CE690083848A /* Foundation.framework in Frameworks */,
4549
CE4AA8341571CE690083848A /* CoreGraphics.framework in Frameworks */,
@@ -52,6 +56,7 @@
5256
CE4AA8201571CE680083848A = {
5357
isa = PBXGroup;
5458
children = (
59+
CE46E804157366000027AFE2 /* README.md */,
5560
CE4AA8351571CE690083848A /* CoreLocationSample-Geocoding */,
5661
CE4AA82E1571CE690083848A /* Frameworks */,
5762
CE4AA82C1571CE690083848A /* Products */,
@@ -69,6 +74,7 @@
6974
CE4AA82E1571CE690083848A /* Frameworks */ = {
7075
isa = PBXGroup;
7176
children = (
77+
CEDABEDC1571E2D800A62E43 /* CoreLocation.framework */,
7278
CE4AA82F1571CE690083848A /* UIKit.framework */,
7379
CE4AA8311571CE690083848A /* Foundation.framework */,
7480
CE4AA8331571CE690083848A /* CoreGraphics.framework */,
@@ -220,7 +226,7 @@
220226
GCC_WARN_ABOUT_RETURN_TYPE = YES;
221227
GCC_WARN_UNINITIALIZED_AUTOS = YES;
222228
GCC_WARN_UNUSED_VARIABLE = YES;
223-
IPHONEOS_DEPLOYMENT_TARGET = 5.1;
229+
IPHONEOS_DEPLOYMENT_TARGET = 5.0;
224230
SDKROOT = iphoneos;
225231
TARGETED_DEVICE_FAMILY = "1,2";
226232
};
@@ -238,7 +244,7 @@
238244
GCC_WARN_ABOUT_RETURN_TYPE = YES;
239245
GCC_WARN_UNINITIALIZED_AUTOS = YES;
240246
GCC_WARN_UNUSED_VARIABLE = YES;
241-
IPHONEOS_DEPLOYMENT_TARGET = 5.1;
247+
IPHONEOS_DEPLOYMENT_TARGET = 5.0;
242248
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
243249
SDKROOT = iphoneos;
244250
TARGETED_DEVICE_FAMILY = "1,2";
@@ -287,6 +293,7 @@
287293
CE4AA84E1571CE690083848A /* Release */,
288294
);
289295
defaultConfigurationIsVisible = 0;
296+
defaultConfigurationName = Release;
290297
};
291298
/* End XCConfigurationList section */
292299
};

CoreLocationSample-Geocoding/CoreLocationSample-Geocoding/CoreLocationSample-Geocoding-Info.plist

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,10 @@
3131
<key>UISupportedInterfaceOrientations</key>
3232
<array>
3333
<string>UIInterfaceOrientationPortrait</string>
34-
<string>UIInterfaceOrientationLandscapeLeft</string>
35-
<string>UIInterfaceOrientationLandscapeRight</string>
3634
</array>
3735
<key>UISupportedInterfaceOrientations~ipad</key>
3836
<array>
3937
<string>UIInterfaceOrientationPortrait</string>
40-
<string>UIInterfaceOrientationPortraitUpsideDown</string>
41-
<string>UIInterfaceOrientationLandscapeLeft</string>
42-
<string>UIInterfaceOrientationLandscapeRight</string>
4338
</array>
4439
</dict>
4540
</plist>

CoreLocationSample-Geocoding/CoreLocationSample-Geocoding/ViewController.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@
88

99
#import <UIKit/UIKit.h>
1010

11-
@interface ViewController : UIViewController
11+
@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
12+
13+
@property (retain, nonatomic) IBOutlet UILabel *placeNameLabel;
14+
@property (retain, nonatomic) IBOutlet UITextField *placeNameText;
15+
@property (retain, nonatomic) IBOutlet UILabel *latitudeLabel;
16+
@property (retain, nonatomic) IBOutlet UITextField *latitudeText;
17+
@property (retain, nonatomic) IBOutlet UILabel *longitudeLabel;
18+
@property (retain, nonatomic) IBOutlet UITextField *longitudeText;
19+
@property (retain, nonatomic) IBOutlet UITableView *resultTableView;
20+
21+
- (IBAction)searchPlaceName:(id)sender;
22+
- (IBAction)convertCoordinate:(id)sender;
1223

1324
@end

CoreLocationSample-Geocoding/CoreLocationSample-Geocoding/ViewController.m

Lines changed: 257 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,283 @@
77
//
88

99
#import "ViewController.h"
10+
#import <CoreLocation/CoreLocation.h>
1011

1112
@interface ViewController ()
12-
13+
@property (nonatomic, retain) CLGeocoder *geocoder;
14+
@property (nonatomic, retain) NSMutableArray *addressesArray;
1315
@end
1416

1517
@implementation ViewController
1618

19+
@synthesize geocoder = _geocoder;
20+
@synthesize addressesArray = _addressesArray;
21+
22+
@synthesize placeNameLabel = _placeNameLabel;
23+
@synthesize placeNameText = _placeNameText;
24+
@synthesize latitudeLabel = _latitudeLabel;
25+
@synthesize latitudeText = _latitudeText;
26+
@synthesize longitudeLabel = _longitudeLabel;
27+
@synthesize longitudeText = _longitudeText;
28+
@synthesize resultTableView = _resultTableView;
29+
1730
- (void)viewDidLoad
1831
{
1932
[super viewDidLoad];
20-
// Do any additional setup after loading the view, typically from a nib.
33+
34+
// ジオコーディングのインスタンス生成
35+
_geocoder = [[CLGeocoder alloc] init];
36+
// 履歴を保持する配列
37+
_addressesArray = [[NSMutableArray alloc] init];
2138
}
2239

2340
- (void)viewDidUnload
2441
{
42+
self.geocoder = nil;
43+
self.addressesArray = nil;
44+
45+
self.placeNameLabel = nil;
46+
self.placeNameText = nil;
47+
self.latitudeLabel = nil;
48+
self.latitudeText = nil;
49+
self.longitudeLabel = nil;
50+
self.longitudeText = nil;
51+
self.resultTableView = nil;
52+
2553
[super viewDidUnload];
26-
// Release any retained subviews of the main view.
54+
}
55+
56+
- (void)dealloc {
57+
[_geocoder release];
58+
[_addressesArray release];
59+
60+
[_placeNameLabel release];
61+
[_placeNameText release];
62+
[_latitudeLabel release];
63+
[_longitudeLabel release];
64+
[_latitudeText release];
65+
[_longitudeText release];
66+
[_resultTableView release];
67+
68+
[super dealloc];
2769
}
2870

2971
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
3072
{
31-
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
32-
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
33-
} else {
73+
return (interfaceOrientation == UIInterfaceOrientationPortrait);
74+
}
75+
76+
/* キーボードを閉じるため */
77+
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
78+
{
79+
[self hideKeyboard];
80+
}
81+
82+
- (void)hideKeyboard
83+
{
84+
// キーボードを閉じる
85+
[_placeNameText resignFirstResponder];
86+
[_latitudeText resignFirstResponder];
87+
[_longitudeText resignFirstResponder];
88+
}
89+
90+
#pragma mark - IBAction methods
91+
92+
- (IBAction)searchPlaceName:(id)sender {
93+
// 住所が正しいかをチェック
94+
if (![self placeNameIsValid]) {
95+
return; // エラーがあれば検索しない
96+
}
97+
98+
// キーボードを閉じる
99+
[self hideKeyboard];
100+
101+
// 正ジオコーディングの開始
102+
[_geocoder geocodeAddressString:_placeNameText.text completionHandler:^(NSArray *placemarks, NSError *error) {
103+
if (error) {
104+
NSLog(@"%s | %@", __PRETTY_FUNCTION__, error);
105+
[_addressesArray insertObject:[self errorToString:error] atIndex:0]; // 最新のものを先頭に
106+
} else {
107+
for (CLPlacemark *p in placemarks) {
108+
// ログ出力
109+
NSLog(@"%s", __PRETTY_FUNCTION__);
110+
[self logPlacemark:p];
111+
// 緯度・経度のテキストフィールドに反映
112+
_latitudeText.text = [NSString stringWithFormat:@"%lf", p.location.coordinate.latitude];
113+
_longitudeText.text = [NSString stringWithFormat:@"%lf", p.location.coordinate.longitude];
114+
// 履歴に残す
115+
NSString *formattedAddress = [[p.addressDictionary objectForKey:@"FormattedAddressLines"] componentsJoinedByString:@" "];
116+
[_addressesArray insertObject:formattedAddress atIndex:0]; // 最新のものを先頭に
117+
}
118+
}
119+
// テーブルビューの更新
120+
[_resultTableView reloadData];
121+
}];
122+
}
123+
124+
- (IBAction)convertCoordinate:(id)sender {
125+
// 緯度が正しいかをチェック
126+
if (![self coordinateIsValid]) {
127+
return; // エラーがあれば変換しない
128+
}
129+
130+
// キーボードを閉じる
131+
[self hideKeyboard];
132+
133+
// 入力されている緯度・経度を元にCLLocationを作成
134+
CLLocationDegrees latitude = [_latitudeText.text floatValue];
135+
CLLocationDegrees longitude = [_longitudeText.text floatValue];
136+
CLLocation *location = [[[CLLocation alloc] initWithLatitude:latitude longitude:longitude] autorelease];
137+
138+
// 逆ジオコーディングの開始
139+
[_geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
140+
if (error) {
141+
NSLog(@"%s | %@", __PRETTY_FUNCTION__, error);
142+
[_addressesArray insertObject:[self errorToString:error] atIndex:0]; // 最新のものを先頭に
143+
} else {
144+
if (0 < [placemarks count]) {
145+
// ログ出力
146+
NSLog(@"%s", __PRETTY_FUNCTION__);
147+
CLPlacemark *p = [placemarks objectAtIndex:0];
148+
[self logPlacemark:p];
149+
// 住所のテキストフィールドに反映
150+
NSString *formattedAddress = [[p.addressDictionary objectForKey:@"FormattedAddressLines"] componentsJoinedByString:@" "];
151+
_placeNameText.text = formattedAddress;
152+
// ログに残す
153+
[_addressesArray insertObject:formattedAddress atIndex:0]; // 最新のものを先頭に
154+
}
155+
}
156+
// テーブルビューの更新
157+
[_resultTableView reloadData];
158+
}];
159+
}
160+
161+
#pragma mark - input validation methods
162+
163+
/* 入力されている値が、正しい住所情報であるかを判定 */
164+
- (BOOL)placeNameIsValid
165+
{
166+
// 単純に空欄・スペースのみでないかをチェック
167+
NSRange range = [_placeNameText.text rangeOfString:@"^\\s*$" options:NSRegularExpressionSearch];
168+
if (range.location == NSNotFound) {
169+
// 正常
170+
_placeNameText.textColor = [UIColor blackColor];
34171
return YES;
172+
} else {
173+
// 空欄・スペースのみ
174+
_placeNameText.textColor = [UIColor redColor];
175+
return NO;
176+
}
177+
}
178+
179+
/* 入力されている値が、正しい緯度・経度であるかを判定
180+
* CLLocationCoordinate2DIsValid だと、緯度か経度のどちらが誤っているか検知できない
181+
*/
182+
- (BOOL)coordinateIsValid
183+
{
184+
NSString *coordinateRangeString = @"^[+-]?\\d+(?:\\.\\d+)?$";
185+
BOOL latitudeIsValid = YES;
186+
BOOL longitudeIsValid = YES;
187+
NSRange range;
188+
189+
/* 緯度が正しいかをチェック */
190+
range = [_latitudeText.text rangeOfString:coordinateRangeString options:NSRegularExpressionSearch];
191+
if (range.location == NSNotFound) {
192+
latitudeIsValid = NO; // 緯度ではない
193+
} else {
194+
// 範囲内の数値であるか
195+
CLLocationDegrees latitude = [_latitudeText.text floatValue];
196+
if (latitude < -90 || 90 < latitude) {
197+
latitudeIsValid = NO; // 緯度ではない
198+
}
35199
}
200+
// Viewに反映
201+
if (latitudeIsValid) {
202+
_latitudeLabel.textColor = [UIColor blackColor];
203+
} else {
204+
_latitudeLabel.textColor = [UIColor redColor];
205+
}
206+
207+
/* 経度が正しいかをチェック */
208+
range = [_longitudeText.text rangeOfString:coordinateRangeString options:NSRegularExpressionSearch];
209+
if (range.location == NSNotFound) {
210+
longitudeIsValid = NO; // 経度ではない
211+
} else {
212+
// 範囲内の数値であるか
213+
CLLocationDegrees longitude = [_longitudeText.text floatValue];
214+
if (longitude < -180 || 180 < longitude) {
215+
longitudeIsValid = NO; // 経度ではない
216+
}
217+
}
218+
// Viewに反映
219+
if (longitudeIsValid) {
220+
_longitudeLabel.textColor = [UIColor blackColor];
221+
} else {
222+
_longitudeLabel.textColor = [UIColor redColor];
223+
}
224+
225+
// 緯度・経度の両方が正しい場合のみYES
226+
return (latitudeIsValid && longitudeIsValid);
227+
}
228+
229+
#pragma mark - UITableViewDataSource methods
230+
231+
/* テーブルのセクション数 */
232+
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
233+
{
234+
return [_addressesArray count];
235+
}
236+
237+
/* テーブルのセルに表示する内容 */
238+
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
239+
{
240+
NSString *identifier = @"History";
241+
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
242+
if (cell == nil) {
243+
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier] autorelease];
244+
}
245+
246+
// 最新のものが上に来るように数字を数える
247+
cell.textLabel.text = [NSString stringWithFormat:@"住所%d", ([_addressesArray count] - indexPath.row)];
248+
cell.detailTextLabel.text = [_addressesArray objectAtIndex:indexPath.row];
249+
250+
return cell;
251+
}
252+
253+
#pragma mark - private methods
254+
255+
/* エラーを文字列に変換 */
256+
- (NSString *)errorToString:(NSError *)error
257+
{
258+
switch ([error code]) {
259+
case kCLErrorGeocodeFoundNoResult:
260+
return @"NoResult";
261+
case kCLErrorGeocodeFoundPartialResult:
262+
return @"PartialResult";
263+
case kCLErrorGeocodeCanceled:
264+
return @"Canceled";
265+
default:
266+
return [error description];
267+
}
268+
}
269+
270+
/* プレースマークの情報をログに残すだけ */
271+
- (void)logPlacemark:(CLPlacemark *)placemark
272+
{
273+
NSLog(@"addressDictionary: %@", placemark.addressDictionary);
274+
NSLog(@"administrativeArea: %@", placemark.administrativeArea);
275+
NSLog(@"areasOfInterest: %@", placemark.areasOfInterest);
276+
NSLog(@"country: %@", placemark.country);
277+
NSLog(@"inlandWater: %@", placemark.inlandWater);
278+
NSLog(@"locality: %@", placemark.locality);
279+
NSLog(@"name: %@", placemark.name);
280+
NSLog(@"ocean: %@", placemark.ocean);
281+
NSLog(@"postalCode: %@", placemark.postalCode);
282+
NSLog(@"region: %@", placemark.region);
283+
NSLog(@"subAdministrativeArea: %@", placemark.subAdministrativeArea);
284+
NSLog(@"subLocality: %@", placemark.subLocality);
285+
NSLog(@"subThoroughfare: %@", placemark.subThoroughfare);
286+
NSLog(@"thoroughfare: %@", placemark.thoroughfare);
36287
}
37288

38289
@end

0 commit comments

Comments
 (0)