Compare commits

..

25 Commits

Author SHA1 Message Date
Viktor Govako
e7987a14c0 [generator][tests] Added ScopedDirCleanup helper.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-12-05 19:12:47 +07:00
Kiryl Kaveryn
0c079f5120 [drape] Enable visibleViewport tracking for add place mode
It allows to dynamically update the crosshair position when the place page is dismissed.

Signed-off-by: Kiryl Kaveryn <kirylkaveryn@gmail.com>
2025-12-05 19:12:47 +07:00
Andrei Shkrob
723b84ca5a [map] Remove osm_opening_hours.hpp
Signed-off-by: Andrei Shkrob <github@shkrob.dev>
2025-12-05 19:12:47 +07:00
Viktor Govako
b4093e554d [map] Updated wiki loader.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-12-05 19:12:47 +07:00
Viktor Govako
5ab07ea610 [map] Removed Framework::m_popularityLoader.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-12-05 19:12:47 +07:00
renderexpert
3faf052b32 Fix issue after clang-format
Signed-off-by: renderexpert <expert@renderconsulting.co.uk>
2025-12-05 19:12:47 +07:00
Viktor Govako
6259e396f4 Redundant includes.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-12-05 19:12:47 +07:00
Viktor Govako
c968d79f4f [drape] Refactor VisualParams.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-12-05 19:12:44 +07:00
Viktor Govako
4cb6e65e81 [desktop] Show geometry type in context menu.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-12-05 19:08:18 +07:00
Viktor Govako
a962c61978 [desktop] Cancel downloading.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-12-05 19:08:18 +07:00
Kiryl Kaveryn
6cf791580f [map] Remove DeactivateMapSelection on Save osm edits
The call of `DeactivateMapSelection` is redundant because it try to close the current PP. It produces buggy behaviour on iOS the PP is closed and does not have time to open.
The PP should be only be updated using the `ActivateMapSelection`

Signed-off-by: Kiryl Kaveryn <kirylkaveryn@gmail.com>
2025-12-05 19:08:18 +07:00
Viktor Govako
d1f817c3e6 [drape] Refactor UpdateVisualScale.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
2025-12-05 19:08:18 +07:00
Jean-Baptiste
2762bd50ae [android] Rework shape of zoom buttons
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2025-12-05 16:04:10 +07:00
Leonardo Bishop
2b137a8d12 [drape] Base zoom level on distance to next turn
This commit changes the auto zoom level behaviour during navigation
to be based off the distance to the next turn, rather than naively
coupling it to the current speed. This will improve the navigation
experience during driving.

Signed-off-by: Leonardo Bishop <me@leonardobishop.net>
2025-12-05 16:04:10 +07:00
x7z4w
12ac8e8814 [search] Remove stop words
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-12-05 16:04:10 +07:00
gekeleda
5ab43dd67e Add Toast message at navigation start
Signed-off-by: gekeleda <git@davidgekeler.eu>
2025-12-05 15:50:48 +07:00
gekeleda
2847345324 [android] Update TtsPlayer documentation, prefer en.US default locale over installed TTS locales
Signed-off-by: gekeleda <git@davidgekeler.eu>
2025-12-05 15:50:48 +07:00
gekeleda
c9b3778ecc [android] Consider all langs available in TTS engine
Signed-off-by: gekeleda <git@davidgekeler.eu>
2025-12-05 15:50:48 +07:00
gekeleda
593561bc06 [android] Improve TTS selection logging
Signed-off-by: gekeleda <git@davidgekeler.eu>
2025-12-05 15:50:48 +07:00
gekeleda
1cfbc1a8be [android] Consider all system langs for TTS
Signed-off-by: gekeleda <git@davidgekeler.eu>
2025-12-05 15:50:48 +07:00
gekeleda
ba997f6c05 [android] Fix avg speed display edge case, simplify code
Signed-off-by: gekeleda <git@davidgekeler.eu>
2025-12-05 15:49:00 +07:00
David Gekeler
9c9e8dac63 [android] Clarify speed average behaviour in absence of location updates
Signed-off-by: David Gekeler <git@davidgekeler.eu>
2025-12-05 15:48:58 +07:00
David Gekeler
75c151bbbe [android] Fix formatting
Signed-off-by: David Gekeler <git@davidgekeler.eu>
2025-12-05 15:48:56 +07:00
David Gekeler
f960b3959f [android] Add average speed calculation and change speed view to display it
Signed-off-by: David Gekeler <git@davidgekeler.eu>
2025-12-05 15:48:53 +07:00
Konstantin Pastbin
24c9802a2a [planet] Update map data to 251203
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-12-05 12:53:12 +07:00
70 changed files with 2962 additions and 2867 deletions

View File

@@ -105,17 +105,17 @@ jobs:
run: | run: |
echo "Cloning $FORGEJO_SERVER_URL/$FORGEJO_REPOSITORY branch $FORGEJO_REF_NAME" echo "Cloning $FORGEJO_SERVER_URL/$FORGEJO_REPOSITORY branch $FORGEJO_REF_NAME"
cd ~ 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 - name: Checkout wikiparser repo
shell: bash shell: bash
run: | run: |
cd ~ 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 - name: Checkout subways repo
shell: bash shell: bash
run: | run: |
cd ~ cd ~
git clone --depth 1 --single-branch https://codeberg.org/comaps/subways.git git clone https://codeberg.org/comaps/subways.git
copy-coasts: copy-coasts:
# if: inputs.run-copy-coasts # if: inputs.run-copy-coasts

View File

@@ -107,6 +107,7 @@ import app.organicmaps.sdk.routing.RoutingOptions;
import app.organicmaps.sdk.search.SearchEngine; import app.organicmaps.sdk.search.SearchEngine;
import app.organicmaps.sdk.settings.RoadType; import app.organicmaps.sdk.settings.RoadType;
import app.organicmaps.sdk.settings.UnitLocale; import app.organicmaps.sdk.settings.UnitLocale;
import app.organicmaps.sdk.sound.TtsPlayer;
import app.organicmaps.sdk.util.Config; import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.LocationUtils; import app.organicmaps.sdk.util.LocationUtils;
import app.organicmaps.sdk.util.PowerManagment; import app.organicmaps.sdk.util.PowerManagment;
@@ -1813,6 +1814,17 @@ public class MwmActivity extends BaseMwmFragmentActivity
return false; 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() private boolean showStartPointNotice()
{ {
final RoutingController controller = RoutingController.get(); final RoutingController controller = RoutingController.get();
@@ -2189,6 +2201,8 @@ public class MwmActivity extends BaseMwmFragmentActivity
if (!showRoutingDisclaimer()) if (!showRoutingDisclaimer())
return; return;
deliverTtsMessage();
closeFloatingPanels(); closeFloatingPanels();
setFullscreen(false); setFullscreen(false);
RoutingController.get().start(); RoutingController.get().start();

View File

@@ -18,6 +18,7 @@ import app.organicmaps.R;
import app.organicmaps.maplayer.MapButtonsViewModel; import app.organicmaps.maplayer.MapButtonsViewModel;
import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.Router; import app.organicmaps.sdk.Router;
import app.organicmaps.sdk.location.LocationHelper;
import app.organicmaps.sdk.maplayer.traffic.TrafficManager; import app.organicmaps.sdk.maplayer.traffic.TrafficManager;
import app.organicmaps.sdk.routing.CarDirection; import app.organicmaps.sdk.routing.CarDirection;
import app.organicmaps.sdk.routing.RoutingController; import app.organicmaps.sdk.routing.RoutingController;
@@ -267,16 +268,18 @@ public class NavigationController implements TrafficManager.TrafficCallback, Nav
private void updateSpeedWidgets(@NonNull final RoutingInfo info) private void updateSpeedWidgets(@NonNull final RoutingInfo info)
{ {
final Location location = MwmApplication.from(mFrame.getContext()).getLocationHelper().getSavedLocation(); final LocationHelper locationHelper = MwmApplication.from(mFrame.getContext()).getLocationHelper();
final Location location = locationHelper.getSavedLocation();
if (location == null) if (location == null)
{ {
mSpeedLimit.setSpeedLimit(-1, false); mSpeedLimit.setSpeedLimit(-1, false);
mCurrentSpeed.setCurrentSpeed(-1); mCurrentSpeed.setCurrentSpeed(-1);
return; return;
} }
final double currentAvgSpeed = locationHelper.getAverageSpeed();
final int fSpeedLimit = StringUtils.nativeFormatSpeed(info.speedLimitMps); final int fSpeedLimit = StringUtils.nativeFormatSpeed(info.speedLimitMps);
final boolean speedLimitExceeded = fSpeedLimit < StringUtils.nativeFormatSpeed(location.getSpeed()); final boolean speedLimitExceeded = fSpeedLimit < StringUtils.nativeFormatSpeed(currentAvgSpeed);
mSpeedLimit.setSpeedLimit(fSpeedLimit, speedLimitExceeded); mSpeedLimit.setSpeedLimit(fSpeedLimit, speedLimitExceeded);
mCurrentSpeed.setCurrentSpeed(location.getSpeed()); mCurrentSpeed.setCurrentSpeed(currentAvgSpeed);
} }
} }

View File

@@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="960" android:viewportWidth="24"
android:viewportHeight="960"> android:viewportHeight="24">
<path <path
android:pathData="M240,520q-17,0 -28.5,-11.5T200,480q0,-17 11.5,-28.5T240,440h480q17,0 28.5,11.5T760,480q0,17 -11.5,28.5T720,520L240,520Z" android:pathData="M19,13H5v-2h14v2z"
android:fillColor="#ffffff"/> android:fillColor="#ffffff"/>
</vector> </vector>

View File

@@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="960" android:viewportWidth="24"
android:viewportHeight="960"> android:viewportHeight="24">
<path <path
android:pathData="M440,520L240,520q-17,0 -28.5,-11.5T200,480q0,-17 11.5,-28.5T240,440h200v-200q0,-17 11.5,-28.5T480,200q17,0 28.5,11.5T520,240v200h200q17,0 28.5,11.5T760,480q0,17 -11.5,28.5T720,520L520,520v200q0,17 -11.5,28.5T480,760q-17,0 -28.5,-11.5T440,720v-200Z" android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"
android:fillColor="@android:color/white"/> android:fillColor="@android:color/white"/>
</vector> </vector>

View File

@@ -11,14 +11,14 @@
style="@style/MwmWidget.M3.FAB.MapButton.Zoom" style="@style/MwmWidget.M3.FAB.MapButton.Zoom"
android:tint="?iconTint" android:tint="?iconTint"
app:srcCompat="@drawable/ic_plus" app:srcCompat="@drawable/ic_plus"
app:shapeAppearance="@style/Widget.MaterialComponents.FloatingActionButton" app:shapeAppearanceOverlay="@style/ShapeAppearance.MapButton.Zoom.Minus"
android:layout_marginBottom="@dimen/margin_half" android:layout_marginBottom="@dimen/margin_eighth"
android:contentDescription="@string/zoom_in"/> android:contentDescription="@string/zoom_in"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/nav_zoom_out" android:id="@+id/nav_zoom_out"
style="@style/MwmWidget.M3.FAB.MapButton.Zoom" style="@style/MwmWidget.M3.FAB.MapButton.Zoom"
android:tint="?iconTint" android:tint="?iconTint"
app:srcCompat="@drawable/ic_minus" app:srcCompat="@drawable/ic_minus"
app:shapeAppearance="@style/Widget.MaterialComponents.FloatingActionButton" app:shapeAppearanceOverlay="@style/ShapeAppearance.MapButton.Zoom.Plus"
android:contentDescription="@string/zoom_out"/> android:contentDescription="@string/zoom_out"/>
</LinearLayout> </LinearLayout>

View File

@@ -932,6 +932,7 @@
<string name="share_track">Share Track</string> <string name="share_track">Share Track</string>
<string name="delete_track_dialog_title">Delete %s?</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="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="unknown_power_output">unknown</string>
<string name="charge_socket_type2">Type 2 (no cable)</string> <string name="charge_socket_type2">Type 2 (no cable)</string>
<string name="charge_socket_type2_cable">Type 2 (w/ cable)</string> <string name="charge_socket_type2_cable">Type 2 (w/ cable)</string>

View File

@@ -424,4 +424,17 @@
<item name="android:maxWidth">@dimen/map_buttons_bottom_max_width</item> <item name="android:maxWidth">@dimen/map_buttons_bottom_max_width</item>
<item name="android:padding">@dimen/nav_frame_padding</item> <item name="android:padding">@dimen/nav_frame_padding</item>
</style> </style>
<style name="ShapeAppearance.MapButton.Zoom.Plus" parent="">
<item name="cornerSizeTopLeft">10%</item>
<item name="cornerSizeTopRight">10%</item>
<item name="cornerSizeBottomRight">50%</item>
<item name="cornerSizeBottomLeft">50%</item>
</style>
<style name="ShapeAppearance.MapButton.Zoom.Minus" parent="">
<item name="cornerSizeBottomLeft">10%</item>
<item name="cornerSizeBottomRight">10%</item>
<item name="cornerSizeTopLeft">50%</item>
<item name="cornerSizeTopRight">50%</item>
</style>
</resources> </resources>

View File

@@ -26,6 +26,7 @@ import app.organicmaps.sdk.util.LocationUtils;
import app.organicmaps.sdk.util.NetworkPolicy; import app.organicmaps.sdk.util.NetworkPolicy;
import app.organicmaps.sdk.util.log.Logger; import app.organicmaps.sdk.util.log.Logger;
import org.chromium.base.ObserverList; import org.chromium.base.ObserverList;
import java.util.ArrayList;
public class LocationHelper implements BaseLocationProvider.Listener public class LocationHelper implements BaseLocationProvider.Listener
{ {
@@ -35,6 +36,8 @@ public class LocationHelper implements BaseLocationProvider.Listener
private static final long AGPS_EXPIRATION_TIME_MS = 16 * 60 * 60 * 1000; // 16 hours private static final long AGPS_EXPIRATION_TIME_MS = 16 * 60 * 60 * 1000; // 16 hours
private static final long LOCATION_UPDATE_TIMEOUT_MS = 30 * 1000; // 30 seconds private static final long LOCATION_UPDATE_TIMEOUT_MS = 30 * 1000; // 30 seconds
private static final double SPEED_AVERAGING_TIME = 0.5; // 0.5 seconds
@NonNull @NonNull
private final Context mContext; private final Context mContext;
@NonNull @NonNull
@@ -56,6 +59,10 @@ public class LocationHelper implements BaseLocationProvider.Listener
private Handler mHandler; private Handler mHandler;
private Runnable mLocationTimeoutRunnable = this::notifyLocationUpdateTimeout; private Runnable mLocationTimeoutRunnable = this::notifyLocationUpdateTimeout;
private double mTimeElapsedAtLastAverage = Double.NaN;
private float mLastAverageSpeed = Float.NaN;
private ArrayList<Float> mSpeedHistory = new ArrayList<>();
@NonNull @NonNull
private final GnssStatusCompat.Callback mGnssStatusCallback = new GnssStatusCompat.Callback() { private final GnssStatusCompat.Callback mGnssStatusCallback = new GnssStatusCompat.Callback() {
@Override @Override
@@ -167,6 +174,8 @@ public class LocationHelper implements BaseLocationProvider.Listener
mSavedLocation.getLongitude(), mSavedLocation.getAccuracy(), mSavedLocation.getLongitude(), mSavedLocation.getAccuracy(),
mSavedLocation.getAltitude(), mSavedLocation.getSpeed(), mSavedLocation.getAltitude(), mSavedLocation.getSpeed(),
mSavedLocation.getBearing()); mSavedLocation.getBearing());
updateSpeedHistory();
} }
private void notifyLocationUpdateTimeout() private void notifyLocationUpdateTimeout()
@@ -479,4 +488,41 @@ public class LocationHelper implements BaseLocationProvider.Listener
Framework.nativeRunFirstLaunchAnimation(); Framework.nativeRunFirstLaunchAnimation();
} }
} }
private void updateSpeedHistory()
{
if (mSavedLocation == null)
{
return;
}
if (Double.isNaN(mTimeElapsedAtLastAverage))
{
mTimeElapsedAtLastAverage = mSavedLocation.getElapsedRealtimeNanos() * 1.0E-9;
}
mSpeedHistory.add(mSavedLocation.getSpeed());
}
public float getAverageSpeed()
{
if (mSavedLocation == null)
return Float.NaN;
if (Double.isNaN(mTimeElapsedAtLastAverage))
updateSpeedHistory();
double timeDiff = mSavedLocation.getElapsedRealtimeNanos() * 1.0E-9 - mTimeElapsedAtLastAverage;
if (timeDiff < SPEED_AVERAGING_TIME || mSpeedHistory.isEmpty())
{
if (!Float.isNaN(mLastAverageSpeed))
return mLastAverageSpeed;
else
return mSavedLocation.getSpeed();
}
else {
mLastAverageSpeed = mSpeedHistory.stream().reduce(0.0F, Float::sum);
mLastAverageSpeed /= mSpeedHistory.size();
mSpeedHistory.clear();
mTimeElapsedAtLastAverage = mSavedLocation.getElapsedRealtimeNanos() * 1.0E-9;
return mLastAverageSpeed;
}
}
} }

