Compare commits

...

43 Commits

Author SHA1 Message Date
map-per
498dcc4240 [android] Use separate function to check for MapTooOldToEdit
Signed-off-by: map-per <map-per@gmx.de>
2025-12-17 16:52:11 +07:00
Yannik Bloscheck
67d88b4fa9 Fix Romania roadhsield name
Signed-off-by: Yannik Bloscheck <git@yannikbloscheck.com>
2025-12-17 16:22:51 +07:00
Yannik Bloscheck
4f443edc13 Remove duplciate Latvia code
Signed-off-by: Yannik Bloscheck <git@yannikbloscheck.com>
2025-12-17 16:22:51 +07:00
vikiawv
a883dfb7ff Added DX Roadshield Type
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
568bd8a3cc Restored Latvia
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
d81a9958be Added missing variable for Austrian B-Roads to fix an error on B225
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
8b9440f407 Corrected Syntax of SVG Graphics
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
f5437c725c Corrected Syntax of SVG Garphics
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
42d2b4e2a9 Restoring Lativa PART
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
8f12b53d62 corrected Romania
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
2d8ef64b17 Update libs/indexer/road_shields_parser.cpp 2025-12-17 16:22:51 +07:00
vikiawv
15b919cf72 Upload files to "data/styles/default/dark/symbols"
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
94aa41cf44 Upload files to "data/styles/default/light/symbols"
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
16381cdebd Format corrected
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
bc740aceb8 corrected formatting
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
794d5c872e Reverting Switzerland, because I'll make a seperate PR for that
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
095040a060 corrected formattiong 2025-12-17 16:22:51 +07:00
vikiawv
30e5657c4f Correcting Albania, Adding Switzerland Variants
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
9d38deff1c Updated italy
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
b5068c9915 Corrected austria
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
4178148e47 corrected italy
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
97d5178c72 typo
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
68b90d3c2e corrected spelling of Latvia
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
4582972591 corrected portugal
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
624f364805 Update libs/indexer/road_shields_parser.hpp
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:22:51 +07:00
vikiawv
4e7c968beb Update libs/indexer/road_shields_parser.cpp 2025-12-17 16:22:51 +07:00
vikiawv
29ab48dc49 Update libs/drape_frontend/apply_feature_functors.cpp 2025-12-17 16:22:51 +07:00
vikiawv
cfcff9f882 Upload files to "data/styles/default/dark/symbols" 2025-12-17 16:21:17 +07:00
vikiawv
44d281e109 Upload files to "data/styles/default/light/symbols" 2025-12-17 16:21:17 +07:00
vikiawv
8a92018efe Adding Albania Highwayshield
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:21:17 +07:00
vikiawv
fd873dfc88 Fixed spelling Latvia
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:21:17 +07:00
vikiawv
b052b26081 Removing Ref from Roadshields (AT, RO)
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2025-12-17 16:21:17 +07:00
NoelClick
764a0758c5 [android] Unify custom map server dialog logic and UI
- Add setting icon for custom map server download option.
- Extract shared custom map server dialog helper.
- Clean up based on reviewers' feedback.

Signed-off-by: NoelClick <dev@noel.click>
2025-12-17 11:07:04 +07:00
NoelClick
d5e0889c9a [android] Improve custom map server dialog UX
Signed-off-by: NoelClick <dev@noel.click>
2025-12-17 11:07:04 +07:00
NoelClick
a1a13caa4e [android] Add validation for custom map download URL
- Add validation for custom map download URL.
- Re-enable advanced server button after failed or paused downloads.

Signed-off-by: NoelClick <dev@noel.click>
2025-12-17 11:07:04 +07:00
NoelClick
c75d1fc79d [android] Clarify custom map download URL strings
Signed-off-by: NoelClick <dev@noel.click>
2025-12-17 11:07:04 +07:00
NoelClick
3195ef6c3b [core] Treat custom map download URL as CDN base, not meta server
- Update `MapFilesDownloader::LoadMetaConfig()` to skip the metaserver when a
  custom base URL is set and build MetaConfig with that URL as the only server.
- Keep the existing metaserver-based behavior when no custom base URL is set.

Signed-off-by: NoelClick <dev@noel.click>
2025-12-17 11:07:04 +07:00
NoelClick
cf43bf6b1c [android] Add custom world map download URL option
- Allow setting a custom map download URL in the "world-download" screen.

Signed-off-by: NoelClick <dev@noel.click>
2025-12-17 11:07:04 +07:00
NoelClick
9966cee168 [android] Add custom map download URL setting
Signed-off-by: NoelClick <dev@noel.click>
2025-12-17 11:07:04 +07:00
NoelClick
023afecaa2 [android] Make it possible to set a custom map download URL
Signed-off-by: NoelClick <dev@noel.click>
2025-12-17 11:07:04 +07:00
NoelClick
6e7ba078c8 [core] Allow overriding map metaserver URL and reset downloader cache
- Add custom meta server API.
- Implement override.
- Add reset hook and implement reset.
- Expose reset from Storage.
- Let JNI set URL and reset cache.

Signed-off-by: NoelClick <dev@noel.click>
2025-12-17 11:07:04 +07:00
x7z4w
b39631fe51 [drape] Set Harfbuzz language to map language
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-12-17 10:56:05 +07:00
x7z4w
d2fee9ff8e [drape] Lower tap delays
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-12-17 10:55:21 +07:00
42 changed files with 605 additions and 77 deletions

View File

@@ -10,6 +10,7 @@ CoMaps contributors:
Bastian Greshake Tzovaras Bastian Greshake Tzovaras
clover sage clover sage
Harry Bond <me@hbond.xyz> Harry Bond <me@hbond.xyz>
NoelClick
thesupertechie thesupertechie
vikiawv vikiawv
Yannik Bloscheck Yannik Bloscheck

View File

@@ -18,6 +18,7 @@ import android.location.Location;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.View; import android.view.View;
import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts; import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.CallSuper; import androidx.annotation.CallSuper;
@@ -25,7 +26,15 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.checkbox.MaterialCheckBox;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.progressindicator.LinearProgressIndicator;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.base.BaseMwmFragmentActivity; import app.organicmaps.base.BaseMwmFragmentActivity;
import app.organicmaps.dialog.CustomMapServerDialog;
import app.organicmaps.downloader.MapManagerHelper; import app.organicmaps.downloader.MapManagerHelper;
import app.organicmaps.intent.Factory; import app.organicmaps.intent.Factory;
import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Framework;
@@ -38,11 +47,7 @@ import app.organicmaps.sdk.util.StringUtils;
import app.organicmaps.util.UiUtils; import app.organicmaps.util.UiUtils;
import app.organicmaps.util.Utils; import app.organicmaps.util.Utils;
import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener; import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.checkbox.MaterialCheckBox;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.progressindicator.LinearProgressIndicator;
import com.google.android.material.textview.MaterialTextView;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@@ -54,6 +59,7 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
private MaterialTextView mTvMessage; private MaterialTextView mTvMessage;
private LinearProgressIndicator mProgress; private LinearProgressIndicator mProgress;
private MaterialButton mBtnDownload; private MaterialButton mBtnDownload;
private MaterialButton mBtnAdvanced;
private MaterialCheckBox mChbDownloadCountry; private MaterialCheckBox mChbDownloadCountry;
private String mCurrentCountry; private String mCurrentCountry;
@@ -267,6 +273,14 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
mProgress = findViewById(R.id.progressbar); mProgress = findViewById(R.id.progressbar);
mBtnDownload = findViewById(R.id.btn_download_resources); mBtnDownload = findViewById(R.id.btn_download_resources);
mChbDownloadCountry = findViewById(R.id.chb_download_country); mChbDownloadCountry = findViewById(R.id.chb_download_country);
mBtnAdvanced = findViewById(R.id.btn_advanced);
mBtnAdvanced.setOnClickListener(v -> {
CustomMapServerDialog.show(this, url -> {
prepareFilesDownload(false);
});
});
mBtnAdvanced.setEnabled(true);
mBtnListeners = new View.OnClickListener[BTN_COUNT]; mBtnListeners = new View.OnClickListener[BTN_COUNT];
mBtnNames = new String[BTN_COUNT]; mBtnNames = new String[BTN_COUNT];
@@ -291,6 +305,11 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
{ {
mBtnDownload.setOnClickListener(mBtnListeners[action]); mBtnDownload.setOnClickListener(mBtnListeners[action]);
mBtnDownload.setText(mBtnNames[action]); mBtnDownload.setText(mBtnNames[action]);
// Allow changing server only when idle or after an error.
boolean advancedEnabled = (action == DOWNLOAD || action == TRY_AGAIN || action == RESUME);
mBtnAdvanced.setEnabled(advancedEnabled);
mBtnAdvanced.setAlpha(advancedEnabled ? 1f : 0.5f);
} }
private void doDownload() private void doDownload()
@@ -359,6 +378,9 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
private void finishFilesDownload(int result) private void finishFilesDownload(int result)
{ {
mBtnAdvanced.setEnabled(true);
mBtnAdvanced.setAlpha(1f);
if (result == ERR_NO_MORE_FILES) if (result == ERR_NO_MORE_FILES)
{ {
// World and WorldCoasts has been downloaded, we should register maps again to correctly add them to the model. // World and WorldCoasts has been downloaded, we should register maps again to correctly add them to the model.

View File

@@ -0,0 +1,86 @@
package app.organicmaps.dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.PreferenceManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import app.organicmaps.R;
import app.organicmaps.sdk.Framework;
public final class CustomMapServerDialog
{
public interface OnUrlAppliedListener
{
void onUrlApplied(@NonNull String url);
}
private CustomMapServerDialog() {}
public static void show(@NonNull Context context,
@Nullable OnUrlAppliedListener listener)
{
View dialogView = LayoutInflater.from(context)
.inflate(R.layout.dialog_custom_map_server, null);
TextInputLayout til = dialogView.findViewById(R.id.til_custom_map_server);
TextInputEditText edit = dialogView.findViewById(R.id.edit_custom_map_server);
SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(context);
String current = prefs.getString(context.getString(R.string.pref_custom_map_download_url), "");
edit.setText(current);
MaterialAlertDialogBuilder builder =
new MaterialAlertDialogBuilder(context, R.style.MwmTheme_AlertDialog)
.setTitle(R.string.download_resources_custom_url_title)
.setMessage(R.string.download_resources_custom_url_message)
.setView(dialogView)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.save, null);
AlertDialog dialog = builder.create();
dialog.setOnShowListener(dlg -> {
Button ok = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
ok.setOnClickListener(v -> {
String url = edit.getText() != null ? edit.getText().toString().trim() : "";
if (!url.isEmpty()
&& !url.startsWith("http://")
&& !url.startsWith("https://"))
{
til.setError(context.getString(R.string.download_resources_custom_url_error_scheme));
return;
}
til.setError(null);
String normalizedUrl = Framework.normalizeServerUrl(url);
prefs.edit()
.putString(context.getString(R.string.pref_custom_map_download_url), normalizedUrl)
.apply();
// Apply to native
Framework.applyCustomMapDownloadUrl(context, normalizedUrl);
if (listener != null)
listener.onUrlApplied(normalizedUrl);
dialog.dismiss();
});
});
dialog.show();
}
}

View File

@@ -4,16 +4,23 @@ import static app.organicmaps.leftbutton.LeftButtonsHolder.DISABLE_BUTTON_CODE;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.preference.ListPreference; import androidx.preference.ListPreference;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceManager;
import androidx.preference.TwoStatePreference; import androidx.preference.TwoStatePreference;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import app.organicmaps.MwmApplication; import app.organicmaps.MwmApplication;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.dialog.CustomMapServerDialog;
import app.organicmaps.downloader.OnmapDownloader; import app.organicmaps.downloader.OnmapDownloader;
import app.organicmaps.editor.LanguagesFragment; import app.organicmaps.editor.LanguagesFragment;
import app.organicmaps.editor.ProfileActivity; import app.organicmaps.editor.ProfileActivity;
@@ -35,7 +42,7 @@ import app.organicmaps.sdk.util.SharedPropertiesUtils;
import app.organicmaps.sdk.util.log.LogsManager; import app.organicmaps.sdk.util.log.LogsManager;
import app.organicmaps.util.ThemeSwitcher; import app.organicmaps.util.ThemeSwitcher;
import app.organicmaps.util.Utils; import app.organicmaps.util.Utils;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@@ -73,6 +80,7 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La
initScreenSleepEnabledPrefsCallbacks(); initScreenSleepEnabledPrefsCallbacks();
initShowOnLockScreenPrefsCallbacks(); initShowOnLockScreenPrefsCallbacks();
initLeftButtonPrefs(); initLeftButtonPrefs();
initCustomMapDownloadUrlPrefsCallbacks();
} }
private void initLeftButtonPrefs() private void initLeftButtonPrefs()
@@ -535,6 +543,34 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La
}); });
} }
private void initCustomMapDownloadUrlPrefsCallbacks()
{
Preference customUrlPref = getPreference(getString(R.string.pref_custom_map_download_url));
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(requireContext());
String current = prefs.getString(getString(R.string.pref_custom_map_download_url), "");
String normalizedUrl = Framework.normalizeServerUrl(current);
// Initial summary
customUrlPref.setSummary(normalizedUrl.isEmpty()
? getString(R.string.download_resources_custom_url_summary_none)
: normalizedUrl);
// Sync native
Framework.applyCustomMapDownloadUrl(requireContext(), normalizedUrl);
// Show dialog
customUrlPref.setOnPreferenceClickListener(preference -> {
CustomMapServerDialog.show(requireContext(), url -> {
preference.setSummary(url.isEmpty()
? getString(R.string.download_resources_custom_url_summary_none)
: url);
});
return true;
});
}
private void removePreference(@NonNull String categoryKey, @NonNull Preference preference) private void removePreference(@NonNull String categoryKey, @NonNull Preference preference)
{ {
final PreferenceCategory category = getPreference(categoryKey); final PreferenceCategory category = getPreference(categoryKey);

View File

@@ -700,22 +700,27 @@ public class PlacePageView extends Fragment
if (shouldEnableEditPlace) if (shouldEnableEditPlace)
{ {
mTvEditPlace.setEnabled(true);
mTvAddPlace.setEnabled(true);
mTvEditPlace.setOnClickListener(this); mTvEditPlace.setOnClickListener(this);
mTvAddPlace.setOnClickListener(this); mTvAddPlace.setOnClickListener(this);
} }
else else
{ {
mTvEditPlace.setOnClickListener((v) -> {
Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit);
});
mTvAddPlace.setOnClickListener((v) -> {
Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit);
});
String countryId = MapManager.nativeGetSelectedCountry(); String countryId = MapManager.nativeGetSelectedCountry();
if (countryId != null) if (countryId != null && MapManager.nativeIsMapTooOldToEdit(countryId))
{ {
// map editing is disabled because the map is too old
mTvEditPlace.setEnabled(true);
mTvAddPlace.setEnabled(true);
mTvEditPlace.setOnClickListener((v) -> {
Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit);
});
mTvAddPlace.setOnClickListener((v) -> {
Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit);
});
CountryItem map = CountryItem.fill(countryId); CountryItem map = CountryItem.fill(countryId);
if (map.status == CountryItem.STATUS_UPDATABLE || map.status == CountryItem.STATUS_DONE if (map.status == CountryItem.STATUS_UPDATABLE || map.status == CountryItem.STATUS_DONE
@@ -740,6 +745,12 @@ public class PlacePageView extends Fragment
mapTooOldDescription.setText(R.string.place_page_app_too_old_description); mapTooOldDescription.setText(R.string.place_page_app_too_old_description);
} }
} }
else
{
// map editing is disabled for other reasons
mTvEditPlace.setEnabled(false);
mTvAddPlace.setEnabled(false);
}
} }
final int editButtonColor = final int editButtonColor =

