Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions OsmAnd MapsTests/Search/SearchUICoreTest.mm
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include <OsmAndCore.h>
#include <OsmAndCore/ArchiveReader.h>
#include <OsmAndCore/Search/CommonWords.h>
#include <OsmAndCore/stdlib_common.h>
#include <OsmAndCore/QtExtensions.h>
#include <QString>
Expand Down Expand Up @@ -67,6 +68,24 @@ - (void) tearDown
// Put teardown code here. This method is called after the invocation of each test method in the class.
}

- (void)testSelectMainUnknownWordToSearchSortsCommonWords
{
OASearchPhrase *phrase = [OASearchPhrase emptyPhrase:nil];

NSMutableArray<NSString *> *unknownBeatsCommon = [@[@"street", @"zzxqv"] mutableCopy];
XCTAssertEqualObjects(@"zzxqv", [phrase selectMainUnknownWordToSearch:unknownBeatsCommon]);

NSMutableArray<NSString *> *commonWords = [@[@"road", @"street"] mutableCopy];
XCTAssertGreaterThan(OsmAnd::CommonWords::getCommonSearch(QStringLiteral("street")), OsmAnd::CommonWords::getCommonSearch(QStringLiteral("road")));
XCTAssertEqualObjects(@"street", [phrase selectMainUnknownWordToSearch:commonWords]);

NSMutableArray<NSString *> *longerWithoutDigits = [@[@"zzx123", @"zzxy"] mutableCopy];
XCTAssertEqualObjects(@"zzxy", [phrase selectMainUnknownWordToSearch:longerWithoutDigits]);

NSMutableArray<NSString *> *emptyAndDuplicateWords = [@[@"", @"zzx1", @"zzx1"] mutableCopy];
XCTAssertEqualObjects(@"zzx1", [phrase selectMainUnknownWordToSearch:emptyAndDuplicateWords]);
}

- (void) testSearch
{
_successCount = 0;
Expand Down
83 changes: 47 additions & 36 deletions Sources/Search/OASearchPhrase.mm
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@
static NSArray<NSString *> *CHARS_TO_NORMALIZE_KEY = @[@"’", @"ʼ", @"(", @")", @"´", @"`", @"′", @"‵", @"ʹ"]; // remove () subcities
static NSArray<NSString *> *CHARS_TO_NORMALIZE_VALUE = @[@"'", @"'", @" ", @" ", @"'", @"'", @"'", @"'", @"'"];

static int OALengthWithoutNumbers(NSString *s)
{
int len = 0;
for (int k = 0; k < s.length; k++)
{
unichar ch = [s characterAtIndex:k];
if (ch < '0' || ch > '9')
len++;
}
return len;
}

@interface OASearchPhrase ()

@property (nonatomic) OACollatorStringMatcher *clt;
Expand Down Expand Up @@ -77,9 +89,9 @@ @interface OASearchPhrase ()
@property (nonatomic) OARegionPriorityProvider *regionPriorityProvider;
@property (nonatomic) BOOL acceptPrivate;

@end
- (void)sortCommonWords:(NSMutableArray<NSString *> *)searchWords;

static NSComparator _OACommonWordsComparator = nil;
@end

@implementation OASearchPhrase
{
Expand Down Expand Up @@ -113,30 +125,40 @@ + (void) initialize
@"и",
// Don't add short names ! issues for perfect matching "Drive A", ...
nil];
_OACommonWordsComparator = ^NSComparisonResult(NSString * _Nonnull o1, NSString * _Nonnull o2)
{
int i1 = OsmAnd::CommonWords::getCommonSearch(QString::fromNSString([o1 lowercaseString]));
int i2 = OsmAnd::CommonWords::getCommonSearch(QString::fromNSString([o2 lowercaseString]));

if (i1 != i2)
{
if (i1 == -1)
return NSOrderedAscending;
else if (i2 == -1)
return NSOrderedDescending;

return [OAUtilities compareInt:i2 y:i1];
}

// compare length without numbers to not include house numbers
return [OAUtilities compareInt:[OASearchPhrase lengthWithoutNumbers:o2] y:[OASearchPhrase lengthWithoutNumbers:o1]];
};
}
}

- (NSComparator) commonWordsComparator
- (void)sortCommonWords:(NSMutableArray<NSString *> *)searchWords
{
return _OACommonWordsComparator;
NSMutableDictionary<NSString *, NSNumber *> *commonRanks = [NSMutableDictionary dictionaryWithCapacity:searchWords.count];
NSMutableDictionary<NSString *, NSNumber *> *lengthsWithoutNumbers = [NSMutableDictionary dictionaryWithCapacity:searchWords.count];
for (NSString *word in searchWords)
{
if (commonRanks[word] == nil)
{
commonRanks[word] = @(OsmAnd::CommonWords::getCommonSearch(QString::fromNSString([word lowercaseString])));
lengthsWithoutNumbers[word] = @(OALengthWithoutNumbers(word));
}
}

[searchWords sortUsingComparator:^NSComparisonResult(NSString * _Nonnull o1, NSString * _Nonnull o2)
{
int i1 = commonRanks[o1].intValue;
int i2 = commonRanks[o2].intValue;

if (i1 != i2)
{
if (i1 == -1)
return NSOrderedAscending;
else if (i2 == -1)
return NSOrderedDescending;

return [OAUtilities compareInt:i2 y:i1];
}

// compare length without numbers to not include house numbers
return [OAUtilities compareInt:lengthsWithoutNumbers[o2].intValue y:lengthsWithoutNumbers[o1].intValue];
}];
}

+ (OASearchPhrase *) emptyPhrase
Expand Down Expand Up @@ -362,7 +384,7 @@ - (void) calcMainUnknownWordToSearch
_mainUnknownSearchWordComplete = YES;
NSMutableArray<NSString *> *searchWords = [NSMutableArray arrayWithArray:unknownSearchWords];
[searchWords insertObject:_firstUnknownSearchWord atIndex:0];
[searchWords sortUsingComparator:self.commonWordsComparator];
[self sortCommonWords:searchWords];
for (NSString *s in searchWords)
{
if (s.length > 0)
Expand Down Expand Up @@ -1037,18 +1059,7 @@ + (NSComparisonResult) icompare:(int)x y:(int)y

+ (int) lengthWithoutNumbers:(NSString *)s
{
int len = 0;
for (int k = 0; k < s.length; k++)
{
if ([s characterAtIndex:k] >= '0' && [s characterAtIndex:k] <= '9')
{
}
else
{
len++;
}
}
return len;
return OALengthWithoutNumbers(s);
}

- (int) getUnknownWordToSearchBuildingInd
Expand Down Expand Up @@ -1144,7 +1155,7 @@ + (NSString *) ALLDELIMITERS

- (NSString *) selectMainUnknownWordToSearch:(NSMutableArray<NSString *> *)searchWords
{
[searchWords sortUsingComparator:self.commonWordsComparator];
[self sortCommonWords:searchWords];

for (NSString *s in searchWords)
{
Expand Down