Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
4 changes: 4 additions & 0 deletions OsmAnd.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1518,6 +1518,7 @@
C5CD4CF129EFE6AC00B35C3D /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5CD4CED29EFE6AB00B35C3D /* [email protected] */; };
C5CD4CF229EFE6AC00B35C3D /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5CD4CEE29EFE6AB00B35C3D /* [email protected] */; };
C5CD4CF329EFE6AC00B35C3D /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5CD4CEF29EFE6AC00B35C3D /* [email protected] */; };
C5D3D2B22EE006A100664956 /* ShareLinkItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5D3D2B12EE006A100664956 /* ShareLinkItem.swift */; };
C5D4D7312987C56000D3BC04 /* OAHistorySettingsViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = C5D4D72F2987C56000D3BC04 /* OAHistorySettingsViewController.mm */; };
C5D8F809292F5B2900C01065 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5D8F808292F5B2900C01065 /* [email protected] */; };
C5D8F80B292F5B3A00C01065 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = C5D8F80A292F5B3A00C01065 /* [email protected] */; };
Expand Down Expand Up @@ -5344,6 +5345,7 @@
C5CD4CED29EFE6AB00B35C3D /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "[email protected]"; path = "Resources/Icons/[email protected]"; sourceTree = "<group>"; };
C5CD4CEE29EFE6AB00B35C3D /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "[email protected]"; path = "Resources/Icons/[email protected]"; sourceTree = "<group>"; };
C5CD4CEF29EFE6AC00B35C3D /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "[email protected]"; path = "Resources/Icons/[email protected]"; sourceTree = "<group>"; };
C5D3D2B12EE006A100664956 /* ShareLinkItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareLinkItem.swift; sourceTree = "<group>"; };
C5D4D72E2987C56000D3BC04 /* OAHistorySettingsViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OAHistorySettingsViewController.h; sourceTree = "<group>"; };
C5D4D72F2987C56000D3BC04 /* OAHistorySettingsViewController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = OAHistorySettingsViewController.mm; sourceTree = "<group>"; };
C5D8F808292F5B2900C01065 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "[email protected]"; path = "Resources/Icons/[email protected]"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -13732,6 +13734,7 @@
05898FB12B511E0500E64B58 /* OASvgHelper.mm */,
DAB9AECB28E192D300AD01CE /* OAURLSessionProgress.h */,
DAB9AECC28E192D300AD01CE /* OAURLSessionProgress.m */,
C5D3D2B12EE006A100664956 /* ShareLinkItem.swift */,
32AD5D582A2F10EA00A51B60 /* OAuthHelper */,
DA5A80C226C563A600F274C7 /* OAUtilities.h */,
DA5A809226C563A500F274C7 /* OAUtilities.m */,
Expand Down Expand Up @@ -17651,6 +17654,7 @@
DA5A831826C563A800F274C7 /* OATargetInfoViewCell.m in Sources */,
32EB34492E462D6A004F7C75 /* OAAmenitySearcher.mm in Sources */,
DA5A845726C563A900F274C7 /* OAOsmBugsLayer.mm in Sources */,
C5D3D2B22EE006A100664956 /* ShareLinkItem.swift in Sources */,
C5DF39B52DBB6CA800332496 /* OACoordinatesGridLayer.mm in Sources */,
DA4ABEEC2876DA5D00B996EF /* OAExportSettingsType.mm in Sources */,
DA5A856126C563A900F274C7 /* OAGpxRouteApproximation.mm in Sources */,
Expand Down
1 change: 1 addition & 0 deletions Resources/Localizations/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,7 @@
"shared_string_maximum" = "Maximum";
"osmand_parking_warning" = "Warning";
"shared_string_copy" = "Copy";
"copy_link" = "Copy link";
"shared_string_continue" = "Continue";
"shared_string_deselect_all" = "Deselect all";
"shared_string_preparing" = "Preparing";
Expand Down
181 changes: 172 additions & 9 deletions Sources/AppHost/SceneDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
#import "OAAppDelegate.h"
#import "OAFirstUsageWizardController.h"
#import "StartupLogging.h"
#import "OAFavoritesHelper.h"
#import "OAFavoriteItem.h"

#include <QDir>
#include <QFile>
Expand Down Expand Up @@ -356,6 +358,9 @@ - (BOOL)handleIncomingNavigationURL:(NSURL *)url

