[ios] -Added feature type and country name into the search results table.

- Added support for miles/kilometers to search results
This commit is contained in:
Alex Zolotarev 2012-01-27 22:01:46 +03:00 committed by Alex Zolotarev
parent ae3b33a670
commit a3a8198df4
4 changed files with 201 additions and 72 deletions

View file

@ -0,0 +1,18 @@
#import <UIKit/UIKit.h>
@interface SearchCell : UITableViewCell
{
UILabel * featureName;
UILabel * featureType;
UILabel * featureCountry;
UILabel * featureDistance;
}
@property (nonatomic, retain) IBOutlet UILabel * featureName;
@property (nonatomic, retain) IBOutlet UILabel * featureType;
@property (nonatomic, retain) IBOutlet UILabel * featureCountry;
@property (nonatomic, retain) IBOutlet UILabel * featureDistance;
- (id)initWithReuseIdentifier:(NSString *)identifier;
@end

View file

@ -0,0 +1,63 @@
#import "SearchCell.h"
#import "CompassView.h"
@implementation SearchCell
@synthesize featureName;
@synthesize featureType;
@synthesize featureCountry;
@synthesize featureDistance;
- (id)initWithReuseIdentifier:(NSString *)identifier
{
self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
if (self)
{
// Fonts and sizes are hard-coded because they can't be easily retrieved
UIFont * large = [UIFont fontWithName:@"Helvetica-Bold" size:[UIFont labelFontSize] + 1];
UIFont * small = [UIFont fontWithName:@"Helvetica" size:[UIFont systemFontSize]];
featureName = [[[UILabel alloc] init] autorelease];
featureName.font = large;
featureType = [[[UILabel alloc] init] autorelease];
featureType.font = small;
featureType.textColor = [UIColor grayColor];
featureCountry = [[[UILabel alloc] init] autorelease];
featureCountry.font = small;
featureCountry.textColor = [UIColor grayColor];
featureCountry.textAlignment = UITextAlignmentRight;
featureDistance = [[[UILabel alloc] init] autorelease];
featureDistance.font = small;
featureDistance.textColor = [UIColor grayColor];
featureDistance.textAlignment = UITextAlignmentRight;
[self.contentView addSubview:featureName];
[self.contentView addSubview:featureType];
[self.contentView addSubview:featureCountry];
[self.contentView addSubview:featureDistance];
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
CGRect r = self.contentView.bounds;
// Leave some experimentally choosen padding
CGFloat const KPaddingX = 6.0;
CGFloat const KPaddingBottom = 4.0;
r.origin.x += KPaddingX;
r.size.width -= 2 * KPaddingX;
r.size.height -= KPaddingBottom;
CGFloat const w = r.size.width;
CGFloat const h = r.size.height;
CGFloat const xDelim = r.origin.x + w / 3 * 2;
CGFloat const yDelim = r.origin.y + h / 3 * 2;
featureName.frame = CGRectMake(r.origin.x, r.origin.y, xDelim - r.origin.x, yDelim - r.origin.y);
featureType.frame = CGRectMake(r.origin.x, yDelim, xDelim - r.origin.x, r.origin.y + h - yDelim);
featureCountry.frame = CGRectMake(xDelim, r.origin.y, r.origin.x + w - xDelim, yDelim - r.origin.y);
featureDistance.frame = CGRectMake(xDelim, yDelim, r.origin.x + w - xDelim, r.origin.y + h - yDelim);
}
@end

View file

@ -2,6 +2,7 @@
#import "CompassView.h"
#import "LocationManager.h"
#import "SearchBannerChecker.h"
#import "SearchCell.h"
#include "../../geometry/angles.hpp"
#include "../../geometry/distance_on_sphere.hpp"
@ -9,6 +10,7 @@
#include "../../platform/platform.hpp"
#include "../../indexer/mercator.hpp"
#include "../../map/framework.hpp"
#include "../../map/measurement_utils.hpp"
#include "../../search/result.hpp"
SearchVC * g_searchVC = nil;
@ -48,8 +50,8 @@ static void OnSearchResultCallback(search::Results const & res, int queryId)
{
Wrapper * w = [[Wrapper alloc] initWithResult:res];
[g_searchVC performSelectorOnMainThread:@selector(addResult:)
withObject:w
waitUntilDone:NO];
withObject:w
waitUntilDone:NO];
[w release];
}
}
@ -280,49 +282,54 @@ static void OnSearchResultCallback(search::Results const & res, int queryId)
//*********** End of SearchBar handlers *************************************
//***************************************************************************
- (void)updateCellAngle:(UITableViewCell *)cell withIndex:(NSUInteger)index andAngle:(double)northDeg
+ (NSString *)formatDistance:(double)meters
{
CLLocation * loc = [m_locationManager lastLocation];
if (loc)
if (meters < 0.)
return nil;
uint64_t shortUnits = (uint64_t)meters;
double longUnits = meters/1000.0;
// @TODO localize measurements
static NSString * shortLabel = @"m";
static NSString * longLabel = @"km";
Settings::Units u = Settings::Metric;
Settings::Get("Units", u);
switch (u)
{
m2::PointD const center = m_results[index].GetFeatureCenter();
double const angle = ang::AngleTo(m2::PointD(MercatorBounds::LonToX(loc.coordinate.longitude),
MercatorBounds::LatToY(loc.coordinate.latitude)), center) + northDeg / 180. * math::pi;
case Settings::Foot:
shortUnits = (uint64_t)MeasurementUtils::MetersToFeet(meters);
longUnits = MeasurementUtils::MetersToMiles(meters);
shortLabel = @"ft";
longLabel = @"mi";
break;
if (m_results[index].GetResultType() == search::Result::RESULT_FEATURE)
{
CompassView * cv = (CompassView *)cell.accessoryView;
if (!cv)
{
float const h = m_table.rowHeight * 0.6;
cv = [[CompassView alloc] initWithFrame:CGRectMake(0, 0, h, h)];
cell.accessoryView = cv;
[cv release];
}
cv.angle = angle;
}
}
}
case Settings::Yard:
shortUnits = (uint64_t)MeasurementUtils::MetersToYards(meters);
longUnits = MeasurementUtils::MetersToMiles(meters);
shortLabel = @"yd";
longLabel = @"mi";
break;
- (void)updateCellDistance:(UITableViewCell *)cell withIndex:(NSUInteger)index
{
CLLocation * loc = [m_locationManager lastLocation];
if (loc)
{
m2::PointD const center = m_results[index].GetFeatureCenter();
double const centerLat = MercatorBounds::YToLat(center.y);
double const centerLon = MercatorBounds::XToLon(center.x);
double const distance = ms::DistanceOnEarth(loc.coordinate.latitude, loc.coordinate.longitude, centerLat, centerLon);
// @TODO use imperial system from the settings if needed
// @TODO use meters too
// NSLocalizedString(@"%.1lf m", @"Search results - Metres")
// NSLocalizedString(@"%.1lf ft", @"Search results - Feet")
// NSLocalizedString(@"%.1lf mi", @"Search results - Miles")
// NSLocalizedString(@"%.1lf yd", @"Search results - Yards")
cell.detailTextLabel.text = [NSString stringWithFormat:NSLocalizedString(@"%.1lf km", @"Search results - Kilometres"),
distance / 1000.0];
case Settings::Metric:
shortLabel = @"m";
longLabel = @"km";
break;
}
// NSLocalizedString(@"%.1lf m", @"Search results - Metres")
// NSLocalizedString(@"%.1lf ft", @"Search results - Feet")
// NSLocalizedString(@"%.1lf mi", @"Search results - Miles")
// NSLocalizedString(@"%.1lf yd", @"Search results - Yards")
if (shortUnits < 1000)
return [NSString stringWithFormat:@"%qu %@", shortUnits, shortLabel];
uint64_t const longUnitsRounded = (uint64_t)(longUnits);
// reduce precision for big distances and remove zero for x.0-like numbers
if (longUnitsRounded > 10 || (longUnitsRounded && (uint64_t)(longUnits * 10.0) == longUnitsRounded * 10))
return [NSString stringWithFormat:@"%qu %@", longUnitsRounded, longLabel];
return [NSString stringWithFormat:@"%.1lf %@", longUnits, longLabel];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
@ -335,30 +342,45 @@ static void OnSearchResultCallback(search::Results const & res, int queryId)
return m_results.size();
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"SearchVCTableViewCell"];
if (!cell)
if (indexPath.row >= m_results.size())
{
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"SearchVCTableViewCell"]
autorelease];
ASSERT(false, ("Invalid m_results with size", m_results.size()));
return nil;
}
cell.accessoryView = nil;
if (indexPath.row < m_results.size())
search::Result const & r = m_results[indexPath.row];
switch (r.GetResultType())
{
search::Result const & r = m_results[indexPath.row];
cell.textLabel.text = [NSString stringWithUTF8String:r.GetString()];
if (r.GetResultType() == search::Result::RESULT_FEATURE)
[self updateCellDistance:cell withIndex:indexPath.row];
else
cell.detailTextLabel.text = nil;
case search::Result::RESULT_FEATURE:
{
SearchCell * cell = (SearchCell *)[tableView dequeueReusableCellWithIdentifier:@"FeatureCell"];
if (!cell)
cell = [[[SearchCell alloc] initWithReuseIdentifier:@"FeatureCell"] autorelease];
cell.featureName.text = [NSString stringWithUTF8String:r.GetString()];
cell.featureCountry.text = [NSString stringWithUTF8String:r.GetRegionString()];
cell.featureType.text = [NSString stringWithUTF8String:r.GetFeatureType()];
cell.featureDistance.text = [SearchVC formatDistance:r.GetDistanceFromCenter()];
return cell;
}
break;
case search::Result::RESULT_SUGGESTION:
{
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"SuggestionCell"];
if (!cell)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"SuggestionCell"] autorelease];
cell.textLabel.text = [NSString stringWithUTF8String:r.GetString()];
return cell;
}
break;
default:
ASSERT(false, ("Unsupported search result type"));
return nil;
}
else
cell.textLabel.text = @"BUG";
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
@ -393,6 +415,23 @@ static void OnSearchResultCallback(search::Results const & res, int queryId)
}
- (void)updateCompassFor:(UITableViewCell *)cell withResult:(search::Result const &)res andAngle:(double)angle
{
CompassView * compass = nil;
if (cell.accessoryView == nil)
{
float const h = m_table.rowHeight * 0.6;
compass = [[CompassView alloc] initWithFrame:CGRectMake(0, 0, h, h)];
cell.accessoryView = compass;
[compass release];
}
else if ([cell.accessoryView isKindOfClass:[CompassView class]])
compass = (CompassView *)cell.accessoryView;
if (compass)
compass.angle = angle;
}
//******************************************************************
//*********** Location manager callbacks ***************************
- (void)onLocationStatusChanged:(location::TLocationStatus)newStatus
@ -402,25 +441,28 @@ static void OnSearchResultCallback(search::Results const & res, int queryId)
- (void)onGpsUpdate:(location::GpsInfo const &)info
{
NSArray * cells = [m_table visibleCells];
for (NSUInteger i = 0; i < cells.count; ++i)
{
UITableViewCell * cell = (UITableViewCell *)[cells objectAtIndex:i];
[self updateCellDistance:cell withIndex:[m_table indexPathForCell:cell].row];
}
m_framework->GetSearchEngine()->SetPosition(info.m_latitude, info.m_longitude);
}
- (void)onCompassUpdate:(location::CompassInfo const &)info
{
CLLocation * loc = m_locationManager.lastLocation;
if (loc == nil)
return;
double const northDeg = (info.m_trueHeading < 0) ? info.m_magneticHeading : info.m_trueHeading;
NSArray * cells = [m_table visibleCells];
for (NSUInteger i = 0; i < cells.count; ++i)
{
UITableViewCell * cell = (UITableViewCell *)[cells objectAtIndex:i];
NSInteger const index = [m_table indexPathForCell:cell].row;
if (m_results[index].GetResultType() == search::Result::RESULT_FEATURE)
[self updateCellAngle:cell withIndex:index andAngle:((info.m_trueHeading < 0) ? info.m_magneticHeading : info.m_trueHeading)];
search::Result const & res = m_results[[m_table indexPathForCell:cell].row];
if (res.GetResultType() == search::Result::RESULT_FEATURE)
{
m2::PointD const center = res.GetFeatureCenter();
double const angle = ang::AngleTo(m2::PointD(MercatorBounds::LonToX(loc.coordinate.longitude),
MercatorBounds::LatToY(loc.coordinate.latitude)), center) + northDeg / 180. * math::pi;
[self updateCompassFor:cell withResult:res andAngle:angle];
}
}
}
//*********** End of Location manager callbacks ********************