View File

@@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:tint="?colorControlNormal"
android:height="24dp"
android:width="24dp"
android:viewportHeight="960"
android:viewportWidth="960">
<path android:fillColor="@android:color/white"
android:pathData="M260,800Q169,800 104.5,737Q40,674 40,583Q40,505 87,444Q134,383 210,366Q227,294 295,229Q363,164 440,164Q473,164 496.5,187.5Q520,211 520,244L520,486L584,424L640,480L480,640L320,480L376,424L440,486L440,244Q364,258 322,317.5Q280,377 280,440L260,440Q202,440 161,481Q120,522 120,580Q120,638 161,679Q202,720 260,720L740,720Q782,720 811,691Q840,662 840,620Q840,578 811,549Q782,520 740,520L680,520L680,440Q680,392 658,350.5Q636,309 600,280L600,187Q674,222 717,290.5Q760,359 760,440L760,440L760,440Q829,448 874.5,499.5Q920,551 920,620Q920,695 867.5,747.5Q815,800 740,800L260,800ZM480,442Q480,442 480,442Q480,442 480,442L480,442Q480,442 480,442Q480,442 480,442L480,442Q480,442 480,442Q480,442 480,442L480,442Q480,442 480,442Q480,442 480,442Q480,442 480,442Q480,442 480,442L480,442Q480,442 480,442Q480,442 480,442Q480,442 480,442Q480,442 480,442L480,442L480,442Q480,442 480,442Q480,442 480,442Z"/>
</vector>

View File

@@ -11,6 +11,18 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_above="@+id/button_container" android:layout_above="@+id/button_container"
android:layout_gravity="center"> android:layout_gravity="center">
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_advanced"
style="@style/Widget.Material3.Button.IconButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:icon="@drawable/ic_settings"
app:iconTint="?iconTint"
android:contentDescription="@string/download_resources_custom_url_title"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_margin="@dimen/margin_half" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.textfield.TextInputLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/til_custom_map_server"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/margin_base"
android:paddingEnd="@dimen/margin_base"
android:paddingTop="@dimen/margin_base"
android:paddingBottom="@dimen/margin_half"
android:hint="@string/download_resources_custom_url_title"
app:placeholderText="@string/download_resources_custom_url_hint"
app:endIconMode="clear_text">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_custom_map_server"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textUri"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>

View File

@@ -43,6 +43,7 @@
<string name="pref_backup" translatable="false">Backup</string> <string name="pref_backup" translatable="false">Backup</string>
<string name="pref_left_button" translatable="false">LeftButton</string> <string name="pref_left_button" translatable="false">LeftButton</string>
<string name="pref_power" translatable="false">pref_power</string> <string name="pref_power" translatable="false">pref_power</string>
<string name="pref_custom_map_download_url" translatable="false">CustomMapDownloadUrl</string>
<string name="notification_ticker_ltr" translatable="false">%1$s: %2$s</string> <string name="notification_ticker_ltr" translatable="false">%1$s: %2$s</string>
<string name="notification_ticker_rtl" translatable="false">%2$s :%1$s</string> <string name="notification_ticker_rtl" translatable="false">%2$s :%1$s</string>

View File

@@ -966,4 +966,10 @@
<string name="offline_explanation_title">Offline Maps</string> <string name="offline_explanation_title">Offline Maps</string>
<string name="offline_explanation_text">A map needs to be downloaded to view and navigate the area.\nDownload maps for areas you want to travel.</string> <string name="offline_explanation_text">A map needs to be downloaded to view and navigate the area.\nDownload maps for areas you want to travel.</string>
<string name="list_description_empty">Edit the list to add a description</string> <string name="list_description_empty">Edit the list to add a description</string>
<!-- Custom Download URL -->
<string name="download_resources_custom_url_title">Custom Map Server</string>
<string name="download_resources_custom_url_message">Override the default map download server used for map downloads. Leave empty to use CoMaps default server.</string>
<string name="download_resources_custom_url_hint">https://cdn-fi-1.comaps.app/</string>
<string name="download_resources_custom_url_summary_none">Not set</string>
<string name="download_resources_custom_url_error_scheme">Please enter a full URL starting with https:// and ending with /</string>
</resources> </resources>

View File

@@ -212,5 +212,11 @@
android:defaultValue="true" android:defaultValue="true"
android:widgetLayout="@layout/preference_switch" android:widgetLayout="@layout/preference_switch"
android:order="2"/> android:order="2"/>
<Preference
android:key="@string/pref_custom_map_download_url"
android:title="@string/download_resources_custom_url_title"
app:icon="@drawable/ic_cloud_download"
android:order="3" />
</androidx.preference.PreferenceCategory> </androidx.preference.PreferenceCategory>
</androidx.preference.PreferenceScreen> </androidx.preference.PreferenceScreen>

View File

@@ -124,6 +124,7 @@ dependencies {
implementation libs.androidx.lifecycle.process implementation libs.androidx.lifecycle.process
implementation libs.androidx.media implementation libs.androidx.media
implementation libs.androidx.recyclerview implementation libs.androidx.recyclerview
implementation libs.androidx.preference
implementation libs.android.material implementation libs.android.material
testImplementation libs.junit testImplementation libs.junit

View File

@@ -42,12 +42,16 @@ using namespace std::placeholders;
namespace namespace
{ {
std::unique_ptr<MapFilesDownloader> & LegacyDownloader()
{
static auto downloader = storage::GetDownloader();
return downloader;
}
static std::vector<platform::CountryFile> g_filesToDownload; static std::vector<platform::CountryFile> g_filesToDownload;
static int g_totalDownloadedBytes; static int g_totalDownloadedBytes;
static int g_totalBytesToDownload; static int g_totalBytesToDownload;
static std::shared_ptr<HttpRequest> g_currentRequest; static std::shared_ptr<HttpRequest> g_currentRequest;
} // namespace } // namespace
extern "C" extern "C"
@@ -152,11 +156,11 @@ JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_DownloadResourcesLegacyActivity_
return ERR_NO_MORE_FILES; return ERR_NO_MORE_FILES;
/// @todo One downloader instance with cached servers. All this routine will be refactored some time. /// @todo One downloader instance with cached servers. All this routine will be refactored some time.
static auto downloader = storage::GetDownloader(); auto & downloader = LegacyDownloader();
storage::Storage const & storage = g_framework->GetStorage(); storage::Storage const & storage = g_framework->GetStorage();
downloader->SetDataVersion(storage.GetCurrentDataVersion()); downloader->SetDataVersion(storage.GetCurrentDataVersion());
downloader->EnsureMetaConfigReady([&storage, ptr = jni::make_global_ref(listener)]() downloader->EnsureMetaConfigReady([&storage, ptr = jni::make_global_ref(listener), &downloader]()
{ {
auto const & curFile = g_filesToDownload.back(); auto const & curFile = g_filesToDownload.back();
auto const fileName = curFile.GetFileName(MapFileType::Map); auto const fileName = curFile.GetFileName(MapFileType::Map);
@@ -177,4 +181,12 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_DownloadResourcesLegacyActivity_
LOG(LDEBUG, ("cancelCurrentFile, currentRequest=", g_currentRequest)); LOG(LDEBUG, ("cancelCurrentFile, currentRequest=", g_currentRequest));
g_currentRequest.reset(); g_currentRequest.reset();
} }
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_DownloadResourcesLegacyActivity_nativeResetMetaConfig(JNIEnv *,
jclass)
{
auto & downloader = LegacyDownloader();
if (downloader)
downloader->ResetMetaConfig();
}
} }

View File

@@ -1505,6 +1505,22 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Framework_nativeGet3dMode(JNIEnv
env->SetBooleanField(result, buildingsField, buildings); env->SetBooleanField(result, buildingsField, buildings);
} }
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Framework_nativeSetCustomMapDownloadUrl(JNIEnv * env, jclass,
jstring url)
{
std::string nativeUrl = jni::ToNativeString(env, url);
GetPlatform().SetCustomMapServerUrl(nativeUrl);
if (g_framework)
{
frm()->GetStorage().ResetMapDownloadMetaConfig();
}
else
{
LOG(LINFO, ("nativeSetCustomMapDownloadUrl: framework not created yet, skipping ResetMapDownloadMetaConfig"));
}
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Framework_nativeSetAutoZoomEnabled(JNIEnv * env, jclass, JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Framework_nativeSetAutoZoomEnabled(JNIEnv * env, jclass,
jboolean enabled) jboolean enabled)
{ {

View File

@@ -587,4 +587,11 @@ JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeG
storage::CountryId const & res = g_framework->GetPlacePageInfo().GetCountryId(); storage::CountryId const & res = g_framework->GetPlacePageInfo().GetCountryId();
return (res == storage::kInvalidCountryId ? nullptr : jni::ToJavaString(env, res)); return (res == storage::kInvalidCountryId ? nullptr : jni::ToJavaString(env, res));
} }
// static native boolean nativeIsMapTooOldToEdit(String countryId);
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeIsMapTooOldToEdit(JNIEnv *env, jclass clazz,
jstring country_id)
{
return GetStorage().IsMapTooOldToEdit(jni::ToNativeString(env, country_id));
}
} // extern "C" } // extern "C"

View File

@@ -27,4 +27,5 @@ public class DownloadResourcesLegacyActivity
public static native int nativeGetBytesToDownload(); public static native int nativeGetBytesToDownload();
public static native int nativeStartNextFileDownload(Listener listener); public static native int nativeStartNextFileDownload(Listener listener);
public static native void nativeCancelCurrentFile(); public static native void nativeCancelCurrentFile();
public static native void nativeResetMetaConfig();
} }