View File

@@ -1,6 +1,7 @@
package app.organicmaps.sdk.sound; package app.organicmaps.sdk.sound;
import android.content.Context; import android.content.Context;
import android.content.res.Configuration;
import android.database.ContentObserver; import android.database.ContentObserver;
import android.media.AudioManager; import android.media.AudioManager;
import android.os.Bundle; import android.os.Bundle;
@@ -13,6 +14,8 @@ import android.text.TextUtils;
import android.util.Pair; import android.util.Pair;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.os.ConfigurationCompat;
import androidx.core.os.LocaleListCompat;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.media.AudioAttributesCompat; import androidx.media.AudioAttributesCompat;
import androidx.media.AudioFocusRequestCompat; import androidx.media.AudioFocusRequestCompat;
@@ -23,6 +26,7 @@ import app.organicmaps.sdk.util.log.Logger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Set;
/** /**
* {@code TtsPlayer} class manages available TTS voice languages. * {@code TtsPlayer} class manages available TTS voice languages.
@@ -33,9 +37,9 @@ import java.util.Locale;
* unsupported voices are excluded. * unsupported voices are excluded.
* <p> * <p>
* At startup we check whether currently selected language is in our list of supported voices and its data is * 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 English language. Finally, * downloaded. If not, we check system default locale. If failed, the same check is made for other system locales.
* if mentioned checks fail we manually disable TTS, so the user must go to the settings and select preferred voice * If those fail too, we check for English language. Then, as a final resort, all installed TTS locales are checked.
* language by hand. <p> If no core supported languages can be used by the system, TTS is locked down and can not be * <p> If no core supported languages can be used by the system, TTS is locked down and can not be
* enabled and used. * enabled and used.
*/ */
public enum TtsPlayer public enum TtsPlayer
@@ -78,6 +82,8 @@ public enum TtsPlayer
// TTS is locked down due to absence of supported languages // TTS is locked down due to absence of supported languages
private boolean mUnavailable; private boolean mUnavailable;
private LocaleListCompat mInstalledSystemLocales;
TtsPlayer() {} TtsPlayer() {}
private static @Nullable LanguageData findSupportedLanguage(String internalCode, List<LanguageData> langs) private static @Nullable LanguageData findSupportedLanguage(String internalCode, List<LanguageData> langs)
@@ -126,30 +132,56 @@ public enum TtsPlayer
return (lang != null && setLanguageInternal(lang)); 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) private static @Nullable LanguageData getDefaultLanguage(List<LanguageData> langs)
{ {
LanguageData res; LanguageData res;
Locale defLocale = Locale.getDefault(); // Try default app locale (en.US)
if (defLocale != null)
{
res = findSupportedLanguage(defLocale, langs);
if (res != null && res.downloaded)
return res;
}
res = findSupportedLanguage(DEFAULT_LOCALE, langs); res = findSupportedLanguage(DEFAULT_LOCALE, langs);
if (res != null && res.downloaded) if (res != null && res.downloaded)
return res; return res;
return null; return null;
} }
public static @Nullable LanguageData getSelectedLanguage(List<LanguageData> langs)
{
return findSupportedLanguage(Config.TTS.getLanguage(), langs);
}
private void lockDown() private void lockDown()
{ {
mUnavailable = true; mUnavailable = true;
@@ -167,6 +199,10 @@ public enum TtsPlayer
// TextToSpeech.OnInitListener() can be called from a non-main thread // TextToSpeech.OnInitListener() can be called from a non-main thread
// on LineageOS '20.0-20231127-RELEASE-thyme' 'Xiaomi/thyme/thyme'. // on LineageOS '20.0-20231127-RELEASE-thyme' 'Xiaomi/thyme/thyme'.
// https://github.com/organicmaps/organicmaps/issues/6903 // https://github.com/organicmaps/organicmaps/issues/6903
Configuration config = context.getResources().getConfiguration();
mInstalledSystemLocales = ConfigurationCompat.getLocales(config);
mTts = new TextToSpeech(context, status -> UiThread.run(() -> { mTts = new TextToSpeech(context, status -> UiThread.run(() -> {
if (status == TextToSpeech.ERROR) if (status == TextToSpeech.ERROR)
{ {
@@ -239,6 +275,17 @@ public enum TtsPlayer
return (INSTANCE.mTts != null && !INSTANCE.mUnavailable && !INSTANCE.mInitializing); 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) public void speak(String textToSpeak)
{ {
if (Config.TTS.isEnabled()) if (Config.TTS.isEnabled())
@@ -328,24 +375,45 @@ public enum TtsPlayer
if (outList.isEmpty()) if (outList.isEmpty())
{ {
// No supported languages found, lock down TTS :( Logger.d("TtsPlayer", "No supported languages found, lock down TTS :( ");
lockDown(); lockDown();
return null; return null;
} }
LanguageData res = getSelectedLanguage(outList); LanguageData res = getSelectedLanguage(outList);
if (res == null || !res.downloaded) if (res != null && res.downloaded)
// Selected locale is not available or not downloaded
res = getDefaultLanguage(outList);
if (res == null || !res.downloaded)
{ {
// Default locale can not be used too Logger.d("TtsPlayer", "Selected locale " + res.internalCode + " will be used for TTS");
Config.TTS.setEnabled(false); return res;
return null; }
Logger.d("TtsPlayer", "Selected locale " + Config.TTS.getLanguage() + " is not available or not downloaded, trying system locales...");
res = getSystemLanguage(outList);
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;
} }
return res; Logger.d("TtsPlayer", "None of the TTS engine locales are available, or they are not downloaded, disabling TTS :( ");
Config.TTS.setEnabled(false);
return null;
} }
public @NonNull List<LanguageData> refreshLanguages() public @NonNull List<LanguageData> refreshLanguages()

View File

@@ -36,6 +36,7 @@ public final class Config
private static final String KEY_PREF_USE_GS = "UseGoogleServices"; private static final String KEY_PREF_USE_GS = "UseGoogleServices";
private static final String KEY_MISC_DISCLAIMER_ACCEPTED = "IsDisclaimerApproved"; 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_LOCATION_REQUESTED = "LocationRequested";
private static final String KEY_MISC_USE_MOBILE_DATA = "UseMobileData"; private static final String KEY_MISC_USE_MOBILE_DATA = "UseMobileData";
private static final String KEY_MISC_USE_MOBILE_DATA_TIMESTAMP = "UseMobileDataTimestamp"; private static final String KEY_MISC_USE_MOBILE_DATA_TIMESTAMP = "UseMobileDataTimestamp";
@@ -237,6 +238,16 @@ public final class Config
setBool(KEY_MISC_DISCLAIMER_ACCEPTED); 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() public static boolean isLocationRequested()
{ {
return getBool(KEY_MISC_LOCATION_REQUESTED); return getBool(KEY_MISC_LOCATION_REQUESTED);

File diff suppressed because it is too large Load Diff

View File

@@ -502,11 +502,11 @@ int main(int argc, char * argv[])
if (ImGui::GetIO().WantCaptureMouse) if (ImGui::GetIO().WantCaptureMouse)
framework.MakeFrameActive(); framework.MakeFrameActive();
if (touchActive)
#if defined(OMIM_OS_MAC) #if defined(OMIM_OS_MAC)
x *= visualScale; x *= visualScale;
y *= visualScale; y *= visualScale;
#endif #endif
if (touchActive)
framework.TouchEvent(GetTouchEvent(framework, x, y, touchMods, df::TouchEvent::TOUCH_MOVE)); framework.TouchEvent(GetTouchEvent(framework, x, y, touchMods, df::TouchEvent::TOUCH_MOVE));
}; };
glfwSetCursorPosCallback(window, [](GLFWwindow *, double x, double y) { handlers.onMouseMove(x, y); }); glfwSetCursorPosCallback(window, [](GLFWwindow *, double x, double y) { handlers.onMouseMove(x, y); });

View File

@@ -165,18 +165,16 @@ void TestAltitudesBuilding(std::vector<TPoint3DList> const & roads, bool hasAlti
AltitudeGetter & altitudeGetter) AltitudeGetter & altitudeGetter)
{ {
classificator::Load(); classificator::Load();
Platform & platform = GetPlatform();
std::string const testDirFullPath = base::JoinPath(platform.WritableDir(), kTestDir); std::string const testDirFullPath = base::JoinPath(GetPlatform().WritableDir(), kTestDir);
ScopedDirCleanup testScopedDir(testDirFullPath);
// Building mwm without altitude section. // Building mwm without altitude section.
LocalCountryFile country(testDirFullPath, CountryFile(kTestMwm), 1); LocalCountryFile country(testDirFullPath, CountryFile(kTestMwm), 1);
ScopedDir testScopedDir(kTestDir);
ScopedFile testScopedMwm(base::JoinPath(kTestDir, kTestMwm + DATA_FILE_EXTENSION), ScopedFile::Mode::Create);
BuildMwmWithoutAltitudes(roads, country); BuildMwmWithoutAltitudes(roads, country);
// Adding altitude section to mwm. // Adding altitude section to mwm.
auto const mwmPath = testScopedMwm.GetFullPath(); auto const mwmPath = base::JoinPath(testDirFullPath, kTestMwm + DATA_FILE_EXTENSION);
BuildRoadAltitudes(mwmPath, altitudeGetter); BuildRoadAltitudes(mwmPath, altitudeGetter);
// Reading from mwm and testing altitude information. // Reading from mwm and testing altitude information.

View File

@@ -64,18 +64,15 @@ std::unique_ptr<CityRoads> LoadCityRoads(LocalCountryFile const & country)
/// section and then read from it. /// section and then read from it.
void TestCityRoadsBuilding(vector<uint32_t> && cityRoadFeatureIds) void TestCityRoadsBuilding(vector<uint32_t> && cityRoadFeatureIds)
{ {
string const writableDir = GetPlatform().WritableDir(); string const testDir = base::JoinPath(GetPlatform().WritableDir(), kTestDir);
ScopedDirCleanup scopedDir(testDir);
// Building empty mwm. // Building empty mwm.
LocalCountryFile country(base::JoinPath(writableDir, kTestDir), CountryFile(kTestMwm), 0 /* version */); LocalCountryFile country(testDir, CountryFile(kTestMwm), 0 /* version */);
ScopedDir const scopedDir(kTestDir);
string const mwmRelativePath = base::JoinPath(kTestDir, kTestMwm + DATA_FILE_EXTENSION);
ScopedFile const scopedMwm(mwmRelativePath, ScopedFile::Mode::Create);
BuildEmptyMwm(country); BuildEmptyMwm(country);
// Adding city_roads section to mwm. // Adding city_roads section to mwm.
string const mwmFullPath = base::JoinPath(writableDir, mwmRelativePath); string const mwmFullPath = base::JoinPath(testDir, kTestMwm + DATA_FILE_EXTENSION);
vector<uint32_t> originalCityRoadFeatureIds = cityRoadFeatureIds; vector<uint32_t> originalCityRoadFeatureIds = cityRoadFeatureIds;
routing_builder::SerializeCityRoads(mwmFullPath, std::move(cityRoadFeatureIds)); routing_builder::SerializeCityRoads(mwmFullPath, std::move(cityRoadFeatureIds));

View File

@@ -73,19 +73,18 @@ void TestMaxspeedsSection(Features const & roads, string const & maxspeedsCsvCon
FeatureIdToOsmId const & featureIdToOsmId) FeatureIdToOsmId const & featureIdToOsmId)
{ {
classificator::Load(); classificator::Load();
string const testDirFullPath = base::JoinPath(GetPlatform().WritableDir(), kTestDir); string const testDirFullPath = base::JoinPath(GetPlatform().WritableDir(), kTestDir);
ScopedDir testScopedDir(kTestDir); ScopedDirCleanup testScopedDir(testDirFullPath);
// Writing |maxspeedsCsvContent| to a file in |kTestDir|. // Writing |maxspeedsCsvContent| to a file in |kTestDir|.
ScopedFile testScopedMaxspeedsCsv(base::JoinPath(kTestDir, kCsv), maxspeedsCsvContent); ScopedFile testScopedMaxspeedsCsv(base::JoinPath(kTestDir, kCsv), maxspeedsCsvContent);
// Writing |roads| to test mwm. // Writing |roads| to test mwm.
LocalCountryFile country(testDirFullPath, CountryFile(kTestMwm), 1 /* version */); LocalCountryFile country(testDirFullPath, CountryFile(kTestMwm), 1 /* version */);
string const testMwm = kTestMwm + DATA_FILE_EXTENSION;
ScopedFile testScopedMwm(base::JoinPath(kTestDir, testMwm), ScopedFile::Mode::Create);
BuildGeometry(roads, country); BuildGeometry(roads, country);
string const testMwmFullPath = base::JoinPath(testDirFullPath, testMwm); string const testMwmFullPath = base::JoinPath(testDirFullPath, kTestMwm + DATA_FILE_EXTENSION);
// Create routing graph for test mwm. // Create routing graph for test mwm.
auto const countryParentGetter = [](std::string const &) { return string(); }; auto const countryParentGetter = [](std::string const &) { return string(); };

View File

@@ -134,33 +134,26 @@ void LoadRestrictions(string const & mwmFilePath, vector<Restriction> & restrict
/// loads the restriction section and test loaded restrictions. /// loads the restriction section and test loaded restrictions.
/// \param |restrictionPath| comma separated text with restrictions in osm id terms. /// \param |restrictionPath| comma separated text with restrictions in osm id terms.
/// \param |osmIdsToFeatureIdContent| comma separated text with mapping from osm ids to feature ids. /// \param |osmIdsToFeatureIdContent| comma separated text with mapping from osm ids to feature ids.
void TestRestrictionBuilding(string const & restrictionPath, string const & osmIdsToFeatureIdContent, void TestRestrictionBuilding(string const & restrictionContent, string const & osmIdsToFeatureIdContent,
unique_ptr<IndexGraph> graph, vector<Restriction> & expectedNotUTurn, unique_ptr<IndexGraph> graph, vector<Restriction> & expectedNotUTurn,
vector<RestrictionUTurnForTests> & expectedUTurn) vector<RestrictionUTurnForTests> & expectedUTurn)
{ {
Platform & platform = GetPlatform(); string const targetDir = base::JoinPath(GetPlatform().WritableDir(), kTestDir);
string const writableDir = platform.WritableDir(); ScopedDirCleanup scopedDir(targetDir);
string const targetDir = base::JoinPath(writableDir, kTestDir);
// Building empty mwm. // Building empty mwm.
LocalCountryFile country(targetDir, CountryFile(kTestMwm), 0 /* version */); LocalCountryFile country(targetDir, CountryFile(kTestMwm), 0 /* version */);
ScopedDir const scopedDir(kTestDir);
string const mwmRelativePath = base::JoinPath(kTestDir, kTestMwm + DATA_FILE_EXTENSION);
ScopedFile const scopedMwm(mwmRelativePath, ScopedFile::Mode::Create);
BuildEmptyMwm(country); BuildEmptyMwm(country);
// Creating a file with restrictions. // Creating a file with restrictions.
string const restrictionRelativePath = base::JoinPath(kTestDir, kRestrictionFileName); ScopedFile const restrictionScopedFile(base::JoinPath(kTestDir, kRestrictionFileName), restrictionContent);
ScopedFile const restrictionScopedFile(restrictionRelativePath, restrictionPath);
// Creating osm ids to feature ids mapping. // Creating osm ids to feature ids mapping.
string const mappingRelativePath = base::JoinPath(kTestDir, kOsmIdsToFeatureIdsName); string const osmIdsToFeatureIdFullPath = base::JoinPath(targetDir, kOsmIdsToFeatureIdsName);
ScopedFile const mappingFile(mappingRelativePath, ScopedFile::Mode::Create);
string const & osmIdsToFeatureIdFullPath = mappingFile.GetFullPath();
ReEncodeOsmIdsToFeatureIdsMapping(osmIdsToFeatureIdContent, osmIdsToFeatureIdFullPath); ReEncodeOsmIdsToFeatureIdsMapping(osmIdsToFeatureIdContent, osmIdsToFeatureIdFullPath);
string const restrictionFullPath = base::JoinPath(writableDir, restrictionRelativePath); string const restrictionFullPath = base::JoinPath(targetDir, kRestrictionFileName);
string const & mwmFullPath = scopedMwm.GetFullPath(); string const mwmFullPath = base::JoinPath(targetDir, kTestMwm + DATA_FILE_EXTENSION);
// Prepare data to collector. // Prepare data to collector.
auto restrictionCollector = auto restrictionCollector =

View File

@@ -2,8 +2,6 @@
#include "indexer/data_source.hpp" #include "indexer/data_source.hpp"
#include "base/assert.hpp"
#include "defines.hpp" #include "defines.hpp"
namespace descriptions namespace descriptions
@@ -20,17 +18,28 @@ std::string Loader::GetWikiDescription(FeatureID const & featureId, std::vector<
if (!value.m_cont.IsExist(DESCRIPTIONS_FILE_TAG)) if (!value.m_cont.IsExist(DESCRIPTIONS_FILE_TAG))
return {}; return {};
EntryPtr entry; // No need to have separate mutexes for each MWM since there is no concurrent Wiki pages reading.
{ // Pros: lock is called once and a simple logic with OnMwmDeregistered synchronization.
std::lock_guard<std::mutex> lock(m_mutex); /// @todo Consider removing mutex at all or make wiki loading async (PlacePage info).
entry = m_deserializers.try_emplace(featureId.m_mwmId, std::make_shared<Entry>()).first->second;
}
ASSERT(entry, ()); std::lock_guard lock(m_mutex);
Deserializer & deserializer = m_deserializers[featureId.m_mwmId];
auto readerPtr = value.m_cont.GetReader(DESCRIPTIONS_FILE_TAG); auto readerPtr = value.m_cont.GetReader(DESCRIPTIONS_FILE_TAG);
return deserializer.Deserialize(*readerPtr.GetPtr(), featureId.m_index, langPriority);
std::lock_guard<std::mutex> lock(entry->m_mutex);
return entry->m_deserializer.Deserialize(*readerPtr.GetPtr(), featureId.m_index, langPriority);
} }
void Loader::OnMwmDeregistered(platform::LocalCountryFile const & countryFile)
{
std::lock_guard lock(m_mutex);
for (auto it = m_deserializers.begin(); it != m_deserializers.end(); ++it)
{
if (it->first.IsDeregistered(countryFile))
{
m_deserializers.erase(it);
break;
}
}
}
} // namespace descriptions } // namespace descriptions

View File

@@ -5,9 +5,7 @@
#include "indexer/feature_decl.hpp" #include "indexer/feature_decl.hpp"
#include "indexer/mwm_set.hpp" #include "indexer/mwm_set.hpp"
#include <cstdint>
#include <map> #include <map>
#include <memory>
#include <mutex> #include <mutex>
#include <string> #include <string>
#include <vector> #include <vector>
@@ -23,18 +21,11 @@ public:
explicit Loader(DataSource const & dataSource) : m_dataSource(dataSource) {} explicit Loader(DataSource const & dataSource) : m_dataSource(dataSource) {}
std::string GetWikiDescription(FeatureID const & featureId, std::vector<int8_t> const & langPriority); std::string GetWikiDescription(FeatureID const & featureId, std::vector<int8_t> const & langPriority);
void OnMwmDeregistered(platform::LocalCountryFile const & countryFile);
private: private:
struct Entry
{
std::mutex m_mutex;
Deserializer m_deserializer;
};
using EntryPtr = std::shared_ptr<Entry>;
DataSource const & m_dataSource; DataSource const & m_dataSource;
std::map<MwmSet::MwmId, EntryPtr> m_deserializers; std::map<MwmSet::MwmId, Deserializer> m_deserializers;
std::mutex m_mutex; std::mutex m_mutex;
}; };
} // namespace descriptions } // namespace descriptions

View File

@@ -231,14 +231,6 @@ void SymbolsTexture::Invalidate(ref_ptr<dp::GraphicsContext> context, std::strin
Load(context, skinPathName, allocator); Load(context, skinPathName, allocator);
} }
void SymbolsTexture::Invalidate(ref_ptr<dp::GraphicsContext> context, std::string const & skinPathName,
ref_ptr<HWTextureAllocator> allocator,
std::vector<drape_ptr<HWTexture>> & internalTextures)
{
internalTextures.push_back(std::move(m_hwTexture));
Invalidate(context, skinPathName, allocator);
}
ref_ptr<Texture::ResourceInfo> SymbolsTexture::FindResource(Texture::Key const & key, bool & newResource) ref_ptr<Texture::ResourceInfo> SymbolsTexture::FindResource(Texture::Key const & key, bool & newResource)
{ {
newResource = false; newResource = false;

View File

@@ -36,8 +36,6 @@ public:
void Invalidate(ref_ptr<dp::GraphicsContext> context, std::string const & skinPathName, void Invalidate(ref_ptr<dp::GraphicsContext> context, std::string const & skinPathName,
ref_ptr<HWTextureAllocator> allocator); ref_ptr<HWTextureAllocator> allocator);
void Invalidate(ref_ptr<dp::GraphicsContext> context, std::string const & skinPathName,
ref_ptr<HWTextureAllocator> allocator, std::vector<drape_ptr<HWTexture>> & internalTextures);
bool IsSymbolContained(std::string const & symbolName) const; bool IsSymbolContained(std::string const & symbolName) const;

View File

@@ -73,6 +73,12 @@ public:
static bool IsPowerOfTwo(uint32_t width, uint32_t height); static bool IsPowerOfTwo(uint32_t width, uint32_t height);
void DeferredCleanup(std::vector<drape_ptr<HWTexture>> & toCleanup)
{
toCleanup.push_back(std::move(m_hwTexture));
Destroy();
}
protected: protected:
void Destroy(); void Destroy();
bool AllocateTexture(ref_ptr<dp::GraphicsContext> context, ref_ptr<HWTextureAllocator> allocator); bool AllocateTexture(ref_ptr<dp::GraphicsContext> context, ref_ptr<HWTextureAllocator> allocator);

View File

@@ -87,6 +87,10 @@ drape_ptr<Texture> CreateArrowTexture(ref_ptr<dp::GraphicsContext> context,
useDefaultResourceFolder ? StaticTexture::kDefaultResource : std::string(), useDefaultResourceFolder ? StaticTexture::kDefaultResource : std::string(),
dp::TextureFormat::RGBA8, textureAllocator, true /* allowOptional */); dp::TextureFormat::RGBA8, textureAllocator, true /* allowOptional */);
} }
// There is no "arrow-texture.png".
// BackendRenderer::m_arrow3dPreloadedData mesh is used by default.
/// @todo Texture arrow is still present in case if somebody wants to use it?
return make_unique_dp<StaticTexture>(context, "arrow-texture.png", StaticTexture::kDefaultResource, return make_unique_dp<StaticTexture>(context, "arrow-texture.png", StaticTexture::kDefaultResource,
dp::TextureFormat::RGBA8, textureAllocator, true /* allowOptional */); dp::TextureFormat::RGBA8, textureAllocator, true /* allowOptional */);
} }
@@ -315,39 +319,7 @@ void TextureManager::Init(ref_ptr<dp::GraphicsContext> context, Params const & p
m_smaaSearchTexture = make_unique_dp<StaticTexture>(context, "smaa-search.png", StaticTexture::kDefaultResource, m_smaaSearchTexture = make_unique_dp<StaticTexture>(context, "smaa-search.png", StaticTexture::kDefaultResource,
dp::TextureFormat::Red, make_ref(m_textureAllocator)); dp::TextureFormat::Red, make_ref(m_textureAllocator));
// Initialize patterns (reserved ./data/patterns.txt lines count). InitStipplePen(params);
std::set<PenPatternT> patterns;
double const visualScale = params.m_visualScale;
uint32_t rowsCount = 0;
impl::ParsePatternsList(params.m_patterns, [&](buffer_vector<double, 8> const & pattern)
{
PenPatternT toAdd;
for (double d : pattern)
toAdd.push_back(PatternFloat2Pixel(d * visualScale));
if (!patterns.insert(toAdd).second)
return;
if (IsTrianglePattern(toAdd))
{
rowsCount = rowsCount + toAdd[2] + toAdd[3];
}
else
{
ASSERT_EQUAL(toAdd.size(), 2, ());
++rowsCount;
}
});
m_stipplePenTexture = make_unique_dp<StipplePenTexture>(StipplePenTextureSize(rowsCount, m_maxTextureSize),
make_ref(m_textureAllocator));
LOG(LDEBUG, ("Patterns texture size =", m_stipplePenTexture->GetWidth(), m_stipplePenTexture->GetHeight()));
ref_ptr<StipplePenTexture> stipplePenTex = make_ref(m_stipplePenTexture);
for (auto const & p : patterns)
stipplePenTex->ReservePattern(p);
// Initialize colors (reserved ./data/colors.txt lines count). // Initialize colors (reserved ./data/colors.txt lines count).
std::vector<dp::Color> colors; std::vector<dp::Color> colors;
@@ -380,25 +352,73 @@ void TextureManager::Init(ref_ptr<dp::GraphicsContext> context, Params const & p
m_nothingToUpload.clear(); m_nothingToUpload.clear();
} }
void TextureManager::InitStipplePen(Params const & params)
{
// Initialize patterns (reserved ./data/patterns.txt lines count).
std::set<PenPatternT> patterns;
uint32_t rowsCount = 0;
impl::ParsePatternsList(params.m_patterns, [&](buffer_vector<double, 8> const & pattern)
{
PenPatternT toAdd;
for (double d : pattern)
toAdd.push_back(PatternFloat2Pixel(d * params.m_visualScale));
if (!patterns.insert(toAdd).second)
return;
if (IsTrianglePattern(toAdd))
{
rowsCount = rowsCount + toAdd[2] + toAdd[3];
}
else
{
ASSERT_EQUAL(toAdd.size(), 2, ());
++rowsCount;
}
});
m_stipplePenTexture = make_unique_dp<StipplePenTexture>(StipplePenTextureSize(rowsCount, m_maxTextureSize),
make_ref(m_textureAllocator));
LOG(LDEBUG, ("Patterns texture size =", m_stipplePenTexture->GetWidth(), m_stipplePenTexture->GetHeight()));
ref_ptr<StipplePenTexture> stipplePenTex = make_ref(m_stipplePenTexture);
for (auto const & p : patterns)
stipplePenTex->ReservePattern(p);
}
void TextureManager::OnSwitchMapStyle(ref_ptr<dp::GraphicsContext> context) void TextureManager::OnSwitchMapStyle(ref_ptr<dp::GraphicsContext> context)
{ {
CHECK(m_isInitialized, ()); CHECK(m_isInitialized, ());
bool const isVulkan = context->GetApiVersion() == dp::ApiVersion::Vulkan;
// Here we need invalidate only textures which can be changed in map style switch. // Here we need invalidate only textures which can be changed in map style switch.
// Now we update only symbol textures, if we need update other textures they must be added here. // Now we update only symbol textures, if we need update other textures they must be added here.
// For Vulkan we use m_texturesToCleanup to defer textures destroying. // For Vulkan we use m_texturesToCleanup to defer textures destroying.
for (auto const & m_symbolTexture : m_symbolTextures) for (auto const & texture : m_symbolTextures)
{ {
ref_ptr<SymbolsTexture> symbolsTexture = make_ref(m_symbolTexture); ref_ptr<SymbolsTexture> symbolsTexture = make_ref(texture);
ASSERT(symbolsTexture != nullptr, ()); if (isVulkan)
symbolsTexture->DeferredCleanup(m_texturesToCleanup);
if (context->GetApiVersion() != dp::ApiVersion::Vulkan)
symbolsTexture->Invalidate(context, m_resPostfix, make_ref(m_textureAllocator)); symbolsTexture->Invalidate(context, m_resPostfix, make_ref(m_textureAllocator));
else
symbolsTexture->Invalidate(context, m_resPostfix, make_ref(m_textureAllocator), m_texturesToCleanup);
} }
} }
void TextureManager::OnVisualScaleChanged(ref_ptr<dp::GraphicsContext> context, Params const & params)
{
m_resPostfix = params.m_resPostfix;
OnSwitchMapStyle(context);
if (context->GetApiVersion() == dp::ApiVersion::Vulkan)
m_stipplePenTexture->DeferredCleanup(m_texturesToCleanup);
InitStipplePen(params);
}
void TextureManager::InvalidateArrowTexture(ref_ptr<dp::GraphicsContext> context, void TextureManager::InvalidateArrowTexture(ref_ptr<dp::GraphicsContext> context,
std::string const & texturePath /* = {} */, std::string const & texturePath /* = {} */,
bool useDefaultResourceFolder /* = false */) bool useDefaultResourceFolder /* = false */)
@@ -416,10 +436,13 @@ void TextureManager::ApplyInvalidatedStaticTextures()
} }
} }
void TextureManager::GetTexturesToCleanup(std::vector<drape_ptr<HWTexture>> & textures) std::vector<drape_ptr<HWTexture>> TextureManager::GetTexturesToCleanup()
{ {
CHECK(m_isInitialized, ()); CHECK(m_isInitialized, ());
std::swap(textures, m_texturesToCleanup);
auto res = std::move(m_texturesToCleanup);
m_texturesToCleanup.clear();
return res;
} }
bool TextureManager::GetSymbolRegionSafe(std::string const & symbolName, SymbolRegion & region) bool TextureManager::GetSymbolRegionSafe(std::string const & symbolName, SymbolRegion & region)

View File

@@ -77,7 +77,9 @@ public:
void Init(ref_ptr<dp::GraphicsContext> context, Params const & params); void Init(ref_ptr<dp::GraphicsContext> context, Params const & params);
void OnSwitchMapStyle(ref_ptr<dp::GraphicsContext> context); void OnSwitchMapStyle(ref_ptr<dp::GraphicsContext> context);
void GetTexturesToCleanup(std::vector<drape_ptr<HWTexture>> & textures); void OnVisualScaleChanged(ref_ptr<dp::GraphicsContext> context, Params const & params);
std::vector<drape_ptr<HWTexture>> GetTexturesToCleanup();
bool GetSymbolRegionSafe(std::string const & symbolName, SymbolRegion & region); bool GetSymbolRegionSafe(std::string const & symbolName, SymbolRegion & region);
void GetSymbolRegion(std::string const & symbolName, SymbolRegion & region); void GetSymbolRegion(std::string const & symbolName, SymbolRegion & region);
@@ -121,6 +123,8 @@ public:
ref_ptr<HWTextureAllocator> GetTextureAllocator() const; ref_ptr<HWTextureAllocator> GetTextureAllocator() const;
private: private:
void InitStipplePen(Params const & params);
struct GlyphGroup struct GlyphGroup
{ {
std::set<GlyphFontAndId> m_glyphKeys; std::set<GlyphFontAndId> m_glyphKeys;

View File

@@ -525,9 +525,11 @@ void ApplyPointFeature::ProcessPointRules(SymbolRuleProto const * symbolRule, Ca
params.m_depth = PriorityToDepth(symbolRule->priority(), drule::symbol, 0); params.m_depth = PriorityToDepth(symbolRule->priority(), drule::symbol, 0);
params.m_symbolName = symbolRule->name(); params.m_symbolName = symbolRule->name();
ASSERT_GREATER_OR_EQUAL(symbolRule->min_distance(), 0, ()); ASSERT_GREATER_OR_EQUAL(symbolRule->min_distance(), 0, ());
// Where 0.1 comes from: https://github.com/organicmaps/organicmaps/pull/649
auto const & vp = df::VisualParams::Instance(); auto const & vp = df::VisualParams::Instance();
params.m_extendingSize = params.m_extendingSize = static_cast<uint32_t>(vp.GetVisualScale() * symbolRule->min_distance() * 0.1);
static_cast<uint32_t>(vp.GetVisualScale() * symbolRule->min_distance() * vp.GetPoiExtendScale());
params.m_posZ = m_posZ; params.m_posZ = m_posZ;
params.m_hasArea = HasArea(); params.m_hasArea = HasArea();
params.m_prioritized = createdByEditor; params.m_prioritized = createdByEditor;

View File

@@ -17,8 +17,6 @@
#include "drape/support_manager.hpp" #include "drape/support_manager.hpp"
#include "drape/texture_manager.hpp" #include "drape/texture_manager.hpp"
#include "indexer/scales.hpp"
#include "platform/platform.hpp" #include "platform/platform.hpp"
#include "base/file_name_utils.hpp" #include "base/file_name_utils.hpp"
@@ -355,18 +353,37 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message)
m_trafficGenerator->InvalidateTexturesCache(); m_trafficGenerator->InvalidateTexturesCache();
m_transitBuilder->RebuildSchemes(m_context, m_texMng); m_transitBuilder->RebuildSchemes(m_context, m_texMng);
// For Vulkan we initialize deferred cleaning up. CleanupTextures();
if (m_context->GetApiVersion() == dp::ApiVersion::Vulkan) break;
{
std::vector<drape_ptr<dp::HWTexture>> textures;
m_texMng->GetTexturesToCleanup(textures);
if (!textures.empty())
{
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
make_unique_dp<CleanupTexturesMessage>(std::move(textures)), MessagePriority::Normal);
}
} }
case Message::Type::VisualScaleChanged:
{
ref_ptr<VisualScaleChangedMessage> msg = message;
msg->FilterDependentMessages();
CHECK(m_context != nullptr, ());
dp::TextureManager::Params params;
params.m_resPostfix = VisualParams::Instance().GetResourcePostfix();
params.m_visualScale = df::VisualParams::Instance().GetVisualScale();
#ifdef BUILD_DESIGNER
params.m_patterns = "patterns_design.txt";
#else
params.m_patterns = "patterns.txt";
#endif // BUILD_DESIGNER
m_texMng->OnVisualScaleChanged(m_context, params);
RecacheMapShapes();
RecacheGui(m_lastWidgetsInfo, false /* needResetOldGui */);
#ifdef RENDER_DEBUG_INFO_LABELS
RecacheDebugLabels();
#endif
m_trafficGenerator->InvalidateTexturesCache();
m_transitBuilder->RebuildSchemes(m_context, m_texMng);
CleanupTextures();
break; break;
} }
@@ -611,21 +628,8 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message)
m_arrow3dPreloadedData = Arrow3d::PreloadMesh(m_arrow3dCustomDecl, m_texMng); m_arrow3dPreloadedData = Arrow3d::PreloadMesh(m_arrow3dCustomDecl, m_texMng);
} }
// Recache map shapes.
RecacheMapShapes(); RecacheMapShapes();
CleanupTextures();
// For Vulkan we initialize deferred cleaning up.
if (m_context->GetApiVersion() == dp::ApiVersion::Vulkan)
{
std::vector<drape_ptr<dp::HWTexture>> textures;
m_texMng->GetTexturesToCleanup(textures);
if (!textures.empty())
{
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
make_unique_dp<CleanupTexturesMessage>(std::move(textures)), MessagePriority::Normal);
}
}
break; break;
} }
@@ -772,6 +776,18 @@ void BackendRenderer::RecacheMapShapes()
m_commutator->PostMessage(ThreadsCommutator::RenderThread, std::move(msg), MessagePriority::Normal); m_commutator->PostMessage(ThreadsCommutator::RenderThread, std::move(msg), MessagePriority::Normal);
} }
void BackendRenderer::CleanupTextures()
{
// For Vulkan we initialize deferred cleaning up.
if (m_context->GetApiVersion() == dp::ApiVersion::Vulkan)
{
auto textures = m_texMng->GetTexturesToCleanup();
if (!textures.empty())
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
make_unique_dp<CleanupTexturesMessage>(std::move(textures)), MessagePriority::Normal);
}
}
void BackendRenderer::FlushGeometry(TileKey const & key, dp::RenderState const & state, void BackendRenderer::FlushGeometry(TileKey const & key, dp::RenderState const & state,
drape_ptr<dp::RenderBucket> && buffer) drape_ptr<dp::RenderBucket> && buffer)
{ {

View File

@@ -83,6 +83,7 @@ private:
void RecacheGui(gui::TWidgetsInitInfo const & initInfo, bool needResetOldGui); void RecacheGui(gui::TWidgetsInitInfo const & initInfo, bool needResetOldGui);
void RecacheChoosePositionMark(); void RecacheChoosePositionMark();
void RecacheMapShapes(); void RecacheMapShapes();
void CleanupTextures();
#ifdef RENDER_DEBUG_INFO_LABELS #ifdef RENDER_DEBUG_INFO_LABELS
void RecacheDebugLabels(); void RecacheDebugLabels();

View File

@@ -441,11 +441,12 @@ void DrapeEngine::SetCompassInfo(location::CompassInfo const & info)
MessagePriority::Normal); MessagePriority::Normal);
} }
void DrapeEngine::SetGpsInfo(location::GpsInfo const & info, bool isNavigable, void DrapeEngine::SetGpsInfo(location::GpsInfo const & info, bool isNavigable, double distToNextTurn, double speedLimit,
location::RouteMatchingInfo const & routeInfo) location::RouteMatchingInfo const & routeInfo)
{ {
m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, m_threadCommutator->PostMessage(
make_unique_dp<GpsInfoMessage>(info, isNavigable, routeInfo), ThreadsCommutator::RenderThread,
make_unique_dp<GpsInfoMessage>(info, isNavigable, distToNextTurn, speedLimit, routeInfo),
MessagePriority::Normal); MessagePriority::Normal);
} }
@@ -896,10 +897,8 @@ void DrapeEngine::UpdateVisualScale(double vs, bool needStopRendering)
if (needStopRendering) if (needStopRendering)
SetRenderingEnabled(); SetRenderingEnabled();
RecacheGui(false); m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp<UpdateVisualScaleMessage>(),
RecacheMapShapes(); MessagePriority::High);
m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread,
make_unique_dp<RecoverContextDependentResourcesMessage>(), MessagePriority::Normal);
} }
void DrapeEngine::UpdateMyPositionRoutingOffset(bool useDefault, int offsetY) void DrapeEngine::UpdateMyPositionRoutingOffset(bool useDefault, int offsetY)

