Compare commits

..

7 Commits

Author SHA1 Message Date
Konstantin Pastbin
a04b59b047 fix env comparison 2025-12-05 15:21:16 +07:00
x7z4w
2bf22bd8a7 [routing] Faster IndexGraph
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-12-05 13:31:40 +07:00
Konstantin Pastbin
75f345288e [generator] Clone shallowly --depth 1
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-12-05 13:30:22 +07:00
Konstantin Pastbin
85cb731693 [generator] Fix boolean action options handling
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-12-05 13:27:29 +07:00
Konstantin Pastbin
3f9b6e82b5 [generator] Fix GENARGS in docker_maps_generator.sh
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-12-05 13:24:50 +07:00
Konstantin Pastbin
dd204ae036 [generator] Use 64 threads for Features stage
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-12-05 13:24:50 +07:00
Konstantin Pastbin
1bd734d417 [generator] Make Taiwan_North use 3 threads for Index stage 2025-12-05 13:24:36 +07:00
36 changed files with 196 additions and 311 deletions

View File

@@ -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();

View File

@@ -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>

View File

@@ -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"

View File

@@ -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>

View File

@@ -35,10 +35,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="2"
android:padding="@dimen/margin_half"
android:padding="@dimen/margin_quarter"
android:autoSizeTextType="uniform"
android:autoSizeMinTextSize="19sp"
android:autoSizeMaxTextSize="24sp"
android:autoSizeMaxTextSize="25sp"
android:minHeight="60dp"
android:layout_gravity="center_vertical"
android:gravity="center"

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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()

View File

@@ -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);

View File

@@ -13,6 +13,7 @@ node[shop],
node[amenity=car_wash],
node[amenity=fuel],
node[amenity=studio],
node[amenity=toilets],
node[amenity=vehicle_inspection],
node[craft],
node[landuse=industrial][industrial=mine],
@@ -137,7 +138,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],

View File

@@ -151,7 +151,7 @@ public:
// Set speed as-is from parent link.
if (parentHwType == hwType)
return {{s.GetForward(), s.GetUnits()}};
/*
using routing::HighwayType;
if ((*parentHwType == HighwayType::HighwayMotorway && hwType == HighwayType::HighwayMotorwayLink) ||
(*parentHwType == HighwayType::HighwayTrunk && hwType == HighwayType::HighwayTrunkLink) ||
@@ -163,7 +163,6 @@ public:
return converter.ClosestValidMacro(
{base::asserted_cast<MaxspeedType>(std::lround(s.GetForward() * kLinkToMainSpeedFactor)), s.GetUnits()});
}
*/
return {};
};

View File

@@ -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()

View File

@@ -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();

View File

@@ -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())

View File

@@ -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;
};

View File

@@ -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
{

View File

@@ -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,

View File

@@ -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()

View File

@@ -11,6 +11,7 @@
#include "base/assert.hpp"
#include "base/buffer_vector.hpp"
#include <execution>
#include <string>
#include <unordered_map>
#include <vector>
@@ -117,27 +118,31 @@ public:
template <class FnT>
void ForEachEnter(FnT && fn) const
{
for (auto const & [key, transit] : m_transitions)
std::for_each(std::execution::par_unseq, m_transitions.begin(), m_transitions.end(), [&](auto const & pair)
{
auto const & [key, transit] = pair;
if (transit.m_forwardIsEnter)
fn(transit.m_enterIdx, Segment(m_mwmId, key.m_featureId, key.m_segmentIdx, true));
if (!transit.m_oneWay && !transit.m_forwardIsEnter)
fn(transit.m_enterIdx, Segment(m_mwmId, key.m_featureId, key.m_segmentIdx, false));
}
});
}
template <class FnT>
void ForEachExit(FnT && fn) const
{
for (auto const & [key, transit] : m_transitions)
std::for_each(std::execution::par_unseq, m_transitions.begin(), m_transitions.end(), [&](auto const & pair)
{
auto const & [key, transit] = pair;
if (!transit.m_forwardIsEnter)
fn(transit.m_exitIdx, Segment(m_mwmId, key.m_featureId, key.m_segmentIdx, true));
if (!transit.m_oneWay && transit.m_forwardIsEnter)
fn(transit.m_exitIdx, Segment(m_mwmId, key.m_featureId, key.m_segmentIdx, false));
}
});
}
void GetOutgoingEdgeList(Segment const & segment, EdgeListT & edges) const

View File