View File

@@ -1,10 +1,13 @@
package app.organicmaps.sdk; package app.organicmaps.sdk;
import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import androidx.annotation.Keep; import androidx.annotation.Keep;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.Size; import androidx.annotation.Size;
import app.organicmaps.sdk.api.ParsedRoutingData; import app.organicmaps.sdk.api.ParsedRoutingData;
import app.organicmaps.sdk.api.ParsedSearchRequest; import app.organicmaps.sdk.api.ParsedSearchRequest;
import app.organicmaps.sdk.api.RequestType; import app.organicmaps.sdk.api.RequestType;
@@ -23,6 +26,7 @@ import app.organicmaps.sdk.routing.RoutingRecommendationListener;
import app.organicmaps.sdk.routing.TransitRouteInfo; import app.organicmaps.sdk.routing.TransitRouteInfo;
import app.organicmaps.sdk.settings.SpeedCameraMode; import app.organicmaps.sdk.settings.SpeedCameraMode;
import app.organicmaps.sdk.util.Constants; import app.organicmaps.sdk.util.Constants;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
@@ -348,4 +352,20 @@ public class Framework
public static native void nativeMemoryWarning(); public static native void nativeMemoryWarning();
public static native void nativeSaveRoute(); public static native void nativeSaveRoute();
public static native void nativeSetCustomMapDownloadUrl(String url);
public static void applyCustomMapDownloadUrl(@NonNull Context context, @Nullable String url)
{
nativeSetCustomMapDownloadUrl(normalizeServerUrl(url));
// Reset the legacy downloader too (world/coasts).
app.organicmaps.sdk.DownloadResourcesLegacyActivity.nativeResetMetaConfig();
}
public static String normalizeServerUrl(@Nullable String url)
{
String out = url != null ? url.trim() : "";
if (!out.isEmpty() && !out.endsWith("/"))
out = out + "/";
return out;
}
} }

View File

@@ -2,10 +2,13 @@ package app.organicmaps.sdk;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ProcessLifecycleOwner; import androidx.lifecycle.ProcessLifecycleOwner;
import androidx.preference.PreferenceManager;
import app.organicmaps.sdk.bookmarks.data.BookmarkManager; import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
import app.organicmaps.sdk.bookmarks.data.Icon; import app.organicmaps.sdk.bookmarks.data.Icon;
import app.organicmaps.sdk.downloader.Android7RootCertificateWorkaround; import app.organicmaps.sdk.downloader.Android7RootCertificateWorkaround;
@@ -25,6 +28,7 @@ import app.organicmaps.sdk.util.SharedPropertiesUtils;
import app.organicmaps.sdk.util.StorageUtils; import app.organicmaps.sdk.util.StorageUtils;
import app.organicmaps.sdk.util.log.Logger; import app.organicmaps.sdk.util.log.Logger;
import app.organicmaps.sdk.util.log.LogsManager; import app.organicmaps.sdk.util.log.LogsManager;
import java.io.IOException; import java.io.IOException;
public final class OrganicMaps implements DefaultLifecycleObserver public final class OrganicMaps implements DefaultLifecycleObserver
@@ -167,6 +171,11 @@ public final class OrganicMaps implements DefaultLifecycleObserver
/* isTablet */ false); /* isTablet */ false);
Config.setStoragePath(writablePath); Config.setStoragePath(writablePath);
// Use the same prefs as SettingsPrefsFragment
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
final String savedUrl = prefs.getString(mContext.getString(R.string.pref_custom_map_download_url), "");
Framework.nativeSetCustomMapDownloadUrl(savedUrl.trim());
mPlatformInitialized = true; mPlatformInitialized = true;
Logger.i(TAG, "Platform initialized"); Logger.i(TAG, "Platform initialized");
} }

View File

@@ -261,4 +261,9 @@ public final class MapManager
* Returns country ID which the current PP object points to, or {@code null}. * Returns country ID which the current PP object points to, or {@code null}.
*/ */
public static native @Nullable String nativeGetSelectedCountry(); public static native @Nullable String nativeGetSelectedCountry();
/**
* Returns true when the map exists and is too old for map editing.
*/
public static native boolean nativeIsMapTooOldToEdit(String countryId);
} }

View File

