diff --git a/Sources/Controllers/TargetMenu/OATargetInfoViewController.mm b/Sources/Controllers/TargetMenu/OATargetInfoViewController.mm index 2c67f3c7e5..4dbb6dc052 100644 --- a/Sources/Controllers/TargetMenu/OATargetInfoViewController.mm +++ b/Sources/Controllers/TargetMenu/OATargetInfoViewController.mm @@ -60,6 +60,8 @@ @interface OATargetInfoViewController() +@property (nonatomic) BOOL wikiCardsReady; + @end @implementation OATargetInfoViewController @@ -74,7 +76,6 @@ @implementation OATargetInfoViewController OARowInfo *_nearbyImagesRowInfo; BOOL _otherCardsReady; - BOOL _wikiCardsReady; } - (void) setRows:(NSMutableArray *)rows @@ -499,7 +500,22 @@ - (void)getCard:(NSDictionary *)feature - (void)addOtherCards:(NSString *)imageTagContent mapillary:(NSString *)mapillaryTagContent cards:(NSMutableArray *)cards rowInfo:(OARowInfo *)nearbyImagesRowInfo { - NSString *urlString = [NSString stringWithFormat:@"https://osmand.net/api/cm_place?lat=%f&lon=%f", self.location.latitude, self.location.longitude]; + CLLocation *myLocation = [OsmAndApp instance].locationServices.lastKnownLocation; + OAAppSettings *settings = [OAAppSettings sharedManager]; + NSString *preferredLang = [settings.settingPrefMapLanguage get]; + if (!preferredLang) + preferredLang = [OAUtilities currentLang]; + + NSString *urlString = [NSString stringWithFormat:@"https://osmand.net/api/cm_place?lat=%f&lon=%f&app=%@", + self.location.latitude, + self.location.longitude, + [OAIAPHelper isPaidVersion] ? @"paid" : @"free"]; + + if (preferredLang && preferredLang.length > 0) + urlString = [urlString stringByAppendingFormat:@"&lang=%@", preferredLang]; + if (myLocation) + urlString = [urlString stringByAppendingFormat:@"&mloc=%f,%f", myLocation.coordinate.latitude, myLocation.coordinate.longitude]; + if (imageTagContent) urlString = [urlString stringByAppendingString:[NSString stringWithFormat:@"&osm_image=%@", imageTagContent]]; if (mapillaryTagContent) @@ -988,10 +1004,19 @@ - (void)onViewExpanded [cardsView setCards:@[[[OAImageCard alloc] initWithData:@{@"key": @"loading"}]]]; } - [[OAWikiImageHelper sharedInstance] sendNearbyWikiImagesRequest:_nearbyImagesRowInfo targetObj:self.getTargetObj addOtherImagesOnComplete:^(NSMutableArray *cards) { + if ([OAPlugin isEnabled:OAWikipediaPlugin.class]) + { + __weak OATargetInfoViewController *selfWeak = self; + [[OAWikiImageHelper sharedInstance] sendNearbyWikiImagesRequest:_nearbyImagesRowInfo targetObj:self.getTargetObj addOtherImagesOnComplete:^(NSMutableArray *cards) { + selfWeak.wikiCardsReady = YES; + [selfWeak sendNearbyOtherImagesRequest:cards]; + }]; + } + else + { _wikiCardsReady = YES; - [self sendNearbyOtherImagesRequest:cards]; - }]; + [self sendNearbyOtherImagesRequest:[NSMutableArray array]]; + } } #pragma mark - OAEditDescriptionViewControllerDelegate diff --git a/Sources/Helpers/OAWikiImageHelper.h b/Sources/Helpers/OAWikiImageHelper.h index b407fccbae..75fc6525a7 100644 --- a/Sources/Helpers/OAWikiImageHelper.h +++ b/Sources/Helpers/OAWikiImageHelper.h @@ -23,6 +23,11 @@ #define THUMB_SIZE 500 +static const NSString *OSMAND_API_ENDPOINT = @"https://osmand.net/api/"; +static const NSString *OSMAND_API_WIKIDATA_ARTICLE_ACTION = @"wiki_place?article="; +static const NSString *OSMAND_API_WIKIDATA_CATEGORY_ACTION = @"wiki_place?category="; +static const BOOL USE_OSMAND_WIKI_API = YES; + @class OARowInfo; @class OAAbstractCard; diff --git a/Sources/Helpers/OAWikiImageHelper.mm b/Sources/Helpers/OAWikiImageHelper.mm index 6608229dfc..5faf0a4afd 100644 --- a/Sources/Helpers/OAWikiImageHelper.mm +++ b/Sources/Helpers/OAWikiImageHelper.mm @@ -60,6 +60,19 @@ - (void)sendNearbyWikiImagesRequest:(OARowInfo *)nearbyImagesRowInfo targetObj:( [self addWikidataCards:wikidataTagContent cards:cards rowInfo:nearbyImagesRowInfo]; } +- (OAWikiImage *)getOsmandApiWikiImage:(NSString *)imageUrl +{ + NSString *url = [imageUrl stringByRemovingPercentEncoding]; + NSString *imageHiResUrl = [url stringByReplacingOccurrencesOfString:@" " withString:@"_"]; + NSString *imageFileName = url.lastPathComponent; + NSString *imageName = imageFileName.stringByDeletingPathExtension; + NSString *imageStubUrl = [NSString stringWithFormat:@"%@%@%i", imageHiResUrl, @"?width=", THUMB_SIZE]; + return [[OAWikiImage alloc] initWithWikiMediaTag:imageFileName + imageName:imageName + imageStubUrl:imageStubUrl + imageHiResUrl:imageHiResUrl]; +} + - (OAWikiImage *)getWikiImage:(NSString *)imageFileName { NSString *imageName = [imageFileName stringByRemovingPercentEncoding]; @@ -78,46 +91,121 @@ - (OAWikiImage *)getWikiImage:(NSString *)imageFileName return [[OAWikiImage alloc] initWithWikiMediaTag:urlSafeFileName imageName:imageName imageStubUrl:imageStubUrl imageHiResUrl:imageHiResUrl]; } -- (void)addWikidataCards:(NSString *)wikidataTagContent cards:(NSMutableArray *)cards rowInfo:(OARowInfo *)nearbyImagesRowInfo +- (void)addOsmandAPIWikidataImageListByCategory:(NSString *)categoryName + cards:(NSMutableArray *)cards { - if (wikidataTagContent && [wikidataTagContent hasPrefix:WIKIDATA_PREFIX]) - { - NSString *safeWikidataTagContent = [wikidataTagContent stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; - NSURL *urlObj = [[NSURL alloc] initWithString: [NSString stringWithFormat:@"%@%@%@%@", WIKIDATA_API_ENDPOINT, WIKIDATA_ACTION, safeWikidataTagContent, FORMAT_JSON]]; - NSURLSession *aSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; - [[aSession dataTaskWithURL:urlObj completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { - OAWikiImageCard *resultCard = nil; - if (((NSHTTPURLResponse *)response).statusCode == 200) + NSString *url = [NSString stringWithFormat:@"%@%@%@", OSMAND_API_ENDPOINT, OSMAND_API_WIKIDATA_CATEGORY_ACTION, categoryName]; + [self addOsmandAPIImageList:url cards:cards byCategory:YES]; +} + +- (void)addOsmandAPIWikidataImageList:(NSString *)wikidataTagContent + cards:(NSMutableArray *)cards +{ + NSString *url = [NSString stringWithFormat:@"%@%@%@", OSMAND_API_ENDPOINT, OSMAND_API_WIKIDATA_ARTICLE_ACTION, wikidataTagContent]; + [self addOsmandAPIImageList:url cards:cards byCategory:NO]; +} + +- (void)addOsmandAPIImageList:(NSString *)url + cards:(NSMutableArray *)cards + byCategory:(BOOL)byCategory +{ + url = [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; + NSURL *urlObj = [[NSURL alloc] initWithString:url]; + NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; + [[session dataTaskWithURL:urlObj completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + NSMutableArray *resultCards = [NSMutableArray array]; + if (((NSHTTPURLResponse *)response).statusCode == 200) + { + if (data) { - if (data && !error) + NSError *error; + NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; + NSArray *images = jsonDict[@"features"]; + if (!error && images) { - NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; - if (jsonDict) + for (NSString *image in images) { - try { - NSArray *records = jsonDict[@"claims"][@"P18"]; - if (records && records.count > 0) - { - NSString *imageName = records.firstObject[@"mainsnak"][@"datavalue"][@"value"]; - if (imageName) - resultCard = [[OAWikiImageCard alloc] initWithWikiImage:[self getWikiImage:imageName] type:@"wikidata-photo"]; - } - } - catch(NSException *e) - { - NSLog(@"Wikidata image json serialising error"); - } + OAWikiImageCard *card = [[OAWikiImageCard alloc] initWithWikiImage:[self getOsmandApiWikiImage:image] type:@"wikimedia-photo" wikimediaCategory:NO]; + if (card) + [resultCards addObject:card]; } } } - dispatch_async(dispatch_get_main_queue(), ^{ - if (resultCard) - [cards addObject:resultCard]; + } + else + { + NSLog(@"Error retrieving Wikimedia photos (OsmandApi): %@", error); + } + dispatch_async(dispatch_get_main_queue(), ^{ + [cards addObjectsFromArray:resultCards]; + if (byCategory) + { + _wikimediaCardsReady = YES; + if (_wikidataCardsReady) + _addOtherImagesFunction(cards); + } + else + { _wikidataCardsReady = YES; if (_wikimediaCardsReady) _addOtherImagesFunction(cards); - }); - }] resume]; + } + }); + }] resume]; +} + + +- (void)addWikidataCards:(NSString *)wikidataTagContent cards:(NSMutableArray *)cards rowInfo:(OARowInfo *)nearbyImagesRowInfo +{ + if (wikidataTagContent) + { + if (USE_OSMAND_WIKI_API) + { + [self addOsmandAPIWikidataImageList:wikidataTagContent cards:cards]; + } + else if ([wikidataTagContent hasPrefix:WIKIDATA_PREFIX]) + { + NSString *safeWikidataTagContent = [wikidataTagContent stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; + NSURL *urlObj = [[NSURL alloc] initWithString: [NSString stringWithFormat:@"%@%@%@%@", WIKIDATA_API_ENDPOINT, WIKIDATA_ACTION, safeWikidataTagContent, FORMAT_JSON]]; + NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; + [[session dataTaskWithURL:urlObj completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + OAWikiImageCard *resultCard = nil; + if (((NSHTTPURLResponse *)response).statusCode == 200) + { + if (data && !error) + { + NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; + if (jsonDict) + { + try { + NSArray *records = jsonDict[@"claims"][@"P18"]; + if (records && records.count > 0) + { + NSString *imageName = records.firstObject[@"mainsnak"][@"datavalue"][@"value"]; + if (imageName) + resultCard = [[OAWikiImageCard alloc] initWithWikiImage:[self getWikiImage:imageName] type:@"wikidata-photo"]; + } + } + catch(NSException *e) + { + NSLog(@"Wikidata image json serialising error"); + } + } + } + } + else + { + NSLog(@"Error retrieving Wikidata photos: %@", error); + } + dispatch_async(dispatch_get_main_queue(), ^{ + if (resultCard) + [cards addObject:resultCard]; + _wikidataCardsReady = YES; + if (_wikimediaCardsReady) + _addOtherImagesFunction(cards); + }); + }] resume]; + } } else { @@ -143,41 +231,53 @@ - (void)addWikimediaCards:(NSString *)wikiMediaTagContent cards:(NSMutableArray< } else if (wikiMediaTagContent && [wikiMediaTagContent hasPrefix:WIKIMEDIA_CATEGORY]) { - NSString *url = [NSString stringWithFormat:@"%@%@%@%@%@", WIKIMEDIA_API_ENDPOINT, WIKIMEDIA_ACTION, wikiMediaTagContent, CM_LIMIT, FORMAT_JSON]; - url = [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; - NSURL *urlObj = [[NSURL alloc] initWithString:url]; - NSURLSession *aSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; - [[aSession dataTaskWithURL:urlObj completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { - NSMutableArray *resultCards = [NSMutableArray array]; - if (((NSHTTPURLResponse *)response).statusCode == 200) - { - if (data) + if (USE_OSMAND_WIKI_API) + { + NSString *categoryName = [wikiMediaTagContent stringByReplacingOccurrencesOfString:WIKIMEDIA_CATEGORY withString:@""]; + [self addOsmandAPIWikidataImageListByCategory:categoryName cards:cards]; + } + else + { + NSString *url = [NSString stringWithFormat:@"%@%@%@%@%@", WIKIMEDIA_API_ENDPOINT, WIKIMEDIA_ACTION, wikiMediaTagContent, CM_LIMIT, FORMAT_JSON]; + url = [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; + NSURL *urlObj = [[NSURL alloc] initWithString:url]; + NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; + [[session dataTaskWithURL:urlObj completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + NSMutableArray *resultCards = [NSMutableArray array]; + if (((NSHTTPURLResponse *)response).statusCode == 200) { - NSError *error; - NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; - NSDictionary *imagesDict = jsonDict[@"query"][@"categorymembers"]; - if (!error && imagesDict) + if (data) { - for (NSDictionary *imageDict in imagesDict) + NSError *error; + NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; + NSDictionary *imagesDict = jsonDict[@"query"][@"categorymembers"]; + if (!error && imagesDict) { - NSString *imageName = imageDict[@"title"]; - if (imageName) + for (NSDictionary *imageDict in imagesDict) { - OAWikiImageCard *card = [[OAWikiImageCard alloc] initWithWikiImage:[self getWikiImage:imageName] type:@"wikimedia-photo" wikimediaCategory:YES]; - if (card) - [resultCards addObject:card]; + NSString *imageName = imageDict[@"title"]; + if (imageName) + { + OAWikiImageCard *card = [[OAWikiImageCard alloc] initWithWikiImage:[self getWikiImage:imageName] type:@"wikimedia-photo" wikimediaCategory:YES]; + if (card) + [resultCards addObject:card]; + } } } } } - } - dispatch_async(dispatch_get_main_queue(), ^{ - [cards addObjectsFromArray:resultCards]; - _wikimediaCardsReady = YES; - if (_wikidataCardsReady) - _addOtherImagesFunction(cards); - }); - }] resume]; + else + { + NSLog(@"Error retrieving Wikimedia photos: %@", error); + } + dispatch_async(dispatch_get_main_queue(), ^{ + [cards addObjectsFromArray:resultCards]; + _wikimediaCardsReady = YES; + if (_wikidataCardsReady) + _addOtherImagesFunction(cards); + }); + }] resume]; + } } else {