View File

@@ -154,7 +154,8 @@ public:
void UpdateMapStyle(); void UpdateMapStyle();
void SetCompassInfo(location::CompassInfo const & info); void SetCompassInfo(location::CompassInfo const & info);
void SetGpsInfo(location::GpsInfo const & info, bool isNavigable, location::RouteMatchingInfo const & routeInfo); void SetGpsInfo(location::GpsInfo const & info, bool isNavigable, double distToNextTurn, double speedLimit,
location::RouteMatchingInfo const & routeInfo);
void SwitchMyPositionNextMode(); void SwitchMyPositionNextMode();
void LoseLocation(); void LoseLocation();
void StopLocationFollow(); void StopLocationFollow();

View File

@@ -438,7 +438,8 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
break; break;
#endif #endif
ref_ptr<GpsInfoMessage> msg = message; ref_ptr<GpsInfoMessage> msg = message;
m_myPositionController->OnLocationUpdate(msg->GetInfo(), msg->IsNavigable(), m_userEventStream.GetCurrentScreen()); m_myPositionController->OnLocationUpdate(msg->GetInfo(), msg->IsNavigable(), msg->GetDistanceToNextTurn(),
msg->GetSpeedLimit(), m_userEventStream.GetCurrentScreen());
location::RouteMatchingInfo const & info = msg->GetRouteInfo(); location::RouteMatchingInfo const & info = msg->GetRouteInfo();
if (info.HasDistanceFromBegin()) if (info.HasDistanceFromBegin())
@@ -639,51 +640,11 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
break; break;
} }
case Message::Type::RecoverContextDependentResources: case Message::Type::RecoverContextDependentResources: UpdateContextDependentResources(); break;
{
UpdateContextDependentResources();
break;
}
case Message::Type::UpdateMapStyle: case Message::Type::UpdateMapStyle: UpdateAll<SwitchMapStyleMessage>(); break;
{
#ifdef BUILD_DESIGNER
classificator::Load();
#endif // BUILD_DESIGNER
// Clear all graphics. case Message::Type::VisualScaleChanged: UpdateAll<VisualScaleChangedMessage>(); break;
for (RenderLayer & layer : m_layers)
{
layer.m_renderGroups.clear();
layer.m_isDirty = false;
}
// Must be recreated on map style changing.
CHECK(m_context != nullptr, ());
m_transitBackground = make_unique_dp<ScreenQuadRenderer>(m_context);
// Invalidate read manager.
{
BaseBlockingMessage::Blocker blocker;
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
make_unique_dp<InvalidateReadManagerRectMessage>(blocker), MessagePriority::Normal);
blocker.Wait();
}
// Delete all messages which can contain render states (and textures references inside).
auto f = [this]() { InstantMessageFilter([](ref_ptr<Message> msg) { return msg->ContainsRenderState(); }); };
// Notify backend renderer and wait for completion.
{
BaseBlockingMessage::Blocker blocker;
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
make_unique_dp<SwitchMapStyleMessage>(blocker, std::move(f)), MessagePriority::Normal);
blocker.Wait();
}
UpdateContextDependentResources();
break;
}
case Message::Type::AllowAutoZoom: case Message::Type::AllowAutoZoom:
{ {
@@ -809,7 +770,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
zoom = scales::GetAddNewPlaceScale(); zoom = scales::GetAddNewPlaceScale();
AddUserEvent(make_unique_dp<SetCenterEvent>( AddUserEvent(make_unique_dp<SetCenterEvent>(
pt ? *pt : m_userEventStream.GetCurrentScreen().GlobalRect().Center(), zoom, true /* isAnim */, pt ? *pt : m_userEventStream.GetCurrentScreen().GlobalRect().Center(), zoom, true /* isAnim */,
false /* trackVisibleViewport */, nullptr /* parallelAnimCreator */)); true /* trackVisibleViewport */, nullptr /* parallelAnimCreator */));
} }
else else
{ {
@@ -1022,6 +983,46 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
} }
} }
template <class MessageT>
void FrontendRenderer::UpdateAll()
{
#ifdef BUILD_DESIGNER
classificator::Load();
#endif // BUILD_DESIGNER
// Clear all graphics.
for (RenderLayer & layer : m_layers)
{
layer.m_renderGroups.clear();
layer.m_isDirty = false;
}
// Must be recreated on map style changing.
CHECK(m_context != nullptr, ());
m_transitBackground = make_unique_dp<ScreenQuadRenderer>(m_context);
// Invalidate read manager.
{
BaseBlockingMessage::Blocker blocker;
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
make_unique_dp<InvalidateReadManagerRectMessage>(blocker), MessagePriority::Normal);
blocker.Wait();
}
// Delete all messages which can contain render states (and textures references inside).
auto f = [this]() { InstantMessageFilter([](ref_ptr<Message> msg) { return msg->ContainsRenderState(); }); };
// Notify backend renderer and wait for completion.
{
BaseBlockingMessage::Blocker blocker;
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp<MessageT>(blocker, std::move(f)),
MessagePriority::Normal);
blocker.Wait();
}
UpdateContextDependentResources();
}
std::unique_ptr<threads::IRoutine> FrontendRenderer::CreateRoutine() std::unique_ptr<threads::IRoutine> FrontendRenderer::CreateRoutine()
{ {
return std::make_unique<Routine>(*this); return std::make_unique<Routine>(*this);

View File

@@ -247,6 +247,9 @@ private:
void ReleaseResources(); void ReleaseResources();
void UpdateContextDependentResources(); void UpdateContextDependentResources();
template <class MessageT>
void UpdateAll();
void BeginUpdateOverlayTree(ScreenBase const & modelView); void BeginUpdateOverlayTree(ScreenBase const & modelView);
void UpdateOverlayTree(ScreenBase const & modelView, drape_ptr<RenderGroup> & renderGroup); void UpdateOverlayTree(ScreenBase const & modelView, drape_ptr<RenderGroup> & renderGroup);
void EndUpdateOverlayTree(); void EndUpdateOverlayTree();

View File

@@ -103,6 +103,7 @@ std::string DebugPrint(Message::Type msgType)
case Message::Type::EnableIsolines: return "EnableIsolines"; case Message::Type::EnableIsolines: return "EnableIsolines";
case Message::Type::OnEnterBackground: return "OnEnterBackground"; case Message::Type::OnEnterBackground: return "OnEnterBackground";
case Message::Type::Arrow3dRecache: return "Arrow3dRecache"; case Message::Type::Arrow3dRecache: return "Arrow3dRecache";
case Message::Type::VisualScaleChanged: return "VisualScaleChanged";
} }
ASSERT(false, ("Unknown message type.")); ASSERT(false, ("Unknown message type."));
return "Unknown type"; return "Unknown type";