@@ -3,4 +3,5 @@
<string name="pref_file_name" translatable="false">OrganicMapsPrefs</string> <string name="pref_file_name" translatable="false">OrganicMapsPrefs</string>
<string name="pref_enable_logging" translatable="false">EnableLogging</string> <string name="pref_enable_logging" translatable="false">EnableLogging</string>
<string name="pref_emulate_bad_external_storage" translatable="false">EmulateBadExternalStorage</string> <string name="pref_emulate_bad_external_storage" translatable="false">EmulateBadExternalStorage</string>
<string name="pref_custom_map_download_url" translatable="false">CustomMapDownloadUrl</string>
</resources> </resources>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
id="svg3604"
width="41"
height="35.213001"
viewBox="0 0 820 704.26"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" />
<g
id="g3612"
transform="matrix(0,-0.08,-0.08,0,1056,751.84)">
<path
id="path3660"
style="fill:#999999;fill-opacity:1;stroke-width:10.9979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
d="M 2787,4111 C 3245,3388 4042,2950 4898,2950 H 9398 V 13200 H 4898 c -856,0 -1653,-440 -2112,-1160 L 866.3,9013 C 504.2,8440 504.2,7710 866.3,7137 L 2786,4110" />
<path
d="M 9021,12820 H 4898 c -728,0 -1405,-370 -1795,-990 L 1183,8811 C 898.3,8362 898.3,7788 1183,7338 L 3103,4311 c 390,-613 1067,-986 1795,-986 h 4123 z"
style="fill:#294c88;stroke-width:10.9979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;fill-opacity:1"
id="path3628" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1004 B

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
id="svg3604"
width="34.599998"
height="30.212999"
viewBox="0 0 823.80951 719.35714"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" />
<g
id="g3612"
transform="matrix(0,-0.08,-0.08,0,1056,751.84)">
<path
id="path3660"
style="fill:#999999;fill-opacity:1;stroke-width:10.9979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
d="m 2692.6554,4087.1907 c 458,-723 1255,-1161 2111,-1161 h 4500 V 13176.19 h -4500 c -856,0 -1653,-440 -2112,-1160 L 771.95535,8989.1907 c -362.1,-573 -362.1,-1303 0,-1876 l 1919.70005,-3027" />
<path
d="m 8926.6554,12796.19 h -4123 c -728,0 -1405,-370 -1795,-990 l -1920,-3018.9993 c -284.70005,-449 -284.70005,-1023 0,-1473 l 1920,-3027 c 390,-613 1067,-986 1795,-986 h 4123 z"
style="fill:#294c88;fill-opacity:1;stroke-width:10.9979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
id="path3628" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
id="svg848"
xml:space="preserve"
width="38.514999"
height="37"
viewBox="0 0 770.29999 740"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" />
<path
id="path874"
style="fill:#999999;stroke-width:0.9312;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;fill-opacity:1"
d="m 612.9,7.16 -7.6,7.04 -7.7,6.64 -8,6.48 -8.2,6.24 -8.2,6 -8.6,5.68 -8.7,5.44 -8.8,5.12 -9,4.96 -9.1,4.64 -9.4,4.24 -9.4,4.08 -9.6,3.68 -9.6,3.52 -9.8,3.12 -9.8,2.8 -10,2.56 -10,2.24 -10,1.84 -10.3,1.6 -10.1,1.28 -10.3,0.88 -10.2,0.72 -10.3,0.32 H 380 l -10.2,-0.32 -10.3,-0.72 -10.2,-0.88 -10.2,-1.28 -10.1,-1.6 -10,-1.84 -10,-2.24 -10,-2.56 -9.9,-2.8 -9.7,-3.12 -9.7,-3.52 -9.5,-3.68 -9.5,-4.08 -9.3,-4.24 -9.2,-4.64 -8.9,-4.96 -8.5,-5.12 -9.6,-5.44 -8,-5.68 -8,-6 -8.8,-6.24 -8,-6.48 -7.2,-6.64 -8,-7.04 L 150,-0.04 0.4,150 l 4.8,5.5 5.6,5.7 4,5.9 4.8,6.1 4,6.4 4,6.4 4,6.6 4,6.7 2.4,6.8 3.2,7.1 2.4,7.1 2.4,7.2 2.4,7.3 1.6,7.3 1.6,7.5 0.8,7.6 1.6,7.5 v 7.5 l 0.8,7.6 v 7.6 l -0.8,7.6 -0.8,7.5 -0.8,7.5 -0.8,7.6 -1.6,7.3 -2.4,7.5 -1.6,7.2 -2.4,7.2 -3.2,7.1 -2.4,7 -3.2,6.9 -3.2,6.7 -4,6.6 c -36,58.7 -36.8,131.8 -3.2,191.5 34.4,59.6 96.8,96.5 165.6,96.5 l 1.6,-0.1 8.8,0.2 10.4,0.4 9.6,0.8 9.2,1.1 9.5,1.3 9.4,1.7 9.3,2 9.4,2.3 9.2,2.6 9.2,2.8 9,3.1 8.9,3.5 8.8,3.7 8.7,4 8.6,4.3 8.4,4.5 8.3,4.8 8.1,5.1 8,5.3 7.8,5.6 7.6,5.8 7.3,6.1 7.5,-6.1 7.6,-5.8 7.7,-5.6 7.9,-5.3 8.2,-5.1 8.3,-4.8 8.4,-4.5 8.5,-4.3 8.8,-4 8.8,-3.7 8.9,-3.5 9.1,-3.1 9.1,-2.8 9.2,-2.6 9.3,-2.3 9.4,-2 9.4,-1.7 9.4,-1.3 9.6,-1.1 9.6,-0.8 9.5,-0.4 10.1,-0.2 c 69.2,0 132.4,-36.9 166.1,-96.5 33.7,-59.6 32.7,-132.8 -2.5,-191.4 l -3.9,-6.6 -3.4,-6.7 -3.3,-6.9 -3,-7 -2.7,-7.1 -2.4,-7.2 -2.1,-7.2 -1.7,-7.5 -1.6,-7.3 -1.2,-7.6 -1,-7.5 -0.6,-7.5 -0.3,-7.6 v -7.6 l 0.2,-7.6 0.6,-7.5 0.9,-7.5 1.2,-7.6 1.5,-7.5 1.8,-7.3 2.1,-7.3 2.3,-7.2 2.6,-7.1 3,-7.1 3.2,-6.8 3.5,-6.7 3.8,-6.6 4,-6.4 4.2,-6.4 4.5,-6.1 4.8,-5.9 5,-5.7 5.2,-5.5 -150,-150.04 z" />
<path
id="path872"
style="fill:#9f1a17;stroke-width:0.9312;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;fill-opacity:1"
d="m 729.4,151.6 -4.8,6.6 -4.4,6.8 -4.3,7 -4,7 -3.7,7.2 -3.4,7.4 -3.2,7.5 -2.9,7.6 -2.6,7.7 -2.3,7.7 -2,7.9 -1.8,8 -1.4,8 -1.2,8 -0.8,8.1 -0.6,8.2 -0.2,8.1 v 8.1 l 0.4,8.1 0.7,8.1 0.9,8.1 1.2,8 1.6,8 1.7,8 2.3,7.8 2.4,7.8 2.7,7.6 2.9,7.6 3.2,7.4 3.6,7.3 3.8,7.2 4,7 c 29.6,49.5 30.5,111.1 2.2,161.2 -28.4,50.3 -81.6,81.4 -140,81.4 l -10.9,0.1 -10.3,0.5 -10.4,0.8 -10.3,1.1 -10.2,1.5 -10.2,1.8 -10.1,2.1 -10,2.4 -10,2.7 -10,3.1 -9.7,3.2 -9.8,3.7 -9.5,4 -9.4,4.3 -9.3,4.5 -9.1,4.8 -9.1,5.1 -8.8,5.5 -8.7,5.7 -8.5,5.9 -8.4,-5.9 -8.7,-5.7 -8.8,-5.5 -9,-5.1 -9.2,-4.8 -9.2,-4.5 -9.5,-4.3 -9.6,-4 -9.7,-3.7 -9.7,-3.2 -9.9,-3.1 -10,-2.7 -10.1,-2.4 -10.1,-2.1 -10.2,-1.8 -10.3,-1.5 -10.2,-1.1 -10.1,-0.8 -11.2,-0.5 H 190.8 C 132.4,639.2 78.8,608 50.8,557.8 22,507.6 22.8,446 53.2,396.5 l 4,-7 4,-7.2 2.4,-7.3 4,-7.4 3.2,-7.6 2.4,-7.6 2.4,-7.8 2.4,-7.8 1.6,-8 1.6,-8 1.6,-8 0.8,-8.1 0.8,-8.1 v -8.1 -8.1 -8.1 l -0.8,-8.2 -0.8,-8.1 -0.8,-8 -1.6,-8 -1.6,-8 -2.4,-7.9 -2.4,-7.7 -2.4,-7.7 -3.2,-7.6 -3.2,-7.5 -3.2,-7.4 -3.2,-7.2 -4,-7 -4.8,-7 -4.8,-6.8 -4.8,-6.6 110.4,-109.96 8,6.64 8,6.48 8.8,6.16 8.8,5.92 8.8,5.76 8,5.44 9.6,5.12 8.8,4.96 9.5,4.64 9.5,4.4 9.6,4.04 9.6,3.8 9.9,3.6 9.8,3.3 10,2.9 10,2.7 10.2,2.4 10.1,2.1 10.3,1.7 10.3,1.6 10.3,1.1 10.4,1 10.4,0.6 10.4,0.2 h 10.4 l 10.4,-0.2 10.4,-0.6 10.4,-1 10.3,-1.1 10.4,-1.6 10.2,-1.7 10.2,-2.1 10.1,-2.4 10.1,-2.7 10,-2.9 9.9,-3.3 9.8,-3.6 9.7,-3.8 9.6,-4.04 9.4,-4.4 9.3,-4.64 9.2,-4.96 9,-5.12 8.9,-5.44 8.6,-5.76 8.7,-5.92 8.3,-6.16 8.2,-6.48 8,-6.64 z" />
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
id="svg848"
xml:space="preserve"
width="32.514999"
height="31"
viewBox="0 0 774.16667 738.09526"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" />
<path
id="path874"
style="fill:#999999;fill-opacity:1;stroke-width:0.9312;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
d="m 612.9,7.16 -7.6,7.04 -7.7,6.64 -8,6.48 -8.2,6.24 -8.2,6 -8.6,5.68 -8.7,5.44 -8.8,5.12 -9,4.96 -9.1,4.64 -9.4,4.24 -9.4,4.08 -9.6,3.68 -9.6,3.52 -9.8,3.12 -9.8,2.8 -10,2.56 -10,2.24 -10,1.84 -10.3,1.6 -10.1,1.28 -10.3,0.88 -10.2,0.72 -10.3,0.32 H 380 l -10.2,-0.32 -10.3,-0.72 -10.2,-0.88 -10.2,-1.28 -10.1,-1.6 -10,-1.84 -10,-2.24 -10,-2.56 -9.9,-2.8 -9.7,-3.12 -9.7,-3.52 -9.5,-3.68 -9.5,-4.08 -9.3,-4.24 -9.2,-4.64 -8.9,-4.96 -8.5,-5.12 -9.6,-5.44 -8,-5.68 -8,-6 -8.8,-6.24 -8,-6.48 -7.2,-6.64 -8,-7.04 L 150,-0.04 0.4,150 l 4.8,5.5 5.6,5.7 4,5.9 4.8,6.1 4,6.4 4,6.4 4,6.6 4,6.7 2.4,6.8 3.2,7.1 2.4,7.1 2.4,7.2 2.4,7.3 1.6,7.3 1.6,7.5 0.8,7.6 1.6,7.5 v 7.5 l 0.8,7.6 v 7.6 l -0.8,7.6 -0.8,7.5 -0.8,7.5 -0.8,7.6 -1.6,7.3 -2.4,7.5 -1.6,7.2 -2.4,7.2 -3.2,7.1 -2.4,7 -3.2,6.9 -3.2,6.7 -4,6.6 c -36,58.7 -36.8,131.8 -3.2,191.5 34.4,59.6 96.8,96.5 165.6,96.5 l 1.6,-0.1 8.8,0.2 10.4,0.4 9.6,0.8 9.2,1.1 9.5,1.3 9.4,1.7 9.3,2 9.4,2.3 9.2,2.6 9.2,2.8 9,3.1 8.9,3.5 8.8,3.7 8.7,4 8.6,4.3 8.4,4.5 8.3,4.8 8.1,5.1 8,5.3 7.8,5.6 7.6,5.8 7.3,6.1 7.5,-6.1 7.6,-5.8 7.7,-5.6 7.9,-5.3 8.2,-5.1 8.3,-4.8 8.4,-4.5 8.5,-4.3 8.8,-4 8.8,-3.7 8.9,-3.5 9.1,-3.1 9.1,-2.8 9.2,-2.6 9.3,-2.3 9.4,-2 9.4,-1.7 9.4,-1.3 9.6,-1.1 9.6,-0.8 9.5,-0.4 10.1,-0.2 c 69.2,0 132.4,-36.9 166.1,-96.5 33.7,-59.6 32.7,-132.8 -2.5,-191.4 l -3.9,-6.6 -3.4,-6.7 -3.3,-6.9 -3,-7 -2.7,-7.1 -2.4,-7.2 -2.1,-7.2 -1.7,-7.5 -1.6,-7.3 -1.2,-7.6 -1,-7.5 -0.6,-7.5 -0.3,-7.6 v -7.6 l 0.2,-7.6 0.6,-7.5 0.9,-7.5 1.2,-7.6 1.5,-7.5 1.8,-7.3 2.1,-7.3 2.3,-7.2 2.6,-7.1 3,-7.1 3.2,-6.8 3.5,-6.7 3.8,-6.6 4,-6.4 4.2,-6.4 4.5,-6.1 4.8,-5.9 5,-5.7 5.2,-5.5 -150,-150.04 z" />
<path
id="path872"
style="fill:#9f1a17;fill-opacity:1;stroke-width:0.9312;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
d="m 729.4,151.6 -4.8,6.6 -4.4,6.8 -4.3,7 -4,7 -3.7,7.2 -3.4,7.4 -3.2,7.5 -2.9,7.6 -2.6,7.7 -2.3,7.7 -2,7.9 -1.8,8 -1.4,8 -1.2,8 -0.8,8.1 -0.6,8.2 -0.2,8.1 v 8.1 l 0.4,8.1 0.7,8.1 0.9,8.1 1.2,8 1.6,8 1.7,8 2.3,7.8 2.4,7.8 2.7,7.6 2.9,7.6 3.2,7.4 3.6,7.3 3.8,7.2 4,7 c 29.6,49.5 30.5,111.1 2.2,161.2 -28.4,50.3 -81.6,81.4 -140,81.4 l -10.9,0.1 -10.3,0.5 -10.4,0.8 -10.3,1.1 -10.2,1.5 -10.2,1.8 -10.1,2.1 -10,2.4 -10,2.7 -10,3.1 -9.7,3.2 -9.8,3.7 -9.5,4 -9.4,4.3 -9.3,4.5 -9.1,4.8 -9.1,5.1 -8.8,5.5 -8.7,5.7 -8.5,5.9 -8.4,-5.9 -8.7,-5.7 -8.8,-5.5 -9,-5.1 -9.2,-4.8 -9.2,-4.5 -9.5,-4.3 -9.6,-4 -9.7,-3.7 -9.7,-3.2 -9.9,-3.1 -10,-2.7 -10.1,-2.4 -10.1,-2.1 -10.2,-1.8 -10.3,-1.5 -10.2,-1.1 -10.1,-0.8 -11.2,-0.5 H 190.8 C 132.4,639.2 78.8,608 50.8,557.8 22,507.6 22.8,446 53.2,396.5 l 4,-7 4,-7.2 2.4,-7.3 4,-7.4 3.2,-7.6 2.4,-7.6 2.4,-7.8 2.4,-7.8 1.6,-8 1.6,-8 1.6,-8 0.8,-8.1 0.8,-8.1 v -8.1 -8.1 -8.1 l -0.8,-8.2 -0.8,-8.1 -0.8,-8 -1.6,-8 -1.6,-8 -2.4,-7.9 -2.4,-7.7 -2.4,-7.7 -3.2,-7.6 -3.2,-7.5 -3.2,-7.4 -3.2,-7.2 -4,-7 -4.8,-7 -4.8,-6.8 -4.8,-6.6 110.4,-109.96 8,6.64 8,6.48 8.8,6.16 8.8,5.92 8.8,5.76 8,5.44 9.6,5.12 8.8,4.96 9.5,4.64 9.5,4.4 9.6,4.04 9.6,3.8 9.9,3.6 9.8,3.3 10,2.9 10,2.7 10.2,2.4 10.1,2.1 10.3,1.7 10.3,1.6 10.3,1.1 10.4,1 10.4,0.6 10.4,0.2 h 10.4 l 10.4,-0.2 10.4,-0.6 10.4,-1 10.3,-1.1 10.4,-1.6 10.2,-1.7 10.2,-2.1 10.1,-2.4 10.1,-2.7 10,-2.9 9.9,-3.3 9.8,-3.6 9.7,-3.8 9.6,-4.04 9.4,-4.4 9.3,-4.64 9.2,-4.96 9,-5.12 8.9,-5.44 8.6,-5.76 8.7,-5.92 8.3,-6.16 8.2,-6.48 8,-6.64 z" />
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
id="svg3604"
width="41"
height="35.213001"
viewBox="0 0 820 704.26"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" />
<g
id="g3612"
transform="matrix(0,-0.08,-0.08,0,1056,751.84)">
<path
id="path3660"
style="fill:#ffffff;fill-opacity:1;stroke-width:10.9979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
d="M 2787,4111 C 3245,3388 4042,2950 4898,2950 H 9398 V 13200 H 4898 c -856,0 -1653,-440 -2112,-1160 L 866.3,9013 C 504.2,8440 504.2,7710 866.3,7137 L 2786,4110" />
<path
d="M 9021,12820 H 4898 c -728,0 -1405,-370 -1795,-990 L 1183,8811 C 898.3,8362 898.3,7788 1183,7338 L 3103,4311 c 390,-613 1067,-986 1795,-986 h 4123 z"
style="fill:#1A5EC1;stroke-width:10.9979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;fill-opacity:1"
id="path3628" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1004 B

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
id="svg3604"
width="34.599998"
height="30.212999"
viewBox="0 0 823.80951 719.35714"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" />
<g
id="g3612"
transform="matrix(0,-0.08,-0.08,0,1056,751.84)">
<path
id="path3660"
style="fill:#ffffff;fill-opacity:1;stroke-width:10.9979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
d="m 2692.6554,4087.1907 c 458,-723 1255,-1161 2111,-1161 h 4500 V 13176.19 h -4500 c -856,0 -1653,-440 -2112,-1160 L 771.95535,8989.1907 c -362.1,-573 -362.1,-1303 0,-1876 l 1919.70005,-3027" />
<path
d="m 8926.6554,12796.19 h -4123 c -728,0 -1405,-370 -1795,-990 l -1920,-3018.9993 c -284.70005,-449 -284.70005,-1023 0,-1473 l 1920,-3027 c 390,-613 1067,-986 1795,-986 h 4123 z"
style="fill:#1A5EC1;fill-opacity:1;stroke-width:10.9979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
id="path3628" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
id="svg848"
xml:space="preserve"
width="38.514999"
height="37"
viewBox="0 0 770.29999 740"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" />
<path
id="path874"
style="fill:#ffffff;stroke-width:0.9312;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;fill-opacity:1"
d="m 612.9,7.16 -7.6,7.04 -7.7,6.64 -8,6.48 -8.2,6.24 -8.2,6 -8.6,5.68 -8.7,5.44 -8.8,5.12 -9,4.96 -9.1,4.64 -9.4,4.24 -9.4,4.08 -9.6,3.68 -9.6,3.52 -9.8,3.12 -9.8,2.8 -10,2.56 -10,2.24 -10,1.84 -10.3,1.6 -10.1,1.28 -10.3,0.88 -10.2,0.72 -10.3,0.32 H 380 l -10.2,-0.32 -10.3,-0.72 -10.2,-0.88 -10.2,-1.28 -10.1,-1.6 -10,-1.84 -10,-2.24 -10,-2.56 -9.9,-2.8 -9.7,-3.12 -9.7,-3.52 -9.5,-3.68 -9.5,-4.08 -9.3,-4.24 -9.2,-4.64 -8.9,-4.96 -8.5,-5.12 -9.6,-5.44 -8,-5.68 -8,-6 -8.8,-6.24 -8,-6.48 -7.2,-6.64 -8,-7.04 L 150,-0.04 0.4,150 l 4.8,5.5 5.6,5.7 4,5.9 4.8,6.1 4,6.4 4,6.4 4,6.6 4,6.7 2.4,6.8 3.2,7.1 2.4,7.1 2.4,7.2 2.4,7.3 1.6,7.3 1.6,7.5 0.8,7.6 1.6,7.5 v 7.5 l 0.8,7.6 v 7.6 l -0.8,7.6 -0.8,7.5 -0.8,7.5 -0.8,7.6 -1.6,7.3 -2.4,7.5 -1.6,7.2 -2.4,7.2 -3.2,7.1 -2.4,7 -3.2,6.9 -3.2,6.7 -4,6.6 c -36,58.7 -36.8,131.8 -3.2,191.5 34.4,59.6 96.8,96.5 165.6,96.5 l 1.6,-0.1 8.8,0.2 10.4,0.4 9.6,0.8 9.2,1.1 9.5,1.3 9.4,1.7 9.3,2 9.4,2.3 9.2,2.6 9.2,2.8 9,3.1 8.9,3.5 8.8,3.7 8.7,4 8.6,4.3 8.4,4.5 8.3,4.8 8.1,5.1 8,5.3 7.8,5.6 7.6,5.8 7.3,6.1 7.5,-6.1 7.6,-5.8 7.7,-5.6 7.9,-5.3 8.2,-5.1 8.3,-4.8 8.4,-4.5 8.5,-4.3 8.8,-4 8.8,-3.7 8.9,-3.5 9.1,-3.1 9.1,-2.8 9.2,-2.6 9.3,-2.3 9.4,-2 9.4,-1.7 9.4,-1.3 9.6,-1.1 9.6,-0.8 9.5,-0.4 10.1,-0.2 c 69.2,0 132.4,-36.9 166.1,-96.5 33.7,-59.6 32.7,-132.8 -2.5,-191.4 l -3.9,-6.6 -3.4,-6.7 -3.3,-6.9 -3,-7 -2.7,-7.1 -2.4,-7.2 -2.1,-7.2 -1.7,-7.5 -1.6,-7.3 -1.2,-7.6 -1,-7.5 -0.6,-7.5 -0.3,-7.6 v -7.6 l 0.2,-7.6 0.6,-7.5 0.9,-7.5 1.2,-7.6 1.5,-7.5 1.8,-7.3 2.1,-7.3 2.3,-7.2 2.6,-7.1 3,-7.1 3.2,-6.8 3.5,-6.7 3.8,-6.6 4,-6.4 4.2,-6.4 4.5,-6.1 4.8,-5.9 5,-5.7 5.2,-5.5 -150,-150.04 z" />
<path
id="path872"
style="fill:#E63534;stroke-width:0.9312;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;fill-opacity:1"
d="m 729.4,151.6 -4.8,6.6 -4.4,6.8 -4.3,7 -4,7 -3.7,7.2 -3.4,7.4 -3.2,7.5 -2.9,7.6 -2.6,7.7 -2.3,7.7 -2,7.9 -1.8,8 -1.4,8 -1.2,8 -0.8,8.1 -0.6,8.2 -0.2,8.1 v 8.1 l 0.4,8.1 0.7,8.1 0.9,8.1 1.2,8 1.6,8 1.7,8 2.3,7.8 2.4,7.8 2.7,7.6 2.9,7.6 3.2,7.4 3.6,7.3 3.8,7.2 4,7 c 29.6,49.5 30.5,111.1 2.2,161.2 -28.4,50.3 -81.6,81.4 -140,81.4 l -10.9,0.1 -10.3,0.5 -10.4,0.8 -10.3,1.1 -10.2,1.5 -10.2,1.8 -10.1,2.1 -10,2.4 -10,2.7 -10,3.1 -9.7,3.2 -9.8,3.7 -9.5,4 -9.4,4.3 -9.3,4.5 -9.1,4.8 -9.1,5.1 -8.8,5.5 -8.7,5.7 -8.5,5.9 -8.4,-5.9 -8.7,-5.7 -8.8,-5.5 -9,-5.1 -9.2,-4.8 -9.2,-4.5 -9.5,-4.3 -9.6,-4 -9.7,-3.7 -9.7,-3.2 -9.9,-3.1 -10,-2.7 -10.1,-2.4 -10.1,-2.1 -10.2,-1.8 -10.3,-1.5 -10.2,-1.1 -10.1,-0.8 -11.2,-0.5 H 190.8 C 132.4,639.2 78.8,608 50.8,557.8 22,507.6 22.8,446 53.2,396.5 l 4,-7 4,-7.2 2.4,-7.3 4,-7.4 3.2,-7.6 2.4,-7.6 2.4,-7.8 2.4,-7.8 1.6,-8 1.6,-8 1.6,-8 0.8,-8.1 0.8,-8.1 v -8.1 -8.1 -8.1 l -0.8,-8.2 -0.8,-8.1 -0.8,-8 -1.6,-8 -1.6,-8 -2.4,-7.9 -2.4,-7.7 -2.4,-7.7 -3.2,-7.6 -3.2,-7.5 -3.2,-7.4 -3.2,-7.2 -4,-7 -4.8,-7 -4.8,-6.8 -4.8,-6.6 110.4,-109.96 8,6.64 8,6.48 8.8,6.16 8.8,5.92 8.8,5.76 8,5.44 9.6,5.12 8.8,4.96 9.5,4.64 9.5,4.4 9.6,4.04 9.6,3.8 9.9,3.6 9.8,3.3 10,2.9 10,2.7 10.2,2.4 10.1,2.1 10.3,1.7 10.3,1.6 10.3,1.1 10.4,1 10.4,0.6 10.4,0.2 h 10.4 l 10.4,-0.2 10.4,-0.6 10.4,-1 10.3,-1.1 10.4,-1.6 10.2,-1.7 10.2,-2.1 10.1,-2.4 10.1,-2.7 10,-2.9 9.9,-3.3 9.8,-3.6 9.7,-3.8 9.6,-4.04 9.4,-4.4 9.3,-4.64 9.2,-4.96 9,-5.12 8.9,-5.44 8.6,-5.76 8.7,-5.92 8.3,-6.16 8.2,-6.48 8,-6.64 z" />
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
id="svg848"
xml:space="preserve"
width="32.514999"
height="31"
viewBox="0 0 774.16667 738.09526"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" />
<path
id="path874"
style="fill:#ffffff;fill-opacity:1;stroke-width:0.9312;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
d="m 612.9,7.16 -7.6,7.04 -7.7,6.64 -8,6.48 -8.2,6.24 -8.2,6 -8.6,5.68 -8.7,5.44 -8.8,5.12 -9,4.96 -9.1,4.64 -9.4,4.24 -9.4,4.08 -9.6,3.68 -9.6,3.52 -9.8,3.12 -9.8,2.8 -10,2.56 -10,2.24 -10,1.84 -10.3,1.6 -10.1,1.28 -10.3,0.88 -10.2,0.72 -10.3,0.32 H 380 l -10.2,-0.32 -10.3,-0.72 -10.2,-0.88 -10.2,-1.28 -10.1,-1.6 -10,-1.84 -10,-2.24 -10,-2.56 -9.9,-2.8 -9.7,-3.12 -9.7,-3.52 -9.5,-3.68 -9.5,-4.08 -9.3,-4.24 -9.2,-4.64 -8.9,-4.96 -8.5,-5.12 -9.6,-5.44 -8,-5.68 -8,-6 -8.8,-6.24 -8,-6.48 -7.2,-6.64 -8,-7.04 L 150,-0.04 0.4,150 l 4.8,5.5 5.6,5.7 4,5.9 4.8,6.1 4,6.4 4,6.4 4,6.6 4,6.7 2.4,6.8 3.2,7.1 2.4,7.1 2.4,7.2 2.4,7.3 1.6,7.3 1.6,7.5 0.8,7.6 1.6,7.5 v 7.5 l 0.8,7.6 v 7.6 l -0.8,7.6 -0.8,7.5 -0.8,7.5 -0.8,7.6 -1.6,7.3 -2.4,7.5 -1.6,7.2 -2.4,7.2 -3.2,7.1 -2.4,7 -3.2,6.9 -3.2,6.7 -4,6.6 c -36,58.7 -36.8,131.8 -3.2,191.5 34.4,59.6 96.8,96.5 165.6,96.5 l 1.6,-0.1 8.8,0.2 10.4,0.4 9.6,0.8 9.2,1.1 9.5,1.3 9.4,1.7 9.3,2 9.4,2.3 9.2,2.6 9.2,2.8 9,3.1 8.9,3.5 8.8,3.7 8.7,4 8.6,4.3 8.4,4.5 8.3,4.8 8.1,5.1 8,5.3 7.8,5.6 7.6,5.8 7.3,6.1 7.5,-6.1 7.6,-5.8 7.7,-5.6 7.9,-5.3 8.2,-5.1 8.3,-4.8 8.4,-4.5 8.5,-4.3 8.8,-4 8.8,-3.7 8.9,-3.5 9.1,-3.1 9.1,-2.8 9.2,-2.6 9.3,-2.3 9.4,-2 9.4,-1.7 9.4,-1.3 9.6,-1.1 9.6,-0.8 9.5,-0.4 10.1,-0.2 c 69.2,0 132.4,-36.9 166.1,-96.5 33.7,-59.6 32.7,-132.8 -2.5,-191.4 l -3.9,-6.6 -3.4,-6.7 -3.3,-6.9 -3,-7 -2.7,-7.1 -2.4,-7.2 -2.1,-7.2 -1.7,-7.5 -1.6,-7.3 -1.2,-7.6 -1,-7.5 -0.6,-7.5 -0.3,-7.6 v -7.6 l 0.2,-7.6 0.6,-7.5 0.9,-7.5 1.2,-7.6 1.5,-7.5 1.8,-7.3 2.1,-7.3 2.3,-7.2 2.6,-7.1 3,-7.1 3.2,-6.8 3.5,-6.7 3.8,-6.6 4,-6.4 4.2,-6.4 4.5,-6.1 4.8,-5.9 5,-5.7 5.2,-5.5 -150,-150.04 z" />
<path
id="path872"
style="fill:#E63534;fill-opacity:1;stroke-width:0.9312;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
d="m 729.4,151.6 -4.8,6.6 -4.4,6.8 -4.3,7 -4,7 -3.7,7.2 -3.4,7.4 -3.2,7.5 -2.9,7.6 -2.6,7.7 -2.3,7.7 -2,7.9 -1.8,8 -1.4,8 -1.2,8 -0.8,8.1 -0.6,8.2 -0.2,8.1 v 8.1 l 0.4,8.1 0.7,8.1 0.9,8.1 1.2,8 1.6,8 1.7,8 2.3,7.8 2.4,7.8 2.7,7.6 2.9,7.6 3.2,7.4 3.6,7.3 3.8,7.2 4,7 c 29.6,49.5 30.5,111.1 2.2,161.2 -28.4,50.3 -81.6,81.4 -140,81.4 l -10.9,0.1 -10.3,0.5 -10.4,0.8 -10.3,1.1 -10.2,1.5 -10.2,1.8 -10.1,2.1 -10,2.4 -10,2.7 -10,3.1 -9.7,3.2 -9.8,3.7 -9.5,4 -9.4,4.3 -9.3,4.5 -9.1,4.8 -9.1,5.1 -8.8,5.5 -8.7,5.7 -8.5,5.9 -8.4,-5.9 -8.7,-5.7 -8.8,-5.5 -9,-5.1 -9.2,-4.8 -9.2,-4.5 -9.5,-4.3 -9.6,-4 -9.7,-3.7 -9.7,-3.2 -9.9,-3.1 -10,-2.7 -10.1,-2.4 -10.1,-2.1 -10.2,-1.8 -10.3,-1.5 -10.2,-1.1 -10.1,-0.8 -11.2,-0.5 H 190.8 C 132.4,639.2 78.8,608 50.8,557.8 22,507.6 22.8,446 53.2,396.5 l 4,-7 4,-7.2 2.4,-7.3 4,-7.4 3.2,-7.6 2.4,-7.6 2.4,-7.8 2.4,-7.8 1.6,-8 1.6,-8 1.6,-8 0.8,-8.1 0.8,-8.1 v -8.1 -8.1 -8.1 l -0.8,-8.2 -0.8,-8.1 -0.8,-8 -1.6,-8 -1.6,-8 -2.4,-7.9 -2.4,-7.7 -2.4,-7.7 -3.2,-7.6 -3.2,-7.5 -3.2,-7.4 -3.2,-7.2 -4,-7 -4.8,-7 -4.8,-6.8 -4.8,-6.6 110.4,-109.96 8,6.64 8,6.48 8.8,6.16 8.8,5.92 8.8,5.76 8,5.44 9.6,5.12 8.8,4.96 9.5,4.64 9.5,4.4 9.6,4.04 9.6,3.8 9.9,3.6 9.8,3.3 10,2.9 10,2.7 10.2,2.4 10.1,2.1 10.3,1.7 10.3,1.6 10.3,1.1 10.4,1 10.4,0.6 10.4,0.2 h 10.4 l 10.4,-0.2 10.4,-0.6 10.4,-1 10.3,-1.1 10.4,-1.6 10.2,-1.7 10.2,-2.1 10.1,-2.4 10.1,-2.7 10,-2.9 9.9,-3.3 9.8,-3.6 9.7,-3.8 9.6,-4.04 9.4,-4.4 9.3,-4.64 9.2,-4.96 9,-5.12 8.9,-5.44 8.6,-5.76 8.7,-5.92 8.3,-6.16 8.2,-6.48 8,-6.64 z" />
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -81,7 +81,7 @@ public:
QPainter painter(device); QPainter painter(device);
painter.fillRect(QRectF(0.0, 0.0, device->width(), device->height()), Qt::white); painter.fillRect(QRectF(0.0, 0.0, device->width(), device->height()), Qt::white);
auto const shapedText = m_mng->ShapeText(m_utf8, m_fontPixelSize, m_lang); auto const shapedText = m_mng->ShapeText(m_utf8, m_fontPixelSize);
std::cout << "Total width: " << shapedText.m_lineWidthInPixels << '\n'; std::cout << "Total width: " << shapedText.m_lineWidthInPixels << '\n';
std::cout << "Max height: " << shapedText.m_maxLineHeightInPixels << '\n'; std::cout << "Max height: " << shapedText.m_maxLineHeightInPixels << '\n';

