[API] Allow parsing and sharing coordinates in omaps.app links #10231

Open
hemanggs wants to merge 4 commits from hemanggs/parse-coordinate-links into master
Contributor

Partially Fixes #7482 ( iOS update remaining )

  • When Sharing location , Replaced the om:// format with URL with coordinates
before after
before image
  • Updated parser to accept coordinate URL's

Before

https://github.com/user-attachments/assets/cf5e56fa-de19-4576-809f-6e2165d55bc1

After

https://github.com/user-attachments/assets/bf054866-6235-435c-a479-f61fee3208ac

  • Wrote basic unit tests for the parser

image

  • Next step : Update parser for iOS
Partially Fixes #7482 ( iOS update remaining ) - When Sharing location , Replaced the `om://` format with URL with coordinates | before | after | |---------|---------| | ![before](https://github.com/user-attachments/assets/784b4657-9934-4248-8467-4237da050329)| ![image](https://github.com/user-attachments/assets/d0a80ec6-8e4a-48c4-9f37-a2a4c186c656)| - Updated parser to accept coordinate URL's # Before https://github.com/user-attachments/assets/cf5e56fa-de19-4576-809f-6e2165d55bc1 # After https://github.com/user-attachments/assets/bf054866-6235-435c-a479-f61fee3208ac - Wrote basic unit tests for the parser ![image](https://github.com/user-attachments/assets/a0465f30-66ae-4427-ab4b-d1bcd9a363bc) - Next step : Update parser for iOS
RedAuburn reviewed 2025-02-09 15:34:51 +00:00
pastk reviewed 2025-02-09 15:34:51 +00:00
biodranik (Migrated from github.com) reviewed 2025-02-09 15:34:51 +00:00
RedAuburn requested changes 2025-02-09 17:08:33 +00:00
RedAuburn left a comment
Member

Thanks!

Thanks!
@ -120,11 +120,11 @@ public class SharingUtils
final String subject = context.getString(R.string.share);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);

nit:

    final String text = context.getString(R.string.my_position_share_sms, httpUrl, coordUrl); 
nit: ```suggestion final String text = context.getString(R.string.my_position_share_sms, httpUrl, coordUrl); ```
@ -140,12 +140,12 @@ public class SharingUtils
context.getString(R.string.bookmark_share_email_subject);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);

nit:

    final String text = context.getString(R.string.my_position_share_email, address, httpUrl, coordUrl );
nit: ```suggestion final String text = context.getString(R.string.my_position_share_email, address, httpUrl, coordUrl ); ```

It'd be good to append the POI name here like in the other URLs, then the encoded URL can be removed from the share message altogether (best to keep the handling though)

It'd be good to append the POI name here like in the other URLs, then the encoded URL can be removed from the share message altogether (best to keep the handling though)
@ -161,3 +161,2 @@
final String geoUrl = Framework.nativeGetGe0Url(bookmark.getLat(), bookmark.getLon(),
bookmark.getScale(), bookmark.getName());
final String coordUrl = Framework.nativeGetCoordUrl(bookmark.getLat(), bookmark.getLon(),

same for adding a name here

same for adding a name here
biodranik (Migrated from github.com) reviewed 2025-02-09 17:33:59 +00:00
biodranik (Migrated from github.com) left a comment

Thanks for the good start! A few comments about the implementation.

Thanks for the good start! A few comments about the implementation.
@ -140,12 +140,12 @@ public class SharingUtils
context.getString(R.string.bookmark_share_email_subject);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
biodranik (Migrated from github.com) commented 2025-02-09 17:33:30 +00:00

The idea is that the full link (that includes zoom, name, and maybe in the future some other parameters) is generated in C++. Then iOS, Android and desktop platforms can reuse it and extend it without unnecessary copy-pasting.

The idea is that the full link (that includes zoom, name, and maybe in the future some other parameters) is generated in C++. Then iOS, Android and desktop platforms can reuse it and extend it without unnecessary copy-pasting.
biodranik (Migrated from github.com) commented 2025-02-09 16:51:00 +00:00

Add test with one or more slashes after the text (Place)? Also, adding ? and # in tests may be helpful. Note that any URL can be passed to the app, and the code should properly handle any possible combination (including harmful links made by bad actors).

Add test with one or more slashes after the text (Place)? Also, adding `?` and `#` in tests may be helpful. Note that _any_ URL can be passed to the app, and the code should properly handle _any_ possible combination (including harmful links made by bad actors).
biodranik (Migrated from github.com) commented 2025-02-09 16:51:57 +00:00

Add tests for /0,0, /-10,10, /10,0.32, /.123,-.456? Should they be valid or invalid?

Add tests for `/0,0`, `/-10,10`, `/10,0.32`, `/.123,-.456`? Should they be valid or invalid?
@ -312,4 +312,74 @@ UNIT_TEST(OtherPrefixes)
TestSuccess("https://omaps.app/Byqqqqqqqq", 45, 0, 4.25, "");
TestFailure("https://omaps.app/Byqqqqqqq");
}
UNIT_TEST(PlainCoordinateUrl_Valid)
biodranik (Migrated from github.com) commented 2025-02-09 17:03:10 +00:00

