Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[android] Show the speed limit like in iOS #3817

Closed
wants to merge 2 commits into from

Conversation

alensiljak
Copy link

@alensiljak alensiljak commented Nov 4, 2022

Implements #952, text-only

@alensiljak
Copy link
Author

alensiljak commented Nov 4, 2022

I have concerns about the whole value fitting once the numbers are in double- or triple-digits. Need to try it while driving and eventually adjust the font size for the display.

@pm4rcin
Copy link

pm4rcin commented Nov 4, 2022

I have concerns about the whole value fitting once the numbers are in double- or triple-digits. Need to try it while driving and eventually adjust the font size for the display.

It could be easily tested on Android Emulator.

@alensiljak
Copy link
Author

alensiljak commented Nov 4, 2022

It could be easily tested on Android Emulator.

It's not about Android Emulator but this being a Friday night, the end of a work week. Simple solutions seem the hardest to think of right now. ;)

@pm4rcin
Copy link

pm4rcin commented Nov 4, 2022

You can import GPX/KML file (from Google Earth for example) or create a route like I did. I hope you understand from the screenshot:
1667596674-wayshot
EDIT: And you have to speed up simulation from menu so the car moves faster in emulator. I'll try to test by myself if I manage to patch and compile the thing (but can't promise it because I'm new to Android development).

@alensiljak
Copy link
Author

Thanks, @pm4rcin, I did not know about that feature. I did test in the most simple way possible, by setting the string to "180 (130)" and checking it on the phone.

@alensiljak
Copy link
Author

I'll try to test by myself if I manage to patch and compile the thing (but can't promise it because I'm new to Android development).

Seems fairly straightforward by following the instructions. I did not experience any issues. The sub-repos need to be fetched and the configure.sh needs to be run in Linux environment, i.e. WSL if on Windows.

That's a really cool tip about the driving simulation. I'll have to try that. OsmAnd can create GPX routes easily.

@Jean-BaptisteC
Copy link
Member

Can you add [android] before PR name to trigger Android workflow ;)
More information here

@alensiljak alensiljak changed the title Showing speed limit, if available [android] Showing speed limit, if available Nov 4, 2022
@alensiljak
Copy link
Author

alensiljak commented Nov 4, 2022

@pm4rcin, could you tell me how to get the route (GPX) into Organic Maps, please? If I choose OM for opening the GPX file from i.e. Material Files, nothing happens. And I don't see options to import directly from inside the app.
This would be really handy in order to test the issues with speed cameras that I've noticed.

@pm4rcin
Copy link

pm4rcin commented Nov 4, 2022

@alensiljak I don't think GPX import is supported in any way currently. See #624

@pm4rcin
Copy link

pm4rcin commented Nov 4, 2022

What is this (36)? It's on motorway with 130pkh limit so it displays a different thing than wanted. When on 80kph limit it's (22) and on 50kph it's (14). Something's wrong with your PR but it's close to displaying correct thing.
1667605175-wayshot

@alensiljak
Copy link
Author

alensiljak commented Nov 4, 2022

What is this (36)?

Oh, right. The speed is apparently expressed in meters per second. I need to convert it to km/h the selected unit.

@alensiljak
Copy link
Author

alensiljak commented Nov 5, 2022

The decimals are removed for display. That would explain the slight differences in numbers.

@RedAuburn
Copy link
Sponsor Member

Nice! It'd be good to display the speed limit as iOS does, in the format currentSpeed/speedLimit (iOS PR for reference: #2963)

@biodranik
Copy link
Member

@alensiljak you can convert GPX to KML using any online convertor.

@alensiljak
Copy link
Author

alensiljak commented Nov 5, 2022

Guys, thanks for all the tips so far! I now have a decent setup and toolbox, and can hopefully debug and check other issues that I experience, like speed cameras.

The conversion and formatting are now in place and I'd say the PR is functionally ready. Please review.

Edit: FYI, I found https://gpx.studio/ to be quite convenient in providing GPX routes with defined travel speed. This is quite helpful when combined with Android Studio feature of simulating location and movement. Thanks, @pm4rcin!

@alensiljak
Copy link
Author

Oh, the code formatting sucks. The change is now really hard to identify on GitHub. I've tried throwing an Exception and then removed that code, reformatting the file to fix the spacing. Now the whole file is indicated as changed. :S

Copy link
Member

@biodranik biodranik left a comment

Choose a reason for hiding this comment

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

Why did you change the indentation? We have some rules for code formatting, please try to follow them. There are some code formatters at tools/android/formatter for example.

@alensiljak
Copy link
Author