View File

@@ -5,6 +5,7 @@
#include "drape/harfbuzz_shaping.hpp" #include "drape/harfbuzz_shaping.hpp"
#include "platform/platform.hpp" #include "platform/platform.hpp"
#include "platform/preferred_languages.hpp"
#include "coding/hex.hpp" #include "coding/hex.hpp"
#include "coding/reader.hpp" #include "coding/reader.hpp"
@@ -328,6 +329,9 @@ FreetypeError constexpr g_FT_Errors[] =
TUniBlockIter m_lastUsedBlock; TUniBlockIter m_lastUsedBlock;
std::vector<std::unique_ptr<Font>> m_fonts; std::vector<std::unique_ptr<Font>> m_fonts;
std::string const lang = languages::GetCurrentOrig();
hb_language_t const m_language = hb_language_from_string(lang.data(), static_cast<int>(lang.size()));
// Required to use std::string_view as a search key for std::unordered_map::find(). // Required to use std::string_view as a search key for std::unordered_map::find().
struct StringHash : public std::hash<std::string_view> struct StringHash : public std::hash<std::string_view>
{ {
@@ -563,21 +567,8 @@ FreetypeError constexpr g_FT_Errors[] =
return m_impl->m_fonts[key.m_fontIndex]->GetGlyphImage(key.m_glyphId, pixelHeight, sdf); return m_impl->m_fonts[key.m_fontIndex]->GetGlyphImage(key.m_glyphId, pixelHeight, sdf);
} }
namespace
{
hb_language_t OrganicMapsLanguageToHarfbuzzLanguage(int8_t lang)
{
// TODO(AB): can langs be converted faster?
auto const svLang = StringUtf8Multilang::GetLangByCode(lang);
auto const hbLanguage = hb_language_from_string(svLang.data(), static_cast<int>(svLang.size()));
if (hbLanguage == HB_LANGUAGE_INVALID)
return hb_language_get_default();
return hbLanguage;
}
} // namespace
// This method is NOT multithreading-safe. // This method is NOT multithreading-safe.
text::TextMetrics GlyphManager::ShapeText(std::string_view utf8, int fontPixelHeight, int8_t lang) text::TextMetrics GlyphManager::ShapeText(std::string_view utf8, int fontPixelHeight)
{ {
#ifdef DEBUG #ifdef DEBUG
static int const fontSize = fontPixelHeight; static int const fontSize = fontPixelHeight;
@@ -591,9 +582,6 @@ FreetypeError constexpr g_FT_Errors[] =
auto const [text, segments] = harfbuzz_shaping::GetTextSegments(utf8); auto const [text, segments] = harfbuzz_shaping::GetTextSegments(utf8);
// TODO(AB): Optimize language conversion.
hb_language_t const hbLanguage = OrganicMapsLanguageToHarfbuzzLanguage(lang);
text::TextMetrics allGlyphs; text::TextMetrics allGlyphs;
// For SplitText it's enough to know if the last visual (first logical) segment is RTL. // For SplitText it's enough to know if the last visual (first logical) segment is RTL.
allGlyphs.m_isRTL = segments.back().m_direction == HB_DIRECTION_RTL; allGlyphs.m_isRTL = segments.back().m_direction == HB_DIRECTION_RTL;
@@ -609,7 +597,8 @@ FreetypeError constexpr g_FT_Errors[] =
static_cast<int>(text.size()), substring.m_start, substring.m_length); static_cast<int>(text.size()), substring.m_start, substring.m_length);
hb_buffer_set_direction(m_impl->m_harfbuzzBuffer, substring.m_direction); hb_buffer_set_direction(m_impl->m_harfbuzzBuffer, substring.m_direction);
hb_buffer_set_script(m_impl->m_harfbuzzBuffer, substring.m_script); hb_buffer_set_script(m_impl->m_harfbuzzBuffer, substring.m_script);
hb_buffer_set_language(m_impl->m_harfbuzzBuffer, hbLanguage); // TODO: This property is static, is it possible to set it only once?
hb_buffer_set_language(m_impl->m_harfbuzzBuffer, m_impl->m_language);
auto u32CharacterIter{text.begin() + substring.m_start}; auto u32CharacterIter{text.begin() + substring.m_start};
auto const end{u32CharacterIter + substring.m_length}; auto const end{u32CharacterIter + substring.m_length};
@@ -646,10 +635,4 @@ FreetypeError constexpr g_FT_Errors[] =
return allGlyphs; return allGlyphs;
} }
text::TextMetrics GlyphManager::ShapeText(std::string_view utf8, int fontPixelHeight, char const * lang)
{
return ShapeText(utf8, fontPixelHeight, StringUtf8Multilang::GetLangIndex(lang));
}
} // namespace dp } // namespace dp