The current ge0 format stores and passes zoom level, so opened links can show roughly the same picture on the screen as it was when the link was created. This is very handy because the best zoom is already chosen at the moment of sharing the link.

There are different ways how to support zoom level in links, which one would be the best (compact, readable)? Maybe /lat,lon,zoom/name ? It likely also should be optional, and support floating-point format for better precision, right?

The current ge0 format stores and passes zoom level, so opened links can show roughly the same picture on the screen as it was when the link was created. This is very handy because the best zoom is already chosen at the moment of sharing the link. There are different ways how to support zoom level in links, which one would be the best (compact, readable)? Maybe `/lat,lon,zoom/name` ? It likely also should be optional, and support floating-point format for better precision, right?
@ -315,0 +374,4 @@
TestFailure("https://omaps.app//Name");
TestFailure("https://omaps.app/13.02227,77.76043foo");
TestFailure("https://omaps.app/foo13.02227,77.76043");
biodranik (Migrated from github.com) commented 2025-02-09 16:50:02 +00:00

Add tests for lat/lon that are out of the valid range?

Add tests for lat/lon that are out of the valid range?
biodranik (Migrated from github.com) commented 2025-02-09 17:05:53 +00:00

std::string_view avoids creating copies of the original string, while uses the same string api.

std::string_view avoids creating copies of the original string, while uses the same string api.
biodranik (Migrated from github.com) commented 2025-02-09 17:26:02 +00:00

Would using sscanf be cleaner/easier to read and support? For example:

    double lat, lon, zoom;
    switch (sscanf(url.c_str(), "%lf,%lf,%lf", &lat, &lon, &zoom))
    {
      case 2:  // Only lat and lon were parsed.
      break;
      case 3:  // lat, lon and zoom were parsed.
      break;
      default:  // Incompatible URL format
      break;
    }