- (BOOL)handleIncomingSetPinOnMapURL:(NSURL *)url
{
if ([self handleIncomingMapPoiURL:url])
return YES;

NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
NSArray<NSURLQueryItem *> *queryItems = components.queryItems;
BOOL hasPin = NO;
Expand All @@ -376,23 +381,181 @@ - (BOOL)handleIncomingSetPinOnMapURL:(NSURL *)url
{
double lat = latLon.coordinate.latitude;
double lon = latLon.coordinate.longitude;
int zoom;

NSString *pathPrefix = [@"/map?pin=" stringByAppendingString:latLonParam];
NSInteger pathStartIndex = [[url.absoluteString stringByRemovingPercentEncoding] indexOf:pathPrefix];
NSArray<NSString *> *params = [[[url.absoluteString stringByRemovingPercentEncoding] substringFromIndex:pathStartIndex + pathPrefix.length] componentsSeparatedByString:@"/"];
if (params.count == 3) // #15/52.3187/4.8801
zoom = [[params.firstObject stringByReplacingOccurrencesOfString:@"#" withString:@""] intValue];
else
zoom = _rootViewController.mapPanel.mapViewController.mapView.zoom;
int zoom = _rootViewController.mapPanel.mapViewController.mapView.zoom;
NSString *decoded = [url.absoluteString stringByRemovingPercentEncoding];
NSString *pathPrefix = [@"pin=" stringByAppendingString:latLonParam];
NSRange range = [decoded rangeOfString:pathPrefix];
if (range.location != NSNotFound)
{
NSString *afterPin = [decoded substringFromIndex:(range.location + range.length)];
NSArray<NSString *> *params = [afterPin componentsSeparatedByString:@"/"];
if (params.count == 3)
zoom = [[params.firstObject stringByReplacingOccurrencesOfString:@"#" withString:@""] intValue];
}

[self moveMapToLat:lat lon:lon zoom:zoom withTitle:nil];
return YES;
}
}

return NO;
}

- (BOOL)handleIncomingMapPoiURL:(NSURL *)url
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There shouldn’t be any link-parsing code in the SceneDelegate class. All parsing should be moved to the DeepLinkParser class

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to introduce the following structure:

@objcMembers
final class DeepLinkManager: NSObject {
    static let shared = DeepLinkManager()

    private let deepLinkParser = DeepLinkParser()

    func handleDeepLink(url: URL) -> Bool {
        deepLinkParser.parseDeepLink(url)
    }
}

This logic should be moved into DeepLinkParser:

return [self handleIncomingFileURL:url]
    || [self handleIncomingActionsURL:url]
    || [self handleIncomingNavigationURL:url]
    || [self handleIncomingSetPinOnMapURL:url]
    || [self handleIncomingMoveMapToLocationURL:url]
    || [self handleIncomingOpenLocationMenuURL:url]
    || [self handleIncomingTileSourceURL:url]
    || [self handleIncomingOsmAndCloudURL:url];

{
if (![OAUtilities isOsmAndSite:url] || ![OAUtilities isPathPrefix:url pathPrefix:@"/map/poi"])
return NO;

NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
NSArray<NSURLQueryItem *> *items = components.queryItems ?: @[];
NSString *nameParam = nil;
NSString *typeParam = nil;
for (NSURLQueryItem *item in items)
{
NSString *key = item.name.lowercaseString;
if ([key isEqualToString:@"name"])
nameParam = item.value;
else if ([key isEqualToString:@"type"])
typeParam = item.value;
}

if (typeParam.length > 0)
return [self handleIncomingAmenityURL:url];
else if (nameParam.length > 0)
return [self handleIncomingFavouriteURL:url];

return NO;
}

- (BOOL)handleIncomingAmenityURL:(NSURL *)url
{
if (!_rootViewController)
return NO;

NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
NSArray<NSURLQueryItem *> *items = components.queryItems ?: @[];
NSString *name = nil;
NSString *type = nil;
NSString *wikiDataId = nil;
NSString *osmId = nil;
NSString *latLonParam = nil;
for (NSURLQueryItem *item in items)
{
NSString *key = item.name.lowercaseString;
if ([key isEqualToString:@"name"])
name = item.value;
else if ([key isEqualToString:@"type"])
type = item.value;
else if ([key isEqualToString:@"wikidataid"])
wikiDataId = item.value;
else if ([key isEqualToString:@"osmid"])
osmId = item.value;
else if ([key isEqualToString:@"pin"])
latLonParam = item.value;
}

CLLocation *latLon = latLonParam.length == 0 ? nil : [OAUtilities parseLatLon:latLonParam];
if (latLon != nil)
{
double pinLat = latLon.coordinate.latitude;
double pinLon = latLon.coordinate.longitude;
int zoom = _rootViewController.mapPanel.mapViewController.mapView.zoom;
BaseDetailsObject *amenity = [self searchBaseDetailsObjectWithPinLat:pinLat pinLon:pinLon name:name poiType:type wikiDataId:wikiDataId osmId:osmId];
if (amenity == nil)
return NO;

OATargetPoint*targetPoint=[_rootViewController.mapPanel.mapViewController.mapLayers.poiLayer getTargetPoint:[amenity syntheticAmenity]];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you run out of spaces on your keyboard? )

targetPoint.location = latLon.coordinate;
[targetPoint initAdderssIfNeeded];
targetPoint.centerMap = YES;
[OARootViewController.instance.mapPanel showContextMenu:targetPoint saveState:NO preferredZoom:zoom];
return YES;
}