View File

@@ -73,8 +73,7 @@ public:
int GetFontIndex(strings::UniChar unicodePoint); int GetFontIndex(strings::UniChar unicodePoint);
int GetFontIndex(std::u16string_view sv); int GetFontIndex(std::u16string_view sv);
text::TextMetrics ShapeText(std::string_view utf8, int fontPixelHeight, int8_t lang); text::TextMetrics ShapeText(std::string_view utf8, int fontPixelHeight);
text::TextMetrics ShapeText(std::string_view utf8, int fontPixelHeight, char const * lang);
GlyphImage GetGlyphImage(GlyphFontAndId key, int pixelHeight, bool sdf) const; GlyphImage GetGlyphImage(GlyphFontAndId key, int pixelHeight, bool sdf) const;

View File

@@ -372,7 +372,7 @@ void TextureManager::Init(ref_ptr<dp::GraphicsContext> context, Params const & p
m_maxGlypsCount = static_cast<uint32_t>(ceil(kGlyphAreaCoverage * textureSquare / averageGlyphSquare)); m_maxGlypsCount = static_cast<uint32_t>(ceil(kGlyphAreaCoverage * textureSquare / averageGlyphSquare));
std::string_view constexpr kSpace{" "}; std::string_view constexpr kSpace{" "};
m_spaceGlyph = m_glyphManager->ShapeText(kSpace, dp::kBaseFontSizePixels, "en").m_glyphs.front().m_key; m_spaceGlyph = m_glyphManager->ShapeText(kSpace, dp::kBaseFontSizePixels).m_glyphs.front().m_key;
LOG(LDEBUG, ("Glyphs texture size =", kGlyphsTextureSize, "with max glyphs count =", m_maxGlypsCount)); LOG(LDEBUG, ("Glyphs texture size =", kGlyphsTextureSize, "with max glyphs count =", m_maxGlypsCount));
@@ -467,8 +467,7 @@ text::TextMetrics TextureManager::ShapeSingleTextLine(float fontPixelHeight, std
// TODO(AB): Is this mutex too slow? // TODO(AB): Is this mutex too slow?
std::lock_guard lock(m_calcGlyphsMutex); std::lock_guard lock(m_calcGlyphsMutex);
// TODO(AB): Fix hard-coded lang. auto textMetrics = m_glyphManager->ShapeText(utf8, fontPixelHeight);
auto textMetrics = m_glyphManager->ShapeText(utf8, fontPixelHeight, "en");
auto const & glyphs = textMetrics.m_glyphs; auto const & glyphs = textMetrics.m_glyphs;

View File

@@ -196,7 +196,7 @@ m2::PointF GetOffset(int offsetX, int offsetY)
bool IsSymbolRoadShield(ftypes::RoadShield const & shield) bool IsSymbolRoadShield(ftypes::RoadShield const & shield)
{ {
return shield.m_type == ftypes::RoadShieldType::Highway_Hexagon_Green || shield.m_type == ftypes::RoadShieldType::Highway_Hexagon_Blue || shield.m_type == ftypes::RoadShieldType::Highway_Hexagon_Red || shield.m_type == ftypes::RoadShieldType::Highway_Hexagon_Turkey || shield.m_type == ftypes::RoadShieldType::US_Interstate || shield.m_type == ftypes::RoadShieldType::US_Highway || shield.m_type == ftypes::RoadShieldType::Italy_Autostrada || shield.m_type == ftypes::RoadShieldType::Hungary_Green || shield.m_type == ftypes::RoadShieldType::Hungary_Blue; return shield.m_type == ftypes::RoadShieldType::Highway_Hexagon_Green || shield.m_type == ftypes::RoadShieldType::Highway_Hexagon_Blue || shield.m_type == ftypes::RoadShieldType::Highway_Hexagon_Red || shield.m_type == ftypes::RoadShieldType::Highway_Hexagon_Turkey || shield.m_type == ftypes::RoadShieldType::US_Interstate || shield.m_type == ftypes::RoadShieldType::US_Highway || shield.m_type == ftypes::RoadShieldType::Italy_Autostrada || shield.m_type == ftypes::RoadShieldType::Hungary_Green || shield.m_type == ftypes::RoadShieldType::Hungary_Blue || shield.m_type == ftypes::RoadShieldType::Romania_DN || shield.m_type == ftypes::RoadShieldType::Romania_DJ;
} }
std::string GetRoadShieldSymbolName(ftypes::RoadShield const & shield, double fontScale) std::string GetRoadShieldSymbolName(ftypes::RoadShield const & shield, double fontScale)
@@ -221,6 +221,10 @@ std::string GetRoadShieldSymbolName(ftypes::RoadShield const & shield, double fo
result = "shield-hungary-green"; result = "shield-hungary-green";
else if (shield.m_type == ftypes::RoadShieldType::Hungary_Blue) else if (shield.m_type == ftypes::RoadShieldType::Hungary_Blue)
result = "shield-hungary-blue"; result = "shield-hungary-blue";
else if (shield.m_type == ftypes::RoadShieldType::Romania_DN)
result = "shield-ro-dn";
else if (shield.m_type == ftypes::RoadShieldType::Romania_DJ)
result = "shield-ro-dj";
else else
ASSERT(false, ("This shield type doesn't support symbols:", shield.m_type)); ASSERT(false, ("This shield type doesn't support symbols:", shield.m_type));
@@ -327,7 +331,9 @@ dp::Color GetRoadShieldTextColor(dp::Color const & baseColor, ftypes::RoadShield
{RoadShieldType::UK_Highway, kRoadShieldUKYellowTextColor}, {RoadShieldType::UK_Highway, kRoadShieldUKYellowTextColor},
{RoadShieldType::Italy_Autostrada, kRoadShieldWhiteTextColor}, {RoadShieldType::Italy_Autostrada, kRoadShieldWhiteTextColor},
{RoadShieldType::Hungary_Green, kRoadShieldWhiteTextColor}, {RoadShieldType::Hungary_Green, kRoadShieldWhiteTextColor},
{RoadShieldType::Hungary_Blue, kRoadShieldWhiteTextColor}}; {RoadShieldType::Hungary_Blue, kRoadShieldWhiteTextColor},
{RoadShieldType::Romania_DN, kRoadShieldWhiteTextColor},
{RoadShieldType::Romania_DJ, kRoadShieldWhiteTextColor}};
if (auto const * cl = kColors.Find(shield.m_type); cl) if (auto const * cl = kColors.Find(shield.m_type); cl)
return df::GetColorConstant(*cl); return df::GetColorConstant(*cl);

View File

@@ -31,9 +31,9 @@ namespace df
{ {
namespace namespace
{ {
uint64_t constexpr kDoubleTapPauseMs = 250; uint64_t constexpr kDoubleTapPauseMs = 160;
uint64_t constexpr kLongTouchMs = 500; uint64_t constexpr kLongTouchMs = 300;
uint64_t constexpr kKineticDelayMs = 500; uint64_t constexpr kKineticDelayMs = 300;
float constexpr kForceTapThreshold = 0.75; float constexpr kForceTapThreshold = 0.75;

View File

@@ -514,9 +514,11 @@ public:
: HighwayClassRoadShieldParser(baseRoadNumber, highwayClass, : HighwayClassRoadShieldParser(baseRoadNumber, highwayClass,
{{"A", HighwayClass::Motorway, RoadShieldType::Generic_Blue_Bordered}, {{"A", HighwayClass::Motorway, RoadShieldType::Generic_Blue_Bordered},
{"S", HighwayClass::Trunk, RoadShieldType::Generic_Blue_Bordered}, {"S", HighwayClass::Trunk, RoadShieldType::Generic_Blue_Bordered},
{"B", HighwayClass::Primary, RoadShieldType::Generic_Blue}, {"B", HighwayClass::Primary, RoadShieldType::Generic_Blue, false, true},
{"L", HighwayClass::Secondary, RoadShieldType::Generic_Pill_White_Bordered}, {"B", HighwayClass::Trunk, RoadShieldType::Generic_Blue, false, true},
{"L", HighwayClass::Tertiary, RoadShieldType::Generic_Pill_White_Bordered}}) {"P", HighwayClass::Primary, RoadShieldType::Generic_Pill_Red_Bordered, false, true},
{"L", HighwayClass::Secondary, RoadShieldType::Generic_Pill_White_Bordered, false, true},
{"L", HighwayClass::Tertiary, RoadShieldType::Generic_Pill_White_Bordered, false, true}})
{} {}
}; };
@@ -554,9 +556,22 @@ class ItalyRoadShieldParser : public SimpleRoadShieldParser
public: public:
explicit ItalyRoadShieldParser(std::string const & baseRoadNumber) explicit ItalyRoadShieldParser(std::string const & baseRoadNumber)
: SimpleRoadShieldParser(baseRoadNumber, {{"A", RoadShieldType::Italy_Autostrada}, : SimpleRoadShieldParser(baseRoadNumber, {{"A", RoadShieldType::Italy_Autostrada},
{"SS", RoadShieldType::Generic_Blue}, {"T", RoadShieldType::Italy_Autostrada},
{"SR", RoadShieldType::Generic_Blue}, {"RA", RoadShieldType::Generic_Green_Bordered},
{"SP", RoadShieldType::Generic_Blue}}) {"E", RoadShieldType::Generic_Green_Bordered},
{"SS", RoadShieldType::Generic_Blue_Bordered},
{"SR", RoadShieldType::Generic_Blue_Bordered},
{"SP", RoadShieldType::Generic_Blue_Bordered}})
{}
};
class AlbaniaRoadShieldParser : public SimpleRoadShieldParser
{
public:
explicit AlbaniaRoadShieldParser(std::string const & baseRoadNumber)
: SimpleRoadShieldParser(baseRoadNumber, {{"A", RoadShieldType::Italy_Autostrada},
{"SH", RoadShieldType::Generic_Blue_Bordered},
{"RR", RoadShieldType::Generic_Blue_Bordered},
{"E", RoadShieldType::Generic_Green_Bordered}})
{} {}
}; };
@@ -577,14 +592,6 @@ public:
{} {}
}; };
class LativaRoadShieldParser : public SimpleRoadShieldParser
{
public:
explicit LativaRoadShieldParser(std::string const & baseRoadNumber)
: SimpleRoadShieldParser(baseRoadNumber, {{"A", RoadShieldType::Generic_Red}, {"P", RoadShieldType::Generic_Blue}})
{}
};
class MoldovaRoadShieldParser : public SimpleRoadShieldParser class MoldovaRoadShieldParser : public SimpleRoadShieldParser
{ {
public: public:
@@ -599,7 +606,9 @@ public:
explicit PortugalRoadShieldParser(std::string const & baseRoadNumber) explicit PortugalRoadShieldParser(std::string const & baseRoadNumber)
: SimpleRoadShieldParser(baseRoadNumber, {{"A", RoadShieldType::Generic_Blue}, : SimpleRoadShieldParser(baseRoadNumber, {{"A", RoadShieldType::Generic_Blue},
{"N", RoadShieldType::Generic_White_Bordered}, {"N", RoadShieldType::Generic_White_Bordered},
{"IP", RoadShieldType::Generic_Red},
{"EN", RoadShieldType::Generic_White_Bordered}, {"EN", RoadShieldType::Generic_White_Bordered},
{"IC", RoadShieldType::Generic_White_Bordered},
{"R", RoadShieldType::Generic_Orange}, {"R", RoadShieldType::Generic_Orange},
{"EM", RoadShieldType::Generic_Orange}, {"EM", RoadShieldType::Generic_Orange},
{"CM", RoadShieldType::Generic_Orange}}) {"CM", RoadShieldType::Generic_Orange}})
@@ -611,9 +620,10 @@ class RomaniaRoadShieldParser : public SimpleRoadShieldParser
public: public:
explicit RomaniaRoadShieldParser(std::string const & baseRoadNumber) explicit RomaniaRoadShieldParser(std::string const & baseRoadNumber)
: SimpleRoadShieldParser(baseRoadNumber, {{"A", RoadShieldType::Generic_Green}, : SimpleRoadShieldParser(baseRoadNumber, {{"A", RoadShieldType::Generic_Green},
{"DN", RoadShieldType::Generic_Red}, {"DN", RoadShieldType::Romania_DN, false, true},
{"DJ", RoadShieldType::Generic_Blue}, {"DJ", RoadShieldType::Romania_DJ, false, true},
{"DC", RoadShieldType::Generic_Blue}}) {"DC", RoadShieldType::Romania_DJ, false, true},
{"DX", RoadShieldType::Romania_DJ, false, true}})
{} {}
}; };
@@ -891,12 +901,14 @@ RoadShieldsSetT GetRoadShields(std::string const & mwmName, std::string const &
return IrelandRoadShieldParser(roadNumber).GetRoadShields(); return IrelandRoadShieldParser(roadNumber).GetRoadShields();
if (mwmName == "Italy") if (mwmName == "Italy")
return ItalyRoadShieldParser(roadNumber).GetRoadShields(); return ItalyRoadShieldParser(roadNumber).GetRoadShields();
if (mwmName == "Albania")
return AlbaniaRoadShieldParser(roadNumber).GetRoadShields();
if (mwmName == "Turkey") if (mwmName == "Turkey")
return TurkeyRoadShieldParser(roadNumber).GetRoadShields(); return TurkeyRoadShieldParser(roadNumber).GetRoadShields();
if (mwmName == "Hungary") if (mwmName == "Hungary")
return HungaryRoadShieldParser(roadNumber).GetRoadShields(); return HungaryRoadShieldParser(roadNumber).GetRoadShields();
if (mwmName == "Lativa") if (mwmName == "Latvia")
return LativaRoadShieldParser(roadNumber).GetRoadShields(); return LatviaRoadShieldParser(roadNumber).GetRoadShields();
if (mwmName == "Moldova") if (mwmName == "Moldova")
return MoldovaRoadShieldParser(roadNumber).GetRoadShields(); return MoldovaRoadShieldParser(roadNumber).GetRoadShields();
if (mwmName == "Portugal") if (mwmName == "Portugal")
@@ -997,6 +1009,8 @@ std::string DebugPrint(RoadShieldType shieldType)
case RoadShieldType::Italy_Autostrada: return "Italy autostrada"; case RoadShieldType::Italy_Autostrada: return "Italy autostrada";
case RoadShieldType::Hungary_Green: return "hungary green"; case RoadShieldType::Hungary_Green: return "hungary green";
case RoadShieldType::Hungary_Blue: return "hungary blue"; case RoadShieldType::Hungary_Blue: return "hungary blue";
case RoadShieldType::Romania_DN: return "romania dn";
case RoadShieldType::Romania_DJ: return "romania dj";
case RoadShieldType::Hidden: return "hidden"; case RoadShieldType::Hidden: return "hidden";
case RoadShieldType::Count: CHECK(false, ("RoadShieldType::Count is not to be used as a type")); case RoadShieldType::Count: CHECK(false, ("RoadShieldType::Count is not to be used as a type"));
} }

