Brion VIBBER has submitted this change and it was merged. Change subject: Moved angle/distance calc into Nearby controller. ......................................................................
Moved angle/distance calc into Nearby controller. Also sped things up a bit by dealing with coordinates with lighter weight struct rather than location object. Change-Id: I957a72b25205415318d809b4899dc33dd927bb8a --- M wikipedia/Networking/Fetchers/NearbyFetcher.m M wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.h M wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.m M wikipedia/View Controllers/Nearby/NearbyThumbnailView.h M wikipedia/View Controllers/Nearby/NearbyThumbnailView.m M wikipedia/View Controllers/Nearby/NearbyViewController.m 6 files changed, 141 insertions(+), 189 deletions(-) Approvals: Brion VIBBER: Looks good to me, approved diff --git a/wikipedia/Networking/Fetchers/NearbyFetcher.m b/wikipedia/Networking/Fetchers/NearbyFetcher.m index 03f72a0..f7ecce6 100644 --- a/wikipedia/Networking/Fetchers/NearbyFetcher.m +++ b/wikipedia/Networking/Fetchers/NearbyFetcher.m @@ -106,6 +106,8 @@ -(NSDictionary *)getParams { + NSString *coords = + [NSString stringWithFormat:@"%f|%f", self.latitude, self.longitude]; return @{ @"action": @"query", @"prop": @"coordinates|pageimages|pageterms", @@ -114,7 +116,8 @@ @"pilimit": @"50", @"wbptterms": @"description", @"generator": @"geosearch", - @"ggscoord": [NSString stringWithFormat:@"%f|%f", self.latitude, self.longitude], + @"ggscoord": coords, + @"codistancefrompoint": coords, @"ggsradius": @"10000", @"ggslimit": @"50", @"format": @"json" @@ -139,7 +142,16 @@ NSString *title = page[@"title"]; NSMutableDictionary *d = @{}.mutableCopy; - if(coords)d[@"coordinates"] = coords; + + NSNumber *lat = coords[@"lat"]; + NSNumber *lon = coords[@"lon"]; + if(lat && lon){ + CLLocationCoordinate2D coordinates = CLLocationCoordinate2DMake(lat.doubleValue, lon.doubleValue); + d[@"coordinate"] = [NSValue value:&coordinates withObjCType:@encode(CLLocationCoordinate2D)]; + } + + NSNumber *dist = coords[@"dist"]; + if(dist)d[@"initialDistance"] = dist; if(pageId)d[@"pageid"] = pageId; if(pageImage)d[@"pageimage"] = pageImage; if(thumbnail)d[@"thumbnail"] = thumbnail; diff --git a/wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.h b/wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.h index 617eaa4..078fa8d 100644 --- a/wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.h +++ b/wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.h @@ -11,11 +11,8 @@ @property (weak, nonatomic) IBOutlet NearbyThumbnailView *thumbView; @property (strong, nonatomic) NSNumber *distance; -@property (nonatomic) CLLocationCoordinate2D location; -@property (nonatomic) CLLocationCoordinate2D deviceLocation; @property (nonatomic) BOOL headingAvailable; -@property (nonatomic) CLLocationDirection deviceHeading; -@property (nonatomic) UIInterfaceOrientation interfaceOrientation; +@property (nonatomic) double angle; @property (strong, nonatomic) UILongPressGestureRecognizer *longPressRecognizer; diff --git a/wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.m b/wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.m index d59130f..5aa4029 100644 --- a/wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.m +++ b/wikipedia/View Controllers/Nearby/NearbyResultCollectionCell.m @@ -9,9 +9,6 @@ #import "NSObject+ConstraintsScale.h" #import "UIView+Debugging.h" -#define RADIANS_TO_DEGREES(radians) ((radians) * (180.0f / M_PI)) -#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0f * M_PI) - #define TITLE_FONT [UIFont systemFontOfSize:(17.0f * MENUS_SCALE_MULTIPLIER)] #define TITLE_FONT_COLOR [UIColor blackColor] @@ -93,8 +90,8 @@ if (self) { self.longPressRecognizer = nil; self.distance = nil; - self.location = CLLocationCoordinate2DMake(0, 0); - self.deviceLocation = CLLocationCoordinate2DMake(0, 0); + self.angle = 0.0; + self.headingAvailable = NO; } return self; } @@ -161,95 +158,16 @@ } } --(void)setLocation:(CLLocationCoordinate2D)location +-(void)setAngle:(double)angle { - _location = location; - - [self applyRotationTransform]; + _angle = angle; + self.thumbView.angle = angle; } --(void)setDeviceHeading:(CLLocationDirection)deviceHeading +-(void)setHeadingAvailable:(BOOL)headingAvailable { - _deviceHeading = deviceHeading; - - [self applyRotationTransform]; + _headingAvailable = headingAvailable; + self.thumbView.headingAvailable = headingAvailable; } - --(double)headingBetweenLocation: (CLLocationCoordinate2D)loc1 - andLocation: (CLLocationCoordinate2D)loc2 -{ - // From: http://www.movable-type.co.uk/scripts/latlong.html - double dy = loc2.longitude - loc1.longitude; - double y = sin(dy) * cos(loc2.latitude); - double x = cos(loc1.latitude) * sin(loc2.latitude) - sin(loc1.latitude) * cos(loc2.latitude) * cos(dy); - return atan2(y, x); -} - --(double)getAngleFromLocation: (CLLocationCoordinate2D)fromLocation - toLocation: (CLLocationCoordinate2D)toLocation - adjustForHeading: (CLLocationDirection)deviceHeading - adjustForOrientation: (UIInterfaceOrientation)interfaceOrientation -{ - // Get angle between device and article coordinates. - double angleRadians = [self headingBetweenLocation:fromLocation andLocation:toLocation]; - - // Adjust for device rotation (deviceHeading is in degrees). - double angleDegrees = RADIANS_TO_DEGREES(angleRadians); - angleDegrees -= deviceHeading; - if (angleDegrees > 360.0) angleDegrees -= 360.0; - if (angleDegrees < -360.0) angleDegrees += 360.0; - - /* - if ([self.titleLabel.text isEqualToString:@"Museum of London"]){ - NSLog(@"angle = %f", angleDegrees); - } - */ - - // Adjust for interface orientation. - switch (interfaceOrientation) { - case UIInterfaceOrientationLandscapeLeft: - angleDegrees += 90.0; - break; - case UIInterfaceOrientationLandscapeRight: - angleDegrees -= 90.0; - break; - case UIInterfaceOrientationPortraitUpsideDown: - angleDegrees += 180.0; - break; - default: //UIInterfaceOrientationPortrait - break; - } - - /* - if ([self.titleLabel.text isEqualToString:@"Museum of London"]){ - NSLog(@"angle = %f", angleDegrees); - } - */ - - return DEGREES_TO_RADIANS(angleDegrees); -} - --(void)applyRotationTransform -{ - self.thumbView.headingAvailable = self.headingAvailable; - if(!self.headingAvailable) return; - - double angle = - [self getAngleFromLocation: self.deviceLocation - toLocation: self.location - adjustForHeading: self.deviceHeading - adjustForOrientation: self.interfaceOrientation]; - - [self.thumbView drawTickAtHeading:angle]; -} - -/* -- (void)setSelected:(BOOL)selected animated:(BOOL)animated -{ - [super setSelected:selected animated:animated]; - - // Configure the view for the selected state -} -*/ @end diff --git a/wikipedia/View Controllers/Nearby/NearbyThumbnailView.h b/wikipedia/View Controllers/Nearby/NearbyThumbnailView.h index 7eccf5c..aac6451 100644 --- a/wikipedia/View Controllers/Nearby/NearbyThumbnailView.h +++ b/wikipedia/View Controllers/Nearby/NearbyThumbnailView.h @@ -7,7 +7,7 @@ -(void)setImage:(UIImage *)image isPlaceHolder:(BOOL)isPlaceholder; --(void)drawTickAtHeading:(double)heading; +@property (nonatomic) double angle; @property (nonatomic) BOOL headingAvailable; diff --git a/wikipedia/View Controllers/Nearby/NearbyThumbnailView.m b/wikipedia/View Controllers/Nearby/NearbyThumbnailView.m index 81f5cb4..c9c23c3 100644 --- a/wikipedia/View Controllers/Nearby/NearbyThumbnailView.m +++ b/wikipedia/View Controllers/Nearby/NearbyThumbnailView.m @@ -22,12 +22,23 @@ @property (strong, nonatomic) UIImageView *thumbImageView; @property (nonatomic) BOOL isPlaceholder; -@property (nonatomic) double tickHeading; @property (nonatomic) CGFloat padding; @end @implementation NearbyThumbnailView + +-(void)setAngle:(double)angle +{ + _angle = angle; + [self setNeedsDisplay]; +} + +-(void)setHeadingAvailable:(BOOL)headingAvailable +{ + _headingAvailable = headingAvailable; + [self setNeedsDisplay]; +} -(void)setImage:(UIImage *)image isPlaceHolder:(BOOL)isPlaceholder; { @@ -40,7 +51,7 @@ self = [super initWithCoder:coder]; if (self) { self.padding = NEARBY_IMAGE_PADDING; - self.tickHeading = 0; + self.angle = 0; self.thumbImageView = [[UIImageView alloc] init]; self.thumbImageView.clipsToBounds = YES; self.thumbImageView.opaque = YES; @@ -92,12 +103,6 @@ views: views] ]; [self addConstraints:[viewConstraintArrays valueForKeyPath:@"@unionOfArrays.self"]]; -} - --(void)drawTickAtHeading:(double)heading -{ - self.tickHeading = heading; - [self setNeedsDisplay]; } - (void)drawRect:(CGRect)rect @@ -170,7 +175,7 @@ // Move to center of circle. CGContextTranslateCTM(ctx, center.x, center.y); // Rotate. - CGContextRotateCTM(ctx, self.tickHeading); + CGContextRotateCTM(ctx, self.angle); // Rotate to other side. CGContextRotateCTM(ctx, DEGREES_TO_RADIANS(180.0f)); @@ -213,7 +218,7 @@ // Move to center of circle. CGContextTranslateCTM(ctx, center.x, center.y); // Rotate. - CGContextRotateCTM(ctx, self.tickHeading); + CGContextRotateCTM(ctx, self.angle); // Move to location to draw tick. CGContextTranslateCTM(ctx, 0, -radius); diff --git a/wikipedia/View Controllers/Nearby/NearbyViewController.m b/wikipedia/View Controllers/Nearby/NearbyViewController.m index b634f26..7f26e8d 100644 --- a/wikipedia/View Controllers/Nearby/NearbyViewController.m +++ b/wikipedia/View Controllers/Nearby/NearbyViewController.m @@ -21,6 +21,9 @@ #define TABLE_CELL_ID @"NearbyResultCollectionCell" +#define RADIANS_TO_DEGREES(radians) ((radians) * (180.0 / M_PI)) +#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI) + @interface NearbyViewController () @property (strong, nonatomic) NSArray *nearbyDataArray; @@ -45,13 +48,8 @@ self.nearbyDataArray = ( ( { - coordinates = { - globe = earth; - lat = "51.5202"; - lon = "-0.095"; - primary = ""; - }; - distance = "207.4141690965082"; + coordinate = *CLLocationCoordinate2D struct*; + initialDistance = "207.4141690965082"; pageid = 26536263; pageimage = "Barbican_Centre_logo.svg"; thumbnail = { @@ -62,13 +60,8 @@ title = "Barbican Centre"; }, { - coordinates = { - globe = earth; - lat = "51.5191"; - lon = "-0.096946"; - primary = ""; - }; - distance = "324.2053114467474"; + coordinates = *CLLocationCoordinate2D struct*; + initialDistance = "324.2053114467474"; pageid = 2303936; pageimage = "William_Davenant.jpg"; thumbnail = { @@ -251,9 +244,8 @@ [self fadeAlert]; self.nearbyDataArray = @[fetchedData]; - [self calculateDistances]; - - NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey: @"distance.doubleValue" + + NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey: @"initialDistance" ascending: YES]; NSArray *arraySortedByDistance = [self.nearbyDataArray[0] sortedArrayUsingDescriptors:@[sortDescriptor]]; self.nearbyDataArray = @[arraySortedByDistance]; @@ -332,17 +324,13 @@ [self downloadData]; self.refreshNeeded = NO; }else{ - [self calculateDistances]; - - [self updateDistancesForOnscreenCells]; + [self updateDistancesAndAnglesOfOnscreenCells]; } } -(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - // Don't wait for heading or location update - on rotate update arrows right away. - [self updateHeadingForOnscreenCells]; - [self updateDistancesForOnscreenCells]; + [self drawOnscreenCells]; } -(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration @@ -355,52 +343,45 @@ { self.deviceHeading = newHeading; - [self updateHeadingForOnscreenCells]; + [self updateDistancesAndAnglesOfOnscreenCells]; } --(void)updateHeadingForOnscreenCells +-(void)drawOnscreenCells +{ + [self.collectionView.visibleCells makeObjectsPerformSelector:@selector(setNeedsDisplay)]; +} + +-(void)updateDistancesAndAnglesOfOnscreenCells { for (NSIndexPath *indexPath in self.collectionView.indexPathsForVisibleItems.copy){ NearbyResultCollectionCell *cell = (NearbyResultCollectionCell *)[self.collectionView cellForItemAtIndexPath:indexPath]; - cell.deviceHeading = self.deviceHeading.trueHeading; - - [cell setNeedsDisplay]; + [self updateDistancesAndAnglesOfCell:cell atIndexPath:indexPath]; } } --(void)updateDistancesForOnscreenCells +-(CLLocationCoordinate2D)getCoordinateFromNSValue:(NSValue *)value { - for (NSIndexPath *indexPath in self.collectionView.indexPathsForVisibleItems.copy){ - NearbyResultCollectionCell *cell = (NearbyResultCollectionCell *)[self.collectionView cellForItemAtIndexPath:indexPath]; - - [self updateLocationDataOfCell:cell atIndexPath:indexPath]; - - [cell setNeedsDisplay]; - } + CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(0, 0); + if(value)[value getValue:&coord]; + return coord; } --(void)calculateDistances +-(CLLocationDistance)getDistanceToCoordinate:(CLLocationCoordinate2D)coord { - NSMutableDictionary *rowsData = (NSMutableDictionary *)self.nearbyDataArray[0]; - if (!rowsData || (rowsData.count == 0)) return; - for (NSMutableDictionary *rowData in rowsData.copy){ - NSDictionary *coords = rowData[@"coordinates"]; - NSNumber *latitude = coords[@"lat"]; - NSNumber *longitude = coords[@"lon"]; - CLLocationDegrees lat1 = latitude.floatValue; - CLLocationDegrees long1 = longitude.floatValue; - - CLLocation *locA = - [[CLLocation alloc] initWithLatitude: self.deviceLocation.coordinate.latitude - longitude: self.deviceLocation.coordinate.longitude]; - - CLLocation *locB = [[CLLocation alloc] initWithLatitude:lat1 longitude:long1]; - - CLLocationDistance distance = [locA distanceFromLocation:locB]; - - rowData[@"distance"] = @(distance); - } + CLLocation *articleLocation = + [[CLLocation alloc] initWithLatitude: coord.latitude + longitude: coord.longitude]; + + return [self.deviceLocation distanceFromLocation:articleLocation]; +} + +-(double)getAngleToCoordinate:(CLLocationCoordinate2D)coord +{ + return [self getAngleFromLocation: self.deviceLocation.coordinate + toLocation: coord + adjustForHeading: self.deviceHeading.trueHeading + adjustForOrientation: self.interfaceOrientation]; } - (void)viewDidLoad @@ -409,6 +390,12 @@ // Do any additional setup after loading the view. self.locationManager.delegate = self; + + self.locationManager.headingFilter = 1.5; + self.locationManager.distanceFilter = 1.0; + + ((UIScrollView *)self.collectionView).decelerationRate = UIScrollViewDecelerationRateFast; + [self.locationManager startUpdatingLocation]; if (self.headingAvailable) { [self.locationManager startUpdatingHeading]; @@ -443,25 +430,20 @@ return sectionArray.count; } --(void)updateLocationDataOfCell:(NearbyResultCollectionCell *)cell atIndexPath:(NSIndexPath *)indexPath +-(void)updateDistancesAndAnglesOfCell:(NearbyResultCollectionCell *)cell atIndexPath:(NSIndexPath *)indexPath { cell.headingAvailable = self.headingAvailable; - cell.deviceLocation = self.deviceLocation.coordinate; - - cell.interfaceOrientation = self.interfaceOrientation; - NSDictionary *rowData = [self getRowDataForIndexPath:indexPath]; - NSNumber *distance = rowData[@"distance"]; - cell.distance = distance; - - NSDictionary *coords = rowData[@"coordinates"]; - NSNumber *latitude = coords[@"lat"]; - NSNumber *longitude = coords[@"lon"]; - - cell.location = - CLLocationCoordinate2DMake(latitude.doubleValue, longitude.doubleValue); + NSValue *coordVal = rowData[@"coordinate"]; + CLLocationCoordinate2D coord = [self getCoordinateFromNSValue:coordVal]; + + CLLocationDistance distance = [self getDistanceToCoordinate:coord]; + cell.distance = @(distance); + + double angle = [self getAngleToCoordinate:coord]; + cell.angle = angle; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath @@ -516,7 +498,7 @@ [cell setTitle:rowData[@"title"] description:rowData[@"description"]]; - [self updateLocationDataOfCell:cell atIndexPath:indexPath]; + [self updateDistancesAndAnglesOfCell:cell atIndexPath:indexPath]; } - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath @@ -571,22 +553,60 @@ NSDictionary *rowData = [self getRowDataForIndexPath:self.longPressIndexPath]; - NSNumber *lat = rowData[@"coordinates"][@"lat"]; - NSNumber *lon = rowData[@"coordinates"][@"lon"]; + NSValue *coordVal = rowData[@"coordinate"]; + CLLocationCoordinate2D coord = [self getCoordinateFromNSValue:coordVal]; + NSString *title = rowData[@"title"]; - [self openInMaps:CLLocationCoordinate2DMake(lat.doubleValue, lon.doubleValue) withTitle:title]; + [self openInMaps:CLLocationCoordinate2DMake(coord.latitude, coord.longitude) withTitle:title]; } -/* -#pragma mark - Navigation - -// In a storyboard-based application, you will often want to do a little preparation before navigation -- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender +-(double)headingBetweenLocation: (CLLocationCoordinate2D)loc1 + andLocation: (CLLocationCoordinate2D)loc2 { - // Get the new view controller using [segue destinationViewController]. - // Pass the selected object to the new view controller. + // From: http://www.movable-type.co.uk/scripts/latlong.html + double dy = loc2.longitude - loc1.longitude; + double y = sin(dy) * cos(loc2.latitude); + double x = cos(loc1.latitude) * sin(loc2.latitude) - sin(loc1.latitude) * cos(loc2.latitude) * cos(dy); + return atan2(y, x); } -*/ + +-(double)getAngleFromLocation: (CLLocationCoordinate2D)fromLocation + toLocation: (CLLocationCoordinate2D)toLocation + adjustForHeading: (CLLocationDirection)deviceHeading + adjustForOrientation: (UIInterfaceOrientation)interfaceOrientation +{ + // Get angle between device and article coordinates. + double angleRadians = [self headingBetweenLocation:fromLocation andLocation:toLocation]; + + // Adjust for device rotation (deviceHeading is in degrees). + double angleDegrees = RADIANS_TO_DEGREES(angleRadians); + angleDegrees -= deviceHeading; + + if (angleDegrees > 360.0) { + angleDegrees -= 360.0; + }else if (angleDegrees < 0.0){ + angleDegrees += 360.0; + } + + // Adjust for interface orientation. + switch (interfaceOrientation) { + case UIInterfaceOrientationLandscapeLeft: + angleDegrees += 90.0; + break; + case UIInterfaceOrientationLandscapeRight: + angleDegrees -= 90.0; + break; + case UIInterfaceOrientationPortraitUpsideDown: + angleDegrees += 180.0; + break; + default: //UIInterfaceOrientationPortrait + break; + } + + //NSLog(@"angle = %f", angleDegrees); + + return DEGREES_TO_RADIANS(angleDegrees); +} @end -- To view, visit https://gerrit.wikimedia.org/r/179979 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I957a72b25205415318d809b4899dc33dd927bb8a Gerrit-PatchSet: 1 Gerrit-Project: apps/ios/wikipedia Gerrit-Branch: master Gerrit-Owner: Mhurd <mh...@wikimedia.org> Gerrit-Reviewer: Brion VIBBER <br...@wikimedia.org> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits