[core] Switch to ankerl::unordered_dense

Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
This commit is contained in:
x7z4w
2025-11-24 17:34:56 +00:00
parent 7e561d09d3
commit 0288b97b13
282 changed files with 4385 additions and 1457 deletions

83
3party/ankerl/stl.h Normal file
View File

@@ -0,0 +1,83 @@
///////////////////////// ankerl::unordered_dense::{map, set} /////////////////////////
// A fast & densely stored hashmap and hashset based on robin-hood backward shift deletion.
// Version 4.8.1
// https://github.com/martinus/unordered_dense
//
// Licensed under the MIT License <http://opensource.org/licenses/MIT>.
// SPDX-License-Identifier: MIT
// Copyright (c) 2022 Martin Leitner-Ankerl <martin.ankerl@gmail.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifndef ANKERL_STL_H
#define ANKERL_STL_H
#include <array> // for array
#include <cstdint> // for uint64_t, uint32_t, std::uint8_t, UINT64_C
#include <cstring> // for size_t, memcpy, memset
#include <functional> // for equal_to, hash
#include <initializer_list> // for initializer_list
#include <iterator> // for pair, distance
#include <limits> // for numeric_limits
#include <memory> // for allocator, allocator_traits, shared_ptr
#include <optional> // for optional
#include <stdexcept> // for out_of_range
#include <string> // for basic_string
#include <string_view> // for basic_string_view, hash
#include <tuple> // for forward_as_tuple
#include <type_traits> // for enable_if_t, declval, conditional_t, ena...
#include <utility> // for forward, exchange, pair, as_const, piece...
#include <vector> // for vector
// <memory_resource> includes <mutex>, which fails to compile if
// targeting GCC >= 13 with the (rewritten) win32 thread model, and
// targeting Windows earlier than Vista (0x600). GCC predefines
// _REENTRANT when using the 'posix' model, and doesn't when using the
// 'win32' model.
#if defined __MINGW64__ && defined __GNUC__ && __GNUC__ >= 13 && !defined _REENTRANT
// _WIN32_WINNT is guaranteed to be defined here because of the
// <cstdint> inclusion above.
# ifndef _WIN32_WINNT
# error "_WIN32_WINNT not defined"
# endif
# if _WIN32_WINNT < 0x600
# define ANKERL_MEMORY_RESOURCE_IS_BAD() 1 // NOLINT(cppcoreguidelines-macro-usage)
# endif
#endif
#ifndef ANKERL_MEMORY_RESOURCE_IS_BAD
# define ANKERL_MEMORY_RESOURCE_IS_BAD() 0 // NOLINT(cppcoreguidelines-macro-usage)
#endif
#if defined(__has_include) && !defined(ANKERL_UNORDERED_DENSE_DISABLE_PMR)
# if __has_include(<memory_resource>) && !ANKERL_MEMORY_RESOURCE_IS_BAD()
# define ANKERL_UNORDERED_DENSE_PMR std::pmr // NOLINT(cppcoreguidelines-macro-usage)
# include <memory_resource> // for polymorphic_allocator
# elif __has_include(<experimental/memory_resource>)
# define ANKERL_UNORDERED_DENSE_PMR std::experimental::pmr // NOLINT(cppcoreguidelines-macro-usage)
# include <experimental/memory_resource> // for polymorphic_allocator
# endif
#endif
#if defined(_MSC_VER) && defined(_M_X64)
# include <intrin.h>
# pragma intrinsic(_umul128)
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -28,7 +28,6 @@ import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import com.github.mikephil.charting.highlight.Highlight; import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener; import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import com.google.android.material.textview.MaterialTextView; import com.google.android.material.textview.MaterialTextView;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;

View File

@@ -253,7 +253,7 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
mProgress.setMax(bytes); mProgress.setMax(bytes);
// Start progress at 1% according to M3 guidelines // Start progress at 1% according to M3 guidelines
mProgress.setProgressCompat(bytes/100, true); mProgress.setProgressCompat(bytes / 100, true);
} }
else else
finishFilesDownload(bytes); finishFilesDownload(bytes);
@@ -372,7 +372,7 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
mTvMessage.setText(getString(R.string.downloading_country_can_proceed, item.name, fileSizeString)); mTvMessage.setText(getString(R.string.downloading_country_can_proceed, item.name, fileSizeString));
mProgress.setMax((int) item.totalSize); mProgress.setMax((int) item.totalSize);
// Start progress at 1% according to M3 guidelines // Start progress at 1% according to M3 guidelines
mProgress.setProgressCompat((int) (item.totalSize/100), true); mProgress.setProgressCompat((int) (item.totalSize / 100), true);
mCountryDownloadListenerSlot = MapManager.nativeSubscribe(mCountryDownloadListener); mCountryDownloadListenerSlot = MapManager.nativeSubscribe(mCountryDownloadListener);
MapManagerHelper.startDownload(mCurrentCountry); MapManagerHelper.startDownload(mCurrentCountry);
@@ -424,17 +424,17 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
default -> throw new AssertionError("Unexpected result code = " + result); default -> throw new AssertionError("Unexpected result code = " + result);
}; };
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
.setTitle(titleId) .setTitle(titleId)
.setMessage(messageId) .setMessage(messageId)
.setCancelable(true) .setCancelable(true)
.setOnCancelListener((dialog) -> setAction(PAUSE)) .setOnCancelListener((dialog) -> setAction(PAUSE))
.setPositiveButton(R.string.try_again, .setPositiveButton(R.string.try_again,
(dialog, which) -> { (dialog, which) -> {
setAction(TRY_AGAIN); setAction(TRY_AGAIN);
onTryAgainClicked(); onTryAgainClicked();
}) })
.setOnDismissListener(dialog -> mAlertDialog = null) .setOnDismissListener(dialog -> mAlertDialog = null)
.show(); .show();
} }
} }

View File

@@ -38,8 +38,9 @@ public class OsmUploadWork extends Worker
{ {
final Constraints c = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build(); final Constraints c = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build();
OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(OsmUploadWork.class).setConstraints(c); OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(OsmUploadWork.class).setConstraints(c);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
builder.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST); {
builder.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST);
} }
final OneTimeWorkRequest wr = builder.build(); final OneTimeWorkRequest wr = builder.build();
WorkManager.getInstance(context).beginUniqueWork("UploadOsmChanges", ExistingWorkPolicy.KEEP, wr).enqueue(); WorkManager.getInstance(context).beginUniqueWork("UploadOsmChanges", ExistingWorkPolicy.KEEP, wr).enqueue();

View File

@@ -17,7 +17,6 @@ import androidx.annotation.NonNull;
import androidx.documentfile.provider.DocumentFile; import androidx.documentfile.provider.DocumentFile;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.sdk.util.log.Logger; import app.organicmaps.sdk.util.log.Logger;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;

View File

@@ -10,7 +10,6 @@ import androidx.fragment.app.DialogFragment;
public class BaseMwmDialogFragment extends DialogFragment public class BaseMwmDialogFragment extends DialogFragment
{ {
protected int getStyle() protected int getStyle()
{ {
return STYLE_NORMAL; return STYLE_NORMAL;

View File

@@ -282,11 +282,13 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
{ {
if (isEmptySearchResults()) if (isEmptySearchResults())
{ {
requirePlaceholder().setContent(R.string.search_not_found, R.string.search_not_found_query, R.drawable.ic_search_fail); requirePlaceholder().setContent(R.string.search_not_found, R.string.search_not_found_query,
R.drawable.ic_search_fail);
} }
else if (isEmpty()) else if (isEmpty())
{ {
requirePlaceholder().setContent(R.string.bookmarks_empty_list_title, R.string.bookmarks_empty_list_message, R.drawable.ic_bookmarks); requirePlaceholder().setContent(R.string.bookmarks_empty_list_title, R.string.bookmarks_empty_list_message,
R.drawable.ic_bookmarks);
} }
boolean isEmptyRecycler = isEmpty() || isEmptySearchResults(); boolean isEmptyRecycler = isEmpty() || isEmptySearchResults();

View File

@@ -23,7 +23,6 @@ import app.organicmaps.util.UiUtils;
import app.organicmaps.util.Utils; import app.organicmaps.util.Utils;
import app.organicmaps.widget.recycler.RecyclerClickListener; import app.organicmaps.widget.recycler.RecyclerClickListener;
import app.organicmaps.widget.recycler.RecyclerLongClickListener; import app.organicmaps.widget.recycler.RecyclerLongClickListener;
import com.google.android.material.button.MaterialButton; import com.google.android.material.button.MaterialButton;
import com.google.android.material.checkbox.MaterialCheckBox; import com.google.android.material.checkbox.MaterialCheckBox;
import com.google.android.material.imageview.ShapeableImageView; import com.google.android.material.imageview.ShapeableImageView;
@@ -458,10 +457,12 @@ public class Holders
String formattedDesc = desc.replace("\n", "<br>"); String formattedDesc = desc.replace("\n", "<br>");
Spanned spannedDesc = Utils.fromHtml(formattedDesc); Spanned spannedDesc = Utils.fromHtml(formattedDesc);
if (!TextUtils.isEmpty(spannedDesc)) { if (!TextUtils.isEmpty(spannedDesc))
{
mDescText.setText(spannedDesc); mDescText.setText(spannedDesc);
} }
else { else
{
mDescText.setText(R.string.list_description_empty); mDescText.setText(R.string.list_description_empty);
} }
} }

View File

@@ -50,8 +50,8 @@ public final class IntentUtils
} }
// https://developer.android.com/reference/androidx/car/app/CarContext#startCarApp(android.content.Intent) // https://developer.android.com/reference/androidx/car/app/CarContext#startCarApp(android.content.Intent)
private static void processNavigationIntent(@NonNull CarContext carContext, private static void processNavigationIntent(@NonNull CarContext carContext, @NonNull Renderer surfaceRenderer,
@NonNull Renderer surfaceRenderer, @NonNull Intent intent) @NonNull Intent intent)
{ {
// TODO (AndrewShkrob): This logic will need to be revised when we introduce support for adding stops during // TODO (AndrewShkrob): This logic will need to be revised when we introduce support for adding stops during
// navigation or route planning. Skip navigation intents during navigation // navigation or route planning. Skip navigation intents during navigation

View File

@@ -31,7 +31,7 @@ public final class RoutingHelpers
default -> Distance.UNIT_METERS; default -> Distance.UNIT_METERS;
}; };
return Distance.create(distance.mDistance, displayUnit); return Distance.create(distance.mDistance, displayUnit);
} }
@NonNull @NonNull
@@ -52,7 +52,7 @@ public final class RoutingHelpers
default -> LaneDirection.SHAPE_UNKNOWN; default -> LaneDirection.SHAPE_UNKNOWN;
}; };
return LaneDirection.create(shape, isRecommended); return LaneDirection.create(shape, isRecommended);
} }
@NonNull @NonNull
@@ -77,7 +77,7 @@ public final class RoutingHelpers
case EXIT_HIGHWAY_TO_LEFT -> Maneuver.TYPE_OFF_RAMP_SLIGHT_LEFT; case EXIT_HIGHWAY_TO_LEFT -> Maneuver.TYPE_OFF_RAMP_SLIGHT_LEFT;
case EXIT_HIGHWAY_TO_RIGHT -> Maneuver.TYPE_OFF_RAMP_SLIGHT_RIGHT; case EXIT_HIGHWAY_TO_RIGHT -> Maneuver.TYPE_OFF_RAMP_SLIGHT_RIGHT;
}; };
final Maneuver.Builder builder = new Maneuver.Builder(maneuverType); final Maneuver.Builder builder = new Maneuver.Builder(maneuverType);
if (maneuverType == Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW) if (maneuverType == Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW)
builder.setRoundaboutExitNumber(roundaboutExitNum > 0 ? roundaboutExitNum : 1); builder.setRoundaboutExitNumber(roundaboutExitNum > 0 ? roundaboutExitNum : 1);
builder.setIcon(new CarIcon.Builder(createManeuverIcon(context, carDirection, roundaboutExitNum)).build()); builder.setIcon(new CarIcon.Builder(createManeuverIcon(context, carDirection, roundaboutExitNum)).build());
@@ -85,7 +85,8 @@ public final class RoutingHelpers
} }
@NonNull @NonNull
private static IconCompat createManeuverIcon(@NonNull final CarContext context, @NonNull CarDirection carDirection, int roundaboutExitNum) private static IconCompat createManeuverIcon(@NonNull final CarContext context, @NonNull CarDirection carDirection,
int roundaboutExitNum)
{ {
if (!CarDirection.isRoundAbout(carDirection) || roundaboutExitNum == 0) if (!CarDirection.isRoundAbout(carDirection) || roundaboutExitNum == 0)
{ {

View File

@@ -39,8 +39,7 @@ public final class UiHelpers
} }
@NonNull @NonNull
public static ActionStrip createMapActionStrip(@NonNull CarContext context, public static ActionStrip createMapActionStrip(@NonNull CarContext context, @NonNull Renderer surfaceRenderer)
@NonNull Renderer surfaceRenderer)
{ {
final CarIcon iconPlus = new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_plus)).build(); final CarIcon iconPlus = new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_plus)).build();
final CarIcon iconMinus = new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_minus)).build(); final CarIcon iconMinus = new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_minus)).build();
@@ -59,15 +58,13 @@ public final class UiHelpers
} }
@NonNull @NonNull
public static MapController createMapController(@NonNull CarContext context, public static MapController createMapController(@NonNull CarContext context, @NonNull Renderer surfaceRenderer)
@NonNull Renderer surfaceRenderer)
{ {
return new MapController.Builder().setMapActionStrip(createMapActionStrip(context, surfaceRenderer)).build(); return new MapController.Builder().setMapActionStrip(createMapActionStrip(context, surfaceRenderer)).build();
} }
@NonNull @NonNull
public static Action createSettingsAction(@NonNull BaseMapScreen mapScreen, public static Action createSettingsAction(@NonNull BaseMapScreen mapScreen, @NonNull Renderer surfaceRenderer)
@NonNull Renderer surfaceRenderer)
{ {
return createSettingsAction(mapScreen, surfaceRenderer, null); return createSettingsAction(mapScreen, surfaceRenderer, null);
} }
@@ -81,8 +78,7 @@ public final class UiHelpers
} }
@NonNull @NonNull
private static Action createSettingsAction(@NonNull BaseMapScreen mapScreen, private static Action createSettingsAction(@NonNull BaseMapScreen mapScreen, @NonNull Renderer surfaceRenderer,
@NonNull Renderer surfaceRenderer,
@Nullable OnScreenResultListener onScreenResultListener) @Nullable OnScreenResultListener onScreenResultListener)
{ {
final CarContext context = mapScreen.getCarContext(); final CarContext context = mapScreen.getCarContext();
@@ -123,8 +119,7 @@ public final class UiHelpers
return null; return null;
final Row.Builder builder = new Row.Builder(); final Row.Builder builder = new Row.Builder();
builder.setImage( builder.setImage(new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_opening_hours)).build());
new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_opening_hours)).build());
if (isEmptyTT) if (isEmptyTT)
builder.setTitle(ohStr); builder.setTitle(ohStr);

View File

@@ -125,7 +125,8 @@ public class EditTextDialogFragment extends BaseMwmDialogFragment
positiveButton.setOnClickListener(view -> { positiveButton.setOnClickListener(view -> {
final String result = mEtInput.getText().toString(); final String result = mEtInput.getText().toString();
if (validateInput(requireActivity(), result)) { if (validateInput(requireActivity(), result))
{
processInput(result); processInput(result);
editTextDialog.dismiss(); editTextDialog.dismiss();
} }

View File

@@ -4,7 +4,6 @@ import android.location.Location;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import app.organicmaps.MwmActivity; import app.organicmaps.MwmActivity;
@@ -49,7 +48,8 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener
@Override @Override
public void onStatusChanged(List<MapManager.StorageCallbackData> data) public void onStatusChanged(List<MapManager.StorageCallbackData> data)
{ {
if (mCurrentCountry == null) { if (mCurrentCountry == null)
{
updateOfflineExplanationVisibility(); updateOfflineExplanationVisibility();
return; return;
} }
@@ -109,10 +109,13 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener
return enqueued || progress || applying; return enqueued || progress || applying;
} }
private void updateOfflineExplanationVisibility() { private void updateOfflineExplanationVisibility()
if (mOfflineExplanation == null) return; {
if (mOfflineExplanation == null)
return;
// hide once threshold reached; safe to call repeatedly. // hide once threshold reached; safe to call repeatedly.
app.organicmaps.util.UiUtils.showIf(MapManager.nativeGetDownloadedCount() < (DEFAULT_MAP_BASELINE + HIDE_THRESHOLD), mOfflineExplanation); app.organicmaps.util.UiUtils.showIf(MapManager.nativeGetDownloadedCount() < (DEFAULT_MAP_BASELINE + HIDE_THRESHOLD),
mOfflineExplanation);
} }
private void updateProgressState(boolean shouldAutoDownload) private void updateProgressState(boolean shouldAutoDownload)

View File

@@ -15,7 +15,6 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AutoCompleteTextView; import android.widget.AutoCompleteTextView;
import android.widget.GridLayout; import android.widget.GridLayout;
import androidx.annotation.CallSuper; import androidx.annotation.CallSuper;
import androidx.annotation.DrawableRes; import androidx.annotation.DrawableRes;
import androidx.annotation.IdRes; import androidx.annotation.IdRes;
@@ -398,7 +397,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
List<String> SOCKET_TYPES = Arrays.stream(getResources().getStringArray(R.array.charge_socket_types)).toList(); List<String> SOCKET_TYPES = Arrays.stream(getResources().getStringArray(R.array.charge_socket_types)).toList();
for (String socketType : SOCKET_TYPES) for (String socketType : SOCKET_TYPES)
{ {
ChargeSocketDescriptor socket = new ChargeSocketDescriptor(socketType,0,0); ChargeSocketDescriptor socket = new ChargeSocketDescriptor(socketType, 0, 0);
MaterialButton btn = (MaterialButton) inflater.inflate(R.layout.button_socket_type, typeBtns, false); MaterialButton btn = (MaterialButton) inflater.inflate(R.layout.button_socket_type, typeBtns, false);
@@ -406,16 +405,16 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
// load SVG icon converted into VectorDrawable in res/drawable // load SVG icon converted into VectorDrawable in res/drawable
@SuppressLint("DiscouragedApi") @SuppressLint("DiscouragedApi")
int resIconId = int resIconId = getResources().getIdentifier("ic_charge_socket_" + socket.visualType(), "drawable",
getResources().getIdentifier("ic_charge_socket_" + socket.visualType(), "drawable", requireContext().getPackageName()); requireContext().getPackageName());
if (resIconId != 0) if (resIconId != 0)
{ {
btn.setIcon(getResources().getDrawable(resIconId)); btn.setIcon(getResources().getDrawable(resIconId));
} }
@SuppressLint("DiscouragedApi") @SuppressLint("DiscouragedApi")
int resTypeId = int resTypeId = getResources().getIdentifier("charge_socket_" + socket.visualType(), "string",
getResources().getIdentifier("charge_socket_" + socket.visualType(), "string", requireContext().getPackageName()); requireContext().getPackageName());
if (resTypeId != 0) if (resTypeId != 0)
{ {
btn.setText(getResources().getString(resTypeId)); btn.setText(getResources().getString(resTypeId));
@@ -463,13 +462,16 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
// Add a TextWatcher to validate on text change // Add a TextWatcher to validate on text change
countView.addTextChangedListener(new TextWatcher() { countView.addTextChangedListener(new TextWatcher() {
@Override @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {} public void beforeTextChanged(CharSequence s, int start, int count, int after)
{}
@Override @Override
public void onTextChanged(CharSequence s, int start, int before, int count) {} public void onTextChanged(CharSequence s, int start, int before, int count)
{}
@Override @Override
public void afterTextChanged(Editable s) { public void afterTextChanged(Editable s)
{
validatePositiveField(s.toString(), countInputLayout); validatePositiveField(s.toString(), countInputLayout);
} }
}); });
@@ -484,13 +486,16 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
// Add a TextWatcher to validate on text change // Add a TextWatcher to validate on text change
powerView.addTextChangedListener(new TextWatcher() { powerView.addTextChangedListener(new TextWatcher() {
@Override @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {} public void beforeTextChanged(CharSequence s, int start, int count, int after)
{}
@Override @Override
public void onTextChanged(CharSequence s, int start, int before, int count) {} public void onTextChanged(CharSequence s, int start, int before, int count)
{}
@Override @Override
public void afterTextChanged(Editable s) { public void afterTextChanged(Editable s)
{
validatePositiveField(s.toString(), powerInputLayout); validatePositiveField(s.toString(), powerInputLayout);
} }
}); });
@@ -498,74 +503,82 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
return new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog) return new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
.setTitle(R.string.editor_socket) .setTitle(R.string.editor_socket)
.setView(dialogView) .setView(dialogView)
.setPositiveButton(R.string.save, .setPositiveButton(
(dialog, which) -> { R.string.save,
String socketType = ""; (dialog, which) -> {
for (MaterialButton b : buttonList) String socketType = "";
{ for (MaterialButton b : buttonList)
if (b.isChecked()) {
{ if (b.isChecked())
socketType = b.getTag(R.id.socket_type).toString(); {
break; socketType = b.getTag(R.id.socket_type).toString();
} break;
} }
}
int countValue = 0; // 0 means 'unknown count' int countValue = 0; // 0 means 'unknown count'
try try
{ {
countValue = Integer.parseInt(countView.getText().toString()); countValue = Integer.parseInt(countView.getText().toString());
} }
catch (NumberFormatException ignored) catch (NumberFormatException ignored)
{ {
Logger.w(CHARGE_SOCKETS_TAG, "Invalid count value for socket:" + countView.getText().toString()); Logger.w(CHARGE_SOCKETS_TAG, "Invalid count value for socket:" + countView.getText().toString());
} }
if (countValue < 0) if (countValue < 0)
{ {
countValue = 0; countValue = 0;
Logger.w(CHARGE_SOCKETS_TAG, "Invalid count value for socket:" + countView.getText().toString()); Logger.w(CHARGE_SOCKETS_TAG, "Invalid count value for socket:" + countView.getText().toString());
} }
double powerValue = 0; // 0 means 'unknown power' double powerValue = 0; // 0 means 'unknown power'
try try
{ {
powerValue = Double.parseDouble(powerView.getText().toString()); powerValue = Double.parseDouble(powerView.getText().toString());
} }
catch (NumberFormatException ignored) catch (NumberFormatException ignored)
{ {
Logger.w(CHARGE_SOCKETS_TAG, "Invalid power value for socket:" + powerView.getText().toString()); Logger.w(CHARGE_SOCKETS_TAG, "Invalid power value for socket:" + powerView.getText().toString());
} }
if (powerValue < 0) if (powerValue < 0)
{ {
powerValue = 0; powerValue = 0;
Logger.w(CHARGE_SOCKETS_TAG, "Invalid power value for socket:" + powerView.getText().toString()); Logger.w(CHARGE_SOCKETS_TAG, "Invalid power value for socket:" + powerView.getText().toString());
} }
ChargeSocketDescriptor socket = ChargeSocketDescriptor socket = new ChargeSocketDescriptor(socketType, countValue, powerValue);
new ChargeSocketDescriptor(socketType, countValue, powerValue);
updateChargeSockets(socketIndex, socket); updateChargeSockets(socketIndex, socket);
}) })
.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss()); .setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
} }
// Helper method for validation logic // Helper method for validation logic
private boolean validatePositiveField(String text, TextInputLayout layout) { private boolean validatePositiveField(String text, TextInputLayout layout)
if (text.isEmpty()) { {
if (text.isEmpty())
{
layout.setError(null); // No error if empty (assuming 0 is the default) layout.setError(null); // No error if empty (assuming 0 is the default)
return true; return true;
} }
try { try
{
double value = Double.parseDouble(text); double value = Double.parseDouble(text);
if (value < 0) { if (value < 0)
{
layout.setError(getString(R.string.error_value_must_be_positive)); layout.setError(getString(R.string.error_value_must_be_positive));
return false; return false;
} else {
layout.setError(null);
return true;
} }
} catch (NumberFormatException e) { else
{
layout.setError(null);
return true;
}
}
catch (NumberFormatException e)
{
layout.setError(getString(R.string.error_invalid_number)); layout.setError(getString(R.string.error_invalid_number));
return false; return false;
} }
@@ -585,7 +598,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
{ {
sockets[socketIndex] = socket; sockets[socketIndex] = socket;
} }
else { else
{
List<ChargeSocketDescriptor> list = new ArrayList<>(Arrays.asList(sockets)); List<ChargeSocketDescriptor> list = new ArrayList<>(Arrays.asList(sockets));
list.add(socket); list.add(socket);
sockets = list.toArray(new ChargeSocketDescriptor[0]); sockets = list.toArray(new ChargeSocketDescriptor[0]);
@@ -603,7 +617,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
GridLayout socketsGrid = mChargeSockets.findViewById(R.id.socket_grid_editor); GridLayout socketsGrid = mChargeSockets.findViewById(R.id.socket_grid_editor);
socketsGrid.removeAllViews(); socketsGrid.removeAllViews();
for (int i = 0; i < sockets.length; i++) { for (int i = 0; i < sockets.length; i++)
{
final int currentIndex = i; final int currentIndex = i;
ChargeSocketDescriptor socket = sockets[i]; ChargeSocketDescriptor socket = sockets[i];
@@ -614,27 +629,30 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
MaterialTextView power = itemView.findViewById(R.id.socket_power); MaterialTextView power = itemView.findViewById(R.id.socket_power);
MaterialTextView count = itemView.findViewById(R.id.socket_count); MaterialTextView count = itemView.findViewById(R.id.socket_count);
// load SVG icon converted into VectorDrawable in res/drawable // load SVG icon converted into VectorDrawable in res/drawable
@SuppressLint("DiscouragedApi") @SuppressLint("DiscouragedApi")
int resIconId = getResources().getIdentifier("ic_charge_socket_" + socket.visualType(), "drawable", int resIconId = getResources().getIdentifier("ic_charge_socket_" + socket.visualType(), "drawable",
requireContext().getPackageName()); requireContext().getPackageName());
if (resIconId != 0) { if (resIconId != 0)
{
icon.setImageResource(resIconId); icon.setImageResource(resIconId);
} }
@SuppressLint("DiscouragedApi") @SuppressLint("DiscouragedApi")
int resTypeId = int resTypeId = getResources().getIdentifier("charge_socket_" + socket.visualType(), "string",
getResources().getIdentifier("charge_socket_" + socket.visualType(), "string", requireContext().getPackageName()); requireContext().getPackageName());
if (resTypeId != 0) { if (resTypeId != 0)
{
type.setText(resTypeId); type.setText(resTypeId);
} }
if (socket.power() != 0) { if (socket.power() != 0)
{
DecimalFormat df = new DecimalFormat("#.##"); DecimalFormat df = new DecimalFormat("#.##");
power.setText(getString(R.string.kw_label, df.format(socket.power()))); power.setText(getString(R.string.kw_label, df.format(socket.power())));
} }
else if (socket.ignorePower()) { else if (socket.ignorePower())
{
power.setVisibility(INVISIBLE); power.setVisibility(INVISIBLE);
} }
@@ -643,7 +661,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
count.setText(getString(R.string.count_label, socket.count())); count.setText(getString(R.string.count_label, socket.count()));
} }
itemView.setOnClickListener(v -> buildChargeSocketDialog(currentIndex, socket.type(), socket.count(), socket.power()).show()); itemView.setOnClickListener(
v -> buildChargeSocketDialog(currentIndex, socket.type(), socket.count(), socket.power()).show());
socketsGrid.addView(itemView); socketsGrid.addView(itemView);
} }
@@ -789,9 +808,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
View lineContactBlock = View lineContactBlock =
initBlock(view, Metadata.MetadataType.FMD_CONTACT_LINE, R.id.block_line, R.drawable.ic_line_white, initBlock(view, Metadata.MetadataType.FMD_CONTACT_LINE, R.id.block_line, R.drawable.ic_line_white,
R.string.editor_line_social_network, InputType.TYPE_TEXT_VARIATION_URI); R.string.editor_line_social_network, InputType.TYPE_TEXT_VARIATION_URI);
View blueskyContactBlock = View blueskyContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_BLUESKY, R.id.block_bluesky,
initBlock(view, Metadata.MetadataType.FMD_CONTACT_BLUESKY, R.id.block_bluesky, R.drawable.ic_bluesky, R.drawable.ic_bluesky, R.string.bluesky, InputType.TYPE_TEXT_VARIATION_URI);
R.string.bluesky, InputType.TYPE_TEXT_VARIATION_URI);
View operatorBlock = initBlock(view, Metadata.MetadataType.FMD_OPERATOR, R.id.block_operator, View operatorBlock = initBlock(view, Metadata.MetadataType.FMD_OPERATOR, R.id.block_operator,
R.drawable.ic_operator, R.string.editor_operator, 0); R.drawable.ic_operator, R.string.editor_operator, 0);
@@ -1023,14 +1041,15 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
private void placeDisused() private void placeDisused()
{ {
new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog) new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog)
.setTitle(R.string.editor_mark_business_vacant_title) .setTitle(R.string.editor_mark_business_vacant_title)
.setMessage(R.string.editor_mark_business_vacant_description) .setMessage(R.string.editor_mark_business_vacant_description)
.setPositiveButton(R.string.editor_submit, (dlg, which) -> { .setPositiveButton(R.string.editor_submit,
Editor.nativeMarkPlaceAsDisused(); (dlg, which) -> {
mParent.processEditedFeatures(); Editor.nativeMarkPlaceAsDisused();
}) mParent.processEditedFeatures();
.setNegativeButton(android.R.string.cancel, null) })
.show(); .setNegativeButton(android.R.string.cancel, null)
.show();
} }
private void commitPlaceDoesntExists(@NonNull String text) private void commitPlaceDoesntExists(@NonNull String text)

View File

@@ -13,7 +13,6 @@ import app.organicmaps.R;
import app.organicmaps.sdk.editor.data.FeatureCategory; import app.organicmaps.sdk.editor.data.FeatureCategory;
import app.organicmaps.sdk.util.StringUtils; import app.organicmaps.sdk.util.StringUtils;
import app.organicmaps.util.UiUtils; import app.organicmaps.util.UiUtils;
import com.google.android.material.button.MaterialButton; import com.google.android.material.button.MaterialButton;
import com.google.android.material.textfield.TextInputEditText; import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textview.MaterialTextView; import com.google.android.material.textview.MaterialTextView;
@@ -69,8 +68,7 @@ public class FeatureCategoryAdapter extends RecyclerView.Adapter<RecyclerView.Vi
} }
case TYPE_FOOTER -> case TYPE_FOOTER ->
{ {
return new FooterViewHolder(inflater.inflate(R.layout.item_feature_category_footer, parent, false), return new FooterViewHolder(inflater.inflate(R.layout.item_feature_category_footer, parent, false), mFragment);
mFragment);
} }
default -> throw new IllegalArgumentException("Unsupported viewType: " + viewType); default -> throw new IllegalArgumentException("Unsupported viewType: " + viewType);
} }
@@ -134,26 +132,21 @@ public class FeatureCategoryAdapter extends RecyclerView.Adapter<RecyclerView.Vi
mSendNoteButton = itemView.findViewById(R.id.send_note_button); mSendNoteButton = itemView.findViewById(R.id.send_note_button);
mSendNoteButton.setOnClickListener(v -> listener.onSendNoteClicked()); mSendNoteButton.setOnClickListener(v -> listener.onSendNoteClicked());
final ColorStateList bgButtonColor = new ColorStateList( final ColorStateList bgButtonColor = new ColorStateList(
new int[][]{ new int[][] {
new int[]{android.R.attr.state_enabled}, // enabled new int[] {android.R.attr.state_enabled}, // enabled
new int[]{-android.R.attr.state_enabled} // disabled new int[] {-android.R.attr.state_enabled} // disabled
}, },
new int[]{ new int[] {ContextCompat.getColor(mSendNoteButton.getContext(), R.color.base_accent),
ContextCompat.getColor( ContextCompat.getColor(mSendNoteButton.getContext(), R.color.button_accent_disabled)});
mSendNoteButton.getContext(), R.color.base_accent),
ContextCompat.getColor(mSendNoteButton.getContext(), R.color.button_accent_disabled)
});
final ColorStateList textButtonColor = new ColorStateList( final ColorStateList textButtonColor = new ColorStateList(
new int[][]{ new int[][] {
new int[]{android.R.attr.state_enabled}, // enabled new int[] {android.R.attr.state_enabled}, // enabled
new int[]{-android.R.attr.state_enabled} // disabled new int[] {-android.R.attr.state_enabled} // disabled
}, },
new int[]{ new int[] {ContextCompat.getColor(mSendNoteButton.getContext(),
ContextCompat.getColor( UiUtils.getStyledResourceId(mSendNoteButton.getContext(),
mSendNoteButton.getContext(), android.R.attr.textColorPrimaryInverse)),
UiUtils.getStyledResourceId(mSendNoteButton.getContext(), android.R.attr.textColorPrimaryInverse)), ContextCompat.getColor(mSendNoteButton.getContext(), R.color.button_accent_text_disabled)});
ContextCompat.getColor(mSendNoteButton.getContext(), R.color.button_accent_text_disabled)
});
mSendNoteButton.setBackgroundTintList(bgButtonColor); mSendNoteButton.setBackgroundTintList(bgButtonColor);
mSendNoteButton.setTextColor(textButtonColor); mSendNoteButton.setTextColor(textButtonColor);
mNoteEditText.addTextChangedListener(new StringUtils.SimpleTextWatcher() { mNoteEditText.addTextChangedListener(new StringUtils.SimpleTextWatcher() {

View File

@@ -2,19 +2,16 @@ package app.organicmaps.editor;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import com.google.android.material.timepicker.MaterialTimePicker;
import com.google.android.material.timepicker.TimeFormat;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.sdk.editor.data.HoursMinutes; import app.organicmaps.sdk.editor.data.HoursMinutes;
import app.organicmaps.sdk.util.DateUtils; import app.organicmaps.sdk.util.DateUtils;
import com.google.android.material.timepicker.MaterialTimePicker;
import com.google.android.material.timepicker.TimeFormat;
public class FromToTimePicker public class FromToTimePicker
{ {
@@ -32,18 +29,11 @@ public class FromToTimePicker
private boolean mIsFromTimePicked; private boolean mIsFromTimePicked;
private int mInputMode; private int mInputMode;
public static void pickTime(@NonNull Fragment fragment, public static void pickTime(@NonNull Fragment fragment, @NonNull FromToTimePicker.OnPickListener listener,
@NonNull FromToTimePicker.OnPickListener listener, @NonNull HoursMinutes fromTime, @NonNull HoursMinutes toTime, int id,
@NonNull HoursMinutes fromTime,
@NonNull HoursMinutes toTime,
int id,
boolean startWithToTime) boolean startWithToTime)
{ {
FromToTimePicker timePicker = new FromToTimePicker(fragment, FromToTimePicker timePicker = new FromToTimePicker(fragment, listener, fromTime, toTime, id);
listener,
fromTime,
toTime,
id);
if (startWithToTime) if (startWithToTime)
timePicker.showToTimePicker(); timePicker.showToTimePicker();
@@ -51,11 +41,8 @@ public class FromToTimePicker
timePicker.showFromTimePicker(); timePicker.showFromTimePicker();
} }
private FromToTimePicker(@NonNull Fragment fragment, private FromToTimePicker(@NonNull Fragment fragment, @NonNull FromToTimePicker.OnPickListener listener,
@NonNull FromToTimePicker.OnPickListener listener, @NonNull HoursMinutes fromTime, @NonNull HoursMinutes toTime, int id)
@NonNull HoursMinutes fromTime,
@NonNull HoursMinutes toTime,
int id)
{ {
mActivity = fragment.requireActivity(); mActivity = fragment.requireActivity();
mFragmentManager = fragment.getChildFragmentManager(); mFragmentManager = fragment.getChildFragmentManager();
@@ -100,15 +87,12 @@ public class FromToTimePicker
private MaterialTimePicker buildFromTimePicker() private MaterialTimePicker buildFromTimePicker()
{ {
MaterialTimePicker timePicker = buildTimePicker(mFromTime, MaterialTimePicker timePicker = buildTimePicker(mFromTime, mResources.getString(R.string.editor_time_from),
mResources.getString(R.string.editor_time_from), mResources.getString(R.string.next_button), null);
mResources.getString(R.string.next_button),
null);
timePicker.addOnNegativeButtonClickListener(view -> finishTimePicking(false)); timePicker.addOnNegativeButtonClickListener(view -> finishTimePicking(false));
timePicker.addOnPositiveButtonClickListener(view -> timePicker.addOnPositiveButtonClickListener(view -> {
{
mIsFromTimePicked = true; mIsFromTimePicked = true;
saveState(timePicker, true); saveState(timePicker, true);
mFromTimePicker = null; mFromTimePicker = null;
@@ -122,13 +106,10 @@ public class FromToTimePicker
private MaterialTimePicker buildToTimePicker() private MaterialTimePicker buildToTimePicker()
{ {
MaterialTimePicker timePicker = buildTimePicker(mToTime, MaterialTimePicker timePicker = buildTimePicker(mToTime, mResources.getString(R.string.editor_time_to), null,
mResources.getString(R.string.editor_time_to),
null,
mResources.getString(R.string.back)); mResources.getString(R.string.back));
timePicker.addOnNegativeButtonClickListener(view -> timePicker.addOnNegativeButtonClickListener(view -> {
{
saveState(timePicker, false); saveState(timePicker, false);
mToTimePicker = null; mToTimePicker = null;
if (mIsFromTimePicked) if (mIsFromTimePicked)
@@ -137,8 +118,7 @@ public class FromToTimePicker
finishTimePicking(false); finishTimePicking(false);
}); });
timePicker.addOnPositiveButtonClickListener(view -> timePicker.addOnPositiveButtonClickListener(view -> {
{
saveState(timePicker, false); saveState(timePicker, false);
finishTimePicking(true); finishTimePicking(true);
}); });
@@ -149,18 +129,18 @@ public class FromToTimePicker
} }
@NonNull @NonNull
private MaterialTimePicker buildTimePicker(@NonNull HoursMinutes time, private MaterialTimePicker buildTimePicker(@NonNull HoursMinutes time, @NonNull String title,
@NonNull String title,
@Nullable String positiveButtonTextOverride, @Nullable String positiveButtonTextOverride,
@Nullable String negativeButtonTextOverride) @Nullable String negativeButtonTextOverride)
{ {
MaterialTimePicker.Builder builder = new MaterialTimePicker.Builder() MaterialTimePicker.Builder builder =
.setTitleText(title) new MaterialTimePicker.Builder()
.setTimeFormat(mIs24HourFormat ? TimeFormat.CLOCK_24H : TimeFormat.CLOCK_12H) .setTitleText(title)
.setInputMode(mInputMode) .setTimeFormat(mIs24HourFormat ? TimeFormat.CLOCK_24H : TimeFormat.CLOCK_12H)
.setTheme(R.style.MwmTheme_MaterialTimePicker) .setInputMode(mInputMode)
.setHour((int) time.hours) .setTheme(R.style.MwmTheme_MaterialTimePicker)
.setMinute((int) time.minutes); .setHour((int) time.hours)
.setMinute((int) time.minutes);
if (positiveButtonTextOverride != null) if (positiveButtonTextOverride != null)
builder.setPositiveButtonText(positiveButtonTextOverride); builder.setPositiveButtonText(positiveButtonTextOverride);

View File

@@ -7,7 +7,6 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import androidx.annotation.IdRes; import androidx.annotation.IdRes;
import androidx.annotation.IntRange; import androidx.annotation.IntRange;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@@ -122,20 +121,14 @@ class SimpleTimetableAdapter extends RecyclerView.Adapter<SimpleTimetableAdapter
notifyItemChanged(getItemCount() - 1); notifyItemChanged(getItemCount() - 1);
} }
private void pickTime(int position, private void pickTime(int position, @IntRange(from = ID_OPENING_TIME, to = ID_CLOSED_SPAN) int id,
@IntRange(from = ID_OPENING_TIME, to = ID_CLOSED_SPAN) int id,
boolean startWithToTime) boolean startWithToTime)
{ {
final Timetable data = mItems.get(position); final Timetable data = mItems.get(position);
mPickingPosition = position; mPickingPosition = position;
FromToTimePicker.pickTime(mFragment, FromToTimePicker.pickTime(mFragment, this, data.workingTimespan.start, data.workingTimespan.end, id,
this, startWithToTime);
data.workingTimespan.start,
data.workingTimespan.end,
id,
startWithToTime);
} }
@Override @Override
@@ -384,26 +377,21 @@ class SimpleTimetableAdapter extends RecyclerView.Adapter<SimpleTimetableAdapter
final String text = mFragment.getString(R.string.editor_time_add); final String text = mFragment.getString(R.string.editor_time_add);
mAdd.setEnabled(enable); mAdd.setEnabled(enable);
final ColorStateList bgButtonColor = new ColorStateList( final ColorStateList bgButtonColor = new ColorStateList(
new int[][]{ new int[][] {
new int[]{android.R.attr.state_enabled}, // enabled new int[] {android.R.attr.state_enabled}, // enabled
new int[]{-android.R.attr.state_enabled} // disabled new int[] {-android.R.attr.state_enabled} // disabled
}, },
new int[]{ new int[] {ContextCompat.getColor(mAdd.getContext(), R.color.base_accent),
ContextCompat.getColor( ContextCompat.getColor(mAdd.getContext(), R.color.button_accent_disabled)});
mAdd.getContext(), R.color.base_accent),
ContextCompat.getColor(mAdd.getContext(), R.color.button_accent_disabled)
});
final ColorStateList textButtonColor = new ColorStateList( final ColorStateList textButtonColor = new ColorStateList(
new int[][]{ new int[][] {
new int[]{android.R.attr.state_enabled}, // enabled new int[] {android.R.attr.state_enabled}, // enabled
new int[]{-android.R.attr.state_enabled} // disabled new int[] {-android.R.attr.state_enabled} // disabled
}, },
new int[]{ new int[] {
ContextCompat.getColor( ContextCompat.getColor(mAdd.getContext(), UiUtils.getStyledResourceId(
mAdd.getContext(), mAdd.getContext(), android.R.attr.textColorPrimaryInverse)),
UiUtils.getStyledResourceId(mAdd.getContext(), android.R.attr.textColorPrimaryInverse)), ContextCompat.getColor(mAdd.getContext(), R.color.button_accent_text_disabled)});
ContextCompat.getColor(mAdd.getContext(), R.color.button_accent_text_disabled)
});
mAdd.setBackgroundTintList(bgButtonColor); mAdd.setBackgroundTintList(bgButtonColor);
mAdd.setTextColor(textButtonColor); mAdd.setTextColor(textButtonColor);
mAdd.setText(enable ? text + " (" + TimeFormatUtils.formatWeekdays(mComplementItem) + ")" : text); mAdd.setText(enable ? text + " (" + TimeFormatUtils.formatWeekdays(mComplementItem) + ")" : text);

View File

@@ -9,8 +9,8 @@ import androidx.annotation.Nullable;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.base.BaseMwmRecyclerFragment; import app.organicmaps.base.BaseMwmRecyclerFragment;
public class SimpleTimetableFragment extends BaseMwmRecyclerFragment<SimpleTimetableAdapter> public class SimpleTimetableFragment
implements TimetableProvider extends BaseMwmRecyclerFragment<SimpleTimetableAdapter> implements TimetableProvider
{ {
private SimpleTimetableAdapter mAdapter; private SimpleTimetableAdapter mAdapter;
@Nullable @Nullable

View File

@@ -35,25 +35,30 @@ public class LayerBottomSheetItem
@DrawableRes @DrawableRes
int drawableResId = 0; int drawableResId = 0;
@StringRes @StringRes
int buttonTextResource = switch (mode) { int buttonTextResource = switch (mode)
case OUTDOORS -> { {
drawableResId = R.drawable.ic_layers_outdoors; case OUTDOORS ->
yield R.string.button_layer_outdoor; {
} drawableResId = R.drawable.ic_layers_outdoors;
case SUBWAY -> { yield R.string.button_layer_outdoor;
drawableResId = R.drawable.ic_layers_subway; }
yield R.string.subway; case SUBWAY ->
} {
case ISOLINES -> { drawableResId = R.drawable.ic_layers_subway;
drawableResId = R.drawable.ic_layers_isoline; yield R.string.subway;
yield R.string.button_layer_isolines; }
} case ISOLINES ->
case TRAFFIC -> { {
drawableResId = R.drawable.ic_layers_traffic; drawableResId = R.drawable.ic_layers_isoline;
yield R.string.button_layer_traffic; yield R.string.button_layer_isolines;
} }
case TRAFFIC ->
{
drawableResId = R.drawable.ic_layers_traffic;
yield R.string.button_layer_traffic;
}
}; };
return new LayerBottomSheetItem(drawableResId, buttonTextResource, mode, layerItemClickListener); return new LayerBottomSheetItem(drawableResId, buttonTextResource, mode, layerItemClickListener);
} }
@NonNull @NonNull

View File

@@ -5,11 +5,9 @@ import android.widget.ImageView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.adapter.OnItemClickListener; import app.organicmaps.adapter.OnItemClickListener;
import com.google.android.material.textview.MaterialTextView;
class LayerHolder extends RecyclerView.ViewHolder class LayerHolder extends RecyclerView.ViewHolder
{ {

View File

@@ -395,7 +395,7 @@ public class MapButtonsController extends Fragment
0; 0;
// Allow offset tolerance for zoom buttons // Allow offset tolerance for zoom buttons
}; };
showButton(getViewTopOffset(translation, button) >= toleranceOffset, entry.getKey()); showButton(getViewTopOffset(translation, button) >= toleranceOffset, entry.getKey());
} }
} }
} }

View File

@@ -43,7 +43,6 @@ import app.organicmaps.util.UiUtils;
import app.organicmaps.util.Utils; import app.organicmaps.util.Utils;
import app.organicmaps.widget.recycler.DotDividerItemDecoration; import app.organicmaps.widget.recycler.DotDividerItemDecoration;
import app.organicmaps.widget.recycler.MultilineLayoutManager; import app.organicmaps.widget.recycler.MultilineLayoutManager;
import com.google.android.material.button.MaterialButton; import com.google.android.material.button.MaterialButton;
import com.google.android.material.imageview.ShapeableImageView; import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.textview.MaterialTextView; import com.google.android.material.textview.MaterialTextView;
@@ -123,9 +122,9 @@ final class RoutingBottomMenuController implements View.OnClickListener
@NonNull View timeElevationLine, @NonNull View transitFrame, @NonNull View timeElevationLine, @NonNull View transitFrame,
@NonNull MaterialTextView error, @NonNull MaterialButton start, @NonNull MaterialTextView error, @NonNull MaterialButton start,
@NonNull ShapeableImageView altitudeChart, @NonNull MaterialTextView time, @NonNull ShapeableImageView altitudeChart, @NonNull MaterialTextView time,
@NonNull MaterialTextView altitudeDifference, @NonNull MaterialTextView timeVehicle, @NonNull MaterialTextView altitudeDifference,
@Nullable MaterialTextView arrival, @NonNull View actionFrame, @NonNull MaterialTextView timeVehicle, @Nullable MaterialTextView arrival,
@Nullable RoutingBottomMenuListener listener) @NonNull View actionFrame, @Nullable RoutingBottomMenuListener listener)
{ {
mContext = context; mContext = context;
mAltitudeChartFrame = altitudeChartFrame; mAltitudeChartFrame = altitudeChartFrame;

View File

@@ -12,9 +12,6 @@ import androidx.annotation.IdRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsCompat;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.MwmApplication; import app.organicmaps.MwmApplication;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Framework;
@@ -29,6 +26,7 @@ import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener;
import app.organicmaps.widget.RoutingToolbarButton; import app.organicmaps.widget.RoutingToolbarButton;
import app.organicmaps.widget.ToolbarController; import app.organicmaps.widget.ToolbarController;
import app.organicmaps.widget.WheelProgressView; import app.organicmaps.widget.WheelProgressView;
import com.google.android.material.textview.MaterialTextView;
public class RoutingPlanController extends ToolbarController public class RoutingPlanController extends ToolbarController
{ {
@@ -264,7 +262,7 @@ public class RoutingPlanController extends ToolbarController
default -> throw new IllegalArgumentException("unknown router: " + router); default -> throw new IllegalArgumentException("unknown router: " + router);
}; };
RoutingToolbarButton button = mRouterTypes.findViewById(mRouterTypes.getCheckedRadioButtonId()); RoutingToolbarButton button = mRouterTypes.findViewById(mRouterTypes.getCheckedRadioButtonId());
button.progress(); button.progress();
updateProgressLabels(); updateProgressLabels();

View File

@@ -14,12 +14,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.sdk.search.DisplayedCategories; import app.organicmaps.sdk.search.DisplayedCategories;
import app.organicmaps.sdk.util.Language; import app.organicmaps.sdk.util.Language;
import com.google.android.material.textview.MaterialTextView;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.Locale; import java.util.Locale;

View File

@@ -10,14 +10,12 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.sdk.search.SearchResult; import app.organicmaps.sdk.search.SearchResult;
import app.organicmaps.util.Graphics; import app.organicmaps.util.Graphics;
import app.organicmaps.util.ThemeUtils; import app.organicmaps.util.ThemeUtils;
import app.organicmaps.util.UiUtils; import app.organicmaps.util.UiUtils;
import com.google.android.material.textview.MaterialTextView;
class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchDataViewHolder> class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchDataViewHolder>
{ {
@@ -152,7 +150,8 @@ class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchDataViewHol
{ {
final Resources resources = mSearchFragment.getResources(); final Resources resources = mSearchFragment.getResources();
if (result.description.openNow != SearchResult.OPEN_NOW_YES && result.description.openNow != SearchResult.OPEN_NOW_NO) if (result.description.openNow != SearchResult.OPEN_NOW_YES
&& result.description.openNow != SearchResult.OPEN_NOW_NO)
{ {
// Hide if unknown opening hours state // Hide if unknown opening hours state
UiUtils.hide(mOpen); UiUtils.hide(mOpen);
@@ -169,15 +168,18 @@ class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchDataViewHol
{ {
final String minsToChangeStr = resources.getQuantityString( final String minsToChangeStr = resources.getQuantityString(
R.plurals.minutes_short, Math.max(minsToNextState, 1), Math.max(minsToNextState, 1)); R.plurals.minutes_short, Math.max(minsToNextState, 1), Math.max(minsToNextState, 1));
final String nextChangeFormatted = resources.getString(isOpen ? R.string.closes_in : R.string.opens_in, minsToChangeStr); final String nextChangeFormatted =
resources.getString(isOpen ? R.string.closes_in : R.string.opens_in, minsToChangeStr);
UiUtils.setTextAndShow(mOpen, nextChangeFormatted); UiUtils.setTextAndShow(mOpen, nextChangeFormatted);
mOpen.setTextColor(ContextCompat.getColor(mSearchFragment.getContext(), R.color.base_yellow)); mOpen.setTextColor(ContextCompat.getColor(mSearchFragment.getContext(), R.color.base_yellow));
} }
else else
{ {
UiUtils.setTextAndShow(mOpen, isOpen ? resources.getString(R.string.editor_time_open) : resources.getString(R.string.closed)); UiUtils.setTextAndShow(
mOpen.setTextColor(ContextCompat.getColor(mSearchFragment.getContext(), isOpen ? R.color.base_green : R.color.base_red)); mOpen, isOpen ? resources.getString(R.string.editor_time_open) : resources.getString(R.string.closed));
mOpen.setTextColor(
ContextCompat.getColor(mSearchFragment.getContext(), isOpen ? R.color.base_green : R.color.base_red));
} }
} }

View File

@@ -273,7 +273,8 @@ public class SearchFragment extends BaseMwmFragment implements SearchListener, C
RecyclerView mResults = mResultsFrame.findViewById(R.id.recycler); RecyclerView mResults = mResultsFrame.findViewById(R.id.recycler);
setRecyclerScrollListener(mResults); setRecyclerScrollListener(mResults);
mResultsPlaceholder = mResultsFrame.findViewById(R.id.placeholder); mResultsPlaceholder = mResultsFrame.findViewById(R.id.placeholder);
mResultsPlaceholder.setContent(R.string.search_not_found, R.string.search_not_found_query, R.drawable.ic_search_fail); mResultsPlaceholder.setContent(R.string.search_not_found, R.string.search_not_found_query,
R.drawable.ic_search_fail);
mSearchAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() mSearchAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver()
{ {

View File

@@ -5,15 +5,13 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.MwmApplication; import app.organicmaps.MwmApplication;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.sdk.routing.RoutingController; import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.search.SearchRecents; import app.organicmaps.sdk.search.SearchRecents;
import app.organicmaps.util.Graphics; import app.organicmaps.util.Graphics;
import app.organicmaps.widget.SearchToolbarController; import app.organicmaps.widget.SearchToolbarController;
import com.google.android.material.textview.MaterialTextView;
class SearchHistoryAdapter extends RecyclerView.Adapter<SearchHistoryAdapter.ViewHolder> class SearchHistoryAdapter extends RecyclerView.Adapter<SearchHistoryAdapter.ViewHolder>
{ {

View File

@@ -8,14 +8,12 @@ import android.view.ViewGroup;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.material.materialswitch.MaterialSwitch;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.base.BaseMwmToolbarFragment; import app.organicmaps.base.BaseMwmToolbarFragment;
import app.organicmaps.sdk.routing.RoutingController; import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.routing.RoutingOptions; import app.organicmaps.sdk.routing.RoutingOptions;
import app.organicmaps.sdk.settings.RoadType; import app.organicmaps.sdk.settings.RoadType;
import com.google.android.material.materialswitch.MaterialSwitch;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;

View File

@@ -8,165 +8,165 @@ import android.graphics.Typeface;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
public abstract class BaseSignView extends View public abstract class BaseSignView extends View
{ {
private float mBorderWidthRatio = 0.1f; private float mBorderWidthRatio = 0.1f;
protected void setBorderWidthRatio(float ratio) { protected void setBorderWidthRatio(float ratio)
mBorderWidthRatio = ratio; {
} mBorderWidthRatio = ratio;
}
private float mBorderInsetRatio = 0f; private float mBorderInsetRatio = 0f;
protected void setBorderInsetRatio(float ratio) { protected void setBorderInsetRatio(float ratio)
mBorderInsetRatio = ratio; {
} mBorderInsetRatio = ratio;
}
// colors // colors
protected int mBackgroundColor; protected int mBackgroundColor;
protected int mBorderColor; protected int mBorderColor;
protected int mAlertColor; protected int mAlertColor;
protected int mTextColor; protected int mTextColor;
protected int mTextAlertColor; protected int mTextAlertColor;
// paints // paints
protected final Paint mBackgroundPaint; protected final Paint mBackgroundPaint;
protected final Paint mBorderPaint; protected final Paint mBorderPaint;
protected final Paint mTextPaint; protected final Paint mTextPaint;
// geometry // geometry
protected float mWidth; protected float mWidth;
protected float mHeight; protected float mHeight;
protected float mRadius; protected float mRadius;
protected float mBorderWidth; protected float mBorderWidth;
protected float mBorderRadius; protected float mBorderRadius;
public BaseSignView(Context ctx, @Nullable AttributeSet attrs) public BaseSignView(Context ctx, @Nullable AttributeSet attrs)
{
super(ctx, attrs);
mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBorderPaint.setStyle(Paint.Style.STROKE);
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
}
protected void setColors(int backgroundColor, int borderColor, int alertColor, int textColor, int textAlertColor)
{
mBackgroundColor = backgroundColor;
mBorderColor = borderColor;
mAlertColor = alertColor;
mTextColor = textColor;
mTextAlertColor = textAlertColor;
mBackgroundPaint.setColor(mBackgroundColor);
mBorderPaint.setColor(mBorderColor);
mTextPaint.setColor(mTextColor);
}
@Override
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight)
{
super.onSizeChanged(width, height, oldWidth, oldHeight);
final float paddingX = getPaddingLeft() + getPaddingRight();
final float paddingY = getPaddingTop() + getPaddingBottom();
mWidth = width - paddingX;
mHeight = height - paddingY;
mRadius = Math.min(mWidth, mHeight) / 2f;
mBorderWidth = mRadius * mBorderWidthRatio;
// subtract half the stroke PLUS the extra inset
final float gap = mRadius * mBorderInsetRatio;
mBorderRadius = mRadius - (mBorderWidth / 2f) - gap;
configureTextSize();
}
@Override
protected void onDraw(@NonNull Canvas canvas)
{
super.onDraw(canvas);
final String str = getValueString();
if (str == null)
return;
final float cx = mWidth / 2f;
final float cy = mHeight / 2f;
// background & border
boolean alert = isAlert();
mBackgroundPaint.setColor(alert ? mAlertColor : mBackgroundColor);
canvas.drawCircle(cx, cy, mRadius, mBackgroundPaint);
if (!alert)
{ {
super(ctx, attrs); mBorderPaint.setStrokeWidth(mBorderWidth);
mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mBorderPaint.setColor(mBorderColor);
mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); canvas.drawCircle(cx, cy, mBorderRadius, mBorderPaint);
mBorderPaint.setStyle(Paint.Style.STROKE);
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
} }
protected void setColors(int backgroundColor, // text
int borderColor, mTextPaint.setColor(alert ? mTextAlertColor : mTextColor);
int alertColor, drawValueString(canvas, cx, cy, str);
int textColor, }
int textAlertColor)
@Override
public boolean onTouchEvent(@NonNull MotionEvent e)
{
final float cx = mWidth / 2f, cy = mHeight / 2f;
final float dx = e.getX() - cx, dy = e.getY() - cy;
if ((dx * dx) + (dy * dy) <= (mRadius * mRadius))
{ {
mBackgroundColor = backgroundColor; performClick();
mBorderColor = borderColor; return true;
mAlertColor = alertColor;
mTextColor = textColor;
mTextAlertColor = textAlertColor;
mBackgroundPaint.setColor(mBackgroundColor);
mBorderPaint.setColor(mBorderColor);
mTextPaint.setColor(mTextColor);
} }
return false;
}
@Override @Override
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) { public boolean performClick()
super.onSizeChanged(width, height, oldWidth, oldHeight); {
final float paddingX = getPaddingLeft() + getPaddingRight(); super.performClick();
final float paddingY = getPaddingTop() + getPaddingBottom(); return false;
mWidth = width - paddingX; }
mHeight = height - paddingY;
mRadius = Math.min(mWidth, mHeight) / 2f;
mBorderWidth = mRadius * mBorderWidthRatio;
// subtract half the stroke PLUS the extra inset
final float gap = mRadius * mBorderInsetRatio;
mBorderRadius = mRadius - (mBorderWidth / 2f) - gap;
configureTextSize();
}
@Override private void drawValueString(Canvas c, float cx, float cy, String str)
protected void onDraw(@NonNull Canvas canvas) {
Rect b = new Rect();
mTextPaint.getTextBounds(str, 0, str.length(), b);
final float y = cy - b.exactCenterY();
c.drawText(str, cx, y, mTextPaint);
}
void configureTextSize()
{
String text = getValueString();
if (text == null)
return;
final float textRadius = mBorderRadius - mBorderWidth;
final float maxTextSize = 2f * textRadius;
final float maxTextSize2 = maxTextSize * maxTextSize;
float lo = 0f, hi = maxTextSize, sz = maxTextSize;
Rect b = new Rect();
while (lo <= hi)
{ {
super.onDraw(canvas); sz = (lo + hi) / 2f;
final String str = getValueString(); mTextPaint.setTextSize(sz);
if (str == null) return; mTextPaint.getTextBounds(text, 0, text.length(), b);
float area = b.width() * b.width() + b.height() * b.height();
final float cx = mWidth / 2f; if (area <= maxTextSize2)
final float cy = mHeight / 2f; lo = sz + 1f;
else
// background & border hi = sz - 1f;
boolean alert = isAlert();
mBackgroundPaint.setColor(alert ? mAlertColor : mBackgroundColor);
canvas.drawCircle(cx, cy, mRadius, mBackgroundPaint);
if (!alert)
{
mBorderPaint.setStrokeWidth(mBorderWidth);
mBorderPaint.setColor(mBorderColor);
canvas.drawCircle(cx, cy, mBorderRadius, mBorderPaint);
}
// text
mTextPaint.setColor(alert ? mTextAlertColor : mTextColor);
drawValueString(canvas, cx, cy, str);
} }
mTextPaint.setTextSize(Math.max(1f, sz));
}
@Override /** child must return the string to draw, or null if nothing */
public boolean onTouchEvent(@NonNull MotionEvent e) @Nullable
{ protected abstract String getValueString();
final float cx = mWidth / 2f, cy = mHeight / 2f;
final float dx = e.getX() - cx, dy = e.getY() - cy;
if ((dx * dx) + (dy * dy) <= (mRadius * mRadius))
{
performClick();
return true;
}
return false;
}
@Override /** child decides if this is in “alert” state */
public boolean performClick() protected abstract boolean isAlert();
{
super.performClick();
return false;
}
private void drawValueString(Canvas c, float cx, float cy, String str)
{
Rect b = new Rect();
mTextPaint.getTextBounds(str, 0, str.length(), b);
final float y = cy - b.exactCenterY();
c.drawText(str, cx, y, mTextPaint);
}
void configureTextSize()
{
String text = getValueString();
if (text == null) return;
final float textRadius = mBorderRadius - mBorderWidth;
final float maxTextSize = 2f * textRadius;
final float maxTextSize2 = maxTextSize * maxTextSize;
float lo = 0f, hi = maxTextSize, sz = maxTextSize;
Rect b = new Rect();
while (lo <= hi)
{
sz = (lo + hi) / 2f;
mTextPaint.setTextSize(sz);
mTextPaint.getTextBounds(text, 0, text.length(), b);
float area = b.width()*b.width() + b.height()*b.height();
if (area <= maxTextSize2)
lo = sz + 1f;
else
hi = sz - 1f;
}
mTextPaint.setTextSize(Math.max(1f, sz));
}
/** child must return the string to draw, or null if nothing */
@Nullable
protected abstract String getValueString();
/** child decides if this is in “alert” state */
protected abstract boolean isAlert();
} }

View File

@@ -4,9 +4,7 @@ import android.content.Context;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Pair; import android.util.Pair;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.sdk.util.StringUtils; import app.organicmaps.sdk.util.StringUtils;
@@ -22,18 +20,18 @@ public class CurrentSpeedView extends BaseSignView
setBorderWidthRatio(0.1f); setBorderWidthRatio(0.1f);
setBorderInsetRatio(0.05f); setBorderInsetRatio(0.05f);
try (TypedArray a = ctx.getTheme() try (TypedArray a = ctx.getTheme().obtainStyledAttributes(
.obtainStyledAttributes(attrs, R.styleable.CurrentSpeedView /* reuse same attrs or define new */ , 0, 0)) attrs, R.styleable.CurrentSpeedView /* reuse same attrs or define new */, 0, 0))
{ {
int bg = a.getColor(R.styleable.CurrentSpeedView_currentSpeedBackgroundColor, DefaultValues.BACKGROUND_COLOR); int bg = a.getColor(R.styleable.CurrentSpeedView_currentSpeedBackgroundColor, DefaultValues.BACKGROUND_COLOR);
int bd = a.getColor(R.styleable.CurrentSpeedView_currentSpeedBorderColor, DefaultValues.BORDER_COLOR); int bd = a.getColor(R.styleable.CurrentSpeedView_currentSpeedBorderColor, DefaultValues.BORDER_COLOR);
int tc = a.getColor(R.styleable.CurrentSpeedView_currentSpeedTextColor, DefaultValues.TEXT_COLOR); int tc = a.getColor(R.styleable.CurrentSpeedView_currentSpeedTextColor, DefaultValues.TEXT_COLOR);
setColors(bg, bd, 0, tc, 0); setColors(bg, bd, 0, tc, 0);
if (isInEditMode()) if (isInEditMode())
{ {
mSpeedMps = a.getInt(R.styleable.CurrentSpeedView_currentSpeedEditModeCurrentSpeed, 50); mSpeedMps = a.getInt(R.styleable.CurrentSpeedView_currentSpeedEditModeCurrentSpeed, 50);
mSpeedStr = Integer.toString((int)mSpeedMps); mSpeedStr = Integer.toString((int) mSpeedMps);
} }
} }
} }
@@ -47,7 +45,7 @@ public class CurrentSpeedView extends BaseSignView
} }
else else
{ {
Pair<String,String> su = StringUtils.nativeFormatSpeedAndUnits(mps); Pair<String, String> su = StringUtils.nativeFormatSpeedAndUnits(mps);
mSpeedStr = su.first; mSpeedStr = su.first;
} }
requestLayout(); requestLayout();
@@ -70,8 +68,8 @@ public class CurrentSpeedView extends BaseSignView
private interface DefaultValues private interface DefaultValues
{ {
int BACKGROUND_COLOR = 0xFFFFFFFF; int BACKGROUND_COLOR = 0xFFFFFFFF;
int BORDER_COLOR = 0xFF000000; int BORDER_COLOR = 0xFF000000;
int TEXT_COLOR = 0xFF000000; int TEXT_COLOR = 0xFF000000;
} }
} }

View File

@@ -12,12 +12,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.util.UiUtils; import app.organicmaps.util.UiUtils;
import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.textview.MaterialTextView;
public class PlaceholderView extends LinearLayout public class PlaceholderView extends LinearLayout
{ {

View File

@@ -5,16 +5,14 @@ import android.content.res.TypedArray;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.util.AttributeSet; import android.util.AttributeSet;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import app.organicmaps.R; import app.organicmaps.R;
public class SpeedLimitView extends BaseSignView public class SpeedLimitView extends BaseSignView
{ {
private int mSpeedLimit = -1; private int mSpeedLimit = -1;
private boolean mAlert = false; private boolean mAlert = false;
private String mSpeedStr = "-1"; private String mSpeedStr = "-1";
private final int unlimitedBorderColor; private final int unlimitedBorderColor;
private final int unlimitedStripeColor; private final int unlimitedStripeColor;
@@ -27,15 +25,22 @@ public class SpeedLimitView extends BaseSignView
try (TypedArray styleAttrs = ctx.getTheme().obtainStyledAttributes(attrs, R.styleable.SpeedLimitView, 0, 0)) try (TypedArray styleAttrs = ctx.getTheme().obtainStyledAttributes(attrs, R.styleable.SpeedLimitView, 0, 0))
{ {
final int bgColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitBackgroundColor, DefaultValues.BACKGROUND_COLOR); final int bgColor =
final int borderColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitBorderColor, DefaultValues.BORDER_COLOR); styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitBackgroundColor, DefaultValues.BACKGROUND_COLOR);
final int alertColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitAlertColor, DefaultValues.ALERT_COLOR); final int borderColor =
final int textColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitTextColor, DefaultValues.TEXT_COLOR); styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitBorderColor, DefaultValues.BORDER_COLOR);
final int txtAlertColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitTextAlertColor, DefaultValues.TEXT_ALERT_COLOR); final int alertColor =
styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitAlertColor, DefaultValues.ALERT_COLOR);
final int textColor =
styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitTextColor, DefaultValues.TEXT_COLOR);
final int txtAlertColor =
styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitTextAlertColor, DefaultValues.TEXT_ALERT_COLOR);
setColors(bgColor, borderColor, alertColor, textColor, txtAlertColor); setColors(bgColor, borderColor, alertColor, textColor, txtAlertColor);
unlimitedBorderColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitUnlimitedBorderColor, DefaultValues.UNLIMITED_BORDER_COLOR); unlimitedBorderColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitUnlimitedBorderColor,
unlimitedStripeColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitUnlimitedStripeColor, DefaultValues.UNLIMITED_STRIPE_COLOR); DefaultValues.UNLIMITED_BORDER_COLOR);
unlimitedStripeColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitUnlimitedStripeColor,
DefaultValues.UNLIMITED_STRIPE_COLOR);
if (isInEditMode()) if (isInEditMode())
{ {
@@ -51,7 +56,7 @@ public class SpeedLimitView extends BaseSignView
if (mSpeedLimit != limit) if (mSpeedLimit != limit)
{ {
mSpeedLimit = limit; mSpeedLimit = limit;
mSpeedStr = Integer.toString(limit); mSpeedStr = Integer.toString(limit);
requestLayout(); requestLayout();
} }
mAlert = alert; mAlert = alert;
@@ -75,7 +80,7 @@ public class SpeedLimitView extends BaseSignView
@Override @Override
protected void onDraw(Canvas canvas) protected void onDraw(Canvas canvas)
{ {
final float cx = mWidth/2f, cy = mHeight/2f; final float cx = mWidth / 2f, cy = mHeight / 2f;
if (mSpeedLimit == 0) // 0 means unlimited speed (maxspeed=none) if (mSpeedLimit == 0) // 0 means unlimited speed (maxspeed=none)
{ {
@@ -105,7 +110,7 @@ public class SpeedLimitView extends BaseSignView
stripe.setStrokeWidth(mBorderWidth * 0.4f); stripe.setStrokeWidth(mBorderWidth * 0.4f);
final float radius = mRadius * 0.8f; // Shorten to 80% of full radius final float radius = mRadius * 0.8f; // Shorten to 80% of full radius
final float diag = (float) (1/Math.sqrt(2)); // 45 degrees final float diag = (float) (1 / Math.sqrt(2)); // 45 degrees
final float dx = -diag, dy = +diag; final float dx = -diag, dy = +diag;
final float px = -dy, py = +dx; // Perpendicular final float px = -dy, py = +dx; // Perpendicular
final float step = radius * 0.15f; // Spacing final float step = radius * 0.15f; // Spacing
@@ -122,14 +127,13 @@ public class SpeedLimitView extends BaseSignView
} }
} }
private interface DefaultValues private interface DefaultValues
{ {
int BACKGROUND_COLOR = 0xFFFFFFFF; int BACKGROUND_COLOR = 0xFFFFFFFF;
int BORDER_COLOR = 0xFFFF0000; int BORDER_COLOR = 0xFFFF0000;
int ALERT_COLOR = 0xFFFF0000; int ALERT_COLOR = 0xFFFF0000;
int TEXT_COLOR = 0xFF000000; int TEXT_COLOR = 0xFF000000;
int TEXT_ALERT_COLOR = 0xFFFFFFFF; int TEXT_ALERT_COLOR = 0xFFFFFFFF;
int UNLIMITED_BORDER_COLOR = 0xFF000000; int UNLIMITED_BORDER_COLOR = 0xFF000000;
int UNLIMITED_STRIPE_COLOR = 0xFF000000; int UNLIMITED_STRIPE_COLOR = 0xFF000000;
} }

View File

@@ -72,7 +72,7 @@ public class MyPositionButton
case LocationState.FOLLOW_AND_ROTATE -> R.drawable.ic_follow_and_rotate; case LocationState.FOLLOW_AND_ROTATE -> R.drawable.ic_follow_and_rotate;
default -> throw new IllegalArgumentException("Invalid button mode: " + mode); default -> throw new IllegalArgumentException("Invalid button mode: " + mode);
}; };
image = ResourcesCompat.getDrawable(resources, drawableRes, context.getTheme()); image = ResourcesCompat.getDrawable(resources, drawableRes, context.getTheme());
mIcons.put(mode, image); mIcons.put(mode, image);
} }

View File

@@ -1,9 +1,9 @@
package app.organicmaps.widget.placepage; package app.organicmaps.widget.placepage;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.organicmaps.sdk.util.StringUtils; import app.organicmaps.sdk.util.StringUtils;
import com.github.mikephil.charting.charts.BarLineChartBase; import com.github.mikephil.charting.charts.BarLineChartBase;
import androidx.annotation.Nullable;
import com.github.mikephil.charting.components.AxisBase; import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.formatter.IAxisValueFormatter; import com.github.mikephil.charting.formatter.IAxisValueFormatter;

View File

@@ -105,7 +105,8 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View.
public EditBookmarkFragment() {} public EditBookmarkFragment() {}
@Override @Override
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, R.style.MwmTheme_FullScreenDialog); setStyle(DialogFragment.STYLE_NORMAL, R.style.MwmTheme_FullScreenDialog);
} }
@@ -184,10 +185,9 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View.
{ {
super.onStart(); super.onStart();
Dialog dialog = getDialog(); Dialog dialog = getDialog();
if (dialog != null) { if (dialog != null)
dialog.getWindow().setLayout( {
ViewGroup.LayoutParams.MATCH_PARENT, dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
ViewGroup.LayoutParams.MATCH_PARENT);
} }
// Focus name and show keyboard for "Unknown Place" bookmarks // Focus name and show keyboard for "Unknown Place" bookmarks

View File

@@ -6,9 +6,6 @@ import android.widget.RelativeLayout;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.widget.NestedScrollView; import androidx.core.widget.NestedScrollView;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.ChartController; import app.organicmaps.ChartController;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Framework;
@@ -17,6 +14,7 @@ import app.organicmaps.sdk.bookmarks.data.Track;
import app.organicmaps.sdk.bookmarks.data.TrackStatistics; import app.organicmaps.sdk.bookmarks.data.TrackStatistics;
import app.organicmaps.util.UiUtils; import app.organicmaps.util.UiUtils;
import app.organicmaps.util.Utils; import app.organicmaps.util.Utils;
import com.google.android.material.textview.MaterialTextView;
import java.util.Objects; import java.util.Objects;
public class ElevationProfileViewRenderer implements PlacePageStateListener public class ElevationProfileViewRenderer implements PlacePageStateListener

View File

@@ -14,7 +14,8 @@ public class OpenStateTextFormatter
return String.format(Locale.ROOT, "%02d:%02d", hour, minute); return String.format(Locale.ROOT, "%02d:%02d", hour, minute);
int h = hour % 12; int h = hour % 12;
if (h == 0) h = 12; if (h == 0)
h = 12;
String ampm = (hour < 12) ? "AM" : "PM"; String ampm = (hour < 12) ? "AM" : "PM";
return String.format(Locale.ROOT, "%d:%02d %s", h, minute, ampm); return String.format(Locale.ROOT, "%d:%02d %s", h, minute, ampm);
} }
@@ -29,21 +30,13 @@ public class OpenStateTextFormatter
return t.getDayOfWeek().getDisplayName(TextStyle.SHORT, locale); return t.getDayOfWeek().getDisplayName(TextStyle.SHORT, locale);
} }
static String buildAtLabel( static String buildAtLabel(boolean opens, boolean isToday, String dayShort, String time, String opensAtLocalized,
boolean opens, String closesAtLocalized, String opensDayAtLocalized, String closesDayAtLocalized)
boolean isToday,
String dayShort,
String time,
String opensAtLocalized,
String closesAtLocalized,
String opensDayAtLocalized,
String closesDayAtLocalized
)
{ {
if (isToday) if (isToday)
return opens ? String.format(Locale.ROOT, opensAtLocalized, time) // Opens at %s return opens ? String.format(Locale.ROOT, opensAtLocalized, time) // Opens at %s
: String.format(Locale.ROOT, closesAtLocalized, time); // Closes at %s : String.format(Locale.ROOT, closesAtLocalized, time); // Closes at %s
return opens ? String.format(Locale.ROOT, opensDayAtLocalized, dayShort, time) // Opens %s at %s return opens ? String.format(Locale.ROOT, opensDayAtLocalized, dayShort, time) // Opens %s at %s
: String.format(Locale.ROOT, closesDayAtLocalized, dayShort, time); // Closes %s at %s : String.format(Locale.ROOT, closesDayAtLocalized, dayShort, time); // Closes %s at %s
} }
} }

View File

@@ -80,6 +80,6 @@ public class PlacePageButtonFactory
yield R.drawable.ic_more; yield R.drawable.ic_more;
} }
}; };
return new PlacePageButton(titleId, iconId, buttonType); return new PlacePageButton(titleId, iconId, buttonType);
} }
} }

View File

@@ -31,7 +31,6 @@ import androidx.fragment.app.FragmentFactory;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import app.organicmaps.MwmActivity; import app.organicmaps.MwmActivity;
import app.organicmaps.MwmApplication; import app.organicmaps.MwmApplication;
import app.organicmaps.R; import app.organicmaps.R;
@@ -705,12 +704,10 @@ public class PlacePageView extends Fragment
} }
else else
{ {
mTvEditPlace.setOnClickListener((v) -> { mTvEditPlace.setOnClickListener(
Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit); (v) -> { Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit); });
}); mTvAddPlace.setOnClickListener(
mTvAddPlace.setOnClickListener((v) -> { (v) -> { Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit); });
Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit);
});
String countryId = MapManager.nativeGetSelectedCountry(); String countryId = MapManager.nativeGetSelectedCountry();
@@ -753,9 +750,7 @@ public class PlacePageView extends Fragment
mTvAddPlace.setTextColor(editButtonColor); mTvAddPlace.setTextColor(editButtonColor);
mTvEditPlace.setStrokeColor(ColorStateList.valueOf(editButtonColor)); mTvEditPlace.setStrokeColor(ColorStateList.valueOf(editButtonColor));
mTvAddPlace.setStrokeColor(ColorStateList.valueOf(editButtonColor)); mTvAddPlace.setStrokeColor(ColorStateList.valueOf(editButtonColor));
UiUtils.showIf( UiUtils.showIf(UiUtils.isVisible(mEditPlace) || UiUtils.isVisible(mAddPlace), mEditTopSpace);
UiUtils.isVisible(mEditPlace) || UiUtils.isVisible(mAddPlace),
mEditTopSpace);
} }
updateLinksView(); updateLinksView();
updateOpeningHoursView(); updateOpeningHoursView();
@@ -856,10 +851,9 @@ public class PlacePageView extends Fragment
} }
// Get colours // Get colours
final ForegroundColorSpan colorGreen = final ForegroundColorSpan colorGreen = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_green));
new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_green));
final ForegroundColorSpan colorYellow = final ForegroundColorSpan colorYellow =
new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_yellow)); new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_yellow));
final ForegroundColorSpan colorRed = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_red)); final ForegroundColorSpan colorRed = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_red));
// Get next state info // Get next state info
@@ -885,13 +879,12 @@ public class PlacePageView extends Fragment
if (nextStateTime > 0 && nextStateTime < Long.MAX_VALUE / 2) if (nextStateTime > 0 && nextStateTime < Long.MAX_VALUE / 2)
{ {
// NOTE: Timezone is currently device timezone. TODO: use feature-specific timezone. // NOTE: Timezone is currently device timezone. TODO: use feature-specific timezone.
nextChangeLocal = ZonedDateTime.ofInstant( nextChangeLocal = ZonedDateTime.ofInstant(Instant.ofEpochSecond(nextStateTime), ZoneId.systemDefault());
Instant.ofEpochSecond(nextStateTime), ZoneId.systemDefault()
);
hasFiniteNextChange = true; hasFiniteNextChange = true;
} }
} }
catch (Throwable ignored) {} catch (Throwable ignored)
{}
} }
if (!hasFiniteNextChange) // No valid next change if (!hasFiniteNextChange) // No valid next change
@@ -906,7 +899,7 @@ public class PlacePageView extends Fragment
} }
String localizedTimeString = OpenStateTextFormatter.formatHoursMinutes( String localizedTimeString = OpenStateTextFormatter.formatHoursMinutes(
nextChangeLocal.getHour(), nextChangeLocal.getMinute(), DateUtils.is24HourFormat(context)); nextChangeLocal.getHour(), nextChangeLocal.getMinute(), DateUtils.is24HourFormat(context));
final boolean shortHorizonClosing = isOpen && minsToNextState >= 0 && minsToNextState <= SHORT_HORIZON_CLOSE_MIN; final boolean shortHorizonClosing = isOpen && minsToNextState >= 0 && minsToNextState <= SHORT_HORIZON_CLOSE_MIN;
final boolean shortHorizonOpening = !isOpen && minsToNextState >= 0 && minsToNextState <= SHORT_HORIZON_OPEN_MIN; final boolean shortHorizonOpening = !isOpen && minsToNextState >= 0 && minsToNextState <= SHORT_HORIZON_OPEN_MIN;
@@ -914,12 +907,12 @@ public class PlacePageView extends Fragment
if (shortHorizonClosing || shortHorizonOpening) // POI Opens/Closes in 60 mins • at 18:00 if (shortHorizonClosing || shortHorizonOpening) // POI Opens/Closes in 60 mins • at 18:00
{ {
final String minsToChangeStr = getResources().getQuantityString( final String minsToChangeStr = getResources().getQuantityString(
R.plurals.minutes_short, Math.max(minsToNextState, 1), Math.max(minsToNextState, 1)); R.plurals.minutes_short, Math.max(minsToNextState, 1), Math.max(minsToNextState, 1));
final String nextChangeFormatted = getString(isOpen ? R.string.closes_in : R.string.opens_in, minsToChangeStr); final String nextChangeFormatted = getString(isOpen ? R.string.closes_in : R.string.opens_in, minsToChangeStr);
openStateString.append(nextChangeFormatted, colorYellow, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) openStateString.append(nextChangeFormatted, colorYellow, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
.append("") // Add spacer .append("") // Add spacer
.append(getString(R.string.at, localizedTimeString)); .append(getString(R.string.at, localizedTimeString));
} }
else else
{ {
@@ -929,18 +922,16 @@ public class PlacePageView extends Fragment
final String closesDayAtStr = getString(R.string.closes_day_at); // "Closes %1$s at %2$s" final String closesDayAtStr = getString(R.string.closes_day_at); // "Closes %1$s at %2$s"
final boolean isToday = final boolean isToday =
OpenStateTextFormatter.isSameLocalDate(nextChangeLocal, ZonedDateTime.now(nextChangeLocal.getZone())); OpenStateTextFormatter.isSameLocalDate(nextChangeLocal, ZonedDateTime.now(nextChangeLocal.getZone()));
// Full weekday name per design feedback. // Full weekday name per design feedback.
final String dayName = final String dayName = nextChangeLocal.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.getDefault());
nextChangeLocal.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.getDefault());
if (isOpen) // > 60 minutes OR negative (safety). Show “Open now • Closes at 18:00” if (isOpen) // > 60 minutes OR negative (safety). Show “Open now • Closes at 18:00”
{ {
openStateString.append(getString(R.string.open_now), colorGreen, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); openStateString.append(getString(R.string.open_now), colorGreen, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
final String atLabel = final String atLabel = OpenStateTextFormatter.buildAtLabel(
OpenStateTextFormatter.buildAtLabel(false, isToday, dayName, localizedTimeString, false, isToday, dayName, localizedTimeString, opensAtStr, closesAtStr, opensDayAtStr, closesDayAtStr);
opensAtStr, closesAtStr, opensDayAtStr, closesDayAtStr);
if (!TextUtils.isEmpty(atLabel)) if (!TextUtils.isEmpty(atLabel))
openStateString.append("").append(atLabel); openStateString.append("").append(atLabel);
@@ -949,9 +940,8 @@ public class PlacePageView extends Fragment
{ {
openStateString.append(getString(R.string.closed_now), colorRed, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); openStateString.append(getString(R.string.closed_now), colorRed, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
final String atLabel = final String atLabel = OpenStateTextFormatter.buildAtLabel(
OpenStateTextFormatter.buildAtLabel(true, isToday, dayName, localizedTimeString, true, isToday, dayName, localizedTimeString, opensAtStr, closesAtStr, opensDayAtStr, closesDayAtStr);
opensAtStr, closesAtStr, opensDayAtStr, closesDayAtStr);
if (!TextUtils.isEmpty(atLabel)) if (!TextUtils.isEmpty(atLabel))
openStateString.append("").append(atLabel); openStateString.append("").append(atLabel);

View File

@@ -3,9 +3,7 @@ package app.organicmaps.widget.placepage;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModel;
import app.organicmaps.sdk.bookmarks.data.MapObject; import app.organicmaps.sdk.bookmarks.data.MapObject;
import java.util.List; import java.util.List;
public class PlacePageViewModel extends ViewModel public class PlacePageViewModel extends ViewModel

View File

@@ -31,7 +31,8 @@ import app.organicmaps.widget.placepage.PlacePageViewModel;
import com.google.android.material.textview.MaterialTextView; import com.google.android.material.textview.MaterialTextView;
public class PlacePageBookmarkFragment extends Fragment implements View.OnClickListener, View.OnLongClickListener, public class PlacePageBookmarkFragment extends Fragment implements View.OnClickListener, View.OnLongClickListener,
Observer<MapObject>, EditBookmarkFragment.EditBookmarkListener Observer<MapObject>,
EditBookmarkFragment.EditBookmarkListener
{ {
private View mFrame; private View mFrame;
private MaterialTextView mTvBookmarkNote; private MaterialTextView mTvBookmarkNote;

View File

@@ -13,15 +13,13 @@ import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.R; import app.organicmaps.R;
import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.bookmarks.data.ChargeSocketDescriptor; import app.organicmaps.sdk.bookmarks.data.ChargeSocketDescriptor;
import app.organicmaps.sdk.bookmarks.data.MapObject; import app.organicmaps.sdk.bookmarks.data.MapObject;
import app.organicmaps.widget.placepage.PlacePageViewModel; import app.organicmaps.widget.placepage.PlacePageViewModel;
import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.textview.MaterialTextView;
import java.text.DecimalFormat; import java.text.DecimalFormat;
public class PlacePageChargeSocketsFragment extends Fragment implements Observer<MapObject> public class PlacePageChargeSocketsFragment extends Fragment implements Observer<MapObject>
@@ -96,8 +94,8 @@ public class PlacePageChargeSocketsFragment extends Fragment implements Observer
} }
@SuppressLint("DiscouragedApi") @SuppressLint("DiscouragedApi")
int resTypeId = int resTypeId = getResources().getIdentifier("charge_socket_" + socket.visualType(), "string",
getResources().getIdentifier("charge_socket_" + socket.visualType(), "string", requireContext().getPackageName()); requireContext().getPackageName());
if (resTypeId != 0) if (resTypeId != 0)
{ {
type.setText(resTypeId); type.setText(resTypeId);
@@ -108,7 +106,8 @@ public class PlacePageChargeSocketsFragment extends Fragment implements Observer
DecimalFormat df = new DecimalFormat("#.##"); DecimalFormat df = new DecimalFormat("#.##");
power.setText(getString(R.string.kw_label, df.format(socket.power()))); power.setText(getString(R.string.kw_label, df.format(socket.power())));
} }
else if (socket.ignorePower()) { else if (socket.ignorePower())
{
power.setVisibility(INVISIBLE); power.setVisibility(INVISIBLE);
} }

View File

@@ -191,8 +191,9 @@ public class PlacePageLinksFragment extends Fragment implements Observer<MapObje
case FMD_PANORAMAX -> null; // Don't add raw ID to list, as it's useless for users. case FMD_PANORAMAX -> null; // Don't add raw ID to list, as it's useless for users.
default -> mMapObject.getMetadata(type); default -> mMapObject.getMetadata(type);
}; };
// Add user names for social media if available // Add user names for social media if available
if (!TextUtils.isEmpty(title) && !title.equals(url) && !title.contains("/")) items.add(title); if (!TextUtils.isEmpty(title) && !title.equals(url) && !title.contains("/"))
items.add(title);
if (items.size() == 1) if (items.size() == 1)
PlacePageUtils.copyToClipboard(requireContext(), mFrame, items.get(0)); PlacePageUtils.copyToClipboard(requireContext(), mFrame, items.get(0));

View File

@@ -4,11 +4,10 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import org.junit.Test;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.Locale; import java.util.Locale;
import org.junit.Test;
public class OpenStateTextFormatterTest public class OpenStateTextFormatterTest
{ {
@@ -36,10 +35,10 @@ public class OpenStateTextFormatterTest
@Test @Test
public void buildAtLabel_today_open_close() public void buildAtLabel_today_open_close()
{ {
String open = OpenStateTextFormatter.buildAtLabel(true, true, "Sat", "09:00", String open = OpenStateTextFormatter.buildAtLabel(true, true, "Sat", "09:00", OPENS_AT, CLOSES_AT, OPENS_DAY_AT,
OPENS_AT, CLOSES_AT, OPENS_DAY_AT, CLOSES_DAY_AT); CLOSES_DAY_AT);
String close = OpenStateTextFormatter.buildAtLabel(false, true, "Sat", "18:00", String close = OpenStateTextFormatter.buildAtLabel(false, true, "Sat", "18:00", OPENS_AT, CLOSES_AT, OPENS_DAY_AT,
OPENS_AT, CLOSES_AT, OPENS_DAY_AT, CLOSES_DAY_AT); CLOSES_DAY_AT);
assertEquals("Opens at 09:00", open); assertEquals("Opens at 09:00", open);
assertEquals("Closes at 18:00", close); assertEquals("Closes at 18:00", close);
} }
@@ -47,10 +46,10 @@ public class OpenStateTextFormatterTest
@Test @Test
public void buildAtLabel_other_day() public void buildAtLabel_other_day()
{ {
String open = OpenStateTextFormatter.buildAtLabel(true, false, "Sat", "09:00", String open = OpenStateTextFormatter.buildAtLabel(true, false, "Sat", "09:00", OPENS_AT, CLOSES_AT, OPENS_DAY_AT,
OPENS_AT, CLOSES_AT, OPENS_DAY_AT, CLOSES_DAY_AT); CLOSES_DAY_AT);
String close = OpenStateTextFormatter.buildAtLabel(false, false, "Tue", "18:00", String close = OpenStateTextFormatter.buildAtLabel(false, false, "Tue", "18:00", OPENS_AT, CLOSES_AT, OPENS_DAY_AT,
OPENS_AT, CLOSES_AT, OPENS_DAY_AT, CLOSES_DAY_AT); CLOSES_DAY_AT);
assertEquals("Opens Sat at 09:00", open); assertEquals("Opens Sat at 09:00", open);
assertEquals("Closes Tue at 18:00", close); assertEquals("Closes Tue at 18:00", close);
} }

View File

@@ -18,7 +18,6 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <unordered_map>
#include <vector> #include <vector>
namespace namespace
@@ -53,7 +52,7 @@ struct TBatchedData
jobject g_countryChangedListener = nullptr; jobject g_countryChangedListener = nullptr;
DECLARE_THREAD_CHECKER(g_batchingThreadChecker); DECLARE_THREAD_CHECKER(g_batchingThreadChecker);
std::unordered_map<jobject, std::vector<TBatchedData>> g_batchedCallbackData; ankerl::unordered_dense::map<jobject, std::vector<TBatchedData>> g_batchedCallbackData;
bool g_isBatched; bool g_isBatched;
storage::Storage & GetStorage() storage::Storage & GetStorage()

View File

@@ -320,7 +320,7 @@ JNIEXPORT jobject JNICALL Java_app_organicmaps_sdk_editor_OpeningHours_nativeCur
jclass ohStateClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/editor/OhState"); jclass ohStateClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/editor/OhState");
jclass ruleStateClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/editor/OhState$State"); jclass ruleStateClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/editor/OhState$State");
static std::unordered_map<RuleState, char const *> const ruleState = { static ankerl::unordered_dense::map<RuleState, char const *> const ruleState = {
{RuleState::Open, "Open"}, {RuleState::Closed, "Closed"}, {RuleState::Unknown, "Unknown"}}; {RuleState::Open, "Open"}, {RuleState::Closed, "Closed"}, {RuleState::Unknown, "Unknown"}};
jfieldID stateField = jfieldID stateField =

View File

@@ -35,7 +35,8 @@ SOFTWARE.
#include <iterator> #include <iterator>
#include <string> #include <string>
#include <unordered_map>
#include "3party/ankerl/unordered_dense.h"
DECLARE_EXCEPTION(JniException, RootException); DECLARE_EXCEPTION(JniException, RootException);
@@ -151,7 +152,7 @@ public:
} }
private: private:
std::unordered_map<std::string, jfieldID> m_fieldIds; ankerl::unordered_dense::map<std::string, jfieldID> m_fieldIds;
}; };
} // namespace } // namespace