View File

@@ -44,6 +44,8 @@ enum class RoadShieldType
Italy_Autostrada, Italy_Autostrada,
Hungary_Green, Hungary_Green,
Hungary_Blue, Hungary_Blue,
Romania_DN,
Romania_DJ,
Hidden, Hidden,
Count Count
}; };

View File

@@ -150,6 +150,17 @@ std::string Platform::ReadPathForFile(std::string const & file, std::string sear
"\nr: ", m_resourcesDir, "\ns: ", m_settingsDir)); "\nr: ", m_resourcesDir, "\ns: ", m_settingsDir));
} }
void Platform::SetCustomMapServerUrl(std::string & url)
{
strings::Trim(url);
m_customMapServerUrl = std::move(url);
}
std::string const & Platform::CustomMapServerUrl() const
{
return m_customMapServerUrl;
}
std::string Platform::MetaServerUrl() const std::string Platform::MetaServerUrl() const
{ {
return METASERVER_URL; return METASERVER_URL;

View File

@@ -268,6 +268,10 @@ public:
/// @return integer version in yyMMdd format. /// @return integer version in yyMMdd format.
int32_t IntVersion() const; int32_t IntVersion() const;
/// Set custom map server url to allow user-defined download servers
void SetCustomMapServerUrl(std::string & url);
std::string const & CustomMapServerUrl() const;
/// @return url for clients to download maps /// @return url for clients to download maps
std::string MetaServerUrl() const; std::string MetaServerUrl() const;
@@ -339,6 +343,8 @@ private:
void ShutdownThreads(); void ShutdownThreads();
void GetSystemFontNames(FilesList & res) const; void GetSystemFontNames(FilesList & res) const;
std::string m_customMapServerUrl;
}; };
std::string DebugPrint(Platform::EError err); std::string DebugPrint(Platform::EError err);