return NO;
}

- (BOOL)handleIncomingFavouriteURL:(NSURL *)url
{
if (!_rootViewController)
return NO;

NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
NSArray<NSURLQueryItem *> *items = components.queryItems ?: @[];
NSString *name = nil;
NSString *latLonParam = nil;
for (NSURLQueryItem *item in items)
{
NSString *key = item.name.lowercaseString;
if ([key isEqualToString:@"name"])
name = item.value;
else if ([key isEqualToString:@"pin"])
latLonParam = item.value;
}

CLLocation *latLon = latLonParam.length == 0 ? nil : [OAUtilities parseLatLon:latLonParam];
if (latLon && name.length > 0)
{
double lat = latLon.coordinate.latitude;
double lon = latLon.coordinate.longitude;
int zoom = _rootViewController.mapPanel.mapViewController.mapView.zoom;
OAFavoriteItem *point = [OAFavoritesHelper getVisibleFavByLat:lat lon:lon];
if (point && [name isEqualToString:[point getName]])
{
OATargetPoint*targetPoint = [_rootViewController.mapPanel.mapViewController.mapLayers.favoritesLayer getTargetPoint:point];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

up

targetPoint.location = latLon.coordinate;
[targetPoint initAdderssIfNeeded];
targetPoint.centerMap = YES;
[OARootViewController.instance.mapPanel showContextMenu:targetPoint saveState:NO preferredZoom:zoom];
}
else
{
[self moveMapToLat:lat lon:lon zoom:zoom withTitle:name];
}

return YES;
}

return NO;
}

- (nullable BaseDetailsObject *)searchBaseDetailsObjectWithPinLat:(double)pinLat pinLon:(double)pinLon name:(nullable NSString *)name poiType:(nullable NSString *)poiType wikiDataId:(nullable NSString *)wikiDataId osmId:(nullable NSString *)osmId
{
NSMutableArray<NSString *> *names = [NSMutableArray array];
if (name)
[names addObject:name];

int64_t parsedOsmId = -1;
if (osmId.length > 0)
{
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
NSNumber *num = [formatter numberFromString:osmId];
if (num)
parsedOsmId = num.longLongValue;
else
NSLog(@"[SceneDelegate] Incorrect OsmId: %@", osmId);
}

NSString *subType = nil;
OAPOICategory *category = poiType.length == 0 ? nil : [[OAPOIHelper sharedInstance] getPoiCategoryByName:poiType];
if (category == nil || category == [OAPOIHelper sharedInstance].otherPoiCategory)
subType = poiType;

NSString *wikidata = wikiDataId;
if (wikidata.length > 0 && ![wikidata hasPrefix:@"Q"])
wikidata = [@"Q" stringByAppendingString:wikidata];

OAAmenitySearcherRequest *request = [[OAAmenitySearcherRequest alloc] init];
request.type = kEntityTypeNode;
request.latLon = [[CLLocation alloc] initWithLatitude:pinLat longitude:pinLon];
request.names = [names mutableCopy];
request.wikidata = wikidata;
request.osmId = parsedOsmId;
request.mainAmenityType = subType;
return [[OAAmenitySearcher sharedInstance] searchDetailedObject:request];
}

- (BOOL)handleIncomingMoveMapToLocationURL:(NSURL *)url
{
NSString *pathPrefix = @"/map#";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ - (BOOL) showNearestPoi
return YES;
}

- (NSString *)encodedPoiNameForLink
{
return [[_favorite getName] escapeUrl] ?: @"";
}

- (NSString *)getTypeStr
{
NSString *group = [self getItemGroup];
Expand Down
2 changes: 2 additions & 0 deletions Sources/Controllers/TargetMenu/OATargetMenuViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ typedef void (^ContentHeightChangeListenerBlock)(CGFloat newHeight);
- (BOOL) needAddress;
- (nullable NSString *) getTypeStr;
- (NSString *) getCommonTypeStr;
- (NSString *)encodedPoiNameForLink;
- (NSString *)encodedPoiTypeForLink;
- (NSAttributedString *) getAttributedTypeStr;
- (NSAttributedString *) getAttributedCommonTypeStr;

Expand Down
10 changes: 10 additions & 0 deletions Sources/Controllers/TargetMenu/OATargetMenuViewController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,16 @@ - (void) rightControlButtonPressed;
// override
}

- (NSString *)encodedPoiNameForLink
{
return @"";
}