View File

@@ -103,7 +103,8 @@ public:
NotifyGraphicsReady, NotifyGraphicsReady,
EnableIsolines, EnableIsolines,
OnEnterBackground, OnEnterBackground,
Arrow3dRecache Arrow3dRecache,
VisualScaleChanged,
}; };
virtual ~Message() = default; virtual ~Message() = default;

View File

@@ -1,7 +1,6 @@
#pragma once #pragma once
#include "drape_frontend/circles_pack_shape.hpp" #include "drape_frontend/circles_pack_shape.hpp"
#include "drape_frontend/color_constants.hpp"
#include "drape_frontend/custom_features_context.hpp" #include "drape_frontend/custom_features_context.hpp"
#include "drape_frontend/drape_api.hpp" #include "drape_frontend/drape_api.hpp"
#include "drape_frontend/drape_api_builder.hpp" #include "drape_frontend/drape_api_builder.hpp"
@@ -14,8 +13,7 @@
#include "drape_frontend/overlay_batcher.hpp" #include "drape_frontend/overlay_batcher.hpp"
#include "drape_frontend/postprocess_renderer.hpp" #include "drape_frontend/postprocess_renderer.hpp"
#include "drape_frontend/render_node.hpp" #include "drape_frontend/render_node.hpp"
#include "drape_frontend/render_state_extension.hpp" #include "drape_frontend/route_shape.hpp"
#include "drape_frontend/route_builder.hpp"
#include "drape_frontend/selection_shape.hpp" #include "drape_frontend/selection_shape.hpp"
#include "drape_frontend/tile_utils.hpp" #include "drape_frontend/tile_utils.hpp"
#include "drape_frontend/traffic_generator.hpp" #include "drape_frontend/traffic_generator.hpp"
@@ -26,13 +24,10 @@
#include "drape/pointers.hpp" #include "drape/pointers.hpp"
#include "drape/render_bucket.hpp" #include "drape/render_bucket.hpp"
#include "drape/viewport.hpp"
#include "platform/location.hpp" #include "platform/location.hpp"
#include "geometry/polyline2d.hpp"
#include "geometry/rect2d.hpp" #include "geometry/rect2d.hpp"
#include "geometry/screenbase.hpp"
#include "geometry/triangle2d.hpp" #include "geometry/triangle2d.hpp"
#include <condition_variable> #include <condition_variable>
@@ -40,7 +35,6 @@
#include <map> #include <map>
#include <mutex> #include <mutex>
#include <optional> #include <optional>
#include <utility>
#include <vector> #include <vector>
namespace df namespace df
@@ -481,9 +475,12 @@ private:
class GpsInfoMessage : public Message class GpsInfoMessage : public Message
{ {
public: public:
GpsInfoMessage(location::GpsInfo const & info, bool isNavigable, location::RouteMatchingInfo const & routeInfo) GpsInfoMessage(location::GpsInfo const & info, bool isNavigable, double distToNextTurn, double speedLimit,
location::RouteMatchingInfo const & routeInfo)
: m_info(info) : m_info(info)
, m_isNavigable(isNavigable) , m_isNavigable(isNavigable)
, m_distToNextTurn(distToNextTurn)
, m_speedLimit(speedLimit)
, m_routeInfo(routeInfo) , m_routeInfo(routeInfo)
{} {}
@@ -491,11 +488,15 @@ public:
location::GpsInfo const & GetInfo() const { return m_info; } location::GpsInfo const & GetInfo() const { return m_info; }
bool IsNavigable() const { return m_isNavigable; } 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; } location::RouteMatchingInfo const & GetRouteInfo() const { return m_routeInfo; }
private: private:
location::GpsInfo const m_info; location::GpsInfo const m_info;
bool const m_isNavigable; bool const m_isNavigable;
double const m_distToNextTurn;
double const m_speedLimit;
location::RouteMatchingInfo const m_routeInfo; location::RouteMatchingInfo const m_routeInfo;
}; };
@@ -730,6 +731,12 @@ public:
Type GetType() const override { return Type::UpdateMapStyle; } Type GetType() const override { return Type::UpdateMapStyle; }
}; };
class UpdateVisualScaleMessage : public Message
{
public:
Type GetType() const override { return Type::VisualScaleChanged; }
};
class FollowRouteMessage : public Message class FollowRouteMessage : public Message
{ {
public: public:
@@ -776,6 +783,14 @@ private:
FilterMessagesHandler m_filterMessagesHandler; FilterMessagesHandler m_filterMessagesHandler;
}; };
class VisualScaleChangedMessage : public SwitchMapStyleMessage
{
public:
using SwitchMapStyleMessage::SwitchMapStyleMessage;
Type GetType() const override { return Type::VisualScaleChanged; }
};
class InvalidateMessage : public Message class InvalidateMessage : public Message
{ {
public: public:

View File

@@ -56,32 +56,18 @@ inline double GetVisualScale()
return df::VisualParams::Instance().GetVisualScale(); return df::VisualParams::Instance().GetVisualScale();
} }
// Calculate zoom value in meters per pixel double CalculateZoomByMaxSpeed(double speedMpS, bool isPerspectiveAllowed)
double CalculateZoomBySpeed(double speedMpS, bool isPerspectiveAllowed)
{ {
using TSpeedScale = std::pair<double, double>; using TSpeedScale = std::pair<double, double>;
static std::array<TSpeedScale, 6> const scales3d = {{ static std::array<TSpeedScale, 2> const scales2d = {{
{20.0, 0.25}, {0.0, 1.75}, {77.0, 4.50} // 48 mph
{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}}};
static std::array<TSpeedScale, 6> const scales2d = {{ std::array<TSpeedScale, 2> const & scales = isPerspectiveAllowed ? scales3d : 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},
}};
std::array<TSpeedScale, 6> const & scales = isPerspectiveAllowed ? scales3d : scales2d; double constexpr kDefaultSpeedLimitKmpH = 50.0;
double const speedKmpH = speedMpS > 0 ? measurement_utils::MpsToKmph(speedMpS) : kDefaultSpeedLimitKmpH;
double constexpr kDefaultSpeedKmpH = 80.0;
double const speedKmpH = speedMpS >= 0 ? measurement_utils::MpsToKmph(speedMpS) : kDefaultSpeedKmpH;
size_t i = 0; size_t i = 0;
for (size_t sz = scales.size(); i < sz; ++i) for (size_t sz = scales.size(); i < sz; ++i)
@@ -92,20 +78,64 @@ double CalculateZoomBySpeed(double speedMpS, bool isPerspectiveAllowed)
if (i == 0) if (i == 0)
return scales.front().second / vs; return scales.front().second / vs;
if (i == scales.size())
return scales.back().second / vs;
double const minSpeed = scales[i - 1].first; return scales[i - 1].second / vs;
double const maxSpeed = scales[i].first; }
double const k = (speedKmpH - minSpeed) / (maxSpeed - minSpeed);
double const minScale = scales[i - 1].second; double CalculateZoomByDistanceToTurn(double distance, bool isPerspectiveAllowed)
double const maxScale = scales[i].second; {
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 zoom = minScale + k * (maxScale - minScale); double const zoom = minScale + k * (maxScale - minScale);
return zoom / vs; 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) void ResetNotification(uint64_t & notifyId)
{ {
notifyId = DrapeNotifier::kInvalidId; notifyId = DrapeNotifier::kInvalidId;
@@ -395,7 +425,8 @@ void MyPositionController::NextMode(ScreenBase const & screen)
} }
} }
void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool isNavigable, ScreenBase const & screen) void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool isNavigable, double distanceToNextTurn,
double speedLimit, ScreenBase const & screen)
{ {
m2::PointD const oldPos = GetDrawablePosition(); m2::PointD const oldPos = GetDrawablePosition();
double const oldAzimut = GetDrawableAzimut(); double const oldAzimut = GetDrawableAzimut();
@@ -407,11 +438,13 @@ void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool
m_errorRadius = rect.SizeX() * 0.5; m_errorRadius = rect.SizeX() * 0.5;
m_horizontalAccuracy = info.m_horizontalAccuracy; m_horizontalAccuracy = info.m_horizontalAccuracy;
if (info.m_speed > 0.0) if (distanceToNextTurn >= 0.0 || speedLimit >= 0.0)
{ {
double const mercatorPerMeter = m_errorRadius / info.m_horizontalAccuracy; double const mercatorPerMeter = m_errorRadius / info.m_horizontalAccuracy;
m_autoScale2d = mercatorPerMeter * CalculateZoomBySpeed(info.m_speed, false /* isPerspectiveAllowed */); m_autoScale2d =
m_autoScale3d = mercatorPerMeter * CalculateZoomBySpeed(info.m_speed, true /* isPerspectiveAllowed */); mercatorPerMeter * CalculateAutoZoom(speedLimit, distanceToNextTurn, false /* isPerspectiveAllowed */);
m_autoScale3d =
mercatorPerMeter * CalculateAutoZoom(speedLimit, distanceToNextTurn, true /* isPerspectiveAllowed */);
} }
else else
{ {

View File

@@ -117,7 +117,8 @@ public:
void OnEnterBackground(); void OnEnterBackground();
void OnCompassTapped(); void OnCompassTapped();
void OnLocationUpdate(location::GpsInfo const & info, bool isNavigable, ScreenBase const & screen); void OnLocationUpdate(location::GpsInfo const & info, bool isNavigable, double distanceToNextTurn, double speedLimit,
ScreenBase const & screen);
void OnCompassUpdate(location::CompassInfo const & info, 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, void Render(ref_ptr<dp::GraphicsContext> context, ref_ptr<gpu::ProgramManager> mng, ScreenBase const & screen,

View File

@@ -4,14 +4,8 @@
#include "indexer/scales.hpp" #include "indexer/scales.hpp"
#include "platform/settings.hpp"
#include "geometry/angles.hpp" #include "geometry/angles.hpp"
#include "geometry/distance_on_sphere.hpp"
#include "geometry/point2d.hpp" #include "geometry/point2d.hpp"
#include "geometry/transformations.hpp"
#include "base/logging.hpp"
namespace df namespace df
{ {

View File

@@ -2,8 +2,6 @@
#include "geometry/screenbase.hpp" #include "geometry/screenbase.hpp"
#include "base/matrix.hpp"
namespace df namespace df
{ {
extern double const kDefault3dScale; extern double const kDefault3dScale;

View File

@@ -1,9 +1,5 @@
#include "screen_operations.hpp" #include "screen_operations.hpp"
#include "drape_frontend/animation/interpolators.hpp"
#include "drape_frontend/animation/linear_animation.hpp"
#include "drape_frontend/animation/scale_animation.hpp"
#include "drape_frontend/animation_constants.hpp"
#include "drape_frontend/visual_params.hpp" #include "drape_frontend/visual_params.hpp"
#include "indexer/scales.hpp" #include "indexer/scales.hpp"

View File

@@ -1,5 +1,9 @@
#include "drape_frontend/visual_params.hpp" #include "drape_frontend/visual_params.hpp"
#include "indexer/scales.hpp"
#include "coding/point_coding.hpp" // kMwmPointAccuracy
#include "geometry/mercator.hpp" #include "geometry/mercator.hpp"
#include "base/assert.hpp" #include "base/assert.hpp"
@@ -12,21 +16,11 @@
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <limits> #include <limits>
#include <utility>
namespace df namespace df
{ {
using VisualScale = std::pair<std::string, double>; using VisualScale = std::pair<std::string, double>;
#ifdef DEBUG
static bool g_isInited = false;
#define RISE_INITED g_isInited = true
#define ASSERT_INITED ASSERT(g_isInited, ())
#else
#define RISE_INITED
#define ASSERT_INITED
#endif
VisualParams & VisualParams::Instance() VisualParams & VisualParams::Instance()
{ {
static VisualParams vizParams; static VisualParams vizParams;
@@ -35,7 +29,8 @@ VisualParams & VisualParams::Instance()
void VisualParams::Init(double vs, uint32_t tileSize) void VisualParams::Init(double vs, uint32_t tileSize)
{ {
ASSERT_LESS_OR_EQUAL(vs, kMaxVisualScale, ()); CHECK(vs >= 1.0 && vs <= kMaxVisualScale, (vs));
CHECK(tileSize >= 32, (tileSize));
VisualParams & vizParams = Instance(); VisualParams & vizParams = Instance();
vizParams.m_tileSize = tileSize; vizParams.m_tileSize = tileSize;
@@ -47,35 +42,34 @@ void VisualParams::Init(double vs, uint32_t tileSize)
else else
vizParams.m_glyphVisualParams = {0.5f, 0.06f, 0.2f, 0.01f, 0.49f, 0.04f}; vizParams.m_glyphVisualParams = {0.5f, 0.06f, 0.2f, 0.01f, 0.49f, 0.04f};
RISE_INITED; vizParams.m_isInited = true;
LOG(LINFO, ("Visual scale =", vs, "; Tile size =", tileSize, "; Resources =", GetResourcePostfix(vs))); LOG(LINFO, ("Visual scale =", vs, "; Tile size =", tileSize, "; Resources =", GetResourcePostfix(vs)));
} }
double VisualParams::GetFontScale() const double VisualParams::GetFontScale() const
{ {
ASSERT_INITED; ASSERT(m_isInited, ());
return m_fontScale; return m_fontScale;
} }
void VisualParams::SetFontScale(double fontScale) void VisualParams::SetFontScale(double fontScale)
{ {
ASSERT_INITED; ASSERT(m_isInited, ());
m_fontScale = math::Clamp(fontScale, 0.5, 2.0); m_fontScale = math::Clamp(fontScale, 0.5, 2.0);
} }
void VisualParams::SetVisualScale(double visualScale) void VisualParams::SetVisualScale(double vs)
{ {
ASSERT_INITED; ASSERT(m_isInited, ());
ASSERT_LESS_OR_EQUAL(visualScale, kMaxVisualScale, ()); CHECK(vs >= 1.0 && vs <= kMaxVisualScale, (vs));
m_visualScale = visualScale; m_visualScale = vs;
LOG(LINFO, ("Visual scale =", visualScale)); LOG(LINFO, ("Visual scale =", vs));
} }
std::string const & VisualParams::GetResourcePostfix(double visualScale) std::string const & VisualParams::GetResourcePostfix(double visualScale)
{ {
ASSERT_INITED;
static VisualScale postfixes[] = { static VisualScale postfixes[] = {
/// @todo Not used in mobile because of minimal visual scale (@see visual_scale.hpp) /// @todo Not used in mobile because of minimal visual scale (@see visual_scale.hpp)
{"mdpi", kMdpiScale}, {"mdpi", kMdpiScale},
@@ -103,52 +97,61 @@ std::string const & VisualParams::GetResourcePostfix(double visualScale)
std::string const & VisualParams::GetResourcePostfix() const std::string const & VisualParams::GetResourcePostfix() const
{ {
ASSERT_INITED; ASSERT(m_isInited, ());
return VisualParams::GetResourcePostfix(m_visualScale); return VisualParams::GetResourcePostfix(m_visualScale);
} }
double VisualParams::GetVisualScale() const double VisualParams::GetVisualScale() const
{ {
ASSERT_INITED; ASSERT(m_isInited, ());
return m_visualScale; return m_visualScale;
} }
double VisualParams::GetPoiExtendScale() const
{
ASSERT_INITED;
return m_poiExtendScale;
}
uint32_t VisualParams::GetTileSize() const uint32_t VisualParams::GetTileSize() const
{ {
ASSERT_INITED; CHECK(m_isInited, ());
return m_tileSize; return m_tileSize;
} }
uint32_t VisualParams::GetTouchRectRadius() const uint32_t VisualParams::GetTouchRectRadius() const
{ {
<<<<<<< HEAD
ASSERT_INITED; ASSERT_INITED;
float constexpr kRadiusInPixels = 20.0f; float constexpr kRadiusInPixels = 20.0f;
=======
ASSERT(m_isInited, ());
float const kRadiusInPixels = 20.0f;
>>>>>>> 9cff373c8 ([drape] Refactor VisualParams.)
return static_cast<uint32_t>(kRadiusInPixels * GetVisualScale()); return static_cast<uint32_t>(kRadiusInPixels * GetVisualScale());
} }
double VisualParams::GetDragThreshold() const double VisualParams::GetDragThreshold() const
{ {
<<<<<<< HEAD
ASSERT_INITED; ASSERT_INITED;
double constexpr kDragThresholdInPixels = 10.0; double constexpr kDragThresholdInPixels = 10.0;
=======
ASSERT(m_isInited, ());
double const kDragThresholdInPixels = 10.0;
>>>>>>> 9cff373c8 ([drape] Refactor VisualParams.)
return kDragThresholdInPixels * GetVisualScale(); return kDragThresholdInPixels * GetVisualScale();
} }
double VisualParams::GetScaleThreshold() const double VisualParams::GetScaleThreshold() const
{ {
<<<<<<< HEAD
ASSERT_INITED; ASSERT_INITED;
double constexpr kScaleThresholdInPixels = 2.0; double constexpr kScaleThresholdInPixels = 2.0;
=======
ASSERT(m_isInited, ());
double const kScaleThresholdInPixels = 2.0;
>>>>>>> 9cff373c8 ([drape] Refactor VisualParams.)
return kScaleThresholdInPixels * GetVisualScale(); return kScaleThresholdInPixels * GetVisualScale();
} }
VisualParams::GlyphVisualParams const & VisualParams::GetGlyphVisualParams() const VisualParams::GlyphVisualParams const & VisualParams::GetGlyphVisualParams() const
{ {
ASSERT_INITED; ASSERT(m_isInited, ());
return m_glyphVisualParams; return m_glyphVisualParams;
} }
@@ -178,8 +181,7 @@ int GetTileScaleBase(ScreenBase const & s)
int GetTileScaleBase(m2::RectD const & r) int GetTileScaleBase(m2::RectD const & r)
{ {
double const sz = std::max(r.SizeX(), r.SizeY()); double const sz = std::max(std::max(r.SizeX(), r.SizeY()), kMwmPointAccuracy);
ASSERT_GREATER(sz, 0., ("Rect should not be a point:", r));
return std::max(1, math::iround(std::log2(mercator::Bounds::kRangeX / sz))); return std::max(1, math::iround(std::log2(mercator::Bounds::kRangeX / sz)));
} }
@@ -190,7 +192,7 @@ double GetTileScaleBase(double drawScale)
int GetTileScaleIncrement(uint32_t tileSize, double visualScale) int GetTileScaleIncrement(uint32_t tileSize, double visualScale)
{ {
return static_cast<int>(std::log2(tileSize / 256.0 / visualScale)); return math::iround(std::log2(tileSize / 256.0 / visualScale));
} }
int GetTileScaleIncrement() int GetTileScaleIncrement()
@@ -257,10 +259,18 @@ uint32_t CalculateTileSize(uint32_t screenWidth, uint32_t screenHeight)
#endif #endif
} }
namespace
{
double GetDrawTileScale(double baseScale)
{
return baseScale + GetTileScaleIncrement();
}
int GetDrawTileScale(int baseScale, uint32_t tileSize, double visualScale) int GetDrawTileScale(int baseScale, uint32_t tileSize, double visualScale)
{ {
return std::max(1, baseScale + GetTileScaleIncrement(tileSize, visualScale)); return baseScale + GetTileScaleIncrement(tileSize, visualScale);
} }
} // namespace
int GetDrawTileScale(ScreenBase const & s, uint32_t tileSize, double visualScale) int GetDrawTileScale(ScreenBase const & s, uint32_t tileSize, double visualScale)
{ {
@@ -272,17 +282,6 @@ int GetDrawTileScale(m2::RectD const & r, uint32_t tileSize, double visualScale)
return GetDrawTileScale(GetTileScaleBase(r), tileSize, visualScale); return GetDrawTileScale(GetTileScaleBase(r), tileSize, visualScale);
} }
int GetDrawTileScale(int baseScale)
{
VisualParams const & p = VisualParams::Instance();
return GetDrawTileScale(baseScale, p.GetTileSize(), p.GetVisualScale());
}
double GetDrawTileScale(double baseScale)
{
return std::max(1.0, baseScale + GetTileScaleIncrement());
}
int GetDrawTileScale(ScreenBase const & s) int GetDrawTileScale(ScreenBase const & s)
{ {
VisualParams const & p = VisualParams::Instance(); VisualParams const & p = VisualParams::Instance();

View File

@@ -1,15 +1,10 @@
#pragma once #pragma once
#include "indexer/scales.hpp"
#include "geometry/rect2d.hpp" #include "geometry/rect2d.hpp"
#include "geometry/screenbase.hpp" #include "geometry/screenbase.hpp"
#include "base/macros.hpp" #include "base/macros.hpp"
#include <atomic>
#include <cstdint>
#include <string> #include <string>
#include <vector>
namespace df namespace df
{ {
@@ -36,8 +31,6 @@ public:
std::string const & GetResourcePostfix() const; std::string const & GetResourcePostfix() const;
double GetVisualScale() const; double GetVisualScale() const;
/// This is a scale factor to decrease extending of bbox for POI icons. It could be removed with new style
double GetPoiExtendScale() const;
uint32_t GetTileSize() const; uint32_t GetTileSize() const;
/// How many pixels around touch point are used to get bookmark or POI in consideration of visual scale. /// How many pixels around touch point are used to get bookmark or POI in consideration of visual scale.
@@ -62,7 +55,7 @@ public:
void SetFontScale(double fontScale); void SetFontScale(double fontScale);
// This method can be called ONLY if rendering is disabled. // This method can be called ONLY if rendering is disabled.
void SetVisualScale(double visualScale); void SetVisualScale(double vs);
private: private:
VisualParams() = default; VisualParams() = default;
@@ -71,8 +64,8 @@ private:
uint32_t m_tileSize = 0; uint32_t m_tileSize = 0;
double m_visualScale = 0.0; double m_visualScale = 0.0;
double m_poiExtendScale = 0.1; // Found empirically. double m_fontScale = 1.0;
std::atomic<double> m_fontScale = 1.0; bool m_isInited = false;
DISALLOW_COPY_AND_MOVE(VisualParams); DISALLOW_COPY_AND_MOVE(VisualParams);
}; };
@@ -89,11 +82,8 @@ double GetTileScaleBase(double drawScale);
int GetTileScaleIncrement(uint32_t tileSize, double visualScale); int GetTileScaleIncrement(uint32_t tileSize, double visualScale);
int GetTileScaleIncrement(); int GetTileScaleIncrement();
int GetDrawTileScale(int baseScale, uint32_t tileSize, double visualScale);
int GetDrawTileScale(ScreenBase const & s, uint32_t tileSize, double visualScale); int GetDrawTileScale(ScreenBase const & s, uint32_t tileSize, double visualScale);
int GetDrawTileScale(m2::RectD const & r, uint32_t tileSize, double visualScale); int GetDrawTileScale(m2::RectD const & r, uint32_t tileSize, double visualScale);
int GetDrawTileScale(int baseScale);
double GetDrawTileScale(double baseScale);
int GetDrawTileScale(ScreenBase const & s); int GetDrawTileScale(ScreenBase const & s);
int GetDrawTileScale(m2::RectD const & r); int GetDrawTileScale(m2::RectD const & r);

View File

@@ -5,8 +5,6 @@ set(SRC
altitude_loader.hpp altitude_loader.hpp
brands_holder.cpp brands_holder.cpp
brands_holder.hpp brands_holder.hpp
caching_rank_table_loader.cpp
caching_rank_table_loader.hpp
categories_holder.cpp categories_holder.cpp
categories_holder.hpp categories_holder.hpp
categories_holder_loader.cpp categories_holder_loader.cpp
@@ -155,7 +153,6 @@ file(COPY ${OTHER_FILES} DESTINATION ${CMAKE_BINARY_DIR})
omim_add_library(${PROJECT_NAME} ${SRC}) omim_add_library(${PROJECT_NAME} ${SRC})
target_link_libraries(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME}
search # search::DummyRankTable in CachingRankTableLoader
platform platform
geometry geometry
protobuf protobuf

View File

@@ -1,45 +0,0 @@
#include "indexer/caching_rank_table_loader.hpp"
#include "search/dummy_rank_table.hpp"
#include "indexer/data_source.hpp"
CachingRankTableLoader::CachingRankTableLoader(DataSource const & dataSource, std::string const & sectionName)
: m_dataSource(dataSource)
, m_sectionName(sectionName)
{}
uint8_t CachingRankTableLoader::Get(FeatureID const & featureId) const
{
auto const handle = m_dataSource.GetMwmHandleById(featureId.m_mwmId);
if (!handle.IsAlive())
return search::RankTable::kNoRank;
auto it = m_deserializers.find(featureId.m_mwmId);
if (it == m_deserializers.end())
{
auto rankTable = search::RankTable::Load(handle.GetValue()->m_cont, m_sectionName);
if (!rankTable)
rankTable = std::make_unique<search::DummyRankTable>();
auto const result = m_deserializers.emplace(featureId.m_mwmId, std::move(rankTable));
it = result.first;
}
return it->second->Get(featureId.m_index);
}
void CachingRankTableLoader::OnMwmDeregistered(platform::LocalCountryFile const & localFile)
{
for (auto it = m_deserializers.begin(); it != m_deserializers.end(); ++it)
{
if (it->first.IsDeregistered(localFile))
{
m_deserializers.erase(it);
return;
}
}
}

View File

@@ -1,32 +0,0 @@
#pragma once
#include "indexer/feature_decl.hpp"
#include "indexer/mwm_set.hpp"
#include "indexer/rank_table.hpp"
#include "base/macros.hpp"
#include <map>
#include <memory>
#include <string>
class DataSource;
struct FeatureID;
// *NOTE* This class IS NOT thread-safe.
class CachingRankTableLoader
{
public:
CachingRankTableLoader(DataSource const & dataSource, std::string const & sectionName);
/// @return 0 if there is no rank for feature.
uint8_t Get(FeatureID const & featureId) const;
void OnMwmDeregistered(platform::LocalCountryFile const & localFile);
private:
DataSource const & m_dataSource;
std::string const m_sectionName;
mutable std::map<MwmSet::MwmId, std::unique_ptr<search::RankTable>> m_deserializers;
DISALLOW_COPY(CachingRankTableLoader);
};

View File

@@ -276,7 +276,6 @@ Framework::Framework(FrameworkParams const & params, bool loadMaps)
, m_trafficManager(bind(&Framework::GetMwmsByRect, this, _1, false /* rough */), kMaxTrafficCacheSizeBytes, , m_trafficManager(bind(&Framework::GetMwmsByRect, this, _1, false /* rough */), kMaxTrafficCacheSizeBytes,
m_routingManager.RoutingSession()) m_routingManager.RoutingSession())
, m_lastReportedCountry(kInvalidCountryId) , m_lastReportedCountry(kInvalidCountryId)
, m_popularityLoader(m_featuresFetcher.GetDataSource(), POPULARITY_RANKS_FILE_TAG)
, m_descriptionsLoader(std::make_unique<descriptions::Loader>(m_featuresFetcher.GetDataSource())) , m_descriptionsLoader(std::make_unique<descriptions::Loader>(m_featuresFetcher.GetDataSource()))
{ {
// Editor should be initialized from the main thread to set its ThreadChecker. // Editor should be initialized from the main thread to set its ThreadChecker.
@@ -445,7 +444,7 @@ void Framework::OnMapDeregistered(platform::LocalCountryFile const & localFile)
m_transitManager.OnMwmDeregistered(localFile); m_transitManager.OnMwmDeregistered(localFile);
m_isolinesManager.OnMwmDeregistered(localFile); m_isolinesManager.OnMwmDeregistered(localFile);
m_trafficManager.OnMwmDeregistered(localFile); m_trafficManager.OnMwmDeregistered(localFile);
m_popularityLoader.OnMwmDeregistered(localFile); m_descriptionsLoader->OnMwmDeregistered(localFile);
m_storage.DeleteCustomCountryVersion(localFile); m_storage.DeleteCustomCountryVersion(localFile);
}; };
@@ -3072,10 +3071,6 @@ osm::Editor::SaveResult Framework::SaveEditedMapObject(osm::EditableMapObject em
auto const result = osm::Editor::Instance().SaveEditedFeature(emo); auto const result = osm::Editor::Instance().SaveEditedFeature(emo);
// Automatically select newly created and edited objects.
if (m_currentPlacePageInfo)
DeactivateMapSelection();
place_page::BuildInfo info; place_page::BuildInfo info;
info.m_mercator = emo.GetMercator(); info.m_mercator = emo.GetMercator();
info.m_featureId = emo.GetID(); info.m_featureId = emo.GetID();

View File

@@ -32,7 +32,6 @@
#include "editor/new_feature_categories.hpp" #include "editor/new_feature_categories.hpp"
#include "editor/osm_editor.hpp" #include "editor/osm_editor.hpp"
#include "indexer/caching_rank_table_loader.hpp"
#include "indexer/data_source.hpp" #include "indexer/data_source.hpp"
#include "indexer/data_source_helpers.hpp" #include "indexer/data_source_helpers.hpp"
#include "indexer/map_object.hpp" #include "indexer/map_object.hpp"
@@ -484,8 +483,6 @@ private:
TrackRecordingUpdateHandler m_trackRecordingUpdateHandler; TrackRecordingUpdateHandler m_trackRecordingUpdateHandler;
CachingRankTableLoader m_popularityLoader;
std::unique_ptr<descriptions::Loader> m_descriptionsLoader; std::unique_ptr<descriptions::Loader> m_descriptionsLoader;
public: public:

View File

@@ -1171,6 +1171,7 @@ void RoutingManager::SetDrapeEngine(ref_ptr<df::DrapeEngine> engine, bool is3dAl
{ {
auto routeMatchingInfo = GetRouteMatchingInfo(*m_gpsInfoCache); auto routeMatchingInfo = GetRouteMatchingInfo(*m_gpsInfoCache);
m_drapeEngine.SafeCall(&df::DrapeEngine::SetGpsInfo, *m_gpsInfoCache, m_routingSession.IsNavigable(), m_drapeEngine.SafeCall(&df::DrapeEngine::SetGpsInfo, *m_gpsInfoCache, m_routingSession.IsNavigable(),
m_routingSession.GetDistanceToNextTurn(), m_routingSession.GetCurrentSpeedLimit(),
routeMatchingInfo); routeMatchingInfo);
m_gpsInfoCache.reset(); m_gpsInfoCache.reset();
} }
@@ -1515,7 +1516,9 @@ void RoutingManager::OnExtrapolatedLocationUpdate(location::GpsInfo const & info
m_gpsInfoCache = make_unique<location::GpsInfo>(gpsInfo); m_gpsInfoCache = make_unique<location::GpsInfo>(gpsInfo);
auto routeMatchingInfo = GetRouteMatchingInfo(gpsInfo); auto routeMatchingInfo = GetRouteMatchingInfo(gpsInfo);
m_drapeEngine.SafeCall(&df::DrapeEngine::SetGpsInfo, gpsInfo, m_routingSession.IsNavigable(), routeMatchingInfo); m_drapeEngine.SafeCall(&df::DrapeEngine::SetGpsInfo, gpsInfo, m_routingSession.IsNavigable(),
m_routingSession.GetDistanceToNextTurn(), m_routingSession.GetCurrentSpeedLimit(),
routeMatchingInfo);
} }
void RoutingManager::DeleteSavedRoutePoints() void RoutingManager::DeleteSavedRoutePoints()

View File

@@ -57,5 +57,16 @@ std::string DebugPrint(ScopedDir const & dir)
os << "ScopedDir [" << dir.GetFullPath() << "]"; os << "ScopedDir [" << dir.GetFullPath() << "]";
return os.str(); return os.str();
} }
ScopedDirCleanup::ScopedDirCleanup(std::string const & path) : m_fullPath(path)
{
UNUSED_VALUE(Platform::MkDir(m_fullPath));
}
ScopedDirCleanup::~ScopedDirCleanup()
{
UNUSED_VALUE(Platform::RmDirRecursively(m_fullPath));
}
} // namespace tests_support } // namespace tests_support
} // namespace platform } // namespace platform

View File

@@ -38,6 +38,15 @@ private:
DISALLOW_COPY_AND_MOVE(ScopedDir); DISALLOW_COPY_AND_MOVE(ScopedDir);
}; };
class ScopedDirCleanup
{
std::string const m_fullPath;
public:
explicit ScopedDirCleanup(std::string const & path);
~ScopedDirCleanup();
};
std::string DebugPrint(ScopedDir const & dir); std::string DebugPrint(ScopedDir const & dir);
} // namespace tests_support } // namespace tests_support
} // namespace platform } // namespace platform

View File

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

View File

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

View File

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

View File

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

View File

@@ -363,6 +363,32 @@ 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 void RoutingSession::GetRouteFollowingInfo(FollowingInfo & info) const
{ {
CHECK_THREAD_CHECKER(m_threadChecker, ()); CHECK_THREAD_CHECKER(m_threadChecker, ());
@@ -392,14 +418,7 @@ void RoutingSession::GetRouteFollowingInfo(FollowingInfo & info) const
info.m_distToTurn = platform::Distance::CreateFormatted(distanceToTurnMeters); info.m_distToTurn = platform::Distance::CreateFormatted(distanceToTurnMeters);
info.m_turn = turn.m_turn; info.m_turn = turn.m_turn;
SpeedInUnits speedLimit; info.m_speedLimitMps = GetCurrentSpeedLimit();
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. // The turn after the next one.
if (m_routingSettings.m_showTurnAfterNext) if (m_routingSettings.m_showTurnAfterNext)

View File

@@ -100,6 +100,8 @@ public:
SessionState OnLocationPositionChanged(location::GpsInfo const & info); SessionState OnLocationPositionChanged(location::GpsInfo const & info);
void GetRouteFollowingInfo(FollowingInfo & info) const; void GetRouteFollowingInfo(FollowingInfo & info) const;
double GetDistanceToNextTurn() const;
double GetCurrentSpeedLimit() const;
bool MatchLocationToRoute(location::GpsInfo & location, location::RouteMatchingInfo & routeMatchingInfo); bool MatchLocationToRoute(location::GpsInfo & location, location::RouteMatchingInfo & routeMatchingInfo);
void MatchLocationToRoadGraph(location::GpsInfo & location); 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 // ./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/$/,/' | // tail -n +2 numbers.txt | head -78 | sed 's/^.*) \(.*\) \[.*$/"\1"/g;s/[ -/]//g;s/$/,/' |
// sort | uniq // sort | uniq
vector<string> const g_patterns = {"BL", "BLN", "BLNSL", "BN", "BNL", "BNSL", "L", "LL", "LN", "LNL", "LNLN", "LNN", array<string_view, 48> constexpr 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", "N", "NBL", "NBLN", "NBN", "NBNBN", "NBNL", "NL", "NLBN", "NLL", "NLLN", "NLN",
"NLNL", "NLS", "NLSN", "NN", "NNBN", "NNL", "NNLN", "NNN", "NNS", "NS", "NSN", "NSS", "NLNL", "NLS", "NLSN", "NN", "NNBN", "NNL", "NNLN", "NNN", "NNS", "NS", "NSN", "NSS",
"S", "SL", "SLL", "SLN", "SN", "SNBNSS", "SNL", "SNN", "SS", "SSN", "SSS", "SSSS", "S", "SL", "SLL", "SLN", "SN", "SNBNSS", "SNL", "SNN", "SS", "SSN", "SSS", "SSSS",
@@ -85,13 +85,14 @@ vector<string> const g_patterns = {"BL", "BLN", "BLNSL", "BN", "BNL", "BNSL", "L
"NNBNL"}; "NNBNL"};
// List of patterns which look like house numbers more than other patterns. Constructed by hand. // List of patterns which look like house numbers more than other patterns. Constructed by hand.
vector<string> const g_patternsStrict = {"N", "NBN", "NBL", "NL"}; array<string_view, 4> constexpr g_patternsStrict = {"N", "NBN", "NBL", "NL"};
// List of common synonyms for building parts. Constructed by hand. // List of common synonyms for building parts. Constructed by hand.
char const * g_buildingPartSynonyms[] = {"building", "bldg", "bld", "bl", "unit", "block", "blk", "корпус", char const * g_buildingPartSynonyms[] = {"building", "bldg", "bld", "bl", "unit", "block", "blk", "корпус",
"корп", "кор", "литер", "лит", "строение", "стр", "блок", "бл"}; "корп", "кор", "литер", "лит", "строение", "стр", "блок", "бл"};
// List of common stop words for buildings. Constructed by hand. // List of common stop words for buildings. Constructed by hand.
// TODO: add more stop words?
UniString const g_stopWords[] = {MakeUniString("дом"), MakeUniString("house"), MakeUniString("д")}; UniString const g_stopWords[] = {MakeUniString("дом"), MakeUniString("house"), MakeUniString("д")};
bool IsStopWord(UniString const & s, bool isPrefix) bool IsStopWord(UniString const & s, bool isPrefix)
@@ -167,7 +168,8 @@ class HouseNumberClassifier
public: public:
using Patterns = StringSet<Token::Type, 4>; using Patterns = StringSet<Token::Type, 4>;
HouseNumberClassifier(vector<string> const & patterns = g_patterns) template <size_t size>
HouseNumberClassifier(array<string_view, size> const & patterns)
{ {
for (auto const & p : patterns) for (auto const & p : patterns)
m_patterns.Add(make_transform_iterator(p.begin(), &CharToType), make_transform_iterator(p.end(), &CharToType)); m_patterns.Add(make_transform_iterator(p.begin(), &CharToType), make_transform_iterator(p.end(), &CharToType));
@@ -590,7 +592,7 @@ bool HouseNumbersMatchRange(std::string_view const & hnRange, TokensT const & qu
bool LooksLikeHouseNumber(UniString const & s, bool isPrefix) bool LooksLikeHouseNumber(UniString const & s, bool isPrefix)
{ {
static HouseNumberClassifier const classifier; static HouseNumberClassifier const classifier(g_patterns);
return classifier.LooksGood(s, isPrefix); return classifier.LooksGood(s, isPrefix);
} }

View File

@@ -298,7 +298,6 @@ void LocalityScorer::GetDocVecs(uint32_t localityId, vector<DocVec> & dvs) const
DocVec::Builder builder; DocVec::Builder builder;
ForEachNormalizedToken(name, [&](strings::UniString const & token) ForEachNormalizedToken(name, [&](strings::UniString const & token)
{ {
if (!IsStopWord(token))
builder.Add(token); builder.Add(token);
}); });
dvs.emplace_back(std::move(builder)); dvs.emplace_back(std::move(builder));

View File

@@ -69,21 +69,6 @@ m2::RectD GetRectAroundPosition(m2::PointD const & position)
return mercator::RectByCenterXYAndSizeInMeters(position, kMaxPositionRadiusM); 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) void TrimLeadingSpaces(string & s)
{ {
while (!s.empty() && strings::IsASCIISpace(s.front())) while (!s.empty() && strings::IsASCIISpace(s.front()))
@@ -277,9 +262,6 @@ 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) if (!m_isCategorialRequest)
{ {
// Assign tokens and prefix to scorer. // Assign tokens and prefix to scorer.

View File

@@ -1482,13 +1482,7 @@ unordered_map<string, vector<string>> const kSynonyms = {
// QueryParams::Token ------------------------------------------------------------------------------ // QueryParams::Token ------------------------------------------------------------------------------
void QueryParams::Token::AddSynonym(string const & s) void QueryParams::Token::AddSynonym(string const & s)
{ {
AddSynonym(strings::MakeUniString(s)); m_synonyms.push_back(strings::MakeUniString(s));
}
void QueryParams::Token::AddSynonym(String const & s)
{
if (!IsStopWord(s))
m_synonyms.push_back(s);
} }
string DebugPrint(QueryParams::Token const & token) string DebugPrint(QueryParams::Token const & token)
@@ -1510,10 +1504,11 @@ void QueryParams::ClearStreetIndices()
AdditionalCommonTokens() AdditionalCommonTokens()
{ {
char const * arr[] = { char const * arr[] = {
"the", // English "a", "and", "s", "the", // English
"der", "zum", "und", "auf", // German "am", "an", "auf", "der", "im", "und", "zum", // German
"del", "les", // Spanish "d", "da", "de", "del", "di", "du", "el",
"в", "на" // Cyrillic "et", "la", "las", "le", "les", "los", "y", // French, Spanish, Italian
"в", "и", "на", "я" // Cyrillic
}; };
for (char const * s : arr) for (char const * s : arr)
m_strings.insert(NormalizeAndSimplifyString(s)); m_strings.insert(NormalizeAndSimplifyString(s));

View File

@@ -28,7 +28,6 @@ public:
Token(String const & original) : m_original(original) {} Token(String const & original) : m_original(original) {}
void AddSynonym(std::string const & s); void AddSynonym(std::string const & s);
void AddSynonym(String const & s);
template <typename Fn> template <typename Fn>
void ForEachSynonym(Fn && fn) const void ForEachSynonym(Fn && fn) const

View File

@@ -94,42 +94,9 @@ ErrorsMade GetPrefixErrorsMade(QueryParams::Token const & token, strings::UniStr
} }
} // namespace impl } // 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) TokensVector::TokensVector(string_view name)
{ {
ForEachNormalizedToken(name, [this](strings::UniString && token) m_tokens = NormalizeAndTokenizeString(std::move(name));
{
if (!IsStopWord(token))
m_tokens.push_back(std::move(token));
});
Init(); Init();
} }

View File

@@ -180,9 +180,6 @@ struct NameScores
std::string DebugPrint(NameScore const & score); std::string DebugPrint(NameScore const & score);
std::string DebugPrint(NameScores const & scores); 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 class TokensVector
{ {
std::vector<strings::UniString> m_tokens; std::vector<strings::UniString> m_tokens;

View File

@@ -44,11 +44,7 @@ public:
m_scorer.SetPivotForTesting(pivot); m_scorer.SetPivotForTesting(pivot);
vector<UniString> tokens; vector<UniString> tokens;
search::ForEachNormalizedToken(query, [&tokens](strings::UniString && token) tokens = NormalizeAndTokenizeString(query);
{
if (!IsStopWord(token))
tokens.push_back(std::move(token));
});
m_params.Init(query, tokens, lastTokenIsPrefix); m_params.Init(query, tokens, lastTokenIsPrefix);
} }

View File

@@ -339,7 +339,8 @@ void MapWidget::ShowInfoPopup(QMouseEvent * e, m2::PointD const & pt)
auto types = feature::TypesHolder(ft); auto types = feature::TypesHolder(ft);
types.SortBySpec(); types.SortBySpec();
for (auto const & type : types.ToObjectNames()) for (auto const & type : types.ToObjectNames())
concat += type + " "; concat = concat + type + " ";
concat = concat + "| " + DebugPrint(ft.GetGeomType());
addStringFn(concat); addStringFn(concat);
// Name // Name

View File

@@ -8,7 +8,6 @@
#include "base/assert.hpp" #include "base/assert.hpp"
#include "base/logging.hpp" #include "base/logging.hpp"
#include <algorithm>
#include <functional> #include <functional>
#include <limits> #include <limits>
@@ -200,7 +199,7 @@ void UpdateDialog::OnItemClick(QTreeWidgetItem * item, int column)
case NodeStatus::Partly: st.DownloadNode(countryId); break; case NodeStatus::Partly: st.DownloadNode(countryId); break;
case NodeStatus::InQueue: case NodeStatus::InQueue:
case NodeStatus::Downloading: st.DeleteNode(countryId); break; case NodeStatus::Downloading: st.CancelDownloadNode(countryId); break;
case NodeStatus::Applying: case NodeStatus::Applying:
// Do nothing. // Do nothing.

View File

@@ -38,7 +38,7 @@ def multithread_run_if_one_country(func):
kwargs.update({"threads_count": settings.THREADS_COUNT}) kwargs.update({"threads_count": settings.THREADS_COUNT})
# Otherwise index stage of Taiwan_* mwms continues to run after all other mwms have finished: # Otherwise index stage of Taiwan_* mwms continues to run after all other mwms have finished:
elif country == 'Taiwan_North': elif country == 'Taiwan_North':
kwargs.update({"threads_count": 3}) kwargs.update({"threads_count": 6})
elif country == 'Taiwan_South': elif country == 'Taiwan_South':
kwargs.update({"threads_count": 2}) kwargs.update({"threads_count": 2})
func(env, country, **kwargs) 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: # Path to the data/ folder in the repository:
USER_RESOURCE_PATH: ${Developer:OMIM_PATH}/data USER_RESOURCE_PATH: ${Developer:OMIM_PATH}/data
# Features stage only parallelism level. Set to 0 for auto detection. # Features stage only parallelism level. Set to 0 for auto detection.
THREADS_COUNT_FEATURES_STAGE: 64 THREADS_COUNT_FEATURES_STAGE: 0
# Do not change it. This is determined automatically. # Do not change it. This is determined automatically.
NODE_STORAGE: mem NODE_STORAGE: mem

View File

@@ -31,22 +31,22 @@ python3 -m venv /tmp/venv
echo "<$(date +%T)> Copying map generator INI..." echo "<$(date +%T)> Copying map generator INI..."
cp var/etc/map_generator.ini.prod var/etc/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" echo "Marking as a test (non-prod) generation"
# TODO: output test maps into e.g. osm-maps-test/ and use a different generation.log # 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 fi
if [ $MWMCONTINUE == "true" ]; then if [ $MWMCONTINUE -gt 0 ]; then
echo "Continuing from preexisting generator run" echo "Continuing from preexisting generator run"
GENARGS="$GENARGS --continue" $GENARGS="$GENARGS --continue"
fi fi
if [[ -n $MWMCOUNTRIES ]]; then if [[ -n $MWMCOUNTRIES ]]; then
echo "Generating only specific maps for [$MWMCOUNTRIES]" echo "Generating only specific maps for [$MWMCOUNTRIES]"
GENARGS="$GENARGS --countries=$MWMCOUNTRIES" $GENARGS="$GENARGS --countries=$MWMCOUNTRIES"
fi fi
cd ~/comaps/tools/python cd ~/comaps/tools/python

View File

@@ -46,8 +46,6 @@
394E1E0B22BBB5EB00E4BC75 /* utils.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 394E1E0922BBB5EB00E4BC75 /* utils.hpp */; }; 394E1E0B22BBB5EB00E4BC75 /* utils.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 394E1E0922BBB5EB00E4BC75 /* utils.hpp */; };
39F376C0207D32450058E8E0 /* cities_boundaries_serdes_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 39F376BE207D32410058E8E0 /* cities_boundaries_serdes_tests.cpp */; }; 39F376C0207D32450058E8E0 /* cities_boundaries_serdes_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 39F376BE207D32410058E8E0 /* cities_boundaries_serdes_tests.cpp */; };
39F376C3207D32510058E8E0 /* scale_index_reading_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 39F376C1207D324E0058E8E0 /* scale_index_reading_tests.cpp */; }; 39F376C3207D32510058E8E0 /* scale_index_reading_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 39F376C1207D324E0058E8E0 /* scale_index_reading_tests.cpp */; };
3D12E3D72111B4BE0015A9A9 /* caching_rank_table_loader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D12E3D52111B4BD0015A9A9 /* caching_rank_table_loader.cpp */; };
3D12E3D82111B4BE0015A9A9 /* caching_rank_table_loader.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 3D12E3D62111B4BD0015A9A9 /* caching_rank_table_loader.hpp */; };
3D489BC61D3D220F0052AA38 /* editable_map_object_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D489BA71D3D1F8A0052AA38 /* editable_map_object_test.cpp */; }; 3D489BC61D3D220F0052AA38 /* editable_map_object_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D489BA71D3D1F8A0052AA38 /* editable_map_object_test.cpp */; };
3D489BC71D3D22150052AA38 /* features_vector_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D489BA81D3D1F8A0052AA38 /* features_vector_test.cpp */; }; 3D489BC71D3D22150052AA38 /* features_vector_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D489BA81D3D1F8A0052AA38 /* features_vector_test.cpp */; };
3D489BC81D3D22190052AA38 /* string_slice_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D489BA91D3D1F8A0052AA38 /* string_slice_tests.cpp */; }; 3D489BC81D3D22190052AA38 /* string_slice_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D489BA91D3D1F8A0052AA38 /* string_slice_tests.cpp */; };
@@ -271,8 +269,6 @@
394E1E0922BBB5EB00E4BC75 /* utils.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = utils.hpp; sourceTree = "<group>"; }; 394E1E0922BBB5EB00E4BC75 /* utils.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = utils.hpp; sourceTree = "<group>"; };
39F376BE207D32410058E8E0 /* cities_boundaries_serdes_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cities_boundaries_serdes_tests.cpp; sourceTree = "<group>"; }; 39F376BE207D32410058E8E0 /* cities_boundaries_serdes_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cities_boundaries_serdes_tests.cpp; sourceTree = "<group>"; };
39F376C1207D324E0058E8E0 /* scale_index_reading_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scale_index_reading_tests.cpp; sourceTree = "<group>"; }; 39F376C1207D324E0058E8E0 /* scale_index_reading_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scale_index_reading_tests.cpp; sourceTree = "<group>"; };
3D12E3D52111B4BD0015A9A9 /* caching_rank_table_loader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = caching_rank_table_loader.cpp; sourceTree = "<group>"; };
3D12E3D62111B4BD0015A9A9 /* caching_rank_table_loader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = caching_rank_table_loader.hpp; sourceTree = "<group>"; };
3D452AF71EE6D9F5009EAB9B /* wheelchair_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wheelchair_tests.cpp; sourceTree = "<group>"; }; 3D452AF71EE6D9F5009EAB9B /* wheelchair_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wheelchair_tests.cpp; sourceTree = "<group>"; };
3D452AF81EE6D9F5009EAB9B /* feature_names_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = feature_names_test.cpp; sourceTree = "<group>"; }; 3D452AF81EE6D9F5009EAB9B /* feature_names_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = feature_names_test.cpp; sourceTree = "<group>"; };
3D452AF91EE6D9F5009EAB9B /* centers_table_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = centers_table_test.cpp; sourceTree = "<group>"; }; 3D452AF91EE6D9F5009EAB9B /* centers_table_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = centers_table_test.cpp; sourceTree = "<group>"; };
@@ -609,8 +605,6 @@
34664CEF1D49FEC1003D7096 /* altitude_loader.hpp */, 34664CEF1D49FEC1003D7096 /* altitude_loader.hpp */,
4088CE1F21AE993F00E2702A /* brands_holder.cpp */, 4088CE1F21AE993F00E2702A /* brands_holder.cpp */,
4088CE1E21AE993F00E2702A /* brands_holder.hpp */, 4088CE1E21AE993F00E2702A /* brands_holder.hpp */,
3D12E3D52111B4BD0015A9A9 /* caching_rank_table_loader.cpp */,
3D12E3D62111B4BD0015A9A9 /* caching_rank_table_loader.hpp */,
56C74C121C749E4700B71B9F /* categories_holder_loader.cpp */, 56C74C121C749E4700B71B9F /* categories_holder_loader.cpp */,
56C74C131C749E4700B71B9F /* categories_holder.cpp */, 56C74C131C749E4700B71B9F /* categories_holder.cpp */,
56C74C141C749E4700B71B9F /* categories_holder.hpp */, 56C74C141C749E4700B71B9F /* categories_holder.hpp */,
@@ -788,7 +782,6 @@
347F337D1C454242009758CC /* succinct_trie_builder.hpp in Headers */, 347F337D1C454242009758CC /* succinct_trie_builder.hpp in Headers */,
675341381A3F540F00A0A8C3 /* mwm_set.hpp in Headers */, 675341381A3F540F00A0A8C3 /* mwm_set.hpp in Headers */,
456E1B181F90E5B7009C32E1 /* cities_boundaries_serdes.hpp in Headers */, 456E1B181F90E5B7009C32E1 /* cities_boundaries_serdes.hpp in Headers */,
3D12E3D82111B4BE0015A9A9 /* caching_rank_table_loader.hpp in Headers */,
670EE56D1B60033A001E8064 /* unique_index.hpp in Headers */, 670EE56D1B60033A001E8064 /* unique_index.hpp in Headers */,
675340FF1A3F540F00A0A8C3 /* cell_coverer.hpp in Headers */, 675340FF1A3F540F00A0A8C3 /* cell_coverer.hpp in Headers */,
56C74C251C749E4700B71B9F /* search_string_utils.hpp in Headers */, 56C74C251C749E4700B71B9F /* search_string_utils.hpp in Headers */,
@@ -1001,7 +994,6 @@
6753410D1A3F540F00A0A8C3 /* drawing_rules.cpp in Sources */, 6753410D1A3F540F00A0A8C3 /* drawing_rules.cpp in Sources */,
675341301A3F540F00A0A8C3 /* data_source.cpp in Sources */, 675341301A3F540F00A0A8C3 /* data_source.cpp in Sources */,
34664CF61D49FEC1003D7096 /* centers_table.cpp in Sources */, 34664CF61D49FEC1003D7096 /* centers_table.cpp in Sources */,
3D12E3D72111B4BE0015A9A9 /* caching_rank_table_loader.cpp in Sources */,
6753414D1A3F540F00A0A8C3 /* types_mapping.cpp in Sources */, 6753414D1A3F540F00A0A8C3 /* types_mapping.cpp in Sources */,
34583BC71C88552100F94664 /* cuisines.cpp in Sources */, 34583BC71C88552100F94664 /* cuisines.cpp in Sources */,
675341121A3F540F00A0A8C3 /* feature_algo.cpp in Sources */, 675341121A3F540F00A0A8C3 /* feature_algo.cpp in Sources */,

View File

@@ -50,8 +50,6 @@
671ED38F20D403B300D4317E /* search_api_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 671ED38A20D403B300D4317E /* search_api_tests.cpp */; }; 671ED38F20D403B300D4317E /* search_api_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 671ED38A20D403B300D4317E /* search_api_tests.cpp */; };
674A29F01B26FD6F001A525C /* testingmain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 674A29EE1B26FD5F001A525C /* testingmain.cpp */; }; 674A29F01B26FD6F001A525C /* testingmain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 674A29EE1B26FD5F001A525C /* testingmain.cpp */; };
674A2A2F1B26FF7B001A525C /* libmap.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 675345BB1A4054AD00A0A8C3 /* libmap.a */; }; 674A2A2F1B26FF7B001A525C /* libmap.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 675345BB1A4054AD00A0A8C3 /* libmap.a */; };
674A2A361B27011A001A525C /* working_time_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 674A2A351B27011A001A525C /* working_time_tests.cpp */; };
674A2A381B2715FB001A525C /* osm_opening_hours.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 674A2A371B2715FB001A525C /* osm_opening_hours.hpp */; };
674C38621BFF3095000D603B /* user_mark.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 674C385F1BFF3095000D603B /* user_mark.cpp */; }; 674C38621BFF3095000D603B /* user_mark.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 674C385F1BFF3095000D603B /* user_mark.cpp */; };
675346481A4054E800A0A8C3 /* bookmark_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 675345D91A4054E800A0A8C3 /* bookmark_manager.cpp */; }; 675346481A4054E800A0A8C3 /* bookmark_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 675345D91A4054E800A0A8C3 /* bookmark_manager.cpp */; };
675346491A4054E800A0A8C3 /* bookmark_manager.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 675345DA1A4054E800A0A8C3 /* bookmark_manager.hpp */; }; 675346491A4054E800A0A8C3 /* bookmark_manager.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 675345DA1A4054E800A0A8C3 /* bookmark_manager.hpp */; };
@@ -202,8 +200,6 @@
674A29CF1B26FCFE001A525C /* mwm_url_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mwm_url_tests.cpp; sourceTree = "<group>"; }; 674A29CF1B26FCFE001A525C /* mwm_url_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mwm_url_tests.cpp; sourceTree = "<group>"; };
674A29DF1B26FD1C001A525C /* map_tests.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = map_tests.app; sourceTree = BUILT_PRODUCTS_DIR; }; 674A29DF1B26FD1C001A525C /* map_tests.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = map_tests.app; sourceTree = BUILT_PRODUCTS_DIR; };
674A29EE1B26FD5F001A525C /* testingmain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = testingmain.cpp; path = ../../../libs/testing/testingmain.cpp; sourceTree = "<group>"; }; 674A29EE1B26FD5F001A525C /* testingmain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = testingmain.cpp; path = ../../../libs/testing/testingmain.cpp; sourceTree = "<group>"; };
674A2A351B27011A001A525C /* working_time_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = working_time_tests.cpp; sourceTree = "<group>"; };
674A2A371B2715FB001A525C /* osm_opening_hours.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = osm_opening_hours.hpp; sourceTree = "<group>"; };
674C385F1BFF3095000D603B /* user_mark.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = user_mark.cpp; sourceTree = "<group>"; }; 674C385F1BFF3095000D603B /* user_mark.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = user_mark.cpp; sourceTree = "<group>"; };
675345BB1A4054AD00A0A8C3 /* libmap.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libmap.a; sourceTree = BUILT_PRODUCTS_DIR; }; 675345BB1A4054AD00A0A8C3 /* libmap.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libmap.a; sourceTree = BUILT_PRODUCTS_DIR; };
675345D91A4054E800A0A8C3 /* bookmark_manager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bookmark_manager.cpp; sourceTree = "<group>"; }; 675345D91A4054E800A0A8C3 /* bookmark_manager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bookmark_manager.cpp; sourceTree = "<group>"; };
@@ -357,7 +353,6 @@
671ED38A20D403B300D4317E /* search_api_tests.cpp */, 671ED38A20D403B300D4317E /* search_api_tests.cpp */,
674A29EE1B26FD5F001A525C /* testingmain.cpp */, 674A29EE1B26FD5F001A525C /* testingmain.cpp */,
BB421D6A1E8C0026005BFA4D /* transliteration_test.cpp */, BB421D6A1E8C0026005BFA4D /* transliteration_test.cpp */,
674A2A351B27011A001A525C /* working_time_tests.cpp */,
ED49D74B2CEF3CE3004AF27E /* elevation_info_tests.cpp */, ED49D74B2CEF3CE3004AF27E /* elevation_info_tests.cpp */,
ED85D1CF2D5F508700D8075D /* track_statistics_tests.cpp */, ED85D1CF2D5F508700D8075D /* track_statistics_tests.cpp */,
); );
@@ -432,7 +427,6 @@
45F6EE9B1FB1C77500019892 /* mwm_tree.hpp */, 45F6EE9B1FB1C77500019892 /* mwm_tree.hpp */,
675346051A4054E800A0A8C3 /* mwm_url.cpp */, 675346051A4054E800A0A8C3 /* mwm_url.cpp */,
675346061A4054E800A0A8C3 /* mwm_url.hpp */, 675346061A4054E800A0A8C3 /* mwm_url.hpp */,
674A2A371B2715FB001A525C /* osm_opening_hours.hpp */,
34583BCD1C88556800F94664 /* place_page_info.cpp */, 34583BCD1C88556800F94664 /* place_page_info.cpp */,
34583BCE1C88556800F94664 /* place_page_info.hpp */, 34583BCE1C88556800F94664 /* place_page_info.hpp */,
3DF528D5237DC82E000ED0D5 /* position_provider.hpp */, 3DF528D5237DC82E000ED0D5 /* position_provider.hpp */,
@@ -519,7 +513,6 @@
6753469C1A4054E800A0A8C3 /* track.hpp in Headers */, 6753469C1A4054E800A0A8C3 /* track.hpp in Headers */,
675346651A4054E800A0A8C3 /* framework.hpp in Headers */, 675346651A4054E800A0A8C3 /* framework.hpp in Headers */,
BBA014B120754997007402E4 /* user_mark_id_storage.hpp in Headers */, BBA014B120754997007402E4 /* user_mark_id_storage.hpp in Headers */,
674A2A381B2715FB001A525C /* osm_opening_hours.hpp in Headers */,
ED85D1CC2D5F4B5B00D8075D /* track_statistics.hpp in Headers */, ED85D1CC2D5F4B5B00D8075D /* track_statistics.hpp in Headers */,
3DEE1ADF21EE03B400054A91 /* power_manager.hpp in Headers */, 3DEE1ADF21EE03B400054A91 /* power_manager.hpp in Headers */,
F6D2CE7F1EDEB7F500636DFD /* routing_manager.hpp in Headers */, F6D2CE7F1EDEB7F500636DFD /* routing_manager.hpp in Headers */,
@@ -671,7 +664,6 @@
FAA8387426BB3C0F002E54C6 /* countries_names_tests.cpp in Sources */, FAA8387426BB3C0F002E54C6 /* countries_names_tests.cpp in Sources */,
679624B01D1017DB00AE4E3C /* gps_track_storage_test.cpp in Sources */, 679624B01D1017DB00AE4E3C /* gps_track_storage_test.cpp in Sources */,
674A29F01B26FD6F001A525C /* testingmain.cpp in Sources */, 674A29F01B26FD6F001A525C /* testingmain.cpp in Sources */,
674A2A361B27011A001A525C /* working_time_tests.cpp in Sources */,
679624B11D1017DB00AE4E3C /* gps_track_test.cpp in Sources */, 679624B11D1017DB00AE4E3C /* gps_track_test.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;