View File

@@ -156,6 +156,18 @@ std::string GetAcceptLanguage()
MetaConfig MapFilesDownloader::LoadMetaConfig() MetaConfig MapFilesDownloader::LoadMetaConfig()
{ {
Platform & pl = GetPlatform(); Platform & pl = GetPlatform();
// If user sets a custom download server, skip metaserver entirely.
std::string const customServer = pl.CustomMapServerUrl();
if (!customServer.empty())
{
LOG(LINFO, ("Using custom map server URL:", customServer));
MetaConfig metaConfig;
metaConfig.m_serversList = {customServer};
return metaConfig;
}
std::string const metaServerUrl = pl.MetaServerUrl(); std::string const metaServerUrl = pl.MetaServerUrl();
std::string httpResult; std::string httpResult;
@@ -170,7 +182,7 @@ MetaConfig MapFilesDownloader::LoadMetaConfig()
request.RunHttpRequest(httpResult); request.RunHttpRequest(httpResult);
} }
std::optional<MetaConfig> metaConfig = downloader::ParseMetaConfig(httpResult); auto metaConfig = downloader::ParseMetaConfig(httpResult);
if (!metaConfig) if (!metaConfig)
{ {
metaConfig = downloader::ParseMetaConfig(pl.DefaultUrlsJSON()); metaConfig = downloader::ParseMetaConfig(pl.DefaultUrlsJSON());
@@ -181,6 +193,7 @@ MetaConfig MapFilesDownloader::LoadMetaConfig()
{ {
LOG(LINFO, ("Got servers list:", metaConfig->m_serversList)); LOG(LINFO, ("Got servers list:", metaConfig->m_serversList));
} }
CHECK(!metaConfig->m_serversList.empty(), ()); CHECK(!metaConfig->m_serversList.empty(), ());
return *metaConfig; return *metaConfig;
} }
@@ -190,4 +203,10 @@ void MapFilesDownloader::GetMetaConfig(MetaConfigCallback const & callback)
callback(LoadMetaConfig()); callback(LoadMetaConfig());
} }
void MapFilesDownloader::ResetMetaConfig()
{
m_serversList.clear();
m_isMetaConfigRequested = false;
}
} // namespace storage } // namespace storage

View File

@@ -66,6 +66,9 @@ public:
void SetDownloadingPolicy(DownloadingPolicy * policy); void SetDownloadingPolicy(DownloadingPolicy * policy);
void SetDataVersion(int64_t version) { m_dataVersion = version; } void SetDataVersion(int64_t version) { m_dataVersion = version; }
/// Reset after changes, e.g. map download URL.
void ResetMetaConfig();
/// @name Legacy functions for Android resources downloading routine (initial World download). /// @name Legacy functions for Android resources downloading routine (initial World download).
/// @{ /// @{
void EnsureMetaConfigReady(std::function<void()> && callback); void EnsureMetaConfigReady(std::function<void()> && callback);

View File

@@ -1252,16 +1252,33 @@ bool Storage::IsAllowedToEditVersion(CountryId const & countryId) const
case Status::OnDiskOutOfDate: case Status::OnDiskOutOfDate:
{ {
auto const localFile = GetLatestLocalFile(countryId); auto const localFile = GetLatestLocalFile(countryId);
ASSERT(localFile, ("Local file shouldn't be nullptr.")); return IsAllowedToEditFile(localFile);
auto const currentVersionTime = base::YYMMDDToSecondsSinceEpoch(static_cast<uint32_t>(m_currentVersion));
auto const localVersionTime = base::YYMMDDToSecondsSinceEpoch(static_cast<uint32_t>(localFile->GetVersion()));
return currentVersionTime - localVersionTime < kMaxSecondsTillLastVersionUpdate &&
base::SecondsSinceEpoch() - localVersionTime < kMaxSecondsTillNoEdits;
} }
default: return false; default: return false;
} }
} }
bool Storage::IsMapTooOldToEdit(CountryId const & countryId) const
{
auto const status = CountryStatusEx(countryId);
if (status == Status::OnDiskOutOfDate)
{
LocalFilePtr const localFile = GetLatestLocalFile(countryId);
return !IsAllowedToEditFile(localFile);
}
return false;
}
bool Storage::IsAllowedToEditFile(LocalFilePtr const & localFile) const
{
ASSERT(localFile, ("Local file shouldn't be nullptr."));
auto const currentVersionTime = base::YYMMDDToSecondsSinceEpoch(static_cast<uint32_t>(m_currentVersion));
auto const localVersionTime = base::YYMMDDToSecondsSinceEpoch(static_cast<uint32_t>(localFile->GetVersion()));
return currentVersionTime - localVersionTime < kMaxSecondsTillLastVersionUpdate &&
base::SecondsSinceEpoch() - localVersionTime < kMaxSecondsTillNoEdits;
}
int64_t Storage::GetVersion(CountryId const & countryId) const int64_t Storage::GetVersion(CountryId const & countryId) const
{ {
CHECK_THREAD_CHECKER(m_threadChecker, ()); CHECK_THREAD_CHECKER(m_threadChecker, ());

View File

@@ -383,6 +383,9 @@ public:
/// \brief Returns true if the version of countryId can be used to update maps. /// \brief Returns true if the version of countryId can be used to update maps.
bool IsAllowedToEditVersion(CountryId const & countryId) const; bool IsAllowedToEditVersion(CountryId const & countryId) const;
/// \brief Returns true when the map exists and is too old for map editing.
bool IsMapTooOldToEdit(CountryId const & countryId) const;
/// Returns version of downloaded mwm or zero. /// Returns version of downloaded mwm or zero.
int64_t GetVersion(CountryId const & countryId) const; int64_t GetVersion(CountryId const & countryId) const;
@@ -582,6 +585,12 @@ public:
void RestoreDownloadQueue(); void RestoreDownloadQueue();
void ResetMapDownloadMetaConfig()
{
if (m_downloader)
m_downloader->ResetMetaConfig();
}
protected: protected:
void OnFinishDownloading(); void OnFinishDownloading();
@@ -619,6 +628,8 @@ private:
// Returns a path to a place on disk downloader can use for downloaded files. // Returns a path to a place on disk downloader can use for downloaded files.
std::string GetFileDownloadPath(CountryId const & countryId, MapFileType file) const; std::string GetFileDownloadPath(CountryId const & countryId, MapFileType file) const;
bool IsAllowedToEditFile(LocalFilePtr const & localFile) const;
/// Fast version, doesn't check if country is out of date /// Fast version, doesn't check if country is out of date
Status CountryStatus(CountryId const & countryId) const; Status CountryStatus(CountryId const & countryId) const;