Would using [sscanf](https://en.cppreference.com/w/cpp/io/c/fscanf) be cleaner/easier to read and support? For example: ```C++ double lat, lon, zoom; switch (sscanf(url.c_str(), "%lf,%lf,%lf", &lat, &lon, &zoom)) { case 2: // Only lat and lon were parsed. break; case 3: // lat, lon and zoom were parsed. break; default: // Incompatible URL format break; } ```
hemanggs reviewed 2025-02-10 10:35:40 +00:00
@ -140,12 +140,12 @@ public class SharingUtils
context.getString(R.string.bookmark_share_email_subject);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
Author
Contributor

are you sure , we should remove encoded message completely

are you sure , we should remove encoded message completely
hemanggs reviewed 2025-02-10 10:44:48 +00:00
Author
Contributor

okay 👍 , they are in range should be valid.

okay 👍 , they are in range should be valid.
hemanggs reviewed 2025-02-10 11:02:30 +00:00
Author
Contributor

yes that is a lot cleaner , thanks!

yes that is a lot cleaner , thanks!
pastk reviewed 2025-02-26 04:39:21 +00:00

is it url encoded?

is it url encoded?

please use a const for https://omaps.app/

please use a const for `https://omaps.app/`

are there tests for url generation?

are there tests for url generation?
@ -315,0 +326,4 @@
TestSuccess("https://omaps.app/89.99999,-179.99999", 89.99999, -179.99999, 17.0, "");
TestSuccess("https://omaps.app/-89.99999,179.99999", -89.99999, 179.99999, 17.0, "");
TestSuccess("https://omaps.app/12.34567,76.54321/Place", 12.34567, 76.54321, 17.0, "Place");

ideally it'd use default zoom

ideally it'd use default zoom

what about whitespace? works also?

what about whitespace? works also?

better use consts, e.g. there is GetUpperComfortScale() in scales.hpp

better use consts, e.g. there is GetUpperComfortScale() in scales.hpp

max zoom is GetUpperStyleScale()

max zoom is GetUpperStyleScale()

are there any consts for these already?

are there any consts for these already?
@ -53,0 +125,4 @@
zoom = 1.0;
if (zoom > scales::GetUpperStyleScale())
zoom = scales::GetUpperStyleScale();
result.m_lat = lat;

if zoom is out of range then would be better to use default instead of failing completely?
or even better use the closest in-range value
e.g. if its 0.5 then fix to 1
if its 22 then fix to 20

if zoom is out of range then would be better to use default instead of failing completely? or even better use the closest in-range value e.g. if its 0.5 then fix to 1 if its 22 then fix to 20
biodranik (Migrated from github.com) reviewed 2025-03-01 10:07:49 +00:00
biodranik (Migrated from github.com) commented 2025-03-01 10:07:49 +00:00

Why URLs are generated in Android code only? What are the pros of repeating this code in iOS and on desktop? Why it can't be written in C++ and covered with unit tests, as everything else?

Why URLs are generated in Android code only? What are the pros of repeating this code in iOS and on desktop? Why it can't be written in C++ and covered with unit tests, as everything else?
hemanggs reviewed 2025-03-03 08:36:42 +00:00
Author
Contributor

Agreed this is should be better , thanks.

Agreed this is should be better , thanks.
hemanggs reviewed 2025-03-03 11:54:20 +00:00
@ -315,0 +326,4 @@
TestSuccess("https://omaps.app/89.99999,-179.99999", 89.99999, -179.99999, 17.0, "");
TestSuccess("https://omaps.app/-89.99999,179.99999", -89.99999, 179.99999, 17.0, "");
TestSuccess("https://omaps.app/12.34567,76.54321/Place", 12.34567, 76.54321, 17.0, "Place");
Author
Contributor

yes works added a test

yes works added a test
biodranik (Migrated from github.com) reviewed 2025-03-03 20:32:17 +00:00
biodranik (Migrated from github.com) commented 2025-03-03 20:03:18 +00:00

nit:

  std::string const nameStr = jni::ToNativeString(env, name);
nit: ```suggestion std::string const nameStr = jni::ToNativeString(env, name); ```
biodranik (Migrated from github.com) commented 2025-03-03 20:03:27 +00:00
```suggestion ```
biodranik (Migrated from github.com) commented 2025-03-03 20:03:49 +00:00

nit:

  std::string const url = ge0::GenerateCoordUrl(lat, lon, scale, nameStr);
nit: ```suggestion std::string const url = ge0::GenerateCoordUrl(lat, lon, scale, nameStr); ```
biodranik (Migrated from github.com) commented 2025-03-03 20:05:03 +00:00

Is this java wrapper method really needed? Why is it better than calling Framework.nativeGetCoordUrl(lat, lon, zoomLevel, name); directly where necessary?

Is this java wrapper method really needed? Why is it better than calling `Framework.nativeGetCoordUrl(lat, lon, zoomLevel, name);` directly where necessary?
@ -120,11 +120,11 @@ public class SharingUtils
final String subject = context.getString(R.string.share);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
biodranik (Migrated from github.com) commented 2025-03-03 20:08:59 +00:00
```suggestion ```
@ -142,3 +142,2 @@
final String geoUrl = Framework.nativeGetGe0Url(object.getLat(), object.getLon(),
object.getScale(), object.getName());
final String coordUrl = Framework.nativeGetCoordUrl(object.getLat(), object.getLon(),
biodranik (Migrated from github.com) commented 2025-03-03 20:07:40 +00:00

nit:

                                                  object.getScale(), object.getName());
nit: ```suggestion object.getScale(), object.getName()); ```
biodranik (Migrated from github.com) commented 2025-03-03 20:10:13 +00:00
```suggestion ```
@ -163,2 +162,3 @@
bookmark.getScale(), bookmark.getName());
final String coordUrl = Framework.nativeGetCoordUrl(bookmark.getLat(), bookmark.getLon(),
bookmark.getScale(), bookmark.getName());
final String httpUrl = Framework.getHttpGe0Url(bookmark.getLat(), bookmark.getLon(),
biodranik (Migrated from github.com) commented 2025-03-03 20:11:34 +00:00

Did you see any warnings about unused variables?

Did you see any warnings about unused variables? ```suggestion ```
@ -315,0 +343,4 @@
TestSuccess("https://omaps.app/12.34567,76.54321,10.5", 12.34567, 76.54321, 10.5, "");
TestSuccess("https://omaps.app/12.34567,76.54321,15.75/Place", 12.34567, 76.54321, 15.75, "Place");
TestSuccess("https://omaps.app/13.02227,77.76043,18.0", 13.02227, 77.76043, 18.0, "");
biodranik (Migrated from github.com) commented 2025-03-03 20:15:28 +00:00
  TestSuccess("https://omaps.app/13.02227,77.76043,18.0", 13.02227, 77.76043, 18.0, "");
  TestSuccess("https://omaps.app/13.02227,77.76043,18.0#", 13.02227, 77.76043, 18.0, "");
    TestSuccess("https://omaps.app/13.02227,77.76043,18.0?", 13.02227, 77.76043, 18.0, "");
```suggestion TestSuccess("https://omaps.app/13.02227,77.76043,18.0", 13.02227, 77.76043, 18.0, ""); TestSuccess("https://omaps.app/13.02227,77.76043,18.0#", 13.02227, 77.76043, 18.0, ""); TestSuccess("https://omaps.app/13.02227,77.76043,18.0?", 13.02227, 77.76043, 18.0, ""); ```
@ -315,0 +351,4 @@
// Out of range clamping
TestSuccess("https://omaps.app/13.02227,77.76043,100", 13.02227, 77.76043, 20.0, "");
TestSuccess("https://omaps.app/13.02227,77.76043,0.5", 13.02227, 77.76043, 1.0, "");
biodranik (Migrated from github.com) commented 2025-03-03 20:13:28 +00:00

Are negative zoom values discarded or clamped?

Are negative zoom values discarded or clamped?
biodranik (Migrated from github.com) commented 2025-03-03 20:16:37 +00:00

nit here and below:

  auto const url = GenerateCoordUrl(0, 0, 19, "Name");
nit here and below: ```suggestion auto const url = GenerateCoordUrl(0, 0, 19, "Name"); ```
biodranik (Migrated from github.com) commented 2025-03-03 20:18:08 +00:00

Can all these tests be moved to the list of PlainCoordinateUrl_Valid ? Why are they separated?

Can all these tests be moved to the list of PlainCoordinateUrl_Valid ? Why are they separated?
biodranik (Migrated from github.com) commented 2025-03-03 20:23:19 +00:00

No need in introducing unnecessary allocation and copying here:

  std::string url = "https://omaps.app/";
No need in introducing unnecessary allocation and copying here: ```suggestion std::string url = "https://omaps.app/"; ```
biodranik (Migrated from github.com) commented 2025-03-03 20:29:26 +00:00
  auto const writtenChars = snprintf(buf, sizeof(buf), "%.5f,%.5f,%.0f", lat, lon, zoom);
  CHECK(writtenChars > 0 && writtenChars < sizeof(buf), ("Buffer is too small", writtenChars, lat, lon, zoom));
```suggestion auto const writtenChars = snprintf(buf, sizeof(buf), "%.5f,%.5f,%.0f", lat, lon, zoom); CHECK(writtenChars > 0 && writtenChars < sizeof(buf), ("Buffer is too small", writtenChars, lat, lon, zoom)); ```
biodranik (Migrated from github.com) commented 2025-03-03 20:31:37 +00:00
  {
    url.push_back('/');
    url.append(UrlEncodeString(TransformName(name)));
  }
```suggestion { url.push_back('/'); url.append(UrlEncodeString(TransformName(name))); } ```
hemanggs reviewed 2025-03-04 03:09:51 +00:00
@ -315,0 +351,4 @@
// Out of range clamping
TestSuccess("https://omaps.app/13.02227,77.76043,100", 13.02227, 77.76043, 20.0, "");
TestSuccess("https://omaps.app/13.02227,77.76043,0.5", 13.02227, 77.76043, 1.0, "");
Author
Contributor

They are clamped , is it okay this way ? added a test.

They are clamped , is it okay this way ? added a test.
hemanggs reviewed 2025-03-04 03:20:20 +00:00
Author
Contributor

Yeah thats better , although all other tests do follow this kind of separated pattern , do i group them too ?

Yeah thats better , although all other tests do follow this kind of separated pattern , do i group them too ?
This repo is archived. You cannot comment on pull requests.
No labels
Accessibility
Accessibility
Address
Address
Android
Android
Android Auto
Android Auto
Android Automotive (AAOS)
Android Automotive (AAOS)
API
API
AppGallery
AppGallery
AppStore
AppStore
Battery and Performance
Battery and Performance
Blocker
Blocker
Bookmarks and Tracks
Bookmarks and Tracks
Borders
Borders
Bug
Bug
Build
Build
CarPlay
CarPlay
Classificator
Classificator
Community
Community
Core
Core
CrashReports
CrashReports
Cycling
Cycling
Desktop
Desktop
DevEx
DevEx
DevOps
DevOps
dev_sandbox
dev_sandbox
Directions
Directions
Documentation
Documentation
Downloader
Downloader
Drape
Drape
Driving
Driving
Duplicate
Duplicate
Editor
Editor
Elevation
Elevation
Enhancement
Enhancement
Epic
Epic
External Map Datasets
External Map Datasets
F-Droid
F-Droid
Fonts
Fonts
Frequently User Reported
Frequently User Reported
Fund
Fund
Generator
Generator
Good first issue
Good first issue
Google Play
Google Play
GPS
GPS
GSoC
GSoC
iCloud
iCloud
Icons
Icons
iOS
iOS
Legal
Legal
Linux Desktop
Linux Desktop
Linux packaging
Linux packaging
Linux Phone
Linux Phone
Mac OS
Mac OS
Map Data
Map Data
Metro
Metro
Navigation
Navigation
Need Feedback
Need Feedback
Night Mode
Night Mode
NLnet 2024-06-281
NLnet 2024-06-281
No Feature Parity
No Feature Parity
Opening Hours
Opening Hours
Outdoors
Outdoors
POI Info
POI Info
Privacy
Privacy
Public Transport
Public Transport
Raw Idea
Raw Idea
Refactoring
Refactoring
Regional
Regional
Regression
Regression
Releases
Releases
RoboTest
RoboTest
Route Planning
Route Planning
Routing
Routing
Ruler
Ruler
Search
Search
Security
Security
Styles
Styles
Tests
Tests
Track Recording
Track Recording
Translations
Translations
TTS
TTS
UI
UI
UX
UX
Walk Navigation
Walk Navigation
Watches
Watches
Web
Web
Wikipedia
Wikipedia
Windows
Windows
Won't fix
Won't fix
World Map
World Map
No milestone
No project
No assignees
4 participants
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: organicmaps/organicmaps-tmp#10231
No description provided.