Changeset 677
- Timestamp:
- 01/20/10 12:57:19 (8 weeks ago)
- Location:
- apps/iphone/my.tel/trunk/Classes
- Files:
-
- 2 modified
-
LocationViewController.h (modified) (1 diff)
-
LocationViewController.m (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
apps/iphone/my.tel/trunk/Classes/LocationViewController.h
r593 r677 39 39 - (void)resetData; 40 40 - (void)recenterMap; 41 - (void)moveFromLocation:(CLLocation *)fromLoc toLocation:(CLLocation *)toLoc accuracy:(CLLocationDistance)accuracy animated:(BOOL)animated; 41 42 - (void)updateUILocationWithJson:(NSDictionary *)parsedJson; 42 43 - (void)getLocation; -
apps/iphone/my.tel/trunk/Classes/LocationViewController.m
r670 r677 9 9 #import "LocationViewController.h" 10 10 11 #define kKMapDefaultZoomWidthInMeters 1000.0 12 11 13 @interface LocationViewController (PrivateMethods) 12 14 - (void)setDidPreload:(BOOL)preload; 15 - (void)animateZoomIntoRegionUsingNSValue:(NSValue *)aValue; 13 16 @end 14 17 … … 34 37 [theC resetData]; 35 38 if (preload) { 36 theC.view.hidden = NO; // Force preload of the view 37 // theC.theMap.hidden = NO; // Enable this to also force map preload. Beware of needless data access! 39 theC.view.hidden = NO; // Force preload of the view and map 38 40 [theC getLocation]; 39 41 } … … 51 53 - (void)viewDidLoad { 52 54 [super viewDidLoad]; 53 theMap.delegate = self;54 55 [MyCLController sharedInstance].delegate = self; 56 self.theMap.delegate = self; 57 self.theMap.showsUserLocation = YES; 55 58 } 56 59 … … 59 62 // Don't get the data if we preloaded 60 63 if (didPreload) { 61 didPreload = NO;62 64 } else { 63 65 [self getLocation]; … … 67 69 - (void)viewDidAppear:(BOOL)animated { 68 70 [super viewDidAppear:animated]; 69 self.theMap.showsUserLocation = YES; 71 // Only if we preloaded: 72 // Recenter to either span all the annotations, or just the user location 73 if (didPreload) { 74 didPreload = NO; 75 if (self.markerTel != nil) { 76 [self recenterMap]; 77 } else { 78 [self didPressCenterGps:nil]; 79 } 80 } 70 81 } 71 82 … … 89 100 telLocIsAvailable = NO; 90 101 buttonDeleteLoc.enabled = telLocIsAvailable; 102 self.markerTel = nil; 91 103 } 92 104 93 105 - (void)recenterMap { 94 106 // Center and zoom the map so it has all the annotations in it 95 NSArray *coordinates = [self.theMap valueForKeyPath:@"annotations.coordinate"]; 107 108 // Special case if there's only one annotation 109 if ([theMap.annotations count] == 1) { 110 NSObject <MKAnnotation> *ann = [theMap.annotations objectAtIndex:0]; 111 MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(ann.coordinate, kKMapDefaultZoomWidthInMeters, kKMapDefaultZoomWidthInMeters); 112 [theMap setRegion:[theMap regionThatFits:region] animated:YES]; 113 return; 114 } 115 96 116 CLLocationCoordinate2D maxCoord = {-90.0f, -180.0f}; 97 117 CLLocationCoordinate2D minCoord = {90.0f, 180.0f}; 98 for (NSValue *value in coordinates) {99 CLLocationCoordinate2D coord = {0.0f, 0.0f};100 [value getValue:&coord];118 NSObject <MKAnnotation> *ann; 119 for (ann in self.theMap.annotations) { 120 CLLocationCoordinate2D coord = ann.coordinate; 101 121 if(coord.longitude > maxCoord.longitude) { 102 122 maxCoord.longitude = coord.longitude; … … 115 135 region.center.longitude = (minCoord.longitude + maxCoord.longitude) / 2.0; 116 136 region.center.latitude = (minCoord.latitude + maxCoord.latitude) / 2.0; 137 region.span.latitudeDelta = 1.3 * (maxCoord.latitude - minCoord.latitude); // make the region 30% bigger than necessary 117 138 region.span.longitudeDelta = 1.3 * (maxCoord.longitude - minCoord.longitude); // make the region 30% bigger than necessary 118 region.span.latitudeDelta = 1.3 * (maxCoord.latitude - minCoord.latitude); // make the region 30% bigger than necessary 139 if ((region.span.latitudeDelta == 0) && (region.span.longitudeDelta == 0)) 140 region.span.latitudeDelta = region.span.longitudeDelta = kKMapDefaultZoomWidthInMeters; 119 141 [theMap setRegion:[theMap regionThatFits:region] animated:YES]; 120 142 } 121 143 144 - (void)moveFromLocation:(CLLocation *)fromLoc toLocation:(CLLocation *)toLoc accuracy:(CLLocationDistance)accuracy animated:(BOOL)animated { 145 // First zoom out until the new loc is visible, then rezoom back in 146 147 CLLocationDegrees minLat, maxLat, minLong, maxLong; 148 minLat = MIN(fromLoc.coordinate.latitude, toLoc.coordinate.latitude); 149 maxLat = MAX(fromLoc.coordinate.latitude, toLoc.coordinate.latitude); 150 minLong = MIN(fromLoc.coordinate.longitude, toLoc.coordinate.longitude); 151 maxLong = MAX(fromLoc.coordinate.longitude, toLoc.coordinate.longitude); 152 153 MKCoordinateRegion region = {{0.0f, 0.0f}, {0.0f, 0.0f}}; 154 region.center.longitude = (minLong + maxLong) / 2.0; 155 region.center.latitude = (minLat + maxLat) / 2.0; 156 region.span.longitudeDelta = 1.2 * (maxLong - minLong); // make the region 20% bigger than necessary 157 region.span.latitudeDelta = 1.2 * (maxLat - minLat); // make the region 20% bigger than necessary 158 [theMap setRegion:[theMap regionThatFits:region] animated:animated]; 159 160 // Now we've got both items in, we zoom back down into the other loc 161 region = MKCoordinateRegionMakeWithDistance(toLoc.coordinate, accuracy, accuracy); 162 if (animated) { 163 NSValue *regionAsValue = [NSValue valueWithBytes:®ion objCType:@encode(MKCoordinateRegion)]; 164 [self performSelector:@selector(animateZoomIntoRegionUsingNSValue:) withObject:regionAsValue afterDelay:0.1f]; 165 // [self performSelectorOnMainThread:@selector(animateZoomIntoRegionUsingNSValue:) withObject:regionAsValue waitUntilDone:NO]; 166 } else { 167 [theMap setRegion:[theMap regionThatFits:region] animated:NO]; 168 } 169 170 } 171 172 - (void)animateZoomIntoRegionUsingNSValue:(NSValue *)aValue { 173 // wrapper to pass in a MKCoordinateRegion as an object so we can run it asynchronously 174 MKCoordinateRegion region; 175 [aValue getValue:®ion]; 176 [theMap setRegion:[theMap regionThatFits:region] animated:YES]; 177 } 178 122 179 #pragma mark ------ MKMapViewDelegate Methods 123 180 124 - (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views { 125 MKAnnotationView *aV; 126 for (aV in views) { 127 if (aV.annotation == theMap.userLocation) { 128 [theMap setCenterCoordinate:theMap.userLocation.location.coordinate animated:YES]; 129 // zoom in (even if it's updating) 130 CLLocation *theLoc = [MyCLController sharedInstance].myCurrentLoc; 131 CLLocationDistance radiusAccuracy = 1000; 132 if (theLoc.horizontalAccuracy > 0.9 * radiusAccuracy) 133 radiusAccuracy = theLoc.horizontalAccuracy / 0.9; 134 MKCoordinateRegion aR = MKCoordinateRegionMakeWithDistance(theMap.userLocation.location.coordinate, radiusAccuracy, radiusAccuracy); 135 [theMap setRegion:[theMap regionThatFits:aR] animated:YES]; 136 } 137 } 138 } 181 //- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views { 182 // MKAnnotationView *aV; 183 // for (aV in views) { 184 // if (aV.annotation == mapView.userLocation) { 185 // } 186 // } 187 //} 139 188 140 189 #pragma mark ---- MyCLController delegate methods ---- … … 143 192 if (aLoc) { 144 193 gpsLocIsAvailable = YES; 194 self.theMap.showsUserLocation = YES; 145 195 } else { 146 196 gpsLocIsAvailable = NO; 197 self.theMap.showsUserLocation = NO; 147 198 } 148 199 } … … 196 247 197 248 - (IBAction)didPressCenterGps:(id)sender { 198 [self.theMap setCenterCoordinate:[[[MyCLController sharedInstance] myCurrentLoc] coordinate]]; 249 // Move to current loc, and zoom to 500 meters or the current accuracy of gps, whichever is higher 250 CLLocation *currentCenter = [[CLLocation alloc] initWithCoordinate:theMap.centerCoordinate 251 altitude:0.0 252 horizontalAccuracy:10.0 253 verticalAccuracy:10.0 254 timestamp:[NSDate date]]; 255 CLLocation *theLoc = theMap.userLocation.location; 256 CLLocationDistance radiusAccuracy = kKMapDefaultZoomWidthInMeters; 257 if (theLoc.horizontalAccuracy > 0.9 * radiusAccuracy) 258 radiusAccuracy = theLoc.horizontalAccuracy / 0.9; 259 [self moveFromLocation:currentCenter toLocation:[MyCLController sharedInstance].myCurrentLoc accuracy:radiusAccuracy animated:YES]; 260 [currentCenter release]; 199 261 } 200 262 201 263 - (IBAction)didPressCenterTel:(id)sender { 202 [self.theMap setCenterCoordinate:self.markerTel.coordinate]; 264 CLLocation *currentCenter = [[CLLocation alloc] initWithCoordinate:theMap.centerCoordinate 265 altitude:0.0 266 horizontalAccuracy:10.0 267 verticalAccuracy:10.0 268 timestamp:[NSDate date]]; 269 CLLocation *newCenter = [[CLLocation alloc] initWithCoordinate:self.markerTel.coordinate 270 altitude:0.0 271 horizontalAccuracy:10.0 272 verticalAccuracy:10.0 273 timestamp:[NSDate date]]; 274 [self moveFromLocation:currentCenter toLocation:newCenter accuracy:kKMapDefaultZoomWidthInMeters animated:YES]; 275 [currentCenter release]; 276 [newCenter release]; 203 277 } 204 278 … … 226 300 - (IBAction)gpsSwitchToggled:(UISwitch *)sender { 227 301 // Use if there's a switch to turn on or off the GPS 302 self.theMap.showsUserLocation = sender.on; 228 303 if (sender.on) { 229 304 [[MyCLController sharedInstance].locationManager startUpdatingLocation];








