mirror of
https://codeberg.org/comaps/comaps
synced 2025-12-22 06:03:45 +00:00
Compare commits
1 Commits
zyphlar-pa
...
generate-n
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17a6c34e7f |
@@ -105,17 +105,17 @@ jobs:
|
||||
run: |
|
||||
echo "Cloning $FORGEJO_SERVER_URL/$FORGEJO_REPOSITORY branch $FORGEJO_REF_NAME"
|
||||
cd ~
|
||||
git clone --depth 1 --recurse-submodules --shallow-submodules -b $FORGEJO_REF_NAME --single-branch $FORGEJO_SERVER_URL/$FORGEJO_REPOSITORY.git comaps
|
||||
git clone --recurse-submodules --shallow-submodules -b $FORGEJO_REF_NAME --single-branch $FORGEJO_SERVER_URL/$FORGEJO_REPOSITORY.git comaps
|
||||
- name: Checkout wikiparser repo
|
||||
shell: bash
|
||||
run: |
|
||||
cd ~
|
||||
git clone --depth 1 --single-branch https://codeberg.org/comaps/wikiparser.git
|
||||
git clone https://codeberg.org/comaps/wikiparser.git
|
||||
- name: Checkout subways repo
|
||||
shell: bash
|
||||
run: |
|
||||
cd ~
|
||||
git clone --depth 1 --single-branch https://codeberg.org/comaps/subways.git
|
||||
git clone https://codeberg.org/comaps/subways.git
|
||||
|
||||
copy-coasts:
|
||||
# if: inputs.run-copy-coasts
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
This file contains a list of people who have contributed to this project.
|
||||
It is not necessarily comprehensive as contributors must manually add themselves.
|
||||
Its not neccesarily comprehensive.
|
||||
Feel free to add yourself here along with your first contribution!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
CoMaps contributors:
|
||||
(in alphabetical order)
|
||||
(in alphabetic order)
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Bastian Greshake Tzovaras
|
||||
clover sage
|
||||
Harry Bond <me@hbond.xyz>
|
||||
thesupertechie
|
||||
vikiawv
|
||||
Yannik Bloscheck
|
||||
|
||||
|
||||
@@ -107,7 +107,6 @@ import app.organicmaps.sdk.routing.RoutingOptions;
|
||||
import app.organicmaps.sdk.search.SearchEngine;
|
||||
import app.organicmaps.sdk.settings.RoadType;
|
||||
import app.organicmaps.sdk.settings.UnitLocale;
|
||||
import app.organicmaps.sdk.sound.TtsPlayer;
|
||||
import app.organicmaps.sdk.util.Config;
|
||||
import app.organicmaps.sdk.util.LocationUtils;
|
||||
import app.organicmaps.sdk.util.PowerManagment;
|
||||
@@ -133,6 +132,7 @@ import com.google.android.material.appbar.MaterialToolbar;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.textview.MaterialTextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -1813,18 +1813,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
||||
return false;
|
||||
}
|
||||
|
||||
private void deliverTtsMessage()
|
||||
{
|
||||
if (Config.isTtsMessageDelivered())
|
||||
return;
|
||||
|
||||
String navigationStartMessage = getResources().getString(R.string.navigation_start_tts_message);
|
||||
navigationStartMessage += TtsPlayer.INSTANCE.getLanguageDisplayName();
|
||||
Toast.makeText(this, navigationStartMessage, Toast.LENGTH_LONG).show();
|
||||
|
||||
Config.setTtsMessageDelivered();
|
||||
}
|
||||
|
||||
private boolean showStartPointNotice()
|
||||
{
|
||||
final RoutingController controller = RoutingController.get();
|
||||
@@ -2201,8 +2189,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
||||
if (!showRoutingDisclaimer())
|
||||
return;
|
||||
|
||||
deliverTtsMessage();
|
||||
|
||||
closeFloatingPanels();
|
||||
setFullscreen(false);
|
||||
RoutingController.get().start();
|
||||
|
||||
@@ -6,6 +6,7 @@ import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ProgressBar;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.view.ViewCompat;
|
||||
@@ -22,7 +23,6 @@ import app.organicmaps.util.Utils;
|
||||
import app.organicmaps.util.WindowInsetUtils;
|
||||
import app.organicmaps.widget.StackedButtonDialogFragment;
|
||||
import com.google.android.material.imageview.ShapeableImageView;
|
||||
import com.google.android.material.progressindicator.CircularProgressIndicator;
|
||||
import com.google.android.material.textview.MaterialTextView;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
@@ -50,7 +50,7 @@ public class ProfileFragment extends BaseMwmToolbarFragment
|
||||
private MaterialTextView mEditsSent;
|
||||
private MaterialTextView mProfileName;
|
||||
private ShapeableImageView mProfileImage;
|
||||
private CircularProgressIndicator mProfileInfoLoading;
|
||||
private ProgressBar mProfileInfoLoading;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
|
||||
@@ -33,13 +33,9 @@
|
||||
style="@style/MwmWidget.TextView.NavStreet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="@dimen/margin_quarter_plus"
|
||||
android:maxLines="2"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center"
|
||||
android:autoSizeTextType="uniform"
|
||||
android:autoSizeMinTextSize="16sp"
|
||||
android:autoSizeMaxTextSize="25sp"
|
||||
android:textColor="@android:color/white"
|
||||
tools:text="Sample street name.\nLong looooooooong!!!!"/>
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -30,14 +30,12 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/margin_base"
|
||||
android:background="?colorPrimary">
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
<ProgressBar
|
||||
android:id="@+id/user_profile_loading"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:trackColor="@color/text_light"
|
||||
app:indicatorColor="@color/text_light"
|
||||
android:layout_gravity="center"
|
||||
android:indeterminate="true"
|
||||
android:indeterminateTint="@color/text_light"
|
||||
android:visibility="invisible"
|
||||
tools:visibility="visible" />
|
||||
<LinearLayout
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone" />
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
style="@style/Widget.AppCompat.ProgressBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:indeterminate="true"/>
|
||||
android:layout_gravity="center" />
|
||||
<include
|
||||
layout="@layout/feedback_fab"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
style="@style/Widget.AppCompat.ProgressBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:indeterminate="true"/>
|
||||
android:layout_gravity="center"/>
|
||||
|
||||
<include layout="@layout/shadow_top"/>
|
||||
</FrameLayout>
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
android:layout_gravity="center_vertical"
|
||||
android:fontFamily="@string/robotoMedium"
|
||||
tools:text="Some text should go here"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body1"
|
||||
android:textAppearance="@style/MwmTextAppearance.Body3"
|
||||
android:textColor="?colorSecondary"/>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|bottom"
|
||||
android:background="@android:color/transparent"
|
||||
android:clickable="true"
|
||||
android:gravity="start|top"
|
||||
android:text="@string/category_desc_more"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="@dimen/editor_height_field"
|
||||
android:animateLayoutChanges="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
@@ -14,7 +14,8 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:hint="@string/editor_edit_place_name_hint">
|
||||
android:hint="@string/editor_edit_place_name_hint"
|
||||
android:textColorHint="?android:textColorSecondary">
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/input"
|
||||
style="@style/MwmWidget.Editor.FieldLayout.EditText"
|
||||
@@ -30,5 +31,5 @@
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:padding="@dimen/margin_half_plus"
|
||||
app:srcCompat="@drawable/ic_close"
|
||||
app:tint="?iconTint" />
|
||||
app:tint="@color/base_red" />
|
||||
</LinearLayout>
|
||||
@@ -35,10 +35,6 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="2"
|
||||
android:padding="@dimen/margin_half"
|
||||
android:autoSizeTextType="uniform"
|
||||
android:autoSizeMinTextSize="19sp"
|
||||
android:autoSizeMaxTextSize="24sp"
|
||||
android:minHeight="60dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="center"
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
android:textAppearance="?android:attr/textAppearance"
|
||||
android:gravity="start|top"
|
||||
android:textColor="?attr/colorSecondary"
|
||||
android:text="@string/category_desc_more" />
|
||||
android:text="@string/category_desc_more"
|
||||
android:background="@android:color/transparent"/>
|
||||
<include
|
||||
layout="@layout/item_divider"/>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
<ProgressBar
|
||||
style="@style/Widget.AppCompat.ProgressBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"/>
|
||||
android:background="@null" />
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/search_show_on_map"
|
||||
style="@style/MwmWidget.ExtendedFAB"
|
||||
style="@style/FAB"
|
||||
app:icon="@drawable/ic_show_on_map"
|
||||
android:text="@string/search_show_on_map"
|
||||
android:clickable="true"
|
||||
android:focusable="true" />
|
||||
android:focusable="true"
|
||||
app:fabSize="mini"/>
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
<ProgressBar
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
style="@style/Widget.AppCompat.ProgressBar"
|
||||
android:layout_width="@dimen/height_block_base"
|
||||
android:layout_height="@dimen/height_block_base"
|
||||
android:padding="@dimen/margin_half"
|
||||
android:indeterminate="true"
|
||||
app:trackColor="@color/text_light"
|
||||
app:indicatorColor="@color/text_light" />
|
||||
android:background="@null"/>
|
||||
|
||||
@@ -34,17 +34,16 @@
|
||||
android:singleLine="true"
|
||||
android:textCursorDrawable="@drawable/cursor_drawable" />
|
||||
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
style="@style/Widget.AppCompat.ProgressBar"
|
||||
android:layout_width="@dimen/search_progress_size"
|
||||
android:layout_height="@dimen/search_progress_size"
|
||||
android:layout_marginEnd="@dimen/margin_half"
|
||||
android:layout_weight="0"
|
||||
android:background="@null"
|
||||
android:minHeight="@dimen/search_progress_size"
|
||||
android:minWidth="@dimen/search_progress_size"
|
||||
app:trackColor="@color/text_light"
|
||||
app:indicatorColor="@color/text_light"
|
||||
android:indeterminate="true"/>
|
||||
android:minWidth="@dimen/search_progress_size"/>
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/clear"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<style name="MwmTheme.Base" parent="Theme.Material3.DayNight.NoActionBar">
|
||||
<item name="materialCalendarStyle">@style/Widget.Material3.MaterialCalendar</item>
|
||||
<item name="materialCalendarStyle">@style/Widget.MaterialComponents.MaterialCalendar</item>
|
||||
<item name="materialCalendarFullscreenTheme">@style/MwmWidget.MaterialCalendar.Theme.FullScreen.Dark</item>
|
||||
<item name="materialCalendarTheme">@style/MwmWidget.MaterialCalendar.Theme.Dark</item>
|
||||
<item name="android:listViewStyle">@style/MwmWidget.ListView</item>
|
||||
@@ -111,7 +111,7 @@
|
||||
<item name="elevationProfileSelectedPointTriangle">@drawable/ic_ascent</item>
|
||||
<item name="elevationProfileFloatingTriangle">@drawable/ic_triangle_elevation</item>
|
||||
<item name="elevationProfileColor">@color/elevation_profile</item>
|
||||
<item name="android:popupMenuStyle">@style/Widget.Material3.PopupMenu</item>
|
||||
<item name="android:popupMenuStyle">@style/PopupMenu</item>
|
||||
|
||||
<item name="bottomSheetStyle">@style/MwmWidget.BottomSheet</item>
|
||||
<item name="bottomSheetDialogTheme">@style/MwmTheme.BottomSheetDialog</item>
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
|
||||
<!-- Nav menu -->
|
||||
<dimen name="nav_elevation">6dp</dimen>
|
||||
<dimen name="nav_street_height">50dp</dimen>
|
||||
<dimen name="nav_street_height">44dp</dimen>
|
||||
<dimen name="nav_street_left">100dp</dimen>
|
||||
<dimen name="nav_next_turn_frame">88dp</dimen>
|
||||
<dimen name="nav_next_turn_top">8dp</dimen>
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
<string name="pref_tts_info" translatable="false">TtsInfo</string>
|
||||
<string name="pref_tts_info_link" translatable="false">TtsInfoLink</string>
|
||||
<string name="pref_tts_speed_cameras" translatable="false">SpeedCameras</string>
|
||||
<string name="pref_tts_speed_cameras_info" translatable="false">SpeedCamerasInfo</string>
|
||||
<string name="prefs_routing" translatable="false">RoutingOptions</string>
|
||||
<string name="pref_autodownload" translatable="false">AutoDownloadMap</string>
|
||||
<string name="pref_3d" translatable="false">3D</string>
|
||||
|
||||
@@ -609,7 +609,6 @@
|
||||
\nOpen your device\'s settings → Language and input → Speech → Text to speech output.
|
||||
\nHere you can manage settings for speech synthesis (for example, download language pack for offline use) and select another text-to-speech engine.</string>
|
||||
<string name="prefs_languages_information_off_link">For more information please check this guide</string>
|
||||
<string name="prefs_speed_cameras_information">Speed camera warnings are disabled in countries where alerts are prohibited by local law.</string>
|
||||
<string name="transliteration_title">Transliterate into Latin alphabet</string>
|
||||
<string name="learn_more">Learn more</string>
|
||||
<!-- User selected the destination by pressing Route To, but the current position is unknown. User needs to select a starting point of a route using search or by tapping on the map and then pressing "Route From". -->
|
||||
@@ -933,7 +932,6 @@
|
||||
<string name="share_track">Share Track</string>
|
||||
<string name="delete_track_dialog_title">Delete %s?</string>
|
||||
<string name="pref_tts_no_system_tts_short">No text-to-speech engine found, check the app settings</string>
|
||||
<string name="navigation_start_tts_message">"Starting Navigation, voice instruction language: "</string>
|
||||
<string name="unknown_power_output">unknown</string>
|
||||
<string name="charge_socket_type2">Type 2 (no cable)</string>
|
||||
<string name="charge_socket_type2_cable">Type 2 (w/ cable)</string>
|
||||
|
||||
@@ -364,13 +364,23 @@
|
||||
<item name="behavior_hideable">false</item>
|
||||
</style>
|
||||
|
||||
<style name="MwmWidget.ExtendedFAB" parent="Widget.Material3.ExtendedFloatingActionButton.Primary">
|
||||
<style name="FAB" parent="Widget.MaterialComponents.ExtendedFloatingActionButton">
|
||||
<item name="android:minHeight">30dp</item>
|
||||
<item name="android:minWidth">30dp</item>
|
||||
<item name="android:paddingTop">7dp</item>
|
||||
<item name="android:paddingBottom">7dp</item>
|
||||
<item name="android:paddingStart">12dp</item>
|
||||
<item name="android:paddingEnd">12dp</item>
|
||||
<item name="android:paddingLeft">12dp</item>
|
||||
<item name="android:paddingRight">12dp</item>
|
||||
<item name="iconPadding">4dp</item>
|
||||
<item name="iconSize">20dp</item>
|
||||
<item name="iconTint">?accentButtonTextColor</item>
|
||||
<item name="android:textColor">?accentButtonTextColor</item>
|
||||
<item name="backgroundTint">?colorSecondary</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
<item name="textAllCaps">false</item>
|
||||
<item name="android:textAllCaps">false</item>
|
||||
</style>
|
||||
|
||||
<style name="MwmWidget.M3.Button" parent="Widget.Material3.Button">
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
<item name="elevationProfileSelectedPointTriangle">@drawable/ic_ascent</item>
|
||||
<item name="elevationProfileFloatingTriangle">@drawable/ic_triangle_elevation</item>
|
||||
<item name="elevationProfileColor">@color/elevation_profile</item>
|
||||
<item name="android:popupMenuStyle">@style/Widget.Material3.PopupMenu</item>
|
||||
<item name="android:popupMenuStyle">@style/PopupMenu</item>
|
||||
|
||||
<!-- Style used for bottom sheet behavior components -->
|
||||
<item name="bottomSheetStyle">@style/MwmWidget.BottomSheet</item>
|
||||
|
||||
@@ -57,11 +57,4 @@
|
||||
android:entryValues="@array/speed_cameras_values"
|
||||
android:defaultValue="@string/auto_enum_value"
|
||||
app:iconSpaceReserved="false" />
|
||||
<Preference
|
||||
android:enabled="true"
|
||||
android:key="@string/pref_tts_info_link"
|
||||
android:persistent="false"
|
||||
android:selectable="false"
|
||||
android:summary="@string/prefs_speed_cameras_information"
|
||||
app:iconSpaceReserved="false" />
|
||||
</androidx.preference.PreferenceScreen>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package app.organicmaps.sdk.sound;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.database.ContentObserver;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Bundle;
|
||||
@@ -15,8 +14,6 @@ import android.util.Pair;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.os.ConfigurationCompat;
|
||||
import androidx.core.os.LocaleListCompat;
|
||||
import androidx.media.AudioAttributesCompat;
|
||||
import androidx.media.AudioFocusRequestCompat;
|
||||
import androidx.media.AudioManagerCompat;
|
||||
@@ -26,7 +23,6 @@ import app.organicmaps.sdk.util.log.Logger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* {@code TtsPlayer} class manages available TTS voice languages.
|
||||
@@ -37,9 +33,9 @@ import java.util.Set;
|
||||
* unsupported voices are excluded.
|
||||
* <p>
|
||||
* At startup we check whether currently selected language is in our list of supported voices and its data is
|
||||
* downloaded. If not, we check system default locale. If failed, the same check is made for other system locales.
|
||||
* If those fail too, we check for English language. Then, as a final resort, all installed TTS locales are checked.
|
||||
* <p> If no core supported languages can be used by the system, TTS is locked down and can not be
|
||||
* downloaded. If not, we check system default locale. If failed, the same check is made for English language. Finally,
|
||||
* if mentioned checks fail we manually disable TTS, so the user must go to the settings and select preferred voice
|
||||
* language by hand. <p> If no core supported languages can be used by the system, TTS is locked down and can not be
|
||||
* enabled and used.
|
||||
*/
|
||||
public enum TtsPlayer
|
||||
@@ -82,8 +78,6 @@ public enum TtsPlayer
|
||||
// TTS is locked down due to absence of supported languages
|
||||
private boolean mUnavailable;
|
||||
|
||||
private LocaleListCompat mInstalledSystemLocales;
|
||||
|
||||
TtsPlayer() {}
|
||||
|
||||
private static @Nullable LanguageData findSupportedLanguage(String internalCode, List<LanguageData> langs)
|
||||
@@ -132,59 +126,30 @@ public enum TtsPlayer
|
||||
return (lang != null && setLanguageInternal(lang));
|
||||
}
|
||||
|
||||
public static @Nullable LanguageData getSelectedLanguage(List<LanguageData> langs)
|
||||
{
|
||||
return findSupportedLanguage(Config.TTS.getLanguage(), langs);
|
||||
}
|
||||
|
||||
private @Nullable LanguageData getSystemLanguage(List<LanguageData> langs)
|
||||
{
|
||||
LanguageData res;
|
||||
|
||||
// Try default system locale
|
||||
Locale defLocale = Locale.getDefault();
|
||||
res = findSupportedLanguage(defLocale, langs);
|
||||
if (res != null && res.downloaded)
|
||||
return res;
|
||||
|
||||
// Try other installed system locales
|
||||
for (int i = 0; i < mInstalledSystemLocales.size(); i++)
|
||||
{
|
||||
Locale loc = mInstalledSystemLocales.get(i);
|
||||
res = findSupportedLanguage(loc, langs);
|
||||
if (res != null && res.downloaded)
|
||||
return res;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private @Nullable LanguageData getTTSLanguage(List<LanguageData> langs)
|
||||
{
|
||||
LanguageData res;
|
||||
|
||||
// Try all TTS installed languages
|
||||
Set<Locale> ttsLocales = mTts.getAvailableLanguages();
|
||||
for (Locale loc : ttsLocales)
|
||||
{
|
||||
res = findSupportedLanguage(loc, langs);
|
||||
if (res != null && res.downloaded)
|
||||
return res;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static @Nullable LanguageData getDefaultLanguage(List<LanguageData> langs)
|
||||
{
|
||||
LanguageData res;
|
||||
|
||||
// Try default app locale (en.US)
|
||||
Locale defLocale = Locale.getDefault();
|
||||
if (defLocale != null)
|
||||
{
|
||||
res = findSupportedLanguage(defLocale, langs);
|
||||
if (res != null && res.downloaded)
|
||||
return res;
|
||||
}
|
||||
|
||||
res = findSupportedLanguage(DEFAULT_LOCALE, langs);
|
||||
if (res != null && res.downloaded)
|
||||
return res;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static @Nullable LanguageData getSelectedLanguage(List<LanguageData> langs)
|
||||
{
|
||||
return findSupportedLanguage(Config.TTS.getLanguage(), langs);
|
||||
}
|
||||
|
||||
private void lockDown()
|
||||
{
|
||||
mUnavailable = true;
|
||||
@@ -202,10 +167,6 @@ public enum TtsPlayer
|
||||
// TextToSpeech.OnInitListener() can be called from a non-main thread
|
||||
// on LineageOS '20.0-20231127-RELEASE-thyme' 'Xiaomi/thyme/thyme'.
|
||||
// https://github.com/organicmaps/organicmaps/issues/6903
|
||||
|
||||
Configuration config = context.getResources().getConfiguration();
|
||||
mInstalledSystemLocales = ConfigurationCompat.getLocales(config);
|
||||
|
||||
mTts = new TextToSpeech(context, status -> UiThread.run(() -> {
|
||||
if (status == TextToSpeech.ERROR)
|
||||
{
|
||||
@@ -278,17 +239,6 @@ public enum TtsPlayer
|
||||
return (INSTANCE.mTts != null && !INSTANCE.mUnavailable && !INSTANCE.mInitializing);
|
||||
}
|
||||
|
||||
public Locale getVoiceLocale()
|
||||
{
|
||||
return mTts.getVoice().getLocale();
|
||||
}
|
||||
|
||||
public String getLanguageDisplayName()
|
||||
{
|
||||
Locale locale = getVoiceLocale();
|
||||
return locale.getDisplayName(locale);
|
||||
}
|
||||
|
||||
public void speak(String textToSpeak)
|
||||
{
|
||||
if (Config.TTS.isEnabled())
|
||||
@@ -378,49 +328,24 @@ public enum TtsPlayer
|
||||
|
||||
if (outList.isEmpty())
|
||||
{
|
||||
Logger.d("TtsPlayer", "No supported languages found, lock down TTS :( ");
|
||||
// No supported languages found, lock down TTS :(
|
||||
lockDown();
|
||||
return null;
|
||||
}
|
||||
|
||||
LanguageData res = getSelectedLanguage(outList);
|
||||
if (res != null && res.downloaded)
|
||||
{
|
||||
Logger.d("TtsPlayer", "Selected locale " + res.internalCode + " will be used for TTS");
|
||||
return res;
|
||||
}
|
||||
Logger.d("TtsPlayer", "Selected locale " + Config.TTS.getLanguage()
|
||||
+ " is not available or not downloaded, trying system locales...");
|
||||
if (res == null || !res.downloaded)
|
||||
// Selected locale is not available or not downloaded
|
||||
res = getDefaultLanguage(outList);
|
||||
|
||||
res = getSystemLanguage(outList);
|
||||
if (res != null && res.downloaded)
|
||||
if (res == null || !res.downloaded)
|
||||
{
|
||||
Logger.d("TtsPlayer", "System locale " + res.internalCode + " will be used for TTS");
|
||||
return res;
|
||||
}
|
||||
Logger.d("TtsPlayer",
|
||||
"None of the system locales are available, or they are not downloaded, trying default locale...");
|
||||
|
||||
res = getDefaultLanguage(outList);
|
||||
if (res != null && res.downloaded)
|
||||
{
|
||||
Logger.d("TtsPlayer", "Default locale " + res.internalCode + " will be used for TTS");
|
||||
return res;
|
||||
}
|
||||
Logger.d("TtsPlayer",
|
||||
"Default locale " + DEFAULT_LOCALE + " can not be used either, trying all installed TTS locales...");
|
||||
|
||||
res = getTTSLanguage(outList);
|
||||
if (res != null && res.downloaded)
|
||||
{
|
||||
Logger.d("TtsPlayer", "TTS locale " + res.internalCode + " will be used for TTS");
|
||||
return res;
|
||||
// Default locale can not be used too
|
||||
Config.TTS.setEnabled(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
Logger.d("TtsPlayer",
|
||||
"None of the TTS engine locales are available, or they are not downloaded, disabling TTS :( ");
|
||||
Config.TTS.setEnabled(false);
|
||||
return null;
|
||||
return res;
|
||||
}
|
||||
|
||||
public @NonNull List<LanguageData> refreshLanguages()
|
||||
|
||||
@@ -36,7 +36,6 @@ public final class Config
|
||||
private static final String KEY_PREF_USE_GS = "UseGoogleServices";
|
||||
|
||||
private static final String KEY_MISC_DISCLAIMER_ACCEPTED = "IsDisclaimerApproved";
|
||||
private static final String KEY_MISC_TTS_MESSAGE_DELIVERED = "TtsMessageDelivered";
|
||||
private static final String KEY_MISC_LOCATION_REQUESTED = "LocationRequested";
|
||||
private static final String KEY_MISC_USE_MOBILE_DATA = "UseMobileData";
|
||||
private static final String KEY_MISC_USE_MOBILE_DATA_TIMESTAMP = "UseMobileDataTimestamp";
|
||||
@@ -238,16 +237,6 @@ public final class Config
|
||||
setBool(KEY_MISC_DISCLAIMER_ACCEPTED);
|
||||
}
|
||||
|
||||
public static boolean isTtsMessageDelivered()
|
||||
{
|
||||
return getBool(KEY_MISC_TTS_MESSAGE_DELIVERED);
|
||||
}
|
||||
|
||||
public static void setTtsMessageDelivered()
|
||||
{
|
||||
setBool(KEY_MISC_TTS_MESSAGE_DELIVERED);
|
||||
}
|
||||
|
||||
public static boolean isLocationRequested()
|
||||
{
|
||||
return getBool(KEY_MISC_LOCATION_REQUESTED);
|
||||
|
||||
@@ -137,7 +137,6 @@ node[amenity=prison],
|
||||
node[amenity=recycling][recycling_type=centre],
|
||||
node[amenity=sailing_school],
|
||||
node[amenity=school],
|
||||
node[amenity=toilets],
|
||||
node[amenity=townhall],
|
||||
node[amenity=university][name],
|
||||
node[barrier=border_control],
|
||||
|
||||
@@ -9,11 +9,10 @@ This document gives some guidelines to write and review PR with essential elemen
|
||||
- New functionality and unit or integration tests for it should be developed in the same PR
|
||||
- Every commit of all PRs should be compilable under all platforms and all tests should pass. If changes break unit or integration tests, then these tests should be fixed, ideally before opening a PR.
|
||||
- Every commit should reflect a completed idea and have an understandable comment. Review fixes should be merged into one commit
|
||||
- When some source files are changed and then some other source files based on them are auto-generated, they should be committed in different commits. For example, if you change style (mapcss) files, then put auto-generated files into a separate [styles] Regenerate commit
|
||||
- Whitespace and formatting changes should be a separate commit from logical changes, and possibly even be a separate cleanup PR, to make reviewing and merging easier.
|
||||
- All commits and PR captions should be written in English.
|
||||
- We suggest PRs should have prefixes in square brackets depending on the changed subsystem. For example, [routing], [generator], or [android]. Commits may have several prefixes (See `git log --oneline|egrep -o '\[[0-9a-z]*\]'|sort|uniq -c|sort -nr|less` for ideas.)
|
||||
- Use imperative mood in commit's message, e.g. `[core] Fix gcc warnings` not `[core] Fixed gcc warnings`
|
||||
- When some source files are changed and then some other source files based on them are auto-generated, they should be committed in different commits. For example, if you change style (mapcss) files, then put auto-generated files into a separate [styles] Regenerate commit
|
||||
- All code bases should conform to ./docs/CPP_STYLE.md, ./docs/OBJC_STYLE.md, ./docs/JAVA_STYLE.md or other style in ./docs/ depending on the language
|
||||
- The description field of every PR should contain a description to explain **what and why** vs. how.
|
||||
- If your changes are visual (e.g. app UI or map style changes) then please add before/after screenshots or videos.
|
||||
|
||||
@@ -541,8 +541,8 @@
|
||||
|
||||
/* Voice */
|
||||
"voice" = "Voice";
|
||||
"voice_explanation" = "It's possible to pick a better voice in the system settings under *Accessibility*, *Read & Speak*, *Voices*.";
|
||||
"voice_explanation_before_version26" = "It's possible to pick a better voice in the system settings under *Accessibility*, *Spoken Content*, *Voices*.";
|
||||
"voice_explanation" = "It's possible to pick a better voice in the system settings under *Accesibility*, *Read & Speak*, *Voices*.";
|
||||
"voice_explanation_before_version26" = "It's possible to pick a better voice in the system settings under *Accesibility*, *Spoken Content*, *Voices*.";
|
||||
"unknown" = "Unknown";
|
||||
|
||||
/* Place page confirmation messages and time ago formatting */
|
||||
@@ -1045,25 +1045,25 @@
|
||||
/* Message for the bug report alert. */
|
||||
"bugreport_alert_message" = "Would you like to send a bug report to the developers?\nWe rely on our users as CoMaps doesn't collect any error information automatically. Thank you in advance for supporting CoMaps!";
|
||||
|
||||
/* Title for the iCloud synchronization setting */
|
||||
"icloud_sync" = "iCloud Synchronization (Beta)";
|
||||
/* Title for the iCloud syncronization setting */
|
||||
"icloud_sync" = "iCloud Syncronization (Beta)";
|
||||
|
||||
/* Title for the "Enable iCloud Synchronization" alert. */
|
||||
"enable_icloud_synchronization_title" = "Enable iCloud Synchronization";
|
||||
/* Title for the "Enable iCloud Syncronization" alert. */
|
||||
"enable_icloud_synchronization_title" = "Enable iCloud Syncronization";
|
||||
|
||||
/* Message for the "Enable iCloud Synchronization" alert. */
|
||||
/* Message for the "Enable iCloud Syncronization" alert. */
|
||||
"enable_icloud_synchronization_message" = "iCloud synchronization is an experimental feature under development. Make sure that you have made a backup of all your bookmarks and tracks.";
|
||||
|
||||
/* Title for the "iCloud Is Disabled" alert. */
|
||||
"icloud_disabled_title" = "iCloud Is Disabled";
|
||||
|
||||
/* Message for the "iCloud is Disabled" alert. */
|
||||
"icloud_disabled_message" = "Please enable iCloud for CoMaps in your Apple Account's settings to use this feature.";
|
||||
"icloud_disabled_message" = "Please enable iCloud in your device's settings to use this feature.";
|
||||
|
||||
/* Title for the "Enable iCloud Synchronization" alert's "Enable" action button. */
|
||||
/* Title for the "Enable iCloud Syncronization" alert's "Enable" action button. */
|
||||
"enable" = "Enable";
|
||||
|
||||
/* Title for the "Enable iCloud Synchronization" alert's "Backup" action button. */
|
||||
/* Title for the "Enable iCloud Syncronization" alert's "Backup" action button. */
|
||||
"backup" = "Backup";
|
||||
|
||||
/* Title for the "iCloud synchronization failure" alert. */
|
||||
|
||||
@@ -560,8 +560,8 @@
|
||||
|
||||
/* Voice */
|
||||
"voice" = "Voice";
|
||||
"voice_explanation" = "It's possible to pick a better voice in the system settings under *Accessibility*, *Read & Speak*, *Voices*.";
|
||||
"voice_explanation_before_version26" = "It's possible to pick a better voice in the system settings under *Accessibility*, *Spoken Content*, *Voices*.";
|
||||
"voice_explanation" = "It's possible to pick a better voice in the system settings under *Accesibility*, *Read & Speak*, *Voices*.";
|
||||
"voice_explanation_before_version26" = "It's possible to pick a better voice in the system settings under *Accesibility*, *Spoken Content*, *Voices*.";
|
||||
"unknown" = "Unknown";
|
||||
|
||||
/* Place page confirmation messages and time ago formatting */
|
||||
@@ -1070,25 +1070,25 @@
|
||||
/* Message for the bug report alert. */
|
||||
"bugreport_alert_message" = "Would you like to send a bug report to the developers?\nWe rely on our users as CoMaps doesn't collect any error information automatically. Thank you in advance for supporting CoMaps!";
|
||||
|
||||
/* Title for the iCloud synchronization setting */
|
||||
"icloud_sync" = "iCloud Synchronization (Beta)";
|
||||
/* Title for the iCloud syncronization setting */
|
||||
"icloud_sync" = "iCloud Syncronization (Beta)";
|
||||
|
||||
/* Title for the "Enable iCloud Synchronization" alert. */
|
||||
"enable_icloud_synchronization_title" = "Enable iCloud Synchronization";
|
||||
/* Title for the "Enable iCloud Syncronization" alert. */
|
||||
"enable_icloud_synchronization_title" = "Enable iCloud Syncronization";
|
||||
|
||||
/* Message for the "Enable iCloud Synchronization" alert. */
|
||||
/* Message for the "Enable iCloud Syncronization" alert. */
|
||||
"enable_icloud_synchronization_message" = "iCloud synchronization is an experimental feature under development. Make sure that you have made a backup of all your bookmarks and tracks.";
|
||||
|
||||
/* Title for the "iCloud Is Disabled" alert. */
|
||||
"icloud_disabled_title" = "iCloud Is Disabled";
|
||||
|
||||
/* Message for the "iCloud is Disabled" alert. */
|
||||
"icloud_disabled_message" = "Please enable iCloud for CoMaps in your Apple Account's settings to use this feature.";
|
||||
"icloud_disabled_message" = "Please enable iCloud in your device's settings to use this feature.";
|
||||
|
||||
/* Title for the "Enable iCloud Synchronization" alert's "Enable" action button. */
|
||||
/* Title for the "Enable iCloud Syncronization" alert's "Enable" action button. */
|
||||
"enable" = "Enable";
|
||||
|
||||
/* Title for the "Enable iCloud Synchronization" alert's "Backup" action button. */
|
||||
/* Title for the "Enable iCloud Syncronization" alert's "Backup" action button. */
|
||||
"backup" = "Backup";
|
||||
|
||||
/* Title for the "iCloud synchronization failure" alert. */
|
||||
|
||||
@@ -441,13 +441,12 @@ void DrapeEngine::SetCompassInfo(location::CompassInfo const & info)
|
||||
MessagePriority::Normal);
|
||||
}
|
||||
|
||||
void DrapeEngine::SetGpsInfo(location::GpsInfo const & info, bool isNavigable, double distToNextTurn, double speedLimit,
|
||||
void DrapeEngine::SetGpsInfo(location::GpsInfo const & info, bool isNavigable,
|
||||
location::RouteMatchingInfo const & routeInfo)
|
||||
{
|
||||
m_threadCommutator->PostMessage(
|
||||
ThreadsCommutator::RenderThread,
|
||||
make_unique_dp<GpsInfoMessage>(info, isNavigable, distToNextTurn, speedLimit, routeInfo),
|
||||
MessagePriority::Normal);
|
||||
m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread,
|
||||
make_unique_dp<GpsInfoMessage>(info, isNavigable, routeInfo),
|
||||
MessagePriority::Normal);
|
||||
}
|
||||
|
||||
void DrapeEngine::SwitchMyPositionNextMode()
|
||||
|
||||
@@ -154,8 +154,7 @@ public:
|
||||
void UpdateMapStyle();
|
||||
|
||||
void SetCompassInfo(location::CompassInfo const & info);
|
||||
void SetGpsInfo(location::GpsInfo const & info, bool isNavigable, double distToNextTurn, double speedLimit,
|
||||
location::RouteMatchingInfo const & routeInfo);
|
||||
void SetGpsInfo(location::GpsInfo const & info, bool isNavigable, location::RouteMatchingInfo const & routeInfo);
|
||||
void SwitchMyPositionNextMode();
|
||||
void LoseLocation();
|
||||
void StopLocationFollow();
|
||||
|
||||
@@ -438,8 +438,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
|
||||
break;
|
||||
#endif
|
||||
ref_ptr<GpsInfoMessage> msg = message;
|
||||
m_myPositionController->OnLocationUpdate(msg->GetInfo(), msg->IsNavigable(), msg->GetDistanceToNextTurn(),
|
||||
msg->GetSpeedLimit(), m_userEventStream.GetCurrentScreen());
|
||||
m_myPositionController->OnLocationUpdate(msg->GetInfo(), msg->IsNavigable(), m_userEventStream.GetCurrentScreen());
|
||||
|
||||
location::RouteMatchingInfo const & info = msg->GetRouteInfo();
|
||||
if (info.HasDistanceFromBegin())
|
||||
|
||||
@@ -481,12 +481,9 @@ private:
|
||||
class GpsInfoMessage : public Message
|
||||
{
|
||||
public:
|
||||
GpsInfoMessage(location::GpsInfo const & info, bool isNavigable, double distToNextTurn, double speedLimit,
|
||||
location::RouteMatchingInfo const & routeInfo)
|
||||
GpsInfoMessage(location::GpsInfo const & info, bool isNavigable, location::RouteMatchingInfo const & routeInfo)
|
||||
: m_info(info)
|
||||
, m_isNavigable(isNavigable)
|
||||
, m_distToNextTurn(distToNextTurn)
|
||||
, m_speedLimit(speedLimit)
|
||||
, m_routeInfo(routeInfo)
|
||||
{}
|
||||
|
||||
@@ -494,15 +491,11 @@ public:
|
||||
|
||||
location::GpsInfo const & GetInfo() const { return m_info; }
|
||||
bool IsNavigable() const { return m_isNavigable; }
|
||||
double const & GetSpeedLimit() const { return m_speedLimit; }
|
||||
double const & GetDistanceToNextTurn() const { return m_distToNextTurn; }
|
||||
location::RouteMatchingInfo const & GetRouteInfo() const { return m_routeInfo; }
|
||||
|
||||
private:
|
||||
location::GpsInfo const m_info;
|
||||
bool const m_isNavigable;
|
||||
double const m_distToNextTurn;
|
||||
double const m_speedLimit;
|
||||
location::RouteMatchingInfo const m_routeInfo;
|
||||
};
|
||||
|
||||
|
||||
@@ -56,18 +56,32 @@ inline double GetVisualScale()
|
||||
return df::VisualParams::Instance().GetVisualScale();
|
||||
}
|
||||
|
||||
double CalculateZoomByMaxSpeed(double speedMpS, bool isPerspectiveAllowed)
|
||||
// Calculate zoom value in meters per pixel
|
||||
double CalculateZoomBySpeed(double speedMpS, bool isPerspectiveAllowed)
|
||||
{
|
||||
using TSpeedScale = std::pair<double, double>;
|
||||
static std::array<TSpeedScale, 2> const scales2d = {{
|
||||
{0.0, 1.75}, {77.0, 4.50} // 48 mph
|
||||
static std::array<TSpeedScale, 6> const scales3d = {{
|
||||
{20.0, 0.25},
|
||||
{40.0, 0.75},
|
||||
{60.0, 1.50},
|
||||
{75.0, 2.50},
|
||||
{85.0, 3.75},
|
||||
{95.0, 6.00},
|
||||
}};
|
||||
static std::array<TSpeedScale, 2> const scales3d = {{{0.0, 1.00}, {77.0, 4.50}}};
|
||||
|
||||
std::array<TSpeedScale, 2> const & scales = isPerspectiveAllowed ? scales3d : scales2d;
|
||||
static std::array<TSpeedScale, 6> const scales2d = {{
|
||||
{20.0, 0.70},
|
||||
{40.0, 1.25},
|
||||
{60.0, 2.25},
|
||||
{75.0, 3.00},
|
||||
{85.0, 3.75},
|
||||
{95.0, 6.00},
|
||||
}};
|
||||
|
||||
double constexpr kDefaultSpeedLimitKmpH = 50.0;
|
||||
double const speedKmpH = speedMpS > 0 ? measurement_utils::MpsToKmph(speedMpS) : kDefaultSpeedLimitKmpH;
|
||||
std::array<TSpeedScale, 6> const & scales = isPerspectiveAllowed ? scales3d : scales2d;
|
||||
|
||||
double constexpr kDefaultSpeedKmpH = 80.0;
|
||||
double const speedKmpH = speedMpS >= 0 ? measurement_utils::MpsToKmph(speedMpS) : kDefaultSpeedKmpH;
|
||||
|
||||
size_t i = 0;
|
||||
for (size_t sz = scales.size(); i < sz; ++i)
|
||||
@@ -78,64 +92,20 @@ double CalculateZoomByMaxSpeed(double speedMpS, bool isPerspectiveAllowed)
|
||||
|
||||
if (i == 0)
|
||||
return scales.front().second / vs;
|
||||
if (i == scales.size())
|
||||
return scales.back().second / vs;
|
||||
|
||||
return scales[i - 1].second / vs;
|
||||
}
|
||||
double const minSpeed = scales[i - 1].first;
|
||||
double const maxSpeed = scales[i].first;
|
||||
double const k = (speedKmpH - minSpeed) / (maxSpeed - minSpeed);
|
||||
|
||||
double CalculateZoomByDistanceToTurn(double distance, bool isPerspectiveAllowed)
|
||||
{
|
||||
using TSpeedScale = std::pair<double, double>;
|
||||
static std::array<TSpeedScale, 5> const scales2d = {{
|
||||
{200, 0.50},
|
||||
{500, 0.80}, // 0.3 mi
|
||||
{1200, 1.75}, // 0.75 mi
|
||||
{2000, 3.50}, // 1.2 mi
|
||||
{5000, 6.50} // 3 mi
|
||||
}};
|
||||
static std::array<TSpeedScale, 5> const scales3d = {{
|
||||
{200, 0.25},
|
||||
{500, 0.60}, // 0.3 mi
|
||||
{1200, 1.25}, // 0.75 mi
|
||||
{2000, 3.50}, // 1.2 mi
|
||||
{5000, 6.50} // 3 mi
|
||||
}};
|
||||
|
||||
std::array<TSpeedScale, 5> const & scale = isPerspectiveAllowed ? scales3d : scales2d;
|
||||
|
||||
double constexpr kDefaultDistance = 2000;
|
||||
double const distanceM = distance >= 0 ? distance : kDefaultDistance;
|
||||
|
||||
size_t i = 0;
|
||||
for (size_t sz = scale.size(); i < sz; ++i)
|
||||
if (scale[i].first >= distanceM)
|
||||
break;
|
||||
|
||||
double const vs = GetVisualScale();
|
||||
|
||||
if (i == 0)
|
||||
return scale.front().second / vs;
|
||||
if (i == scale.size())
|
||||
return scale.back().second / vs;
|
||||
|
||||
double const minDist = scale[i - 1].first;
|
||||
double const maxDist = scale[i].first;
|
||||
double const k = (distanceM - minDist) / (maxDist - minDist);
|
||||
|
||||
double const minScale = scale[i - 1].second;
|
||||
double const maxScale = scale[i].second;
|
||||
double const minScale = scales[i - 1].second;
|
||||
double const maxScale = scales[i].second;
|
||||
double const zoom = minScale + k * (maxScale - minScale);
|
||||
|
||||
return zoom / vs;
|
||||
}
|
||||
|
||||
double CalculateAutoZoom(double speedMpS, double distanceToTurn, bool isPerspectiveAllowed)
|
||||
{
|
||||
double const zoomByDistance = CalculateZoomByDistanceToTurn(distanceToTurn, isPerspectiveAllowed);
|
||||
double const zoomByMaxSpeed = CalculateZoomByMaxSpeed(speedMpS, isPerspectiveAllowed);
|
||||
|
||||
return std::min(zoomByDistance, zoomByMaxSpeed);
|
||||
}
|
||||
|
||||
void ResetNotification(uint64_t & notifyId)
|
||||
{
|
||||
notifyId = DrapeNotifier::kInvalidId;
|
||||
@@ -425,8 +395,7 @@ void MyPositionController::NextMode(ScreenBase const & screen)
|
||||
}
|
||||
}
|
||||
|
||||
void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool isNavigable, double distanceToNextTurn,
|
||||
double speedLimit, ScreenBase const & screen)
|
||||
void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool isNavigable, ScreenBase const & screen)
|
||||
{
|
||||
m2::PointD const oldPos = GetDrawablePosition();
|
||||
double const oldAzimut = GetDrawableAzimut();
|
||||
@@ -438,13 +407,11 @@ void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool
|
||||
m_errorRadius = rect.SizeX() * 0.5;
|
||||
m_horizontalAccuracy = info.m_horizontalAccuracy;
|
||||
|
||||
if (distanceToNextTurn >= 0.0 || speedLimit >= 0.0)
|
||||
if (info.m_speed > 0.0)
|
||||
{
|
||||
double const mercatorPerMeter = m_errorRadius / info.m_horizontalAccuracy;
|
||||
m_autoScale2d =
|
||||
mercatorPerMeter * CalculateAutoZoom(speedLimit, distanceToNextTurn, false /* isPerspectiveAllowed */);
|
||||
m_autoScale3d =
|
||||
mercatorPerMeter * CalculateAutoZoom(speedLimit, distanceToNextTurn, true /* isPerspectiveAllowed */);
|
||||
m_autoScale2d = mercatorPerMeter * CalculateZoomBySpeed(info.m_speed, false /* isPerspectiveAllowed */);
|
||||
m_autoScale3d = mercatorPerMeter * CalculateZoomBySpeed(info.m_speed, true /* isPerspectiveAllowed */);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -117,8 +117,7 @@ public:
|
||||
void OnEnterBackground();
|
||||
|
||||
void OnCompassTapped();
|
||||
void OnLocationUpdate(location::GpsInfo const & info, bool isNavigable, double distanceToNextTurn, double speedLimit,
|
||||
ScreenBase const & screen);
|
||||
void OnLocationUpdate(location::GpsInfo const & info, bool isNavigable, ScreenBase const & screen);
|
||||
void OnCompassUpdate(location::CompassInfo const & info, ScreenBase const & screen);
|
||||
|
||||
void Render(ref_ptr<dp::GraphicsContext> context, ref_ptr<gpu::ProgramManager> mng, ScreenBase const & screen,
|
||||
|
||||
@@ -1171,7 +1171,6 @@ void RoutingManager::SetDrapeEngine(ref_ptr<df::DrapeEngine> engine, bool is3dAl
|
||||
{
|
||||
auto routeMatchingInfo = GetRouteMatchingInfo(*m_gpsInfoCache);
|
||||
m_drapeEngine.SafeCall(&df::DrapeEngine::SetGpsInfo, *m_gpsInfoCache, m_routingSession.IsNavigable(),
|
||||
m_routingSession.GetDistanceToNextTurn(), m_routingSession.GetCurrentSpeedLimit(),
|
||||
routeMatchingInfo);
|
||||
m_gpsInfoCache.reset();
|
||||
}
|
||||
@@ -1516,9 +1515,7 @@ void RoutingManager::OnExtrapolatedLocationUpdate(location::GpsInfo const & info
|
||||
m_gpsInfoCache = make_unique<location::GpsInfo>(gpsInfo);
|
||||
|
||||
auto routeMatchingInfo = GetRouteMatchingInfo(gpsInfo);
|
||||
m_drapeEngine.SafeCall(&df::DrapeEngine::SetGpsInfo, gpsInfo, m_routingSession.IsNavigable(),
|
||||
m_routingSession.GetDistanceToNextTurn(), m_routingSession.GetCurrentSpeedLimit(),
|
||||
routeMatchingInfo);
|
||||
m_drapeEngine.SafeCall(&df::DrapeEngine::SetGpsInfo, gpsInfo, m_routingSession.IsNavigable(), routeMatchingInfo);
|
||||
}
|
||||
|
||||
void RoutingManager::DeleteSavedRoutePoints()
|
||||
|
||||
@@ -363,32 +363,6 @@ void GetFullRoadName(RouteSegment::RoadNameInfo & road, std::string & name)
|
||||
}
|
||||
}
|
||||
|
||||
double RoutingSession::GetDistanceToNextTurn() const
|
||||
{
|
||||
if (!m_route->IsValid())
|
||||
return -1;
|
||||
|
||||
double distanceToTurnMeters = 0.;
|
||||
turns::TurnItem turn;
|
||||
m_route->GetNearestTurn(distanceToTurnMeters, turn);
|
||||
return distanceToTurnMeters;
|
||||
}
|
||||
|
||||
double RoutingSession::GetCurrentSpeedLimit() const
|
||||
{
|
||||
if (!m_route->IsValid())
|
||||
return -1;
|
||||
|
||||
SpeedInUnits speedLimit;
|
||||
m_route->GetCurrentSpeedLimit(speedLimit);
|
||||
if (speedLimit.IsNumeric())
|
||||
return measurement_utils::KmphToMps(speedLimit.GetSpeedKmPH());
|
||||
else if (speedLimit.GetSpeed() == kNoneMaxSpeed)
|
||||
return 0;
|
||||
else
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
void RoutingSession::GetRouteFollowingInfo(FollowingInfo & info) const
|
||||
{
|
||||
CHECK_THREAD_CHECKER(m_threadChecker, ());
|
||||
@@ -418,7 +392,14 @@ void RoutingSession::GetRouteFollowingInfo(FollowingInfo & info) const
|
||||
info.m_distToTurn = platform::Distance::CreateFormatted(distanceToTurnMeters);
|
||||
info.m_turn = turn.m_turn;
|
||||
|
||||
info.m_speedLimitMps = GetCurrentSpeedLimit();
|
||||
SpeedInUnits speedLimit;
|
||||
m_route->GetCurrentSpeedLimit(speedLimit);
|
||||
if (speedLimit.IsNumeric())
|
||||
info.m_speedLimitMps = measurement_utils::KmphToMps(speedLimit.GetSpeedKmPH());
|
||||
else if (speedLimit.GetSpeed() == kNoneMaxSpeed)
|
||||
info.m_speedLimitMps = 0;
|
||||
else
|
||||
info.m_speedLimitMps = -1.0;
|
||||
|
||||
// The turn after the next one.
|
||||
if (m_routingSettings.m_showTurnAfterNext)
|
||||
|
||||
@@ -100,8 +100,6 @@ public:
|
||||
|
||||
SessionState OnLocationPositionChanged(location::GpsInfo const & info);
|
||||
void GetRouteFollowingInfo(FollowingInfo & info) const;
|
||||
double GetDistanceToNextTurn() const;
|
||||
double GetCurrentSpeedLimit() const;
|
||||
|
||||
bool MatchLocationToRoute(location::GpsInfo & location, location::RouteMatchingInfo & routeMatchingInfo);
|
||||
void MatchLocationToRoadGraph(location::GpsInfo & location);
|
||||
|
||||
@@ -76,7 +76,7 @@ char const * g_strings[] = {
|
||||
// ./clusterize-tag-values.lisp house-number path-to-taginfo-db.db > numbers.txt
|
||||
// tail -n +2 numbers.txt | head -78 | sed 's/^.*) \(.*\) \[.*$/"\1"/g;s/[ -/]//g;s/$/,/' |
|
||||
// sort | uniq
|
||||
array<string_view, 48> constexpr g_patterns = {"BL", "BLN", "BLNSL", "BN", "BNL", "BNSL", "L", "LL", "LN", "LNL", "LNLN", "LNN",
|
||||
vector<string> const g_patterns = {"BL", "BLN", "BLNSL", "BN", "BNL", "BNSL", "L", "LL", "LN", "LNL", "LNLN", "LNN",
|
||||
"N", "NBL", "NBLN", "NBN", "NBNBN", "NBNL", "NL", "NLBN", "NLL", "NLLN", "NLN",
|
||||
"NLNL", "NLS", "NLSN", "NN", "NNBN", "NNL", "NNLN", "NNN", "NNS", "NS", "NSN", "NSS",
|
||||
"S", "SL", "SLL", "SLN", "SN", "SNBNSS", "SNL", "SNN", "SS", "SSN", "SSS", "SSSS",
|
||||
@@ -85,14 +85,13 @@ array<string_view, 48> constexpr g_patterns = {"BL", "BLN", "BLNSL", "BN", "BNL"
|
||||
"NNBNL"};
|
||||
|
||||
// List of patterns which look like house numbers more than other patterns. Constructed by hand.
|
||||
array<string_view, 4> constexpr g_patternsStrict = {"N", "NBN", "NBL", "NL"};
|
||||
vector<string> const g_patternsStrict = {"N", "NBN", "NBL", "NL"};
|
||||
|
||||
// List of common synonyms for building parts. Constructed by hand.
|
||||
char const * g_buildingPartSynonyms[] = {"building", "bldg", "bld", "bl", "unit", "block", "blk", "корпус",
|
||||
"корп", "кор", "литер", "лит", "строение", "стр", "блок", "бл"};
|
||||
|
||||
// List of common stop words for buildings. Constructed by hand.
|
||||
// TODO: add more stop words?
|
||||
UniString const g_stopWords[] = {MakeUniString("дом"), MakeUniString("house"), MakeUniString("д")};
|
||||
|
||||
bool IsStopWord(UniString const & s, bool isPrefix)
|
||||
@@ -168,8 +167,7 @@ class HouseNumberClassifier
|
||||
public:
|
||||
using Patterns = StringSet<Token::Type, 4>;
|
||||
|
||||
template <size_t size>
|
||||
HouseNumberClassifier(array<string_view, size> const & patterns)
|
||||
HouseNumberClassifier(vector<string> const & patterns = g_patterns)
|
||||
{
|
||||
for (auto const & p : patterns)
|
||||
m_patterns.Add(make_transform_iterator(p.begin(), &CharToType), make_transform_iterator(p.end(), &CharToType));
|
||||
@@ -592,7 +590,7 @@ bool HouseNumbersMatchRange(std::string_view const & hnRange, TokensT const & qu
|
||||
|
||||
bool LooksLikeHouseNumber(UniString const & s, bool isPrefix)
|
||||
{
|
||||
static HouseNumberClassifier const classifier(g_patterns);
|
||||
static HouseNumberClassifier const classifier;
|
||||
return classifier.LooksGood(s, isPrefix);
|
||||
}
|
||||
|
||||
|
||||
@@ -298,7 +298,8 @@ void LocalityScorer::GetDocVecs(uint32_t localityId, vector<DocVec> & dvs) const
|
||||
DocVec::Builder builder;
|
||||
ForEachNormalizedToken(name, [&](strings::UniString const & token)
|
||||
{
|
||||
builder.Add(token);
|
||||
if (!IsStopWord(token))
|
||||
builder.Add(token);
|
||||
});
|
||||
dvs.emplace_back(std::move(builder));
|
||||
}
|
||||
|
||||
@@ -69,6 +69,21 @@ m2::RectD GetRectAroundPosition(m2::PointD const & position)
|
||||
return mercator::RectByCenterXYAndSizeInMeters(position, kMaxPositionRadiusM);
|
||||
}
|
||||
|
||||
// Removes all full-token stop words from |tokens|.
|
||||
// Does nothing if all tokens are non-prefix stop words.
|
||||
void RemoveStopWordsIfNeeded(QueryTokens & tokens, strings::UniString & prefix)
|
||||
{
|
||||
size_t numStopWords = 0;
|
||||
for (auto const & token : tokens)
|
||||
if (IsStopWord(token))
|
||||
++numStopWords;
|
||||
|
||||
if (numStopWords == tokens.size() && prefix.empty())
|
||||
return;
|
||||
|
||||
tokens.erase_if(&IsStopWord);
|
||||
}
|
||||
|
||||
void TrimLeadingSpaces(string & s)
|
||||
{
|
||||
while (!s.empty() && strings::IsASCIISpace(s.front()))
|
||||
@@ -262,6 +277,9 @@ void Processor::SetQuery(string const & query, bool categorialRequest /* = false
|
||||
}
|
||||
}
|
||||
|
||||
// Remove stopwords *after* FillCategories call (it makes exact tokens match).
|
||||
RemoveStopWordsIfNeeded(m_query.m_tokens, m_query.m_prefix);
|
||||
|
||||
if (!m_isCategorialRequest)
|
||||
{
|
||||
// Assign tokens and prefix to scorer.
|
||||
|
||||
@@ -1482,7 +1482,13 @@ unordered_map<string, vector<string>> const kSynonyms = {
|
||||
// QueryParams::Token ------------------------------------------------------------------------------
|
||||
void QueryParams::Token::AddSynonym(string const & s)
|
||||
{
|
||||
m_synonyms.push_back(strings::MakeUniString(s));
|
||||
AddSynonym(strings::MakeUniString(s));
|
||||
}
|
||||
|
||||
void QueryParams::Token::AddSynonym(String const & s)
|
||||
{
|
||||
if (!IsStopWord(s))
|
||||
m_synonyms.push_back(s);
|
||||
}
|
||||
|
||||
string DebugPrint(QueryParams::Token const & token)
|
||||
@@ -1504,12 +1510,10 @@ void QueryParams::ClearStreetIndices()
|
||||
AdditionalCommonTokens()
|
||||
{
|
||||
char const * arr[] = {
|
||||
"a", "and", "s", "the", // English
|
||||
"am", "an", "auf", "der", "im", "und", "zum", // German
|
||||
"as", "d", "da", "das", "de", "del", "di", "do",
|
||||
"dos", "du", "e", "el", "et", "la", "las", "le",
|
||||
"les", "los", "o", "os", "y", // French, Italian, Portuguese, Spanish
|
||||
"в", "и", "на", "я" // Cyrillic
|
||||
"the", // English
|
||||
"der", "zum", "und", "auf", // German
|
||||
"del", "les", // Spanish
|
||||
"в", "на" // Cyrillic
|
||||
};
|
||||
for (char const * s : arr)
|
||||
m_strings.insert(NormalizeAndSimplifyString(s));
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
Token(String const & original) : m_original(original) {}
|
||||
|
||||
void AddSynonym(std::string const & s);
|
||||
void AddSynonym(String const & s);
|
||||
|
||||
template <typename Fn>
|
||||
void ForEachSynonym(Fn && fn) const
|
||||
|
||||
@@ -94,9 +94,42 @@ ErrorsMade GetPrefixErrorsMade(QueryParams::Token const & token, strings::UniStr
|
||||
}
|
||||
} // namespace impl
|
||||
|
||||
bool IsStopWord(UniString const & s)
|
||||
{
|
||||
/// @todo Get all common used stop words and take out this array into search_string_utils.cpp module for example.
|
||||
/// Should skip this tokens when building search index?
|
||||
class StopWordsChecker
|
||||
{
|
||||
set<UniString> m_set;
|
||||
|
||||
public:
|
||||
StopWordsChecker()
|
||||
{
|
||||
// Don't want to put _full_ stopwords list, not to break current ranking.
|
||||
// Only 2-letters and the most common.
|
||||
char const * arr[] = {
|
||||
"a", "s", "the", // English
|
||||
"am", "im", "an", // German
|
||||
"d", "da", "de", "di", "du", "la", "le", // French, Spanish, Italian
|
||||
"и", "я" // Cyrillic
|
||||
};
|
||||
for (char const * s : arr)
|
||||
m_set.insert(MakeUniString(s));
|
||||
}
|
||||
bool Has(UniString const & s) const { return m_set.count(s) > 0; }
|
||||
};
|
||||
|
||||
static StopWordsChecker const swChecker;
|
||||
return swChecker.Has(s);
|
||||
}
|
||||
|
||||
TokensVector::TokensVector(string_view name)
|
||||
{
|
||||
m_tokens = NormalizeAndTokenizeString(std::move(name));
|
||||
ForEachNormalizedToken(name, [this](strings::UniString && token)
|
||||
{
|
||||
if (!IsStopWord(token))
|
||||
m_tokens.push_back(std::move(token));
|
||||
});
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
@@ -180,6 +180,9 @@ struct NameScores
|
||||
std::string DebugPrint(NameScore const & score);
|
||||
std::string DebugPrint(NameScores const & scores);
|
||||
|
||||
// Returns true when |s| is a stop-word and may be removed from a query.
|
||||
bool IsStopWord(strings::UniString const & s);
|
||||
|
||||
class TokensVector
|
||||
{
|
||||
std::vector<strings::UniString> m_tokens;
|
||||
|
||||
@@ -44,7 +44,11 @@ public:
|
||||
m_scorer.SetPivotForTesting(pivot);
|
||||
|
||||
vector<UniString> tokens;
|
||||
tokens = NormalizeAndTokenizeString(query);
|
||||
search::ForEachNormalizedToken(query, [&tokens](strings::UniString && token)
|
||||
{
|
||||
if (!IsStopWord(token))
|
||||
tokens.push_back(std::move(token));
|
||||
});
|
||||
|
||||
m_params.Init(query, tokens, lastTokenIsPrefix);
|
||||
}
|
||||
|
||||
@@ -31,22 +31,22 @@ python3 -m venv /tmp/venv
|
||||
echo "<$(date +%T)> Copying map generator INI..."
|
||||
cp var/etc/map_generator.ini.prod var/etc/map_generator.ini
|
||||
|
||||
GENARGS=""
|
||||
$GENARGS=""
|
||||
|
||||
if [ $MWMTEST == "true" ]; then
|
||||
if [ $MWMTEST -gt 0 ]; then
|
||||
echo "Marking as a test (non-prod) generation"
|
||||
# TODO: output test maps into e.g. osm-maps-test/ and use a different generation.log
|
||||
GENARGS="$GENARGS -s=test"
|
||||
$GENARGS="$GENARGS -s=test"
|
||||
fi
|
||||
|
||||
if [ $MWMCONTINUE == "true" ]; then
|
||||
if [ $MWMCONTINUE -gt 0 ]; then
|
||||
echo "Continuing from preexisting generator run"
|
||||
GENARGS="$GENARGS --continue"
|
||||
$GENARGS="$GENARGS --continue"
|
||||
fi
|
||||
|
||||
if [[ -n $MWMCOUNTRIES ]]; then
|
||||
echo "Generating only specific maps for [$MWMCOUNTRIES]"
|
||||
GENARGS="$GENARGS --countries=$MWMCOUNTRIES"
|
||||
$GENARGS="$GENARGS --countries=$MWMCOUNTRIES"
|
||||
fi
|
||||
|
||||
cd ~/comaps/tools/python
|
||||
|
||||
Reference in New Issue
Block a user