The question why, I believe I have answered in my comment above.
I have now applied the project formatter. The XML file has changed more than expected. Something might be missing there. I see the value 4 for continuation indent.

Copy link
Member

@biodranik biodranik left a comment

Choose a reason for hiding this comment

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

I see only unnecessary formatting changes, without an actual improvement.

android/res/layout/layout_nav_bottom_numbers.xml Outdated Show resolved Hide resolved
android/res/layout/layout_nav_bottom_numbers.xml Outdated Show resolved Hide resolved
android/res/layout/layout_nav_bottom_numbers.xml Outdated Show resolved Hide resolved
android/res/layout/layout_nav_bottom_numbers.xml Outdated Show resolved Hide resolved
android/res/layout/layout_nav_bottom_numbers.xml Outdated Show resolved Hide resolved
@pm4rcin
Copy link

pm4rcin commented Nov 7, 2022

@alensiljak I have cleaned up the patch

diff --git a/android/jni/app/organicmaps/Framework.cpp b/android/jni/app/organicmaps/Framework.cpp
index db284b9d64..9cf36b600a 100644
--- a/android/jni/app/organicmaps/Framework.cpp
+++ b/android/jni/app/organicmaps/Framework.cpp
@@ -1185,7 +1185,7 @@ Java_app_organicmaps_Framework_nativeGetRouteFollowingInfo(JNIEnv * env, jclass)
                             "(Ljava/lang/String;Ljava/lang/String;"
                             "Ljava/lang/String;Ljava/lang/String;"
                             "Ljava/lang/String;Ljava/lang/String;DIIIII"
-                            "[Lapp/organicmaps/routing/SingleLaneInfo;ZZ)V");
+                            "[Lapp/organicmaps/routing/SingleLaneInfo;ZZD)V");
 
   vector<routing::FollowingInfo::SingleLaneInfoClient> const & lanes = info.m_lanes;
   jobjectArray jLanes = nullptr;
@@ -1221,7 +1221,8 @@ Java_app_organicmaps_Framework_nativeGetRouteFollowingInfo(JNIEnv * env, jclass)
       jni::ToJavaString(env, info.m_turnUnitsSuffix), jni::ToJavaString(env, info.m_sourceName),
       jni::ToJavaString(env, info.m_displayedStreetName), info.m_completionPercent, info.m_turn,
       info.m_nextTurn, info.m_pedestrianTurn, info.m_exitNum, info.m_time, jLanes,
-      static_cast<jboolean>(isSpeedCamLimitExceeded), static_cast<jboolean>(shouldPlaySignal));
+      static_cast<jboolean>(isSpeedCamLimitExceeded), static_cast<jboolean>(shouldPlaySignal),
+      info.m_speedLimitMps);
   ASSERT(result, (jni::DescribeException()));
   return result;
 }
diff --git a/android/res/layout/layout_nav_bottom_numbers.xml b/android/res/layout/layout_nav_bottom_numbers.xml
index b4614f7f3d..aea50575fd 100644
--- a/android/res/layout/layout_nav_bottom_numbers.xml
+++ b/android/res/layout/layout_nav_bottom_numbers.xml
@@ -13,7 +13,7 @@
     android:id="@+id/speed_view_container"
     android:layout_width="0dp"
     android:layout_height="match_parent"
-    android:layout_weight="1"
+    android:layout_weight="1.2"
     android:background="@drawable/speed_cams_bg"
     android:gravity="center"
     android:minWidth="@dimen/nav_numbers_side_min_width"
@@ -28,8 +28,7 @@
       android:includeFontPadding="false"
       android:lines="1"
       android:textAppearance="@style/MwmTextAppearance.NavMenu.Number"
-      tools:text="999" />
-
+      tools:text="999 (999)" />
     <!-- Speed -->
     <TextView
       android:id="@+id/speed_dimen"
@@ -48,7 +47,7 @@
   <RelativeLayout
     android:layout_width="0dp"
     android:layout_height="match_parent"
-    android:layout_weight="1.5"
+    android:layout_weight="1.2"
     android:gravity="center"
     android:minWidth="@dimen/nav_numbers_side_min_width"
     android:paddingStart="@dimen/nav_numbers_margin"
diff --git a/android/src/app/organicmaps/routing/RoutingInfo.java b/android/src/app/organicmaps/routing/RoutingInfo.java
index 23d0503d26..972b06588e 100644
--- a/android/src/app/organicmaps/routing/RoutingInfo.java
+++ b/android/src/app/organicmaps/routing/RoutingInfo.java
@@ -27,6 +27,7 @@ public class RoutingInfo
   public final CarDirection nextCarDirection;
   public final int exitNum;
   public final SingleLaneInfo[] lanes;