- (NSString *)encodedPoiTypeForLink
{
return @"";
}

- (void) downloadControlButtonPressed
{
if (_localMapIndexItem)
Expand Down
56 changes: 56 additions & 0 deletions Sources/Controllers/TargetMenu/POI/OAPOIViewController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,62 @@ - (NSString *)formatPrefix:(NSString *)prefix units:(NSString *)units
return prefix != nil && prefix.length > 0 ? [NSString stringWithFormat:@"%@, %@", prefix, units] : units;
}

- (NSString *)encodedPoiNameForLink
{
NSString *name = @"";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would be better moved into the OAPOI model

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented in OAPOIViewController since it complies with Android.
Methods should also be overridden in OAFavoriteViewController

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but you can do something like this:

 - (NSString *)encodedPoiNameForLink
{
  return [self.poi encodedPoiNameForLink];
}

if ([self.poi.type.category isWiki])
{
NSString *wikidata = [self.poi getWikidata];
if (wikidata.length == 0)
return @"";

if ([wikidata hasPrefix:@"Q"] || [wikidata hasPrefix:@"q"])
wikidata = [wikidata substringFromIndex:1];

name = wikidata;
}
else
{
name = self.poi.name ?: @"";
if (name.length == 0)
{
int64_t osmId = [self.poi getOsmId];
if (osmId > 0)
name = [NSString stringWithFormat:@"%lld", osmId];
}
}

return [name escapeUrl] ?: @"";
}

- (NSString *)encodedPoiTypeForLink
{
NSString *shareType = @"";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

up

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented in OAPOIViewController since it complies with Android.
Methods should also be overridden in OAFavoriteViewController

BOOL isWiki = [self.poi.type.category isWiki];
NSString *subType = self.poi.subType ?: @"";
NSRange sep = [subType rangeOfString:@";"];
if (sep.location != NSNotFound)
subType = [subType substringToIndex:sep.location];

NSString *typeKey = self.poi.type.category.name;
if (isWiki)
shareType = [self prepareShareType:typeKey.length > 0 ? typeKey : subType];
else
shareType = [self prepareShareType:subType.length > 0 ? subType : typeKey];

NSString *rawType = shareType.length > 0 ? shareType : OSM_WIKI_CATEGORY;
return [rawType escapeUrl] ?: @"";
}

- (NSString *)prepareShareType:(NSString *)strType
{
if (strType.length == 0)
return strType;

NSString *replaced = [strType stringByReplacingOccurrencesOfString:@"_" withString:@" "];
return [OAUtilities capitalizeFirstLetter:replaced];
}

- (BOOL) isNumericValue:(NSString *)value
{
return [value rangeOfCharacterFromSet: [ [NSCharacterSet characterSetWithCharactersInString:@"0123456789.-"] invertedSet] ].location == NSNotFound;
Expand Down
2 changes: 1 addition & 1 deletion Sources/Helpers/OAAmenitySearcher.mm
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ - (nullable BaseDetailsObject *)searchDetailedObject:(OAAmenitySearcherRequest *

for (OAPOI *amenity in amenities)
{
if (amenity.obfId > 0)
if (amenity.obfId != 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i saw a similar change somewhere by @nnngrach. We need to check if there’s a conflict

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't find an identical check in the project.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{
NSString *wiki = [amenity getWikidata];
BOOL wikiEqual = (wiki && [wiki isEqualToString:wikidata]);
Expand Down
10 changes: 6 additions & 4 deletions Sources/Helpers/OAShareMenuActivity.mm
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ - (NSString *)activityTitle
switch (_type)
{
case OAShareMenuActivityClipboard:
return OALocalizedString(@"shared_string_copy");
return OALocalizedString(@"copy_link");
case OAShareMenuActivityCopyAddress:
return OALocalizedString(@"copy_address");
case OAShareMenuActivityCopyPOIName:
Expand All @@ -65,13 +65,15 @@ - (UIImage *)activityImage
switch (_type)
{
case OAShareMenuActivityCopyAddress:
return [UIImage imageNamed:@"ic_share_address"];
return [[UIImage systemImageNamed:@"building.2"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
case OAShareMenuActivityCopyCoordinates:
return [[UIImage systemImageNamed:@"mappin.and.ellipse.circle"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
case OAShareMenuActivityGeo:
return [UIImage imageNamed:@"ic_share_coordinates"];
return [[UIImage systemImageNamed:@"globe.europe.africa"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
case OAShareMenuActivityClipboard:
return [[UIImage systemImageNamed:@"link"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
case OAShareMenuActivityCopyPOIName:
return [UIImage imageNamed:@"ic_share_copy"];
return [[UIImage systemImageNamed:@"document.on.document"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
}
return nil;
}
Expand Down
Loading