@@ -4,16 +4,14 @@
#include "routing/routing_options.hpp"
#include "routing/world_graph.hpp"
#include "platform/settings.hpp"
#include "base/assert.hpp"
#include "base/checked_cast.hpp"
#include "base/exception.hpp"
#include "base/timer.hpp"
#include "geometry/distance_on_sphere.hpp"
#include <algorithm>
#include <execution>
#include <limits>
#include <utility>
@@ -321,7 +319,9 @@ void IndexGraph::ReconstructJointSegment(astar::VertexData<JointSegment, RouteWe
auto const & weightTimeToParent = parentVertexData.m_realDistance;
auto const & parentJoint = parentVertexData.m_vertex;
for (size_t i = 0; i < firstChildren.size(); ++i)
auto const range = std::ranges::views::iota(0uz, firstChildren.size());
std::for_each(std::execution::par_unseq, range.begin(), range.end(), [&, this](auto const i)
{
auto const & firstChild = firstChildren[i];
auto const lastPointId = lastPointIds[i];
@@ -335,22 +335,21 @@ void IndexGraph::ReconstructJointSegment(astar::VertexData<JointSegment, RouteWe
{ return currentPointId < lastPointId ? pointId + 1 : pointId - 1; };
if (IsAccessNoForSure(firstChild.GetFeatureId(), weightTimeToParent, true /* useAccessConditional */))
continue;
return;
if (IsAccessNoForSure(parent.GetRoadPoint(isOutgoing), weightTimeToParent, true /* useAccessConditional */))
continue;
return;
if (IsUTurn(parent, firstChild) && IsUTurnAndRestricted(parent, firstChild, isOutgoing))
continue;
return;
if (IsRestricted(parentJoint, parent.GetFeatureId(), firstChild.GetFeatureId(), isOutgoing, parents))
continue;
return;
RouteWeight summaryWeight;
// Check current JointSegment for bad road access between segments.
RoadPoint rp = firstChild.GetRoadPoint(isOutgoing);
uint32_t start = currentPointId;
bool noRoadAccess = false;
do
{
// This is optimization: we calculate accesses of road points before calculating weight of
@@ -360,19 +359,13 @@ void IndexGraph::ReconstructJointSegment(astar::VertexData<JointSegment, RouteWe
// until this |rp|. But we assume that segments have small length and inaccuracy will not
// affect user.
if (IsAccessNoForSure(rp, weightTimeToParent, true /* useAccessConditional */))
{
noRoadAccess = true;
break;
}
return;
start = increment(start);
rp.SetPointId(start);
}
while (start != lastPointId);
if (noRoadAccess)
continue;
bool forward = currentPointId < lastPointId;
Segment current = firstChild;
Segment prev = parent;
@@ -396,7 +389,7 @@ void IndexGraph::ReconstructJointSegment(astar::VertexData<JointSegment, RouteWe
jointEdges.emplace_back(isOutgoing ? JointSegment(firstChild, prev) : JointSegment(prev, firstChild),
summaryWeight);
}
});
}
void IndexGraph::GetNeighboringEdge(astar::VertexData<Segment, RouteWeight> const & fromVertexData, Segment const & to,

View File

@@ -18,8 +18,6 @@
#include "indexer/feature_meta.hpp"
#include "geometry/point2d.hpp"
#include <memory>
#include <optional>
#include <unordered_map>

View File

@@ -13,6 +13,7 @@
#include "3party/skarupke/bytell_hash_map.hpp" // needed despite of IDE warning
#include <algorithm>
#include <execution>
#include <map>
#include <optional>
#include <queue>
@@ -474,7 +475,8 @@ void IndexGraphStarterJoints<Graph>::GetEdgeList(astar::VertexData<Vertex, Weigh
CHECK(it != m_savedWeight.cend(), ("Can not find weight for:", vertex));
Weight const weight = it->second;
for (size_t i = 0; i < edges.size(); ++i)
auto const range = std::ranges::views::iota(0uz, edges.size());
std::for_each(std::execution::par_unseq, range.begin(), range.end(), [&, this](auto const i)
{
// Saving weight of current edges for returning in the next iterations.
auto & w = edges[i].GetWeight();
@@ -490,7 +492,7 @@ void IndexGraphStarterJoints<Graph>::GetEdgeList(astar::VertexData<Vertex, Weigh
// |parentWeights[]|. So the weight of an ith edge is a cached "weight of parent JointSegment" +
// "parentWeight[i]".
w = weight + parentWeights[i];
}
});
// Delete useless weight of parent JointSegment.
m_savedWeight.erase(vertex);
@@ -498,8 +500,9 @@ void IndexGraphStarterJoints<Graph>::GetEdgeList(astar::VertexData<Vertex, Weigh
else
{
// This needs for correct weights calculation of FakeJointSegments during forward A* search.
for (size_t i = firstFakeId; i < edges.size(); ++i)
edges[i].GetWeight() += parentWeights[i];
auto const range = std::ranges::views::iota(firstFakeId, edges.size());
std::for_each(std::execution::par_unseq, range.begin(), range.end(),
[&edges, &parentWeights](auto const i) { edges[i].GetWeight() += parentWeights[i]; });
}
auto const vertexMwmId = vertex.GetMwmId();
@@ -510,12 +513,12 @@ void IndexGraphStarterJoints<Graph>::GetEdgeList(astar::VertexData<Vertex, Weigh
/// a weight of v1->v2 transition moving backward (v2 ingoing). This is impossible in current (m_savedWeight)
/// logic, so I moved Cross-MWM penalty into separate block here after _all_ weights calculations.
for (auto & e : edges)
std::for_each(std::execution::par_unseq, edges.begin(), edges.end(), [&, this](auto & e)
{
auto const targetMwmId = e.GetTarget().GetMwmId();
if (targetMwmId != kFakeNumMwmId && vertexMwmId != targetMwmId)
e.GetWeight() += m_graph.GetCrossBorderPenalty(vertexMwmId, targetMwmId);
}
});
}
}

View File

@@ -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)

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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));
}

View File

@@ -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.

View File

@@ -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));

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -38,7 +38,7 @@ def multithread_run_if_one_country(func):
kwargs.update({"threads_count": settings.THREADS_COUNT})
# Otherwise index stage of Taiwan_* mwms continues to run after all other mwms have finished:
elif country == 'Taiwan_North':
kwargs.update({"threads_count": 5})
kwargs.update({"threads_count": 3})
elif country == 'Taiwan_South':
kwargs.update({"threads_count": 2})
func(env, country, **kwargs)

View File

@@ -20,7 +20,7 @@ MAIN_OUT_PATH: /mnt/4tbexternal/osm-maps
# Path to the data/ folder in the repository:
USER_RESOURCE_PATH: ${Developer:OMIM_PATH}/data
# Features stage only parallelism level. Set to 0 for auto detection.
THREADS_COUNT_FEATURES_STAGE: 0
THREADS_COUNT_FEATURES_STAGE: 64
# Do not change it. This is determined automatically.
NODE_STORAGE: mem