+  public final double speedLimit;
   // For pedestrian routing.
   public final PedestrianTurnDirection pedestrianTurnDirection;
   private final boolean speedLimitExceeded;
@@ -157,7 +158,7 @@ public class RoutingInfo
   public RoutingInfo(String distToTarget, String units, String distTurn, String turnSuffix, String currentStreet, String nextStreet, double completionPercent,
                      int vehicleTurnOrdinal, int vehicleNextTurnOrdinal, int pedestrianTurnOrdinal, int exitNum,
                      int totalTime, SingleLaneInfo[] lanes, boolean speedLimitExceeded,
-                     boolean shouldPlayWarningSignal)
+                     boolean shouldPlayWarningSignal, double speedLimit)
   {
     this.distToTarget = distToTarget;
     this.targetUnits = units;
@@ -174,6 +175,7 @@ public class RoutingInfo
     this.pedestrianTurnDirection = PedestrianTurnDirection.values()[pedestrianTurnOrdinal];
     this.speedLimitExceeded = speedLimitExceeded;
     this.shouldPlayWarningSignal = shouldPlayWarningSignal;
+    this.speedLimit = speedLimit;
   }
 
   public boolean isSpeedLimitExceeded()
diff --git a/android/src/app/organicmaps/widget/menu/NavMenu.java b/android/src/app/organicmaps/widget/menu/NavMenu.java
index 32cd16d337..bff3a7d6b8 100644
--- a/android/src/app/organicmaps/widget/menu/NavMenu.java
+++ b/android/src/app/organicmaps/widget/menu/NavMenu.java
@@ -208,11 +208,49 @@ public class NavMenu
 
     Pair<String, String> speedAndUnits = StringUtils.nativeFormatSpeedAndUnits(last.getSpeed());
 
+    // (temporarily) show the speed limit together with the current speed.
+    String speedIndicator = formatSpeed(speedAndUnits, info);
+    mSpeedValue.setText(speedIndicator);
+
     mSpeedUnits.setText(speedAndUnits.second);
-    mSpeedValue.setText(speedAndUnits.first);
     mSpeedViewContainer.setActivated(info.isSpeedLimitExceeded());
   }
 
+  private String formatSpeed(Pair<String, String> speedAndUnits, RoutingInfo info)
+  {
+    double currentSpeedMps = Double.parseDouble(speedAndUnits.first);
+    String speedIndicator = String.format("%.0f", currentSpeedMps);
+
+    double speedLimit = convertMpsIntoUnits(info.speedLimit, speedAndUnits.second);
+    if (speedLimit > 0.0)
+    {
+      speedIndicator += String.format("/%.0f", speedLimit);
+    }
+
+    return speedIndicator;
+  }
+
+  private double convertMpsIntoUnits(double speedInMps, String units)
+  {
+    double result;
+
+    switch (units)
+    {
+    case "km/h":
+      // 1 m/s = 3600s/1000m = 3.6 km/h
+      result = speedInMps * 3.6;
+      break;
+    case "mph":
+      // 1 m/s = 2.2369 mph
+      result = speedInMps * 2.2369;
+      break;
+    default:
+      // should throw an exception. Use km/h as a workaround.
+      result = speedInMps * 3.6;
+    }
+    return result;
+  }
+
   public void update(@NonNull RoutingInfo info)
   {
     updateSpeedView(info);

@alensiljak
Copy link
Author

@alensiljak I have cleaned up the patch

Thank you so much! That saves a ton of time. What are the next steps?

@pm4rcin
Copy link

pm4rcin commented Nov 7, 2022

You can reset your local branch and save the diff to the file and then git apply filename. Then commit and force push. WARNING: Force pushing will destroy your commit history but I don't think that we need more than 1 commit for such simple PR.

@alensiljak
Copy link
Author

I'm getting

error: patch failed: android/res/layout/layout_nav_bottom_numbers.xml:13
error: android/res/layout/layout_nav_bottom_numbers.xml: patch does not apply

@alensiljak
Copy link
Author

The PR seems to have closed automatically when the branch was reset.

@alensiljak alensiljak requested review from RedAuburn, biodranik and pm4rcin and removed request for biodranik, RedAuburn and pm4rcin November 7, 2022 16:12
Signed-off-by: Alen Šiljak <dev@alensiljak.eu.org>
result = speedInMps * 3.6;
}
return result;
}
Copy link
Member

@vng vng Nov 8, 2022

Choose a reason for hiding this comment

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

Why not to use existing approach? Like:
Pair<String, String> speedAndUnits = StringUtils.nativeFormatSpeedAndUnits(last.getSpeed());

Copy link
Author