View File

@@ -4,28 +4,30 @@ package app.organicmaps.sdk.bookmarks.data;
* represents the details of the socket available on a particular charging station * represents the details of the socket available on a particular charging station
* *
*/ */
public record ChargeSocketDescriptor(String type, int count, double power) { public record ChargeSocketDescriptor(String type, int count, double power)
{
/** /**
* Some charge sockets have the same visuals as other sockets, even though they are different and are tagged * Some charge sockets have the same visuals as other sockets, even though they are different and are tagged
* differently in OSM. This method returns the 'visual' type that should be used for the socket. * differently in OSM. This method returns the 'visual' type that should be used for the socket.
* *
* @return the 'equivalent' visual style that should be used for this socket * @return the 'equivalent' visual style that should be used for this socket
*/ */
public String visualType() { public String visualType()
if (type.equals("typee")) { {
return "schuko"; if (type.equals("typee"))
} {
return type; return "schuko";
}
/**
* For some sockets (eg, domestic sockets), the power is usually not provided, as it is 'implicit'
*
* @return true if this socket type does not require displaying the power
*/
public Boolean ignorePower() {
return type.equals("typee") || type.equals("schuko");
} }
return type;
}
/**
* For some sockets (eg, domestic sockets), the power is usually not provided, as it is 'implicit'
*
* @return true if this socket type does not require displaying the power
*/
public Boolean ignorePower()
{
return type.equals("typee") || type.equals("schuko");
}
} }

View File

@@ -3,7 +3,6 @@ package app.organicmaps.sdk.editor;
import androidx.annotation.IntRange; import androidx.annotation.IntRange;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import app.organicmaps.sdk.editor.data.Timespan; import app.organicmaps.sdk.editor.data.Timespan;
import app.organicmaps.sdk.editor.data.Timetable; import app.organicmaps.sdk.editor.data.Timetable;

View File

@@ -2,16 +2,14 @@ package app.organicmaps.sdk.util;
import android.content.Context; import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
import androidx.annotation.Keep; import androidx.annotation.Keep;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import app.organicmaps.sdk.R;
import java.text.DateFormat; import java.text.DateFormat;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Locale; import java.util.Locale;
import app.organicmaps.sdk.R;
public final class DateUtils public final class DateUtils
{ {
private DateUtils() {} private DateUtils() {}
@@ -44,7 +42,7 @@ public final class DateUtils
if (days == 1) if (days == 1)
return resources.getString(R.string.yesterday).toLowerCase(); return resources.getString(R.string.yesterday).toLowerCase();
if (days < 7) if (days < 7)
return resources.getString(R.string.days_ago, Integer.toString(days)); return resources.getString(R.string.days_ago, Integer.toString(days));
if (days < 30) if (days < 30)
return resources.getString(days < 14 ? R.string.week_ago : R.string.weeks_ago, Integer.toString(days / 7)); return resources.getString(days < 14 ? R.string.week_ago : R.string.weeks_ago, Integer.toString(days / 7));
if (days < 365) if (days < 365)

View File

@@ -148,11 +148,11 @@
<ul class="license-list"> <ul class="license-list">
<li><a href="https://agg.sourceforge.net/antigrain.com/index.html">Anti-Grain Geometry</a><br>&copy; 2002&ndash;2005 Maxim Shemanarev; <a href="#agg-license" class="license">License</a></li> <li><a href="https://agg.sourceforge.net/antigrain.com/index.html">Anti-Grain Geometry</a><br>&copy; 2002&ndash;2005 Maxim Shemanarev; <a href="#agg-license" class="license">License</a></li>
<li><a href="https://www.boost.org/">Boost</a>; <a href="#boost-license" class="license">Boost License</a></li> <li><a href="https://www.boost.org">Boost</a>; <a href="#boost-license" class="license">Boost License</a></li>
<li><a href="https://www.daemonology.net/bsdiff/">bsdiff</a>; <a href="#bsd3-license" class="license">BSD License</a></li> <li><a href="https://www.daemonology.net/bsdiff">bsdiff</a>; <a href="#bsd3-license" class="license">BSD License</a></li>
<li><a href="https://chromium.googlesource.com/chromium/src/courgette/">Chromium's Courgette</a>; <li><a href="https://chromium.googlesource.com/chromium/src/courgette">Chromium's Courgette</a>;
<a href="#bsd3-license" class="license">BSD License</a></li> <a href="#bsd3-license" class="license">BSD License</a></li>
<li><a href="https://github.com/dpogue/CMake-MetalShaderSupport">CMake Metal support files</a><br> <li><a href="https://github.com/dpogue/CMake-MetalShaderSupport">CMake Metal support files</a><br>
@@ -170,22 +170,22 @@
<li><a href="https://www.freetype.org">FreeType</a><br> <li><a href="https://www.freetype.org">FreeType</a><br>
&copy; 2013 The FreeType Project; <a href="#freetype-license" class="license">FTL</a></li> &copy; 2013 The FreeType Project; <a href="#freetype-license" class="license">FTL</a></li>
<li><a href="https://stephenberry.github.io/glaze/">glaze</a><br> <li><a href="https://stephenberry.github.io/glaze">glaze</a><br>
&copy; 2019 - present, Stephen Berry; <a href="#mit-license" class="license">MIT License</a></li> &copy; 2019 - present, Stephen Berry; <a href="#mit-license" class="license">MIT License</a></li>
<li><a href="https://www.glfw.org/">GLFW</a><br> <li><a href="https://www.glfw.org">GLFW</a><br>
&copy; 2002-2006 Marcus Geelnard;2006-2019 Camilla Löwy; <a href="#zlib-license" class="license">Zlib License</a></li> &copy; 2002-2006 Marcus Geelnard;2006-2019 Camilla Löwy; <a href="#zlib-license" class="license">Zlib License</a></li>
<li><a href="https://www.g-truc.net/project-0016.html">GLM</a><br> <li><a href="https://www.g-truc.net/project-0016.html">GLM</a><br>
&copy; 2005&ndash;2014 G-Truc Creation; <a href="#mit-license" class="license">MIT License</a></li> &copy; 2005&ndash;2014 G-Truc Creation; <a href="#mit-license" class="license">MIT License</a></li>
<li><a href="https://site.icu-project.org/">ICU</a><br> <li><a href="https://site.icu-project.org">ICU</a><br>
&copy; 1995&ndash;2016 IBM Corporation and others; <a href="#icu-license" class="license">ICU License</a></li> &copy; 1995&ndash;2016 IBM Corporation and others; <a href="#icu-license" class="license">ICU License</a></li>
<li><a href="https://www.digip.org/jansson/">Jansson</a><br> <li><a href="https://www.digip.org/jansson">Jansson</a><br>
&copy; 2009-2013 Petri Lehtinen; <a href="#mit-license" class="license">MIT License</a></li> &copy; 2009-2013 Petri Lehtinen; <a href="#mit-license" class="license">MIT License</a></li>
<li><a href="https://libkdtree.alioth.debian.org/">libkdtree++</a><br> <li><a href="https://libkdtree.alioth.debian.org">libkdtree++</a><br>
&copy; 2004-2007 Martin F. Krafft, parts are &copy; 2004-2008 Paul Harris and &copy; 2007-2008 Sylvain Bougerel; <a href="#artistic-license" class="license">Artistic License</a></li> &copy; 2004-2007 Martin F. Krafft, parts are &copy; 2004-2008 Paul Harris and &copy; 2007-2008 Sylvain Bougerel; <a href="#artistic-license" class="license">Artistic License</a></li>
<li><a href="https://github.com/mapsme/omim">MAPS.ME</a><br> <li><a href="https://github.com/mapsme/omim">MAPS.ME</a><br>
@@ -215,7 +215,7 @@
<li><a href="https://github.com/googlesamples/android-vulkan-tutorials">Vulkan Wrapper</a><br> <li><a href="https://github.com/googlesamples/android-vulkan-tutorials">Vulkan Wrapper</a><br>
&copy; 2016 Google Inc.; <a href="#apache2-license" class="license">Apache License</a></li> &copy; 2016 Google Inc.; <a href="#apache2-license" class="license">Apache License</a></li>
<li class="android"><a href="https://cocosw.com/BottomSheet/">BottomSheet</a><br> <li class="android"><a href="https://cocosw.com/BottomSheet">BottomSheet</a><br>
&copy; 2011, 2015 Kai Liao; <a href="#apache2-license" class="license">Apache License</a></li> &copy; 2011, 2015 Kai Liao; <a href="#apache2-license" class="license">Apache License</a></li>
<li><a href="https://github.com/google/open-location-code">Open Location Code</a><br> <li><a href="https://github.com/google/open-location-code">Open Location Code</a><br>
@@ -226,6 +226,9 @@
<li><a href="https://github.com/skarupke/flat_hash_map">Skarupke Hash Tables</a><br> <li><a href="https://github.com/skarupke/flat_hash_map">Skarupke Hash Tables</a><br>
&copy; Malte Skarupke 2017; <a href="#boost-license" class="license">Boost License</a></li> &copy; Malte Skarupke 2017; <a href="#boost-license" class="license">Boost License</a></li>
<li><a href="https://github.com/martinus/unordered_dense"></a><br>
&copy; 2022 Martin Leitner-Ankerl; <a href="#mit-license" class="license">MIT License</a></li>
</ul> </ul>
<p lang="en">Beyond OpenStreetMap, we also use a few other open data sources to improve our map data:</p> <p lang="en">Beyond OpenStreetMap, we also use a few other open data sources to improve our map data:</p>

View File

@@ -18,6 +18,8 @@ Below are our specific (but not all!) exceptions to the Google's coding standard
- We ARE using C++ exceptions. - We ARE using C++ exceptions.
- We are using all features of C++17 and C++23 except `std::filesystem`, `std::to_chars`, `std::from_chars` and `std::format` which are not fully supported on all platforms. - We are using all features of C++17 and C++23 except `std::filesystem`, `std::to_chars`, `std::from_chars` and `std::format` which are not fully supported on all platforms.
- We try to limit the usage of boost libraries which require linking (and prefer C++23 types over their boost counterparts). - We try to limit the usage of boost libraries which require linking (and prefer C++23 types over their boost counterparts).
- Do not use `std::unordered_map` for hashmaps. Use `ankerl::unordered_dense::map` (from `3party/ankerl/unordered_dense.h`). When dealing with integers and not iterating, use `ska::flat_hash_map`.
- Use `ankerl::unordered_dense::set` instead of `std::unordered_set`.
Naming and formatting Naming and formatting

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include "generator/collector_interface.hpp" #include "generator/collector_interface.hpp"
#include <unordered_map> #include "3party/ankerl/unordered_dense.h"
namespace generator namespace generator
{ {
@@ -18,7 +18,7 @@ public:
}; };
private: private:
std::unordered_map<uint64_t, AddressInfo> m_addresses; ankerl::unordered_dense::map<uint64_t, AddressInfo> m_addresses;
public: public:
void Add(feature::FeatureBuilder const & fb); void Add(feature::FeatureBuilder const & fb);
@@ -44,7 +44,7 @@ class AddressesCollector : public CollectorInterface
uint64_t m_beg, m_end; uint64_t m_beg, m_end;
}; };
// OSM Way ID is a key here. // OSM Way ID is a key here.
std::unordered_map<uint64_t, WayInfo> m_interpolWays; ankerl::unordered_dense::map<uint64_t, WayInfo> m_interpolWays;
public: public:
explicit AddressesCollector(std::string const & filename); explicit AddressesCollector(std::string const & filename);