View file

@ -82,6 +82,7 @@
FA5005671287BFCE002961F0 /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FA5005611287BFCE002961F0 /* Icon@2x.png */; };
FA500588128907F0002961F0 /* visibility.txt in Resources */ = {isa = PBXBuildFile; fileRef = FA500587128907F0002961F0 /* visibility.txt */; };
FA64D9A913F975AD00350ECF /* types.txt in Resources */ = {isa = PBXBuildFile; fileRef = FA64D9A813F975AD00350ECF /* types.txt */; };
FA81AE3314D061BF00A0D70D /* SearchCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA81AE3214D061BF00A0D70D /* SearchCell.mm */; };
FA85F633145DDDC20090E1A0 /* packed_polygons.bin in Resources */ = {isa = PBXBuildFile; fileRef = FA85F632145DDDC20090E1A0 /* packed_polygons.bin */; };
FA87151B12B1518F00592DAF /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA87151A12B1518F00592DAF /* SystemConfiguration.framework */; };
FA8F8938132D5DB00048E3FE /* libtomcrypt.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8F8937132D5DB00048E3FE /* libtomcrypt.a */; };
@ -613,7 +614,7 @@
1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
1D3623240D0F684500981E51 /* MapsAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapsAppDelegate.h; sourceTree = "<group>"; };
1D3623250D0F684500981E51 /* MapsAppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = MapsAppDelegate.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
1D6058910D05DD3D006BFB54 /* MapsWithMe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; name = MapsWithMe.app; path = "MWM Beta.app"; sourceTree = BUILT_PRODUCTS_DIR; };
1D6058910D05DD3D006BFB54 /* MapsWithMe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; name = MapsWithMe.app; path = "MWM Dbg Lite.app"; sourceTree = BUILT_PRODUCTS_DIR; };
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
288765070DF74369002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
28A0AB4B0D9B1048005BE974 /* Maps_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = Maps_Prefix.pch; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
@ -699,6 +700,8 @@
FA5005611287BFCE002961F0 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = SOURCE_ROOT; };
FA500587128907F0002961F0 /* visibility.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = visibility.txt; path = ../../data/visibility.txt; sourceTree = SOURCE_ROOT; };
FA64D9A813F975AD00350ECF /* types.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = types.txt; path = ../../data/types.txt; sourceTree = SOURCE_ROOT; };
FA81AE3114D061BF00A0D70D /* SearchCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchCell.h; sourceTree = "<group>"; };
FA81AE3214D061BF00A0D70D /* SearchCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SearchCell.mm; sourceTree = "<group>"; };
FA85F632145DDDC20090E1A0 /* packed_polygons.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = packed_polygons.bin; path = ../../data/packed_polygons.bin; sourceTree = SOURCE_ROOT; };
FA87151A12B1518F00592DAF /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
FA8F8937132D5DB00048E3FE /* libtomcrypt.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libtomcrypt.a; sourceTree = SOURCE_ROOT; };
@ -1269,8 +1272,6 @@
080E96DDFE201D6D7F000001 /* Classes */ = {
isa = PBXGroup;
children = (
FABF223C13FAA97A003D4D49 /* CompassView.h */,
FABF223D13FAA97A003D4D49 /* CompassView.mm */,
FA09E00F13F71F6C007E69CA /* SearchVC.h */,
FA09E01013F71F6C007E69CA /* SearchVC.mm */,
EE7F297C1219ECA300EB67A9 /* RenderBuffer.hpp */,
@ -1285,6 +1286,10 @@
EED10A4411F78D120095FAD4 /* MapViewController.mm */,
FA0B7E5F1487736200CAB3F2 /* SearchBannerChecker.h */,
FA0B7E601487736200CAB3F2 /* SearchBannerChecker.mm */,
FA81AE3114D061BF00A0D70D /* SearchCell.h */,
FA81AE3214D061BF00A0D70D /* SearchCell.mm */,
FABF223C13FAA97A003D4D49 /* CompassView.h */,
FABF223D13FAA97A003D4D49 /* CompassView.mm */,
);
path = Classes;
sourceTree = "<group>";
@ -2648,6 +2653,7 @@
FAA5C2A2144F135F005337F6 /* LocationManager.mm in Sources */,
FA0B7E611487736200CAB3F2 /* SearchBannerChecker.mm in Sources */,
FA0B7E631487747B00CAB3F2 /* GetActiveConnectionType.mm in Sources */,
FA81AE3314D061BF00A0D70D /* SearchCell.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};