Choose a reason for hiding this comment

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

In this case, the unit is already known to the caller and that would somewhat obfuscate the point of the function, I think.

Copy link
Member

Choose a reason for hiding this comment

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

Is this duplication really necessary?

if (info.speedLimit > 0.0)
{
double speedLimit = convertMpsIntoUnits(info.speedLimit, speedAndUnits.second);
speedIndicator += String.format("/%.0f", speedLimit);

Choose a reason for hiding this comment

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

[Pure suggestion as I would love to see this PR merged even without it and I wouldn't slow down the reviewing process]

iOS pr use space around the slash:

Suggested change
speedIndicator += String.format("/%.0f", speedLimit);
speedIndicator += String.format(" / %.0f", speedLimit);

Copy link
Author

Choose a reason for hiding this comment

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

iOS use space around the slash:

The initial implementation was like that. Unfortunately, it takes too much screen space, in my opinion. Hence I narrowed it down.

Choose a reason for hiding this comment

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

Oh ! ok. Sorry I didn't see this from the history because of the force push.

Is there anything I can do to help the merge of this pr ?
Speed limit information is one of key features I really love to see in Organic Maps

@alensiljak alensiljak requested review from biodranik and removed request for RedAuburn January 27, 2023 21:59
Copy link
Member

@biodranik biodranik left a comment

Choose a reason for hiding this comment

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

What does it look like in a vertical orientation on different devices, including lower-end ones (e.g. Android 5-6), with speed 110 and speed limit 120, and with a larger/largest font selected in the device's options?

result = speedInMps * 3.6;
}
return result;
}
Copy link
Member

Choose a reason for hiding this comment

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

Is this duplication really necessary?

Copy link
Member

@biodranik biodranik left a comment

Choose a reason for hiding this comment

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

#4189 is a blocker for this PR and should be fixed first.

@TheAdventurer64
Copy link
Contributor

Looks like the issue was fixed

@biodranik
Copy link
Member

@TheAdventurer64 no, this PR is for Android

@simonschaufi
Copy link
Contributor

simonschaufi commented Apr 16, 2023

Just wanted to inform you that maps.me has implemented this feature.

Screenshot_20230416-134804_MAPSME

And when you are too fast, it changes the color:

Screenshot_20230416-134940_MAPSME

@d4f5409d
Copy link
Contributor

d4f5409d commented Jun 19, 2023

Just wanted to inform you that maps.me has implemented this feature already and their app is also open source. You might have a look at their implementation 😄

https://github.com/mapsme/omim

Screenshot_20230416-134804_MAPSME

And when you are too fast, it changes the color:

Screenshot_20230416-134940_MAPSME

They're currently proprietary. "Their" source code is 2 years old already. Organic Maps is the fork of the Maps.me repo.

@rtsisyk
Copy link
Contributor

rtsisyk commented Nov 23, 2023

@alensiljak what is the current status here?

@rtsisyk rtsisyk self-assigned this Nov 23, 2023
@patepelo patepelo added the Android Android development label Nov 23, 2023
@alensiljak
Copy link
Author

alensiljak commented Nov 23, 2023

@alensiljak what is the current status here?

Hi. I'm probably the wrong person to ask. I've implemented a simple display (i.e. "50/70 kmh") of the speed limit, if available.
It is a decent base for any more-advanced graphical display of the speed limit, where eventually the textual change is reverted and a graphical indicator displayed instead.
No extensive testing on different devices or screen resolutions have been performed as I have neither the time nor other resources to do so.
Considering I don't know what the process for accepting pull requests is, and this has been sitting there for over a year, someone closer to the project might be able to answer that.

@Jean-BaptisteC
Copy link
Member

An other PR to implement speed limit was already started here #5233

@alensiljak
Copy link
Author

alensiljak commented Nov 23, 2023

An other PR to implement speed limit was already started here #5233

"Already"?
If my knowledge of numbers and dates is correct, that commit was created in October 2023 whereas my pull request was submitted in November 2022.

The new one certainly looks the way it should.

@rtsisyk rtsisyk changed the title [android] Showing speed limit, if available [android] Show the speed limit like in iOS Dec 29, 2023
@rtsisyk
Copy link
Contributor

rtsisyk commented Dec 29, 2023

An other PR to implement speed limit was already started here #5233

"Already"? If my knowledge of numbers and dates is correct, that commit was created in October 2023 whereas my pull request was submitted in November 2022.

The new one certainly looks the way it should.

We will merge this text version first and think about a new visual signs later.

@AndrewShkrob
Copy link
Member

I think this PR can be closed

There is a PR with UI implementation of speed limit: #7005

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Android Android development
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

None yet