View File

@@ -133,7 +133,7 @@ template <typename T>
std::vector<std::string> GetHonestAffiliations(T && t, IndexSharedPtr const & index) std::vector<std::string> GetHonestAffiliations(T && t, IndexSharedPtr const & index)
{ {
std::vector<std::string> affiliations; std::vector<std::string> affiliations;
std::unordered_set<borders::CountryPolygons const *> countires; ankerl::unordered_dense::set<borders::CountryPolygons const *> countires;
ForEachPoint(t, [&](auto const & point) ForEachPoint(t, [&](auto const & point)
{ {
std::vector<CountriesFilesIndexAffiliation::Value> values; std::vector<CountriesFilesIndexAffiliation::Value> values;
@@ -196,7 +196,7 @@ CountriesFilesIndexAffiliation::CountriesFilesIndexAffiliation(std::string const
: CountriesFilesAffiliation(borderPath, haveBordersForWholeWorld) : CountriesFilesAffiliation(borderPath, haveBordersForWholeWorld)
{ {
static std::mutex cacheMutex; static std::mutex cacheMutex;
static std::unordered_map<std::string, std::shared_ptr<Tree>> cache; static ankerl::unordered_dense::map<std::string, std::shared_ptr<Tree>> cache;
auto const key = borderPath + std::to_string(haveBordersForWholeWorld); auto const key = borderPath + std::to_string(haveBordersForWholeWorld);
std::lock_guard<std::mutex> lock(cacheMutex); std::lock_guard<std::mutex> lock(cacheMutex);
@@ -228,7 +228,7 @@ std::vector<std::string> CountriesFilesIndexAffiliation::GetAffiliations(m2::Poi
std::shared_ptr<CountriesFilesIndexAffiliation::Tree> CountriesFilesIndexAffiliation::BuildIndex( std::shared_ptr<CountriesFilesIndexAffiliation::Tree> CountriesFilesIndexAffiliation::BuildIndex(
std::vector<m2::RectD> const & net) std::vector<m2::RectD> const & net)
{ {
std::unordered_map<borders::CountryPolygons const *, std::vector<m2::RectD>> countriesRects; ankerl::unordered_dense::map<borders::CountryPolygons const *, std::vector<m2::RectD>> countriesRects;
std::mutex countriesRectsMutex; std::mutex countriesRectsMutex;
std::vector<Value> treeCells; std::vector<Value> treeCells;
std::mutex treeCellsMutex; std::mutex treeCellsMutex;

View File

@@ -262,7 +262,7 @@ CountryPolygonsCollection const & GetOrCreateCountryPolygonsTree(std::string con
{ {
/// @todo Are there many different paths with polygons, that we have to store map? /// @todo Are there many different paths with polygons, that we have to store map?
static std::mutex mutex; static std::mutex mutex;
static std::unordered_map<std::string, CountryPolygonsCollection> countriesMap; static ankerl::unordered_dense::map<std::string, CountryPolygonsCollection> countriesMap;
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);
auto const it = countriesMap.find(baseDir); auto const it = countriesMap.find(baseDir);

View File

@@ -10,10 +10,10 @@
#include "geometry/tree4d.hpp" #include "geometry/tree4d.hpp"
#include <string> #include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector> #include <vector>
#include "3party/ankerl/unordered_dense.h"
#define BORDERS_DIR "borders/" #define BORDERS_DIR "borders/"
#define BORDERS_EXTENSION ".poly" #define BORDERS_EXTENSION ".poly"
@@ -112,7 +112,7 @@ public:
template <typename ToDo> template <typename ToDo>
void ForEachCountryInRect(m2::RectD const & rect, ToDo && toDo) const void ForEachCountryInRect(m2::RectD const & rect, ToDo && toDo) const
{ {
std::unordered_set<CountryPolygons const *> uniq; ankerl::unordered_dense::set<CountryPolygons const *> uniq;
m_regionsTree.ForEachInRect(rect, [&](CountryPolygons const & cp) m_regionsTree.ForEachInRect(rect, [&](CountryPolygons const & cp)
{ {
if (uniq.insert(&cp).second) if (uniq.insert(&cp).second)
@@ -131,7 +131,7 @@ public:
private: private:
m4::Tree<std::reference_wrapper<CountryPolygons const>> m_regionsTree; m4::Tree<std::reference_wrapper<CountryPolygons const>> m_regionsTree;
std::unordered_map<std::string, CountryPolygons> m_countryPolygonsMap; ankerl::unordered_dense::map<std::string, CountryPolygons> m_countryPolygonsMap;
}; };
using PolygonsList = std::vector<Polygon>; using PolygonsList = std::vector<Polygon>;

View File

@@ -15,10 +15,12 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "3party/ankerl/unordered_dense.h"
namespace generator namespace generator
{ {
using base::GeoObjectId; using base::GeoObjectId;
using std::pair, std::string, std::unordered_map, std::vector; using std::pair, std::string, ankerl::unordered_dense::map, std::vector;
DECLARE_EXCEPTION(ParsingError, RootException); DECLARE_EXCEPTION(ParsingError, RootException);
@@ -42,7 +44,7 @@ static void ParseFeatureToBrand(json_t * root, string const & field, GeoObjectId
} }
} }
void ParseTranslations(json_t * root, std::set<string> const & keys, unordered_map<uint32_t, string> & idToKey) void ParseTranslations(json_t * root, std::set<string> const & keys, map<uint32_t, string> & idToKey)
{ {
string const empty; string const empty;
auto getKey = [&](string & translation) -> string const & auto getKey = [&](string & translation) -> string const &
@@ -81,8 +83,7 @@ void ParseTranslations(json_t * root, std::set<string> const & keys, unordered_m
} }
} }
bool LoadBrands(string const & brandsFilename, string const & translationsFilename, bool LoadBrands(string const & brandsFilename, string const & translationsFilename, map<GeoObjectId, string> & brands)
unordered_map<GeoObjectId, string> & brands)
{ {
string jsonBuffer; string jsonBuffer;
try try
@@ -126,7 +127,7 @@ bool LoadBrands(string const & brandsFilename, string const & translationsFilena
return false; return false;
} }
unordered_map<uint32_t, string> idToKey; map<uint32_t, string> idToKey;
try try
{ {
base::Json root(jsonBuffer.c_str()); base::Json root(jsonBuffer.c_str());

View File

@@ -3,7 +3,8 @@
#include "base/geo_object_id.hpp" #include "base/geo_object_id.hpp"
#include <string> #include <string>
#include <unordered_map>
#include "3party/ankerl/unordered_dense.h"
namespace generator namespace generator
{ {
@@ -52,5 +53,5 @@ namespace generator
// name is "Сабвей", then "Сабвэй". // name is "Сабвей", then "Сабвэй".
bool LoadBrands(std::string const & brandsFilename, std::string const & translationsFilename, bool LoadBrands(std::string const & brandsFilename, std::string const & translationsFilename,
std::unordered_map<base::GeoObjectId, std::string> & brands); ankerl::unordered_dense::map<base::GeoObjectId, std::string> & brands);
} // namespace generator } // namespace generator

View File

@@ -16,9 +16,10 @@
#include "base/logging.hpp" #include "base/logging.hpp"
#include <memory> #include <memory>
#include <unordered_map>
#include <vector> #include <vector>
#include "3party/ankerl/unordered_dense.h"
#include "defines.hpp" #include "defines.hpp"
namespace generator namespace generator
@@ -60,7 +61,7 @@ bool BuildCitiesBoundaries(string const & dataPath, BoundariesTable & table, Map
bool BuildCitiesBoundaries(string const & dataPath, OsmIdToBoundariesTable & table) bool BuildCitiesBoundaries(string const & dataPath, OsmIdToBoundariesTable & table)
{ {
std::unordered_map<uint32_t, base::GeoObjectId> mapping; ankerl::unordered_dense::map<uint32_t, base::GeoObjectId> mapping;
if (!ParseFeatureIdToOsmIdMapping(dataPath + OSM2FEATURE_FILE_EXTENSION, mapping)) if (!ParseFeatureIdToOsmIdMapping(dataPath + OSM2FEATURE_FILE_EXTENSION, mapping))
{ {
LOG(LERROR, ("Can't parse feature id to osm id mapping.")); LOG(LERROR, ("Can't parse feature id to osm id mapping."));
@@ -71,7 +72,7 @@ bool BuildCitiesBoundaries(string const & dataPath, OsmIdToBoundariesTable & tab
bool BuildCitiesBoundariesForTesting(string const & dataPath, TestIdToBoundariesTable & table) bool BuildCitiesBoundariesForTesting(string const & dataPath, TestIdToBoundariesTable & table)
{ {
std::unordered_map<uint32_t, uint64_t> mapping; ankerl::unordered_dense::map<uint32_t, uint64_t> mapping;
if (!ParseFeatureIdToTestIdMapping(dataPath, mapping)) if (!ParseFeatureIdToTestIdMapping(dataPath, mapping))
{ {
LOG(LERROR, ("Can't parse feature id to test id mapping.")); LOG(LERROR, ("Can't parse feature id to test id mapping."));

View File

@@ -6,21 +6,18 @@
#include "indexer/data_header.hpp" #include "indexer/data_header.hpp"
#include "indexer/feature_to_osm.hpp" #include "indexer/feature_to_osm.hpp"
#include "search/categories_cache.hpp"
#include "search/cbv.hpp" #include "search/cbv.hpp"
#include "search/localities_source.hpp"
#include "search/mwm_context.hpp"
#include "coding/file_writer.hpp" #include "coding/file_writer.hpp"
#include "coding/files_container.hpp" #include "coding/files_container.hpp"
#include "base/cancellable.hpp"
#include "base/checked_cast.hpp" #include "base/checked_cast.hpp"
#include "base/geo_object_id.hpp" #include "base/geo_object_id.hpp"
#include "base/logging.hpp" #include "base/logging.hpp"
#include <cstdint> #include <cstdint>
#include <unordered_map>
#include "3party/ankerl/unordered_dense.h"
#include "defines.hpp" #include "defines.hpp"
@@ -40,7 +37,7 @@ bool IsWorldMwm(std::string const & path)
} }
void WriteCitiesIdsSectionToFile(std::string const & dataPath, void WriteCitiesIdsSectionToFile(std::string const & dataPath,
std::unordered_map<uint32_t, base::GeoObjectId> const & mapping) ankerl::unordered_dense::map<uint32_t, base::GeoObjectId> const & mapping)
{ {
indexer::FeatureIdToGeoObjectIdBimapMem map; indexer::FeatureIdToGeoObjectIdBimapMem map;
auto const localities = generator::GetLocalities(dataPath); auto const localities = generator::GetLocalities(dataPath);
@@ -89,7 +86,7 @@ bool BuildCitiesIds(std::string const & dataPath, std::string const & osmToFeatu
classificator::Load(); classificator::Load();
std::unordered_map<uint32_t, base::GeoObjectId> mapping; ankerl::unordered_dense::map<uint32_t, base::GeoObjectId> mapping;
if (!ParseFeatureIdToOsmIdMapping(osmToFeaturePath, mapping)) if (!ParseFeatureIdToOsmIdMapping(osmToFeaturePath, mapping))
{ {
LOG(LERROR, ("Can't parse feature id to osm id mapping.")); LOG(LERROR, ("Can't parse feature id to osm id mapping."));
@@ -104,11 +101,11 @@ bool BuildCitiesIdsForTesting(std::string const & dataPath)
{ {
CHECK(IsWorldMwm(dataPath), ()); CHECK(IsWorldMwm(dataPath), ());
std::unordered_map<uint32_t, uint64_t> mapping; ankerl::unordered_dense::map<uint32_t, uint64_t> mapping;
if (!ParseFeatureIdToTestIdMapping(dataPath, mapping)) if (!ParseFeatureIdToTestIdMapping(dataPath, mapping))
return false; return false;
std::unordered_map<uint32_t, base::GeoObjectId> mappingToGeoObjects; ankerl::unordered_dense::map<uint32_t, base::GeoObjectId> mappingToGeoObjects;
for (auto const & entry : mapping) for (auto const & entry : mapping)
{ {
// todo(@m) Make test ids a new source in base::GeoObjectId? // todo(@m) Make test ids a new source in base::GeoObjectId?

View File

@@ -19,9 +19,10 @@
#include "base/stl_helpers.hpp" #include "base/stl_helpers.hpp"
#include <algorithm> #include <algorithm>
#include <unordered_map>
#include <utility> #include <utility>
#include "3party/ankerl/unordered_dense.h"
namespace namespace
{ {
using IdRelationVec = std::vector<std::pair<uint64_t, RelationElement>>; using IdRelationVec = std::vector<std::pair<uint64_t, RelationElement>>;

View File

@@ -6,9 +6,10 @@
#include <optional> #include <optional>
#include <string> #include <string>
#include <tuple> #include <tuple>
#include <unordered_map>
#include <vector> #include <vector>
#include "3party/ankerl/unordered_dense.h"
template <typename T> template <typename T>
class ReaderSource; class ReaderSource;
@@ -82,6 +83,6 @@ private:
IDRInterfacePtr m_cache; IDRInterfacePtr m_cache;
std::vector<uint64_t> m_roadOsmIDs; std::vector<uint64_t> m_roadOsmIDs;
std::unordered_map<uint64_t, CameraInfo> m_speedCameras; ankerl::unordered_dense::map<uint64_t, CameraInfo> m_speedCameras;
}; };
} // namespace routing_builder } // namespace routing_builder

View File

@@ -4,8 +4,7 @@
#include "generator/mini_roundabout_info.hpp" #include "generator/mini_roundabout_info.hpp"
#include "generator/way_nodes_mapper.hpp" #include "generator/way_nodes_mapper.hpp"
#include <unordered_map> #include "3party/ankerl/unordered_dense.h"
#include <unordered_set>
namespace generator namespace generator
{ {
@@ -39,7 +38,7 @@ private:
IDRInterfacePtr m_cache; IDRInterfacePtr m_cache;
WaysIDHolder m_roads; WaysIDHolder m_roads;
std::unordered_map<uint64_t, MiniRoundaboutInfo> m_miniRoundabouts; ankerl::unordered_dense::map<uint64_t, MiniRoundaboutInfo> m_miniRoundabouts;
std::unordered_set<uint64_t> m_miniRoundaboutsExceptions; ankerl::unordered_dense::set<uint64_t> m_miniRoundaboutsExceptions;
}; };
} // namespace generator } // namespace generator

View File

@@ -92,7 +92,7 @@ public:
private: private:
// Value is an index in m_data vector. // Value is an index in m_data vector.
std::unordered_map<IDType, uint64_t> m_id2index; ankerl::unordered_dense::map<IDType, uint64_t> m_id2index;
std::vector<Locality> m_data; std::vector<Locality> m_data;
}; };
@@ -107,10 +107,10 @@ public:
void Save(std::string const & fileName); void Save(std::string const & fileName);
private: private:
std::unordered_map<IDType, Locality> m_id2loc; ankerl::unordered_dense::map<IDType, Locality> m_id2loc;
using IDsSetT = std::unordered_set<IDType>; using IDsSetT = ankerl::unordered_dense::set<IDType>;
std::unordered_map<IDType, IDsSetT> m_node2rel; ankerl::unordered_dense::map<IDType, IDsSetT> m_node2rel;
std::unordered_map<std::string, IDsSetT> m_name2rel; ankerl::unordered_dense::map<std::string, IDsSetT> m_name2rel;
}; };
class RoutingCityBoundariesCollector : public CollectorInterface class RoutingCityBoundariesCollector : public CollectorInterface

View File

@@ -45,9 +45,9 @@ tree_node::Forest<HierarchyEntry> const & ComplexLoader::GetForest(storage::Coun
return it == std::cend(m_forests) ? kEmpty : it->second; return it == std::cend(m_forests) ? kEmpty : it->second;
} }
std::unordered_set<CompositeId> ComplexLoader::GetIdsSet() const ankerl::unordered_dense::set<CompositeId> ComplexLoader::GetIdsSet() const
{ {
std::unordered_set<CompositeId> set; ankerl::unordered_dense::set<CompositeId> set;
ForEach([&](auto const &, auto const & forest) ForEach([&](auto const &, auto const & forest)
{ {
forest.ForEachTree([&](auto const & tree) forest.ForEachTree([&](auto const & tree)
@@ -59,7 +59,7 @@ std::unordered_set<CompositeId> ComplexLoader::GetIdsSet() const
ComplexLoader const & GetOrCreateComplexLoader(std::string const & filename) ComplexLoader const & GetOrCreateComplexLoader(std::string const & filename)
{ {
static std::mutex m; static std::mutex m;
static std::unordered_map<std::string, ComplexLoader> complexLoaders; static ankerl::unordered_dense::map<std::string, ComplexLoader> complexLoaders;
std::lock_guard<std::mutex> lock(m); std::lock_guard<std::mutex> lock(m);
auto const it = complexLoaders.find(filename); auto const it = complexLoaders.find(filename);

View File

@@ -8,10 +8,10 @@
#include <functional> #include <functional>
#include <string> #include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector> #include <vector>
#include "3party/ankerl/unordered_dense.h"
namespace generator namespace generator
{ {
namespace complex namespace complex
@@ -36,10 +36,10 @@ public:
fn(pair.first, pair.second); fn(pair.first, pair.second);
} }
std::unordered_set<CompositeId> GetIdsSet() const; ankerl::unordered_dense::set<CompositeId> GetIdsSet() const;
private: private:
std::unordered_map<storage::CountryId, tree_node::Forest<HierarchyEntry>> m_forests; ankerl::unordered_dense::map<storage::CountryId, tree_node::Forest<HierarchyEntry>> m_forests;
}; };
// Returns true if hierarchy tree is complex; otherwise returns false. // Returns true if hierarchy tree is complex; otherwise returns false.

View File

@@ -8,7 +8,8 @@
#include <array> #include <array>
#include <string> #include <string>
#include <unordered_map>
#include "3party/ankerl/unordered_dense.h"
class FeatureType; class FeatureType;
@@ -22,8 +23,8 @@ public:
std::optional<std::string> GetWikidataId(uint32_t featureId) const; std::optional<std::string> GetWikidataId(uint32_t featureId) const;
private: private:
std::unordered_map<uint32_t, base::GeoObjectId> m_featureIdToOsmId; ankerl::unordered_dense::map<uint32_t, base::GeoObjectId> m_featureIdToOsmId;
std::unordered_map<base::GeoObjectId, std::string> m_osmIdToWikidataId; ankerl::unordered_dense::map<base::GeoObjectId, std::string> m_osmIdToWikidataId;
}; };
class DescriptionsCollectionBuilderStat class DescriptionsCollectionBuilderStat
@@ -88,7 +89,7 @@ public:
descriptions::DescriptionsCollection m_collection; descriptions::DescriptionsCollection m_collection;
private: private:
std::unordered_map<std::string, descriptions::StringIndex> m_path2Index; ankerl::unordered_dense::map<std::string, descriptions::StringIndex> m_path2Index;
WikidataHelper m_wikidataHelper; WikidataHelper m_wikidataHelper;
std::string m_wikipediaDir; std::string m_wikipediaDir;

View File

@@ -220,9 +220,7 @@ bool FeatureBuilder::PreSerialize()
{ {
StringUtf8Multilang nameWithRef; StringUtf8Multilang nameWithRef;
m_params.name.ForEach([&nameWithRef, this](int8_t code, std::string_view name) m_params.name.ForEach([&nameWithRef, this](int8_t code, std::string_view name)
{ { nameWithRef.AddString(code, std::string(name) + " (" + m_params.ref + ")"); });
nameWithRef.AddString(code, std::string(name) + " (" + m_params.ref + ")");
});
m_params.name = std::move(nameWithRef); m_params.name = std::move(nameWithRef);
} }
else if (ftypes::IsEmergencyAccessPointChecker::Instance()(types)) else if (ftypes::IsEmergencyAccessPointChecker::Instance()(types))

View File

@@ -16,9 +16,10 @@
#include "base/stl_helpers.hpp" #include "base/stl_helpers.hpp"
#include <functional> #include <functional>
#include <unordered_map>
#include <utility> #include <utility>
#include "3party/ankerl/unordered_dense.h"
#include "std/target_os.hpp" #include "std/target_os.hpp"
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -214,7 +214,7 @@ void PreserializeLayer::Handle(FeatureBuilder & fb)
LayerBase::Handle(fb); LayerBase::Handle(fb);
} }
ComplexFeaturesMixer::ComplexFeaturesMixer(std::unordered_set<CompositeId> const & hierarchyNodesSet) ComplexFeaturesMixer::ComplexFeaturesMixer(ankerl::unordered_dense::set<CompositeId> const & hierarchyNodesSet)
: m_hierarchyNodesSet(hierarchyNodesSet) : m_hierarchyNodesSet(hierarchyNodesSet)
, m_complexEntryType(classif().GetTypeByPath({"complex_entry"})) , m_complexEntryType(classif().GetTypeByPath({"complex_entry"}))
{ {

View File

@@ -9,7 +9,8 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <string> #include <string>
#include <unordered_set>
#include "3party/ankerl/unordered_dense.h"
namespace generator namespace generator
{ {
@@ -151,7 +152,7 @@ private:
class ComplexFeaturesMixer class ComplexFeaturesMixer
{ {
public: public:
explicit ComplexFeaturesMixer(std::unordered_set<CompositeId> const & hierarchyNodesSet); explicit ComplexFeaturesMixer(ankerl::unordered_dense::set<CompositeId> const & hierarchyNodesSet);
void Process(std::function<void(feature::FeatureBuilder &)> next, void Process(std::function<void(feature::FeatureBuilder &)> next,
feature::FeatureBuilder const & fb); feature::FeatureBuilder const & fb);
@@ -162,7 +163,7 @@ private:
feature::FeatureBuilder MakeComplexLineFrom(feature::FeatureBuilder const & fb); feature::FeatureBuilder MakeComplexLineFrom(feature::FeatureBuilder const & fb);
feature::FeatureBuilder MakeComplexAreaFrom(feature::FeatureBuilder const & fb); feature::FeatureBuilder MakeComplexAreaFrom(feature::FeatureBuilder const & fb);
std::unordered_set<CompositeId> const & m_hierarchyNodesSet; ankerl::unordered_dense::set<CompositeId> const & m_hierarchyNodesSet;
uint32_t const m_complexEntryType; uint32_t const m_complexEntryType;
}; };
*/ */

View File

@@ -39,10 +39,9 @@
#include <functional> #include <functional>
#include <list> #include <list>
#include <string> #include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector> #include <vector>
#include "3party/ankerl/unordered_dense.h"
#include "cppjansson/cppjansson.hpp" #include "cppjansson/cppjansson.hpp"
namespace generator namespace generator
@@ -62,7 +61,7 @@ public:
private: private:
static bool IsMatch(Tags const & elementTags, Tags const & tags); static bool IsMatch(Tags const & elementTags, Tags const & tags);
std::unordered_set<uint64_t> m_skippedIds; ankerl::unordered_dense::set<uint64_t> m_skippedIds;
std::unordered_multimap<std::string, std::reference_wrapper<Tags const>> m_skippedTags; std::unordered_multimap<std::string, std::reference_wrapper<Tags const>> m_skippedTags;
std::list<Tags> m_rulesStorage; std::list<Tags> m_rulesStorage;
}; };

View File

@@ -42,6 +42,7 @@ void CoastlineFinalProcessor::Process()
totalPolygons += fb.GetPolygonsCount(); totalPolygons += fb.GetPolygonsCount();
} }
LOG(LINFO, ("Total coastline features:", totalFeatures, "total polygons:", totalPolygons, "total points:", totalPoints)); LOG(LINFO,
("Total coastline features:", totalFeatures, "total polygons:", totalPolygons, "total points:", totalPoints));
} }
} // namespace generator } // namespace generator

View File

@@ -77,7 +77,7 @@ void ComplexFinalProcessor::Process()
// is contained in an object with tag 'building'. We will split data and work with // is contained in an object with tag 'building'. We will split data and work with
// these cases separately. First of all let's remove objects with tag building:part is // these cases separately. First of all let's remove objects with tag building:part is
// contained in relations. We will add them back after data processing. // contained in relations. We will add them back after data processing.
std::unordered_map<base::GeoObjectId, FeatureBuilder> relationBuildingParts; ankerl::unordered_dense::map<base::GeoObjectId, FeatureBuilder> relationBuildingParts;
auto fbs = ReadAllDatRawFormat<serialization_policy::MaxAccuracy>(path); auto fbs = ReadAllDatRawFormat<serialization_policy::MaxAccuracy>(path);
@@ -141,7 +141,7 @@ void ComplexFinalProcessor::Process()
WriteLines(allLines); WriteLines(allLines);
} }
std::unordered_map<base::GeoObjectId, FeatureBuilder> ComplexFinalProcessor::RemoveRelationBuildingParts( ankerl::unordered_dense::map<base::GeoObjectId, FeatureBuilder> ComplexFinalProcessor::RemoveRelationBuildingParts(
std::vector<FeatureBuilder> & fbs) std::vector<FeatureBuilder> & fbs)
{ {
CHECK(m_buildingToParts, ()); CHECK(m_buildingToParts, ());
@@ -149,7 +149,7 @@ std::unordered_map<base::GeoObjectId, FeatureBuilder> ComplexFinalProcessor::Rem
auto it = std::partition(std::begin(fbs), std::end(fbs), [&](auto const & fb) auto it = std::partition(std::begin(fbs), std::end(fbs), [&](auto const & fb)
{ return !m_buildingToParts->HasBuildingPart(fb.GetMostGenericOsmId()); }); { return !m_buildingToParts->HasBuildingPart(fb.GetMostGenericOsmId()); });
std::unordered_map<base::GeoObjectId, FeatureBuilder> buildingParts; ankerl::unordered_dense::map<base::GeoObjectId, FeatureBuilder> buildingParts;
buildingParts.reserve(static_cast<size_t>(std::distance(it, std::end(fbs)))); buildingParts.reserve(static_cast<size_t>(std::distance(it, std::end(fbs))));
std::transform(it, std::end(fbs), std::inserter(buildingParts, std::begin(buildingParts)), [](auto && fb) std::transform(it, std::end(fbs), std::inserter(buildingParts, std::begin(buildingParts)), [](auto && fb)

View File

@@ -10,9 +10,10 @@
#include <cstddef> #include <cstddef>
#include <memory> #include <memory>
#include <string> #include <string>
#include <unordered_map>
#include <vector> #include <vector>
#include "3party/ankerl/unordered_dense.h"
namespace generator namespace generator
{ {
// Class ComplexFinalProcessor generates hierarchies for each previously filtered mwm.tmp file. // Class ComplexFinalProcessor generates hierarchies for each previously filtered mwm.tmp file.
@@ -37,7 +38,7 @@ public:
private: private:
std::unique_ptr<hierarchy::HierarchyEntryEnricher> CreateEnricher(std::string const & countryName) const; std::unique_ptr<hierarchy::HierarchyEntryEnricher> CreateEnricher(std::string const & countryName) const;
void WriteLines(std::vector<HierarchyEntry> const & lines); void WriteLines(std::vector<HierarchyEntry> const & lines);
std::unordered_map<base::GeoObjectId, feature::FeatureBuilder> RemoveRelationBuildingParts( ankerl::unordered_dense::map<base::GeoObjectId, feature::FeatureBuilder> RemoveRelationBuildingParts(
std::vector<feature::FeatureBuilder> & fbs); std::vector<feature::FeatureBuilder> & fbs);
hierarchy::GetMainTypeFn m_getMainType; hierarchy::GetMainTypeFn m_getMainType;

View File

@@ -13,9 +13,10 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <unordered_map>
#include <vector> #include <vector>
#include "3party/ankerl/unordered_dense.h"
namespace generator namespace generator
{ {
@@ -44,7 +45,7 @@ std::vector<std::vector<std::string>> AppendToMwmTmp(std::vector<feature::Featur
std::string const & temporaryMwmPath, size_t threadsCount = 1) std::string const & temporaryMwmPath, size_t threadsCount = 1)
{ {
auto affiliations = GetAffiliations(fbs, affiliation, threadsCount); auto affiliations = GetAffiliations(fbs, affiliation, threadsCount);
std::unordered_map<std::string, std::vector<size_t>> countryToFbsIndexes; ankerl::unordered_dense::map<std::string, std::vector<size_t>> countryToFbsIndexes;
for (size_t i = 0; i < fbs.size(); ++i) for (size_t i = 0; i < fbs.size(); ++i)
for (auto const & country : affiliations[i]) for (auto const & country : affiliations[i])
countryToFbsIndexes[country].emplace_back(i); countryToFbsIndexes[country].emplace_back(i);

View File

@@ -7,7 +7,8 @@
#include "base/geo_object_id.hpp" #include "base/geo_object_id.hpp"
#include <string> #include <string>
#include <unordered_map>
#include "3party/ankerl/unordered_dense.h"
namespace brands_loader_test namespace brands_loader_test
{ {
@@ -50,7 +51,7 @@ UNIT_TEST(LoadBrands)
ScopedFile const brandsFile("brands.json", kBrandsJson); ScopedFile const brandsFile("brands.json", kBrandsJson);
ScopedFile const translationsFile("translations.json", kBrandTranslationsJson); ScopedFile const translationsFile("translations.json", kBrandTranslationsJson);
std::unordered_map<GeoObjectId, std::string> brands; ankerl::unordered_dense::map<GeoObjectId, std::string> brands;
TEST(LoadBrands(brandsFile.GetFullPath(), translationsFile.GetFullPath(), brands), ()); TEST(LoadBrands(brandsFile.GetFullPath(), translationsFile.GetFullPath(), brands), ());
TEST_EQUAL(brands[GeoObjectId(GeoObjectId::Type::ObsoleteOsmNode, 2132500347)], "mcdonalds", ()); TEST_EQUAL(brands[GeoObjectId(GeoObjectId::Type::ObsoleteOsmNode, 2132500347)], "mcdonalds", ());
TEST_EQUAL(brands[GeoObjectId(GeoObjectId::Type::ObsoleteOsmWay, 440527172)], "mcdonalds", ()); TEST_EQUAL(brands[GeoObjectId(GeoObjectId::Type::ObsoleteOsmWay, 440527172)], "mcdonalds", ());

View File

@@ -57,7 +57,7 @@ UNIT_CLASS_TEST(CitiesIdsTest, BuildCitiesIds)
indexer::FeatureIdToGeoObjectIdTwoWay twoWayMap(GetDataSource()); indexer::FeatureIdToGeoObjectIdTwoWay twoWayMap(GetDataSource());
TEST(twoWayMap.Load(), ()); TEST(twoWayMap.Load(), ());
std::unordered_map<uint32_t, uint64_t> originalMapping; ankerl::unordered_dense::map<uint32_t, uint64_t> originalMapping;
CHECK(ParseFeatureIdToTestIdMapping(worldMwmPath, originalMapping), ()); CHECK(ParseFeatureIdToTestIdMapping(worldMwmPath, originalMapping), ());
{ {

View File

@@ -16,13 +16,14 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <unordered_map>
#include <vector> #include <vector>
#include "3party/ankerl/unordered_dense.h"
namespace collector_boundary_postcode_tests namespace collector_boundary_postcode_tests
{ {
using generator::tests_support::TestWithClassificator; using generator::tests_support::TestWithClassificator;
using std::string, std::vector, std::unordered_map; using std::string, std::vector;
static string const kDumpFileName = "dump.bin"; static string const kDumpFileName = "dump.bin";
@@ -31,7 +32,7 @@ static string const kDumpFileName = "dump.bin";
// 3--4--5 // 3--4--5
// | | | // | | |
// 6--7--8 // 6--7--8
unordered_map<uint64_t, m2::PointD> const kNodes = { ankerl::unordered_dense::map<uint64_t, m2::PointD> const kNodes = {
{0, m2::PointD{-1.0, 1.0}}, {1, m2::PointD{0.0, 1.0}}, {2, m2::PointD{1.0, 1.0}}, {0, m2::PointD{-1.0, 1.0}}, {1, m2::PointD{0.0, 1.0}}, {2, m2::PointD{1.0, 1.0}},
{3, m2::PointD{-1.0, 0.0}}, {4, m2::PointD{0.0, 0.0}}, {5, m2::PointD{1.0, 0.0}}, {3, m2::PointD{-1.0, 0.0}}, {4, m2::PointD{0.0, 0.0}}, {5, m2::PointD{1.0, 0.0}},
{6, m2::PointD{-1.0, -1.0}}, {7, m2::PointD{0.0, -1.0}}, {8, m2::PointD{1.0, -1.0}}}; {6, m2::PointD{-1.0, -1.0}}, {7, m2::PointD{0.0, -1.0}}, {8, m2::PointD{1.0, -1.0}}};
@@ -41,10 +42,10 @@ vector<uint64_t> const kPolygon2 = {6, 3, 4, 7, 6};
vector<uint64_t> const kPolygon3 = {8, 7, 4, 5, 8}; vector<uint64_t> const kPolygon3 = {8, 7, 4, 5, 8};
vector<uint64_t> const kPolygon4 = {0, 1, 4, 4, 0}; vector<uint64_t> const kPolygon4 = {0, 1, 4, 4, 0};
unordered_map<uint64_t, WayElement> const kWays = {{1, WayElement{1, kPolygon1}}, ankerl::unordered_dense::map<uint64_t, WayElement> const kWays = {{1, WayElement{1, kPolygon1}},
{2, WayElement{2, kPolygon2}}, {2, WayElement{2, kPolygon2}},
{3, WayElement{3, kPolygon3}}, {3, WayElement{3, kPolygon3}},
{4, WayElement{4, kPolygon4}}}; {4, WayElement{4, kPolygon4}}};
class IntermediateDataReaderTest : public generator::cache::IntermediateDataReaderInterface class IntermediateDataReaderTest : public generator::cache::IntermediateDataReaderInterface
{ {
@@ -82,12 +83,12 @@ auto const postcodeAreaRelation2 = MakePostcodeAreaRelation(2 /* id */, "127002"
auto const postcodeAreaRelation3 = MakePostcodeAreaRelation(3 /* id */, "127003" /* postcode */, 3 /* wayId */); auto const postcodeAreaRelation3 = MakePostcodeAreaRelation(3 /* id */, "127003" /* postcode */, 3 /* wayId */);
auto const postcodeAreaRelation4 = MakePostcodeAreaRelation(4 /* id */, "127004" /* postcode */, 4 /* wayId */); auto const postcodeAreaRelation4 = MakePostcodeAreaRelation(4 /* id */, "127004" /* postcode */, 4 /* wayId */);
unordered_map<string, vector<m2::PointD>> Read(string const & dumpFilename) ankerl::unordered_dense::map<string, vector<m2::PointD>> Read(string const & dumpFilename)
{ {
FileReader reader(dumpFilename); FileReader reader(dumpFilename);
ReaderSource<FileReader> src(reader); ReaderSource<FileReader> src(reader);
unordered_map<string, vector<m2::PointD>> result; ankerl::unordered_dense::map<string, vector<m2::PointD>> result;
while (src.Size() > 0) while (src.Size() > 0)
{ {
string postcode; string postcode;
@@ -100,7 +101,7 @@ unordered_map<string, vector<m2::PointD>> Read(string const & dumpFilename)
return result; return result;
} }
bool CheckPostcodeExists(unordered_map<string, vector<m2::PointD>> const & data, string const & postcode, bool CheckPostcodeExists(ankerl::unordered_dense::map<string, vector<m2::PointD>> const & data, string const & postcode,
vector<m2::PointD> const & geometry) vector<m2::PointD> const & geometry)
{ {
auto const it = data.find(postcode); auto const it = data.find(postcode);

View File

@@ -12,7 +12,8 @@
#include "platform/platform_tests_support/scoped_file.hpp" #include "platform/platform_tests_support/scoped_file.hpp"
#include <memory> #include <memory>
#include <unordered_map>
#include "3party/ankerl/unordered_dense.h"
namespace collector_building_parts_tests namespace collector_building_parts_tests
{ {
@@ -21,7 +22,7 @@ using namespace generator::tests_support;
class TestOSMElementCacheReader : public generator::cache::OSMElementCacheReaderInterface class TestOSMElementCacheReader : public generator::cache::OSMElementCacheReaderInterface
{ {
public: public:
TestOSMElementCacheReader(std::unordered_map<generator::cache::Key, RelationElement> & m) : m_mapping(m) {} TestOSMElementCacheReader(ankerl::unordered_dense::map<generator::cache::Key, RelationElement> & m) : m_mapping(m) {}
// OSMElementCacheReaderInterface overrides: // OSMElementCacheReaderInterface overrides:
bool Read(generator::cache::Key /* id */, WayElement & /* value */) override { UNREACHABLE(); } bool Read(generator::cache::Key /* id */, WayElement & /* value */) override { UNREACHABLE(); }
@@ -37,13 +38,13 @@ public:
} }
private: private:
std::unordered_map<generator::cache::Key, RelationElement> & m_mapping; ankerl::unordered_dense::map<generator::cache::Key, RelationElement> & m_mapping;
}; };
class IntermediateDataReaderTest : public generator::cache::IntermediateDataReaderInterface class IntermediateDataReaderTest : public generator::cache::IntermediateDataReaderInterface
{ {
public: public:
using IdToIds = std::unordered_map<generator::cache::Key, std::vector<generator::cache::Key>>; using IdToIds = ankerl::unordered_dense::map<generator::cache::Key, std::vector<generator::cache::Key>>;
static generator::cache::Key const kTopRelationId1; static generator::cache::Key const kTopRelationId1;
static generator::cache::Key const kOutlineId1; static generator::cache::Key const kOutlineId1;
@@ -129,7 +130,7 @@ private:
toDo(id, reader); toDo(id, reader);
} }
std::unordered_map<generator::cache::Key, RelationElement> m_IdToRelation; ankerl::unordered_dense::map<generator::cache::Key, RelationElement> m_IdToRelation;
IdToIds m_wayToRelations; IdToIds m_wayToRelations;
IdToIds m_relationToRelations; IdToIds m_relationToRelations;
}; };

View File

@@ -124,12 +124,12 @@ UNIT_CLASS_TEST(TestRawGenerator, HighwayLinks)
using namespace routing; using namespace routing;
MaxspeedType from120 = 104; // like SpeedMacro::Speed104KmPH MaxspeedType from120 = 104; // like SpeedMacro::Speed104KmPH
std::unordered_map<uint64_t, uint16_t> osmID2Speed = { ankerl::unordered_dense::map<uint64_t, uint16_t> osmID2Speed = {
{23011515, from120}, {23011492, from120}, {10689329, from120}, {371581901, from120}, {1017695671, from120}, {23011515, from120}, {23011492, from120}, {10689329, from120}, {371581901, from120}, {1017695671, from120},
{577365212, from120}, {23011612, from120}, {1017695670, from120}, {304871606, from120}, {1017695669, from120}, {577365212, from120}, {23011612, from120}, {1017695670, from120}, {304871606, from120}, {1017695669, from120},
{577365213, from120}, {369541035, from120}, {1014336646, from120}, {466365947, from120}, {23011511, from120}}; {577365213, from120}, {369541035, from120}, {1014336646, from120}, {466365947, from120}, {23011511, from120}};
/// @todo Actually, better to assign speed for this way too. /// @todo Actually, better to assign speed for this way too.
std::unordered_set<uint64_t> osmNoSpeed = {23691193, 1017695668}; ankerl::unordered_dense::set<uint64_t> osmNoSpeed = {23691193, 1017695668};
FrozenDataSource dataSource; FrozenDataSource dataSource;
auto const res = dataSource.RegisterMap(platform::LocalCountryFile::MakeTemporary(GetMwmPath(mwmName))); auto const res = dataSource.RegisterMap(platform::LocalCountryFile::MakeTemporary(GetMwmPath(mwmName)));

View File

@@ -18,7 +18,7 @@ using namespace generator_tests;
class TestOSMElementCacheReader : public OSMElementCacheReaderInterface class TestOSMElementCacheReader : public OSMElementCacheReaderInterface
{ {
public: public:
TestOSMElementCacheReader(std::unordered_map<Key, RelationElement> & m) : m_mapping(m) {} TestOSMElementCacheReader(ankerl::unordered_dense::map<Key, RelationElement> & m) : m_mapping(m) {}
// OSMElementCacheReaderInterface overrides: // OSMElementCacheReaderInterface overrides:
bool Read(Key /* id */, WayElement & /* value */) override { UNREACHABLE(); } bool Read(Key /* id */, WayElement & /* value */) override { UNREACHABLE(); }
@@ -34,7 +34,7 @@ public:
} }
private: private:
std::unordered_map<Key, RelationElement> & m_mapping; ankerl::unordered_dense::map<Key, RelationElement> & m_mapping;
}; };
UNIT_TEST(Process_route_with_ref) UNIT_TEST(Process_route_with_ref)
@@ -62,7 +62,7 @@ UNIT_TEST(Process_route_with_ref)
e1.m_tags.emplace("route", "road"); e1.m_tags.emplace("route", "road");
e1.m_tags.emplace("ref", "E-99"); e1.m_tags.emplace("ref", "E-99");
std::unordered_map<Key, RelationElement> m_IdToRelation = {{1, e1}}; ankerl::unordered_dense::map<Key, RelationElement> m_IdToRelation = {{1, e1}};
TestOSMElementCacheReader reader(m_IdToRelation); TestOSMElementCacheReader reader(m_IdToRelation);
// Create roads. // Create roads.
@@ -111,7 +111,7 @@ UNIT_TEST(Process_route_with_ref_network)
e1.m_tags.emplace("ref", "SP60"); e1.m_tags.emplace("ref", "SP60");
e1.m_tags.emplace("network", "IT:RA"); e1.m_tags.emplace("network", "IT:RA");
std::unordered_map<Key, RelationElement> m_IdToRelation = {{1, e1}}; ankerl::unordered_dense::map<Key, RelationElement> m_IdToRelation = {{1, e1}};
TestOSMElementCacheReader reader(m_IdToRelation); TestOSMElementCacheReader reader(m_IdToRelation);
// Create roads. // Create roads.
@@ -160,7 +160,7 @@ UNIT_TEST(Process_associatedStreet)
e1.m_tags.emplace("name", "Main Street"); e1.m_tags.emplace("name", "Main Street");
e1.m_tags.emplace("wikipedia", "en:Main Street"); e1.m_tags.emplace("wikipedia", "en:Main Street");
std::unordered_map<Key, RelationElement> m_IdToRelation = {{1, e1}}; ankerl::unordered_dense::map<Key, RelationElement> m_IdToRelation = {{1, e1}};
TestOSMElementCacheReader reader(m_IdToRelation); TestOSMElementCacheReader reader(m_IdToRelation);
// Create buildings polygons. // Create buildings polygons.
@@ -219,7 +219,7 @@ UNIT_TEST(RelationTags_GoodBoundary)
e1.m_tags.emplace("name:be", "Лiхтэнштэйн"); e1.m_tags.emplace("name:be", "Лiхтэнштэйн");
e1.m_tags.emplace("wikidata", "Q347"); e1.m_tags.emplace("wikidata", "Q347");
std::unordered_map<Key, RelationElement> m_IdToRelation = {{1, e1}}; ankerl::unordered_dense::map<Key, RelationElement> m_IdToRelation = {{1, e1}};
TestOSMElementCacheReader reader(m_IdToRelation); TestOSMElementCacheReader reader(m_IdToRelation);
// Process ways tags using relation tags. // Process ways tags using relation tags.
@@ -267,7 +267,7 @@ UNIT_TEST(RelationTags_BadBoundary)
e1.m_tags.emplace("name:en", "Italian Peninsula"); e1.m_tags.emplace("name:en", "Italian Peninsula");
e1.m_tags.emplace("wikidata", "Q145694"); e1.m_tags.emplace("wikidata", "Q145694");
std::unordered_map<Key, RelationElement> m_IdToRelation = {{1, e1}}; ankerl::unordered_dense::map<Key, RelationElement> m_IdToRelation = {{1, e1}};
TestOSMElementCacheReader reader(m_IdToRelation); TestOSMElementCacheReader reader(m_IdToRelation);
// Create ways. // Create ways.

View File

@@ -8,9 +8,10 @@
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <string> #include <string>
#include <unordered_map>
#include <vector> #include <vector>
#include "3party/ankerl/unordered_dense.h"
namespace generator namespace generator
{ {
/// \brief Generates a binary file by |mappingContent| with mapping from osm ids to feature ids. /// \brief Generates a binary file by |mappingContent| with mapping from osm ids to feature ids.
@@ -42,7 +43,7 @@ public:
void SetPassThroughAllowed(uint32_t featureId, bool passThroughAllowed); void SetPassThroughAllowed(uint32_t featureId, bool passThroughAllowed);
private: private:
std::unordered_map<uint32_t, RoadGeometry> m_roads; ankerl::unordered_dense::map<uint32_t, RoadGeometry> m_roads;
}; };
std::shared_ptr<EdgeEstimator> CreateEstimatorForCar(traffic::TrafficCache const & trafficCache); std::shared_ptr<EdgeEstimator> CreateEstimatorForCar(traffic::TrafficCache const & trafficCache);

View File

@@ -176,7 +176,7 @@ std::optional<m2::PointD> HierarchyEntryEnricher::GetFeatureCenter(CompositeId c
// because the centers are calculated differently. For example, for an object with a type area, // because the centers are calculated differently. For example, for an object with a type area,
// the area will be computed using the triangles geometry, but for an object with a type line, // the area will be computed using the triangles geometry, but for an object with a type line,
// the area will be computed using the outer geometry of a polygon. // the area will be computed using the outer geometry of a polygon.
std::unordered_map<std::underlying_type_t<feature::GeomType>, m2::PointD> m; ankerl::unordered_dense::map<std::underlying_type_t<feature::GeomType>, m2::PointD> m;
for (auto optId : optIds) for (auto optId : optIds)
{ {
auto const ftPtr = m_featureGetter.GetFeatureByIndex(optId); auto const ftPtr = m_featureGetter.GetFeatureByIndex(optId);

View File

@@ -28,10 +28,11 @@
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <string> #include <string>
#include <unordered_map>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "3party/ankerl/unordered_dense.h"
namespace generator::hierarchy namespace generator::hierarchy
{ {
using GetMainTypeFn = std::function<uint32_t(FeatureParams::Types const &)>; using GetMainTypeFn = std::function<uint32_t(FeatureParams::Types const &)>;

View File

@@ -12,7 +12,8 @@
#include <algorithm> #include <algorithm>
#include <sstream> #include <sstream>
#include <tuple> #include <tuple>
#include <unordered_map>
#include "3party/ankerl/unordered_dense.h"
#include "cppjansson/cppjansson.hpp" #include "cppjansson/cppjansson.hpp"
@@ -140,7 +141,7 @@ HierarchyEntry HierarchyEntryFromCsvRow(coding::CSVReader::Row const & row)
tree_node::types::Ptrs<HierarchyEntry> LoadHierachy(std::string const & filename) tree_node::types::Ptrs<HierarchyEntry> LoadHierachy(std::string const & filename)
{ {
std::unordered_map<CompositeId, tree_node::types::Ptr<HierarchyEntry>> nodes; ankerl::unordered_dense::map<CompositeId, tree_node::types::Ptr<HierarchyEntry>> nodes;
for (auto const & row : coding::CSVRunner(coding::CSVReader(filename, false /* hasHeader */, kCsvDelimiter))) for (auto const & row : coding::CSVRunner(coding::CSVReader(filename, false /* hasHeader */, kCsvDelimiter)))
{ {
auto entry = HierarchyEntryFromCsvRow(row); auto entry = HierarchyEntryFromCsvRow(row);

View File

@@ -260,7 +260,7 @@ public:
private: private:
FileReader m_fileReader; FileReader m_fileReader;
std::unordered_map<uint64_t, LatLon> m_map; ankerl::unordered_dense::map<uint64_t, LatLon> m_map;
}; };
class MapFilePointStorageWriter : public PointStorageWriterBase class MapFilePointStorageWriter : public PointStorageWriterBase
@@ -390,7 +390,7 @@ IntermediateDataObjectsCache::AllocatedObjects & IntermediateDataObjectsCache::G
void IntermediateDataObjectsCache::Clear() void IntermediateDataObjectsCache::Clear()
{ {
std::lock_guard lock(m_mutex); std::lock_guard lock(m_mutex);
std::unordered_map<string, AllocatedObjects>().swap(m_objects); ankerl::unordered_dense::map<string, AllocatedObjects>().swap(m_objects);
} }
IntermediateDataObjectsCache::AllocatedObjects::AllocatedObjects(feature::GenerateInfo::NodeStorageType type, IntermediateDataObjectsCache::AllocatedObjects::AllocatedObjects(feature::GenerateInfo::NodeStorageType type,

View File

@@ -19,9 +19,10 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <type_traits> #include <type_traits>
#include <unordered_map>
#include <vector> #include <vector>
#include "3party/ankerl/unordered_dense.h"
// Classes for reading and writing any data in file with map of offsets for // Classes for reading and writing any data in file with map of offsets for
// fast searching in memory by some key. // fast searching in memory by some key.
namespace generator namespace generator
@@ -141,7 +142,7 @@ public:
private: private:
std::unique_ptr<PointStorageReaderInterface> m_storageReader; std::unique_ptr<PointStorageReaderInterface> m_storageReader;
std::unordered_map<std::string, IndexFileReader> m_fileReaders; ankerl::unordered_dense::map<std::string, IndexFileReader> m_fileReaders;
}; };
// It's thread-safe method. // It's thread-safe method.
@@ -152,7 +153,7 @@ public:
private: private:
std::mutex m_mutex; std::mutex m_mutex;
std::unordered_map<std::string, AllocatedObjects> m_objects; ankerl::unordered_dense::map<std::string, AllocatedObjects> m_objects;
}; };
class OSMElementCacheReader : public OSMElementCacheReaderInterface class OSMElementCacheReader : public OSMElementCacheReaderInterface

View File

@@ -4,7 +4,8 @@
#include <functional> #include <functional>
#include <string> #include <string>
#include <unordered_map>
#include "3party/ankerl/unordered_dense.h"
namespace generator namespace generator
{ {
@@ -21,6 +22,6 @@ private:
uint32_t GetIsolineType(int altitude) const; uint32_t GetIsolineType(int altitude) const;
std::string m_isolinesDir; std::string m_isolinesDir;
std::unordered_map<int, uint32_t> m_altClassToType; ankerl::unordered_dense::map<int, uint32_t> m_altClassToType;
}; };
} // namespace generator } // namespace generator

View File

@@ -89,7 +89,7 @@ class MaxspeedsMwmCollector
static int constexpr kSpeedsCount = MaxspeedsSerializer::DEFAULT_SPEEDS_COUNT; static int constexpr kSpeedsCount = MaxspeedsSerializer::DEFAULT_SPEEDS_COUNT;
static int constexpr kOutsideCityIdx = 0; static int constexpr kOutsideCityIdx = 0;
// 0 - outside a city; 1 - inside a city. // 0 - outside a city; 1 - inside a city.
std::unordered_map<HighwayType, AvgInfo> m_avgSpeeds[kSpeedsCount]; ankerl::unordered_dense::map<HighwayType, AvgInfo> m_avgSpeeds[kSpeedsCount];
base::GeoObjectId GetOsmID(uint32_t fid) const base::GeoObjectId GetOsmID(uint32_t fid) const
{ {
@@ -212,7 +212,7 @@ public:
if (direction) if (direction)
seg = GetOpposite(seg); seg = GetOpposite(seg);
std::unordered_set<uint32_t> reviewed; ankerl::unordered_dense::set<uint32_t> reviewed;
do do
{ {
LOG_MAX_SPEED(("Input seg =", seg)); LOG_MAX_SPEED(("Input seg =", seg));

View File

@@ -5,13 +5,14 @@
#include <cctype> #include <cctype>
#include <limits> #include <limits>
#include <unordered_map>
#include "3party/ankerl/unordered_dense.h"
namespace generator namespace generator
{ {
using measurement_utils::Units; using measurement_utils::Units;
static std::unordered_map<std::string, routing::SpeedInUnits> const kRoadCategoryToSpeed = { static ankerl::unordered_dense::map<std::string, routing::SpeedInUnits> const kRoadCategoryToSpeed = {
{"AR:motorway", {130, Units::Metric}}, {"AR:motorway", {130, Units::Metric}},
{"AR:rural", {110, Units::Metric}}, {"AR:rural", {110, Units::Metric}},
{"AR:urban", {40, Units::Metric}}, {"AR:urban", {40, Units::Metric}},
@@ -108,8 +109,8 @@ static std::unordered_map<std::string, routing::SpeedInUnits> const kRoadCategor
{"FR:urban", {50, Units::Metric}}, {"FR:urban", {50, Units::Metric}},
{"FR:zone30", {30, Units::Metric}}, {"FR:zone30", {30, Units::Metric}},
{"FR:living_street", {20, Units::Metric}}, {"FR:living_street", {20, Units::Metric}},
{"GB:motorway", {70, Units::Imperial}}, // 70 mph = 112.65408 kmph {"GB:motorway", {70, Units::Imperial}}, // 70 mph = 112.65408 kmph
{"GB:nsl_dual", {70, Units::Imperial}}, // 70 mph = 112.65408 kmph {"GB:nsl_dual", {70, Units::Imperial}}, // 70 mph = 112.65408 kmph
{"GB:nsl_restricted", {30, Units::Imperial}}, {"GB:nsl_restricted", {30, Units::Imperial}},
{"GB:nsl_single", {60, Units::Imperial}}, // 60 mph = 96.56064 kmph {"GB:nsl_single", {60, Units::Imperial}}, // 60 mph = 96.56064 kmph
{"GB-WLS:nsl_restricted", {20, Units::Imperial}}, {"GB-WLS:nsl_restricted", {20, Units::Imperial}},
@@ -168,7 +169,7 @@ static std::unordered_map<std::string, routing::SpeedInUnits> const kRoadCategor
{"PH:rural", {80, Units::Metric}}, {"PH:rural", {80, Units::Metric}},
{"PH:urban", {40, Units::Metric}}, {"PH:urban", {40, Units::Metric}},
{"PL:motorway", {140, Units::Metric}}, {"PL:motorway", {140, Units::Metric}},
{"PL:trunk", {100, Units::Metric}}, {"PL:trunk", {100, Units::Metric}},
{"PL:rural", {90, Units::Metric}}, {"PL:rural", {90, Units::Metric}},
{"PL:urban", {50, Units::Metric}}, {"PL:urban", {50, Units::Metric}},
{"PL:living_street", {20, Units::Metric}}, {"PL:living_street", {20, Units::Metric}},

View File

@@ -89,7 +89,7 @@ LineStringMerger::OutputData LineStringMerger::Merge(InputData const & data)
for (auto & lineString : p.second) for (auto & lineString : p.second)
TryMerge(lineString, buffer); TryMerge(lineString, buffer);
std::unordered_set<LinePtr> uniqLineStrings; ankerl::unordered_dense::set<LinePtr> uniqLineStrings;
for (auto const & pb : buffer) for (auto const & pb : buffer)
{ {
auto const & ways = pb.second->GetWays(); auto const & ways = pb.second->GetWays();

View File

@@ -11,9 +11,10 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <string> #include <string>
#include <unordered_map>
#include <vector> #include <vector>
#include "3party/ankerl/unordered_dense.h"
namespace feature namespace feature
{ {
// A string of connected ways. // A string of connected ways.
@@ -70,7 +71,7 @@ public:
static OutputData Merge(InputData const & data); static OutputData Merge(InputData const & data);
private: private:
using Buffer = std::unordered_map<uint64_t, LinePtr>; using Buffer = ankerl::unordered_dense::map<uint64_t, LinePtr>;
static bool TryMerge(LinePtr const & lineString, Buffer & buffer); static bool TryMerge(LinePtr const & lineString, Buffer & buffer);
static bool TryMergeOne(LinePtr const & lineString, Buffer & buffer); static bool TryMergeOne(LinePtr const & lineString, Buffer & buffer);

View File

@@ -7,9 +7,10 @@
#include "geometry/point2d.hpp" #include "geometry/point2d.hpp"
#include <string> #include <string>
#include <unordered_map>
#include <vector> #include <vector>
#include "3party/ankerl/unordered_dense.h"
namespace generator namespace generator
{ {
struct RoundaboutUnit struct RoundaboutUnit
@@ -51,7 +52,7 @@ private:
std::vector<MiniRoundaboutInfo> const & m_roundabouts; std::vector<MiniRoundaboutInfo> const & m_roundabouts;
double const m_radiusMercator = 0.0; double const m_radiusMercator = 0.0;
feature::AffiliationInterface const * m_affiliation = nullptr; feature::AffiliationInterface const * m_affiliation = nullptr;
std::unordered_map<base::GeoObjectId, feature::FeatureBuilder> m_roads; ankerl::unordered_dense::map<base::GeoObjectId, feature::FeatureBuilder> m_roads;
// Skip 2 bytes to satisfy base::GeoObjectId constraints. // Skip 2 bytes to satisfy base::GeoObjectId constraints.
uint64_t m_newWayId = 1ULL << (63 - 16); uint64_t m_newWayId = 1ULL << (63 - 16);
bool m_leftHandTraffic = false; bool m_leftHandTraffic = false;

View File

@@ -18,9 +18,10 @@
#include <cstdlib> #include <cstdlib>
#include <optional> #include <optional>
#include <regex> #include <regex>
#include <unordered_set>
#include <vector> #include <vector>
#include "3party/ankerl/unordered_dense.h"
namespace namespace
{ {
using osm::EditableMapObject; using osm::EditableMapObject;
@@ -33,7 +34,7 @@ auto constexpr kMaxBuildingLevelsInTheWorld = 167;
template <class T> template <class T>
void RemoveDuplicatesAndKeepOrder(std::vector<T> & vec) void RemoveDuplicatesAndKeepOrder(std::vector<T> & vec)
{ {
std::unordered_set<T> seen; ankerl::unordered_dense::set<T> seen;
auto const predicate = [&seen](T const & value) auto const predicate = [&seen](T const & value)
{ {
if (seen.contains(value)) if (seen.contains(value))

View File

@@ -1088,8 +1088,8 @@ void PostprocessElement(OsmElement * p, FeatureBuilderParams & params)
for (uint32_t type : params.m_types) for (uint32_t type : params.m_types)
{ {
ftype::TruncValue(type, 1); ftype::TruncValue(type, 1);
if (type != types.Get(CachedTypes::WheelchairAny) && type != types.Get(CachedTypes::InternetAny) if (type != types.Get(CachedTypes::WheelchairAny) && type != types.Get(CachedTypes::InternetAny) &&
&& type != types.Get(CachedTypes::DisusedBusiness) && type != types.Get(CachedTypes::Building)) type != types.Get(CachedTypes::DisusedBusiness) && type != types.Get(CachedTypes::Building))
{ {
hasPoiType = true; hasPoiType = true;
break; break;

View File

@@ -155,7 +155,7 @@ void BuildPopularPlacesFromWikiDump(std::string const & mwmFile, std::string con
PopularPlaces const & GetOrLoadPopularPlaces(std::string const & filename) PopularPlaces const & GetOrLoadPopularPlaces(std::string const & filename)
{ {
static std::mutex m; static std::mutex m;
static std::unordered_map<std::string, PopularPlaces> placesStorage; static ankerl::unordered_dense::map<std::string, PopularPlaces> placesStorage;
std::lock_guard<std::mutex> lock(m); std::lock_guard<std::mutex> lock(m);
auto const it = placesStorage.find(filename); auto const it = placesStorage.find(filename);

View File

@@ -3,12 +3,13 @@
#include "base/geo_object_id.hpp" #include "base/geo_object_id.hpp"
#include <string> #include <string>
#include <unordered_map>
#include "3party/ankerl/unordered_dense.h"
namespace generator namespace generator
{ {
using PopularityIndex = uint8_t; using PopularityIndex = uint8_t;
using PopularPlaces = std::unordered_map<base::GeoObjectId, PopularityIndex>; using PopularPlaces = ankerl::unordered_dense::map<base::GeoObjectId, PopularityIndex>;
void LoadPopularPlaces(std::string const & srcFilename, PopularPlaces & places); void LoadPopularPlaces(std::string const & srcFilename, PopularPlaces & places);

View File

@@ -56,6 +56,6 @@ private:
std::shared_ptr<TranslatorCollection> m_translators; std::shared_ptr<TranslatorCollection> m_translators;
std::priority_queue<FinalProcessorPtr, std::vector<FinalProcessorPtr>, FinalProcessorPtrCmp> m_finalProcessors; std::priority_queue<FinalProcessorPtr, std::vector<FinalProcessorPtr>, FinalProcessorPtrCmp> m_finalProcessors;
std::vector<std::string> m_names; std::vector<std::string> m_names;
// std::unordered_set<CompositeId> m_hierarchyNodesSet; // ankerl::unordered_dense::set<CompositeId> m_hierarchyNodesSet;
}; };
} // namespace generator } // namespace generator

Some files were not shown because too many files have changed in this diff Show More