Compare commits

..

37 Commits

Author SHA1 Message Date
x7z4w
ad6ea4bec3 Update .git-blame-ignore-revs
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2026-01-09 19:05:09 +00:00
x7z4w
aefb34ff4d [core] Implicit m2::Point hash
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2026-01-09 19:03:38 +00:00
x7z4w
5828fc76ce [generator] Implement hash for OsmElement::Tag
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2026-01-09 19:03:38 +00:00
x7z4w
732210b9a2 [core] Replace SmallMap
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2026-01-09 19:03:38 +00:00
x7z4w
05ba3afa97 [core] Switch to ankerl::unordered_dense
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2026-01-09 19:03:35 +00:00
x7z4w
ae3260f3d1 [drape] nits
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2026-01-09 18:28:30 +00:00
Yannik Bloscheck
53e1361276 [styles] Keep using shorter type for simple charging stations
Signed-off-by: Yannik Bloscheck <git@yannikbloscheck.com>
2026-01-09 18:22:22 +01:00
Yannik Bloscheck
f2a0b4470f [styles] Optimize displaying of charging stations, handle implicit motorcars tagging and add motorcycles
Signed-off-by: Yannik Bloscheck <git@yannikbloscheck.com>
2026-01-09 18:22:22 +01:00
Jean-Baptiste
111fd10af9 [android] Apply new dark background on bottomsheet and map buttons
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2026-01-09 18:15:03 +01:00
Jean-Baptiste
52edb5da6d [android] Enable more languages on Android
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2026-01-09 17:28:16 +01:00
matheusgomesms
70215404c3 [iOS] Improve confirmed existence format
Signed-off-by: matheusgomesms <matheusgomesms@noreply.codeberg.org>
2026-01-09 17:21:00 +01:00
Chris H. Meyer
49b0ec164d [types] Swap abandoned and disused bridge/tunnel
Drop abandoned bridge and tunnel in favor of disused ones.

Signed-off-by: Chris H. Meyer <christian.h.meyer@t-online.de>
2026-01-09 17:07:15 +01:00
Lukas H.
018259bb0f [styles] swap rendering of railway=abandoned and railway=disused
Signed-off-by: Lukas H. <lukas@ideallygrey.uk>
Co-authored-by: Chris H. Meyer <christian.h.meyer@t-online.de>
2026-01-09 17:07:15 +01:00
Jean-Baptiste
b7733786df [android] Remove useless property apply in main TextView style
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2026-01-09 13:56:15 +01:00
Henry Sternberg
245646c45d [routing] parking_aisle fixes v2
Signed-off-by: Henry Sternberg <henry@bluelightmaps.com>
2026-01-09 12:23:33 +00:00
Jean-Baptiste
6799f17c1b [android] Rework text style applied on title in app bar
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2026-01-09 11:44:18 +01:00
Henry Sternberg
e3abbc712b [routing] Fix crash on 32-bit devices with conditional access
The deserialization of conditional road access data was using
size_t which is 8 bytes on 64-bit (where maps are generated)
but only 4 bytes on 32-bit devices. This caused stream
misalignment and eventual std::length_error when garbage data
was interpreted as a huge vector size.

Fix by using uint64_t to always read 8 bytes, matching what
64-bit build servers write.

Signed-off-by: Henry Sternberg <henry@bluelightmaps.com>
2026-01-09 11:15:38 +01:00
Bastian Greshake Tzovaras
0da7869c5b [translation] manually add lt strings
Signed-off-by: Bastian Greshake Tzovaras <bgreshake@googlemail.com>
Co-authored-by: Bastian Greshake Tzovaras <bgreshake@googlemail.com>
Co-committed-by: Bastian Greshake Tzovaras <bgreshake@googlemail.com>
2026-01-09 09:13:48 +01:00
Yannik Bloscheck
2e3a76fc94 [ios] Increasing base version number to new year
Signed-off-by: Yannik Bloscheck <git@yannikbloscheck.com>
2026-01-09 09:12:31 +01:00
Dobri Dabar
85d4226eda [android] Add map Local Language
Signed-off-by: Dobri Dabar <dobridabar@noreply.codeberg.org>
2026-01-09 08:41:22 +01:00
Henry Sternberg
3f9dfd6605 [routing] fix/parking-aisle for pedestrian/cycle routing
Signed-off-by: Henry Sternberg <henry@bluelightmaps.com>
Co-authored-by: Henry Sternberg <henry@bluelightmaps.com>
Co-committed-by: Henry Sternberg <henry@bluelightmaps.com>
2026-01-08 21:41:50 +01:00
Jean-Baptiste
fdf698281a [android] Fix tracks description not showed on the place page
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2026-01-08 18:40:19 +01:00
x7z4w
fd57e71ac4 fix
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2026-01-08 18:24:08 +01:00
thesupertechie
d86049f6d8 [ui][ux] change bookmarks and tracks to favourites
Signed-off-by: thesupertechie <thesupertechie1@gmail.com>
2026-01-08 18:24:08 +01:00
vikiawv
32bba5bc5e Added T-Road to italy
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2026-01-08 18:21:08 +01:00
vikiawv
3068a468a3 Fixed italy again
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2026-01-08 18:21:08 +01:00
vikiawv
267378aa23 Fixed two cases for italy
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2026-01-08 18:21:08 +01:00
Yannik Bloscheck
0a525b7483 Stop interference with county roads in Bavaria
Signed-off-by: Yannik Bloscheck <git@yannikbloscheck.com>
2026-01-08 18:21:08 +01:00
vikiawv
ea4b39ea47 Readding part that hides roadshield letter for some classification types
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2026-01-08 18:21:08 +01:00
vikiawv
67f27482b8 Found mistake in Germany/Austria implementation
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2026-01-08 18:21:08 +01:00
vikiawv
b231f2de6e manually corrected formatting of germany and austria part
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2026-01-08 18:21:08 +01:00
vikiawv
2609dd5588 Update libs/indexer/road_shields_parser.cpp
Corrected albania
2026-01-08 18:21:08 +01:00
vikiawv
08a87c1962 Reverted Austria and Germany to Simpleroadshieldparser and corrected minor things
Signed-off-by: vikiawv <vikiawv@noreply.codeberg.org>
2026-01-08 18:21:08 +01:00
Chris H. Meyer
09b07c2631 [styles] Add railway=turntable
Signed-off-by: Chris H. Meyer <christian.h.meyer@t-online.de>
2026-01-08 18:20:39 +01:00
matheusgomesms
42f5590210 [iOS] Fix display of long addresses in Place Page
Signed-off-by: matheusgomesms <matheusgomesms@noreply.codeberg.org>
2026-01-08 18:19:40 +01:00
matheusgomesms
f7d2e43f09 [iOS] Remove decimals in current speed
Signed-off-by: matheusgomesms <matheusgomesms@noreply.codeberg.org>
2026-01-08 18:19:30 +01:00
Chris H. Meyer
7617f85442 [editor] enable tactile maps
Signed-off-by: Chris H. Meyer <christian.h.meyer@t-online.de>
2026-01-08 18:18:48 +01:00
410 changed files with 5774 additions and 2624 deletions

View File

@@ -2,3 +2,5 @@
480fa6c2fcf53be296504ac6ba8e6b3d70f92b42
a6ede2b1466f0c9d8a443600ef337ba6b5832e58
1377b81bf1cac72bb6da192da7fed6696d5d5281
05ba3afa979104bb33e5f41ede1d43e1ba30a63c
732210b9a24a95d798d092eb3455456a79d4c702

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

@@ -256,17 +256,18 @@ android {
noCompress = ['txt', 'bin', 'html', 'png', 'json', 'mwm', 'ttf', 'sdf', 'ui', 'config', 'csv', 'spv', 'obj']
// Some languages not supported by Android require to be specified here to be applied
localeFilters += [
"en",
"af",
"ar",
"az",
"be",
"bg",
"bn",
"ca",
"cs",
"da",
"de",
"el",
"en",
"en-rGB",
"es",
"es-rMX",
@@ -276,11 +277,16 @@ android {
"fi",
"fr",
"fr-rCA",
"iw",
"gl",
"gsw",
"he",
"hi",
"hu",
"id",
"in",
"is",
"it",
"iw",
"ja",
"kw",
"ko",
@@ -289,16 +295,20 @@ android {
"mr",
"mt",
"nb",
"nb-rNO",
"nl",
"pl",
"pt",
"pt-rBR",
"ro",
"ru",
"sl",
"sk",
"sr",
"sr-rCyrl",
"sr-rLatn",
"sv",
"sw",
"ta",
"th",
"tr",
"uk",

View File

@@ -1 +1 @@
version: 2026.01.08-11-FDroid+26010811
version: 2025.03.02-7-FDroid+25030207

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.listener.OnChartValueSelectedListener;
import com.google.android.material.textview.MaterialTextView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

View File

@@ -18,7 +18,6 @@ import android.location.Location;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.CallSuper;
@@ -26,13 +25,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.core.view.ViewCompat;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.checkbox.MaterialCheckBox;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.progressindicator.LinearProgressIndicator;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.base.BaseMwmFragmentActivity;
import app.organicmaps.dialog.CustomMapServerDialog;
import app.organicmaps.downloader.MapManagerHelper;
@@ -47,7 +39,11 @@ import app.organicmaps.sdk.util.StringUtils;
import app.organicmaps.util.UiUtils;
import app.organicmaps.util.Utils;
import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.checkbox.MaterialCheckBox;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.progressindicator.LinearProgressIndicator;
import com.google.android.material.textview.MaterialTextView;
import java.util.List;
import java.util.Objects;
@@ -259,7 +255,7 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
mProgress.setMax(bytes);
// Start progress at 1% according to M3 guidelines
mProgress.setProgressCompat(bytes/100, true);
mProgress.setProgressCompat(bytes / 100, true);
}
else
finishFilesDownload(bytes);
@@ -275,11 +271,8 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
mChbDownloadCountry = findViewById(R.id.chb_download_country);
mBtnAdvanced = findViewById(R.id.btn_advanced);
mBtnAdvanced.setOnClickListener(v -> {
CustomMapServerDialog.show(this, url -> {
prepareFilesDownload(false);
});
});
mBtnAdvanced.setOnClickListener(
v -> { CustomMapServerDialog.show(this, url -> { prepareFilesDownload(false); }); });
mBtnAdvanced.setEnabled(true);
mBtnListeners = new View.OnClickListener[BTN_COUNT];
@@ -394,7 +387,7 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
mTvMessage.setText(getString(R.string.downloading_country_can_proceed, item.name, fileSizeString));
mProgress.setMax((int) item.totalSize);
// 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);
MapManagerHelper.startDownload(mCurrentCountry);
@@ -446,21 +439,18 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
default -> throw new AssertionError("Unexpected result code = " + result);
};
mAlertDialog = new MaterialAlertDialogBuilder(this)
.setTitle(titleId)
.setMessage(messageId)
.setCancelable(true)
.setOnCancelListener((dialog) -> setAction(RESUME))
.setPositiveButton(R.string.try_again,
(dialog, which) -> {
setAction(TRY_AGAIN);
onTryAgainClicked();
})
.setNegativeButton(R.string.cancel,
(dialog, which) -> {
setAction(RESUME);
})
.setOnDismissListener(dialog -> mAlertDialog = null)
.show();
mAlertDialog = new MaterialAlertDialogBuilder(this)
.setTitle(titleId)
.setMessage(messageId)
.setCancelable(true)
.setOnCancelListener((dialog) -> setAction(RESUME))
.setPositiveButton(R.string.try_again,
(dialog, which) -> {
setAction(TRY_AGAIN);
onTryAgainClicked();
})
.setNegativeButton(R.string.cancel, (dialog, which) -> { setAction(RESUME); })
.setOnDismissListener(dialog -> mAlertDialog = null)
.show();
}
}

View File

@@ -132,7 +132,6 @@ import app.organicmaps.widget.placepage.PlacePageViewModel;
import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.textview.MaterialTextView;
import java.util.ArrayList;
import java.util.Objects;
@@ -712,7 +711,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
if (!TextUtils.isEmpty(appName))
{
setTitle(appName);
((MaterialTextView) mPointChooser.findViewById(R.id.title)).setText(appName);
}
}

View File

@@ -38,8 +38,9 @@ public class OsmUploadWork extends Worker
{
final Constraints c = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build();
OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(OsmUploadWork.class).setConstraints(c);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
builder.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
{
builder.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST);
}
final OneTimeWorkRequest wr = builder.build();
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 app.organicmaps.R;
import app.organicmaps.sdk.util.log.Logger;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;

View File

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

View File

@@ -282,11 +282,13 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<ConcatAdapter
{
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())
{
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();

View File

@@ -23,7 +23,6 @@ import app.organicmaps.util.UiUtils;
import app.organicmaps.util.Utils;
import app.organicmaps.widget.recycler.RecyclerClickListener;
import app.organicmaps.widget.recycler.RecyclerLongClickListener;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.checkbox.MaterialCheckBox;
import com.google.android.material.imageview.ShapeableImageView;
@@ -458,10 +457,12 @@ public class Holders
String formattedDesc = desc.replace("\n", "<br>");
Spanned spannedDesc = Utils.fromHtml(formattedDesc);
if (!TextUtils.isEmpty(spannedDesc)) {
if (!TextUtils.isEmpty(spannedDesc))
{
mDescText.setText(spannedDesc);
}
else {
else
{
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)
private static void processNavigationIntent(@NonNull CarContext carContext,
@NonNull Renderer surfaceRenderer, @NonNull Intent intent)
private static void processNavigationIntent(@NonNull CarContext carContext, @NonNull Renderer surfaceRenderer,
@NonNull Intent intent)
{
// 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

View File

@@ -31,7 +31,7 @@ public final class RoutingHelpers
default -> Distance.UNIT_METERS;
};
return Distance.create(distance.mDistance, displayUnit);
return Distance.create(distance.mDistance, displayUnit);
}
@NonNull
@@ -52,7 +52,7 @@ public final class RoutingHelpers
default -> LaneDirection.SHAPE_UNKNOWN;
};
return LaneDirection.create(shape, isRecommended);
return LaneDirection.create(shape, isRecommended);
}
@NonNull
@@ -77,7 +77,7 @@ public final class RoutingHelpers
case EXIT_HIGHWAY_TO_LEFT -> Maneuver.TYPE_OFF_RAMP_SLIGHT_LEFT;
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)
builder.setRoundaboutExitNumber(roundaboutExitNum > 0 ? roundaboutExitNum : 1);
builder.setIcon(new CarIcon.Builder(createManeuverIcon(context, carDirection, roundaboutExitNum)).build());
@@ -85,7 +85,8 @@ public final class RoutingHelpers
}
@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)
{

View File

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

View File

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

View File

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

View File

@@ -4,7 +4,6 @@ import android.location.Location;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import app.organicmaps.MwmActivity;
@@ -49,7 +48,8 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener
@Override
public void onStatusChanged(List<MapManager.StorageCallbackData> data)
{
if (mCurrentCountry == null) {
if (mCurrentCountry == null)
{
updateOfflineExplanationVisibility();
return;
}
@@ -109,10 +109,13 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener
return enqueued || progress || applying;
}
private void updateOfflineExplanationVisibility() {
if (mOfflineExplanation == null) return;
private void updateOfflineExplanationVisibility()
{
if (mOfflineExplanation == null)
return;
// 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)

View File

@@ -15,7 +15,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.AutoCompleteTextView;
import android.widget.GridLayout;
import androidx.annotation.CallSuper;
import androidx.annotation.DrawableRes;
import androidx.annotation.IdRes;
@@ -196,8 +195,9 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
{
final Context context = mInputBuildingLevels.getContext();
final boolean isValid = Editor.nativeIsLevelValid(s.toString());
mInputBuildingLevels.setError(isValid ? null : context.getString(R.string.error_enter_correct_storey_number,
Editor.nativeGetMaxEditableBuildingLevels()));
mInputBuildingLevels.setError(isValid ? null
: context.getString(R.string.error_enter_correct_storey_number,
Editor.nativeGetMaxEditableBuildingLevels()));
}
});
@@ -396,7 +396,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
List<String> SOCKET_TYPES = Arrays.stream(getResources().getStringArray(R.array.charge_socket_types)).toList();
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);
@@ -404,16 +404,16 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
// load SVG icon converted into VectorDrawable in res/drawable
@SuppressLint("DiscouragedApi")
int resIconId =
getResources().getIdentifier("ic_charge_socket_" + socket.visualType(), "drawable", requireContext().getPackageName());
int resIconId = getResources().getIdentifier("ic_charge_socket_" + socket.visualType(), "drawable",
requireContext().getPackageName());
if (resIconId != 0)
{
btn.setIcon(getResources().getDrawable(resIconId));
}
@SuppressLint("DiscouragedApi")
int resTypeId =
getResources().getIdentifier("charge_socket_" + socket.visualType(), "string", requireContext().getPackageName());
int resTypeId = getResources().getIdentifier("charge_socket_" + socket.visualType(), "string",
requireContext().getPackageName());
if (resTypeId != 0)
{
btn.setText(getResources().getString(resTypeId));
@@ -461,13 +461,16 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
// Add a TextWatcher to validate on text change
countView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
public void onTextChanged(CharSequence s, int start, int before, int count)
{}
@Override
public void afterTextChanged(Editable s) {
public void afterTextChanged(Editable s)
{
validatePositiveField(s.toString(), countInputLayout);
}
});
@@ -482,13 +485,16 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
// Add a TextWatcher to validate on text change
powerView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
public void onTextChanged(CharSequence s, int start, int before, int count)
{}
@Override
public void afterTextChanged(Editable s) {
public void afterTextChanged(Editable s)
{
validatePositiveField(s.toString(), powerInputLayout);
}
});
@@ -496,74 +502,82 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
return new MaterialAlertDialogBuilder(requireActivity())
.setTitle(R.string.editor_socket)
.setView(dialogView)
.setPositiveButton(R.string.save,
(dialog, which) -> {
String socketType = "";
for (MaterialButton b : buttonList)
{
if (b.isChecked())
{
socketType = b.getTag(R.id.socket_type).toString();
break;
}
}
.setPositiveButton(
R.string.save,
(dialog, which) -> {
String socketType = "";
for (MaterialButton b : buttonList)
{
if (b.isChecked())
{
socketType = b.getTag(R.id.socket_type).toString();
break;
}
}
int countValue = 0; // 0 means 'unknown count'
try
{
countValue = Integer.parseInt(countView.getText().toString());
}
catch (NumberFormatException ignored)
{
Logger.w(CHARGE_SOCKETS_TAG, "Invalid count value for socket:" + countView.getText().toString());
}
int countValue = 0; // 0 means 'unknown count'
try
{
countValue = Integer.parseInt(countView.getText().toString());
}
catch (NumberFormatException ignored)
{
Logger.w(CHARGE_SOCKETS_TAG, "Invalid count value for socket:" + countView.getText().toString());
}
if (countValue < 0)
{
countValue = 0;
Logger.w(CHARGE_SOCKETS_TAG, "Invalid count value for socket:" + countView.getText().toString());
}
if (countValue < 0)
{
countValue = 0;
Logger.w(CHARGE_SOCKETS_TAG, "Invalid count value for socket:" + countView.getText().toString());
}
double powerValue = 0; // 0 means 'unknown power'
try
{
powerValue = Double.parseDouble(powerView.getText().toString());
}
catch (NumberFormatException ignored)
{
Logger.w(CHARGE_SOCKETS_TAG, "Invalid power value for socket:" + powerView.getText().toString());
}
double powerValue = 0; // 0 means 'unknown power'
try
{
powerValue = Double.parseDouble(powerView.getText().toString());
}
catch (NumberFormatException ignored)
{
Logger.w(CHARGE_SOCKETS_TAG, "Invalid power value for socket:" + powerView.getText().toString());
}
if (powerValue < 0)
{
powerValue = 0;
Logger.w(CHARGE_SOCKETS_TAG, "Invalid power value for socket:" + powerView.getText().toString());
}
if (powerValue < 0)
{
powerValue = 0;
Logger.w(CHARGE_SOCKETS_TAG, "Invalid power value for socket:" + powerView.getText().toString());
}
ChargeSocketDescriptor socket =
new ChargeSocketDescriptor(socketType, countValue, powerValue);
ChargeSocketDescriptor socket = new ChargeSocketDescriptor(socketType, countValue, powerValue);
updateChargeSockets(socketIndex, socket);
})
updateChargeSockets(socketIndex, socket);
})
.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
}
// Helper method for validation logic
private boolean validatePositiveField(String text, TextInputLayout layout) {
if (text.isEmpty()) {
private boolean validatePositiveField(String text, TextInputLayout layout)
{
if (text.isEmpty())
{
layout.setError(null); // No error if empty (assuming 0 is the default)
return true;
}
try {
try
{
double value = Double.parseDouble(text);
if (value < 0) {
if (value < 0)
{
layout.setError(getString(R.string.error_value_must_be_positive));
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));
return false;
}
@@ -583,7 +597,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
{
sockets[socketIndex] = socket;
}
else {
else
{
List<ChargeSocketDescriptor> list = new ArrayList<>(Arrays.asList(sockets));
list.add(socket);
sockets = list.toArray(new ChargeSocketDescriptor[0]);
@@ -601,7 +616,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
GridLayout socketsGrid = mChargeSockets.findViewById(R.id.socket_grid_editor);
socketsGrid.removeAllViews();
for (int i = 0; i < sockets.length; i++) {
for (int i = 0; i < sockets.length; i++)
{
final int currentIndex = i;
ChargeSocketDescriptor socket = sockets[i];
@@ -612,27 +628,30 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
MaterialTextView power = itemView.findViewById(R.id.socket_power);
MaterialTextView count = itemView.findViewById(R.id.socket_count);
// load SVG icon converted into VectorDrawable in res/drawable
@SuppressLint("DiscouragedApi")
int resIconId = getResources().getIdentifier("ic_charge_socket_" + socket.visualType(), "drawable",
requireContext().getPackageName());
if (resIconId != 0) {
requireContext().getPackageName());
if (resIconId != 0)
{
icon.setImageResource(resIconId);
}
@SuppressLint("DiscouragedApi")
int resTypeId =
getResources().getIdentifier("charge_socket_" + socket.visualType(), "string", requireContext().getPackageName());
if (resTypeId != 0) {
int resTypeId = getResources().getIdentifier("charge_socket_" + socket.visualType(), "string",
requireContext().getPackageName());
if (resTypeId != 0)
{
type.setText(resTypeId);
}
if (socket.power() != 0) {
if (socket.power() != 0)
{
DecimalFormat df = new DecimalFormat("#.##");
power.setText(getString(R.string.kw_label, df.format(socket.power())));
}
else if (socket.ignorePower()) {
else if (socket.ignorePower())
{
power.setVisibility(INVISIBLE);
}
@@ -641,7 +660,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
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);
}
@@ -787,9 +807,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
View lineContactBlock =
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);
View blueskyContactBlock =
initBlock(view, Metadata.MetadataType.FMD_CONTACT_BLUESKY, R.id.block_bluesky, R.drawable.ic_bluesky,
R.string.bluesky, InputType.TYPE_TEXT_VARIATION_URI);
View blueskyContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_BLUESKY, R.id.block_bluesky,
R.drawable.ic_bluesky, R.string.bluesky, InputType.TYPE_TEXT_VARIATION_URI);
View operatorBlock = initBlock(view, Metadata.MetadataType.FMD_OPERATOR, R.id.block_operator,
R.drawable.ic_operator, R.string.editor_operator, 0);
@@ -1021,14 +1040,15 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
private void placeDisused()
{
new MaterialAlertDialogBuilder(requireActivity())
.setTitle(R.string.editor_mark_business_vacant_title)
.setMessage(R.string.editor_mark_business_vacant_description)
.setPositiveButton(R.string.editor_submit, (dlg, which) -> {
Editor.nativeMarkPlaceAsDisused();
mParent.processEditedFeatures();
})
.setNegativeButton(android.R.string.cancel, null)
.show();
.setTitle(R.string.editor_mark_business_vacant_title)
.setMessage(R.string.editor_mark_business_vacant_description)
.setPositiveButton(R.string.editor_submit,
(dlg, which) -> {
Editor.nativeMarkPlaceAsDisused();
mParent.processEditedFeatures();
})
.setNegativeButton(android.R.string.cancel, null)
.show();
}
private void commitPlaceDoesntExists(@NonNull String text)

View File

@@ -237,6 +237,7 @@ public class EditorHostFragment
for (LocalizedName name : sNames)
languages.add(name.lang);
args.putStringArrayList(LanguagesFragment.EXISTING_LOCALIZED_NAMES, languages);
args.putBoolean(LanguagesFragment.INCLUDE_LOCAL_LANGUAGE, false);
editWithFragment(Mode.LANGUAGE, R.string.choose_language, args, LanguagesFragment.class, false);
}

View File

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

View File

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

View File

@@ -1,11 +1,14 @@
package app.organicmaps.editor;
import static app.organicmaps.sdk.editor.data.Language.DEFAULT_LANG_CODE;
import android.content.res.Configuration;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.core.os.ConfigurationCompat;
import androidx.core.os.LocaleListCompat;
import androidx.fragment.app.Fragment;
import app.organicmaps.R;
import app.organicmaps.base.BaseMwmRecyclerFragment;
import app.organicmaps.sdk.editor.Editor;
import app.organicmaps.sdk.editor.data.Language;
@@ -21,6 +24,7 @@ import java.util.Set;
public class LanguagesFragment extends BaseMwmRecyclerFragment<LanguagesAdapter>
{
final static String EXISTING_LOCALIZED_NAMES = "ExistingLocalizedNames";
final static String INCLUDE_LOCAL_LANGUAGE = "IncludeLocalLanguage";
public interface Listener
{
@@ -34,6 +38,7 @@ public class LanguagesFragment extends BaseMwmRecyclerFragment<LanguagesAdapter>
protected LanguagesAdapter createAdapter()
{
Bundle args = getArguments();
boolean includeLocalLanguage = args != null ? args.getBoolean(INCLUDE_LOCAL_LANGUAGE) : true;
Set<String> existingLanguages =
args != null ? new HashSet<>(args.getStringArrayList(EXISTING_LOCALIZED_NAMES)) : new HashSet<>();
@@ -68,6 +73,13 @@ public class LanguagesFragment extends BaseMwmRecyclerFragment<LanguagesAdapter>
languages.addAll(0, systemLanguages.stream().filter(Objects::nonNull).toList());
if (includeLocalLanguage)
{
String localLanguageLabel = getString(R.string.pref_maplanguage_local);
Language localLanguage = new Language(DEFAULT_LANG_CODE, localLanguageLabel);
languages.add(0, localLanguage);
}
return new LanguagesAdapter(this, languages.toArray(new Language[languages.size()]));
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -99,9 +99,9 @@ public class NavigationController implements TrafficManager.TrafficCallback, Nav
mCurrentSpeed = topFrame.findViewById(R.id.nav_current_speed);
View mTopbar = topFrame.findViewById(R.id.statutbar);
ViewCompat.setOnApplyWindowInsetsListener(mTopbar,(v, windowInsets) -> {
UiUtils.setViewNavigationTopInsetsMargin(v, windowInsets);
return windowInsets;
ViewCompat.setOnApplyWindowInsetsListener(mTopbar, (v, windowInsets) -> {
UiUtils.setViewNavigationTopInsetsMargin(v, windowInsets);
return windowInsets;
});
// Show a blank view below the navbar to hide the menu content
final View navigationBarBackground = mFrame.findViewById(R.id.nav_bottom_sheet_nav_bar);

View File

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

View File

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

View File

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

View File

@@ -10,14 +10,12 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.R;
import app.organicmaps.sdk.search.SearchResult;
import app.organicmaps.util.Graphics;
import app.organicmaps.util.ThemeUtils;
import app.organicmaps.util.UiUtils;
import com.google.android.material.textview.MaterialTextView;
class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchDataViewHolder>
{
@@ -152,7 +150,8 @@ class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchDataViewHol
{
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
UiUtils.hide(mOpen);
@@ -169,15 +168,18 @@ class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchDataViewHol
{
final String minsToChangeStr = resources.getQuantityString(
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);
mOpen.setTextColor(ContextCompat.getColor(mSearchFragment.getContext(), R.color.base_yellow));
}
else
{
UiUtils.setTextAndShow(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));
UiUtils.setTextAndShow(
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);
setRecyclerScrollListener(mResults);
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()
{

View File

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

View File

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

View File

@@ -1,13 +1,13 @@
package app.organicmaps.settings;
import static app.organicmaps.leftbutton.LeftButtonsHolder.DISABLE_BUTTON_CODE;
import static app.organicmaps.sdk.editor.data.Language.DEFAULT_LANG_CODE;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.ListPreference;
@@ -15,9 +15,6 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceManager;
import androidx.preference.TwoStatePreference;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.dialog.CustomMapServerDialog;
@@ -42,7 +39,7 @@ import app.organicmaps.sdk.util.SharedPropertiesUtils;
import app.organicmaps.sdk.util.log.LogsManager;
import app.organicmaps.util.ThemeSwitcher;
import app.organicmaps.util.Utils;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -140,8 +137,16 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La
private void updateMapLanguageCodeSummary()
{
final Preference pref = getPreference(getString(R.string.pref_map_locale));
Locale locale = new Locale(MapLanguageCode.getMapLanguageCode());
pref.setSummary(locale.getDisplayLanguage());
String mapLanguageCode = MapLanguageCode.getMapLanguageCode();
if (mapLanguageCode.equals(DEFAULT_LANG_CODE))
{
pref.setSummary(R.string.pref_maplanguage_local);
}
else
{
Locale locale = new Locale(mapLanguageCode);
pref.setSummary(locale.getDisplayLanguage());
}
}
private void updateRoutingSettingsPrefsSummary()
@@ -553,9 +558,8 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La
String normalizedUrl = Framework.normalizeServerUrl(current);
// Initial summary
customUrlPref.setSummary(normalizedUrl.isEmpty()
? getString(R.string.download_resources_custom_url_summary_none)
: normalizedUrl);
customUrlPref.setSummary(normalizedUrl.isEmpty() ? getString(R.string.download_resources_custom_url_summary_none)
: normalizedUrl);
// Sync native
Framework.applyCustomMapDownloadUrl(requireContext(), normalizedUrl);
@@ -563,9 +567,7 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La
// Show dialog
customUrlPref.setOnPreferenceClickListener(preference -> {
CustomMapServerDialog.show(requireContext(), url -> {
preference.setSummary(url.isEmpty()
? getString(R.string.download_resources_custom_url_summary_none)
: url);
preference.setSummary(url.isEmpty() ? getString(R.string.download_resources_custom_url_summary_none) : url);
});
return true;
});

View File

@@ -274,10 +274,10 @@ public final class UiUtils
public static void setViewNavigationTopInsetsMargin(View view, WindowInsetsCompat windowInsets)
{
final Insets systemInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
lp.topMargin = systemInsets.top;
view.setLayoutParams(lp);
final Insets systemInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
lp.topMargin = systemInsets.top;
view.setLayoutParams(lp);
}
public static void setupNavigationIcon(@NonNull MaterialToolbar toolbar, @NonNull View.OnClickListener listener)

View File

@@ -53,7 +53,7 @@ public class MenuBottomSheetFragment extends BottomSheetDialogFragment
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState)
{
return new BottomSheetDialog(requireContext(), getTheme()) {
return new BottomSheetDialog(requireContext(), R.style.MwmTheme_BottomSheetDialog) {
@Override
public void onAttachedToWindow()
{

View File

@@ -8,165 +8,165 @@ import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public abstract class BaseSignView extends View
{
private float mBorderWidthRatio = 0.1f;
protected void setBorderWidthRatio(float ratio) {
mBorderWidthRatio = ratio;
}
private float mBorderWidthRatio = 0.1f;
protected void setBorderWidthRatio(float ratio)
{
mBorderWidthRatio = ratio;
}
private float mBorderInsetRatio = 0f;
protected void setBorderInsetRatio(float ratio) {
mBorderInsetRatio = ratio;
}
private float mBorderInsetRatio = 0f;
protected void setBorderInsetRatio(float ratio)
{
mBorderInsetRatio = ratio;
}
// colors
protected int mBackgroundColor;
protected int mBorderColor;
protected int mAlertColor;
protected int mTextColor;
protected int mTextAlertColor;
// colors
protected int mBackgroundColor;
protected int mBorderColor;
protected int mAlertColor;
protected int mTextColor;
protected int mTextAlertColor;
// paints
protected final Paint mBackgroundPaint;
protected final Paint mBorderPaint;
protected final Paint mTextPaint;
// paints
protected final Paint mBackgroundPaint;
protected final Paint mBorderPaint;
protected final Paint mTextPaint;
// geometry
protected float mWidth;
protected float mHeight;
protected float mRadius;
protected float mBorderWidth;
protected float mBorderRadius;
// geometry
protected float mWidth;
protected float mHeight;
protected float mRadius;
protected float mBorderWidth;
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);
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));
mBorderPaint.setStrokeWidth(mBorderWidth);
mBorderPaint.setColor(mBorderColor);
canvas.drawCircle(cx, cy, mBorderRadius, mBorderPaint);
}
protected void setColors(int backgroundColor,
int borderColor,
int alertColor,
int textColor,
int textAlertColor)
// text
mTextPaint.setColor(alert ? mTextAlertColor : mTextColor);
drawValueString(canvas, cx, cy, str);
}
@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;
mBorderColor = borderColor;
mAlertColor = alertColor;
mTextColor = textColor;
mTextAlertColor = textAlertColor;
mBackgroundPaint.setColor(mBackgroundColor);
mBorderPaint.setColor(mBorderColor);
mTextPaint.setColor(mTextColor);
performClick();
return true;
}
return false;
}
@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
public boolean performClick()
{
super.performClick();
return false;
}
@Override
protected void onDraw(@NonNull Canvas canvas)
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)
{
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)
{
mBorderPaint.setStrokeWidth(mBorderWidth);
mBorderPaint.setColor(mBorderColor);
canvas.drawCircle(cx, cy, mBorderRadius, mBorderPaint);
}
// text
mTextPaint.setColor(alert ? mTextAlertColor : mTextColor);
drawValueString(canvas, cx, cy, str);
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));
}
@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))
{
performClick();
return true;
}
return false;
}
/** child must return the string to draw, or null if nothing */
@Nullable
protected abstract String getValueString();
@Override
public boolean performClick()
{
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();
/** 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.util.AttributeSet;
import android.util.Pair;
import androidx.annotation.Nullable;
import app.organicmaps.R;
import app.organicmaps.sdk.util.StringUtils;
@@ -22,18 +20,18 @@ public class CurrentSpeedView extends BaseSignView
setBorderWidthRatio(0.1f);
setBorderInsetRatio(0.05f);
try (TypedArray a = ctx.getTheme()
.obtainStyledAttributes(attrs, R.styleable.CurrentSpeedView /* reuse same attrs or define new */ , 0, 0))
try (TypedArray a = ctx.getTheme().obtainStyledAttributes(
attrs, R.styleable.CurrentSpeedView /* reuse same attrs or define new */, 0, 0))
{
int bg = a.getColor(R.styleable.CurrentSpeedView_currentSpeedBackgroundColor, DefaultValues.BACKGROUND_COLOR);
int bd = a.getColor(R.styleable.CurrentSpeedView_currentSpeedBorderColor, DefaultValues.BORDER_COLOR);
int tc = a.getColor(R.styleable.CurrentSpeedView_currentSpeedTextColor, DefaultValues.TEXT_COLOR);
int bg = a.getColor(R.styleable.CurrentSpeedView_currentSpeedBackgroundColor, DefaultValues.BACKGROUND_COLOR);
int bd = a.getColor(R.styleable.CurrentSpeedView_currentSpeedBorderColor, DefaultValues.BORDER_COLOR);
int tc = a.getColor(R.styleable.CurrentSpeedView_currentSpeedTextColor, DefaultValues.TEXT_COLOR);
setColors(bg, bd, 0, tc, 0);
if (isInEditMode())
{
mSpeedMps = a.getInt(R.styleable.CurrentSpeedView_currentSpeedEditModeCurrentSpeed, 50);
mSpeedStr = Integer.toString((int)mSpeedMps);
mSpeedMps = a.getInt(R.styleable.CurrentSpeedView_currentSpeedEditModeCurrentSpeed, 50);
mSpeedStr = Integer.toString((int) mSpeedMps);
}
}
}
@@ -47,7 +45,7 @@ public class CurrentSpeedView extends BaseSignView
}
else
{
Pair<String,String> su = StringUtils.nativeFormatSpeedAndUnits(mps);
Pair<String, String> su = StringUtils.nativeFormatSpeedAndUnits(mps);
mSpeedStr = su.first;
}
requestLayout();
@@ -70,8 +68,8 @@ public class CurrentSpeedView extends BaseSignView
private interface DefaultValues
{
int BACKGROUND_COLOR = 0xFFFFFFFF;
int BORDER_COLOR = 0xFF000000;
int TEXT_COLOR = 0xFF000000;
int BACKGROUND_COLOR = 0xFFFFFFFF;
int BORDER_COLOR = 0xFF000000;
int TEXT_COLOR = 0xFF000000;
}
}

View File

@@ -12,12 +12,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
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.util.UiUtils;
import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.textview.MaterialTextView;
public class PlaceholderView extends LinearLayout
{

View File

@@ -5,16 +5,14 @@ import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import androidx.annotation.Nullable;
import app.organicmaps.R;
public class SpeedLimitView extends BaseSignView
{
private int mSpeedLimit = -1;
private boolean mAlert = false;
private String mSpeedStr = "-1";
private int mSpeedLimit = -1;
private boolean mAlert = false;
private String mSpeedStr = "-1";
private final int unlimitedBorderColor;
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))
{
final int bgColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitBackgroundColor, DefaultValues.BACKGROUND_COLOR);
final int borderColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitBorderColor, DefaultValues.BORDER_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);
final int bgColor =
styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitBackgroundColor, DefaultValues.BACKGROUND_COLOR);
final int borderColor =
styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitBorderColor, DefaultValues.BORDER_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);
unlimitedBorderColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitUnlimitedBorderColor, DefaultValues.UNLIMITED_BORDER_COLOR);
unlimitedStripeColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitUnlimitedStripeColor, DefaultValues.UNLIMITED_STRIPE_COLOR);
unlimitedBorderColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitUnlimitedBorderColor,
DefaultValues.UNLIMITED_BORDER_COLOR);
unlimitedStripeColor = styleAttrs.getColor(R.styleable.SpeedLimitView_speedLimitUnlimitedStripeColor,
DefaultValues.UNLIMITED_STRIPE_COLOR);
if (isInEditMode())
{
@@ -51,7 +56,7 @@ public class SpeedLimitView extends BaseSignView
if (mSpeedLimit != limit)
{
mSpeedLimit = limit;
mSpeedStr = Integer.toString(limit);
mSpeedStr = Integer.toString(limit);
requestLayout();
}
mAlert = alert;
@@ -75,7 +80,7 @@ public class SpeedLimitView extends BaseSignView
@Override
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)
{
@@ -105,7 +110,7 @@ public class SpeedLimitView extends BaseSignView
stripe.setStrokeWidth(mBorderWidth * 0.4f);
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 px = -dy, py = +dx; // Perpendicular
final float step = radius * 0.15f; // Spacing
@@ -122,14 +127,13 @@ public class SpeedLimitView extends BaseSignView
}
}
private interface DefaultValues
{
int BACKGROUND_COLOR = 0xFFFFFFFF;
int BORDER_COLOR = 0xFFFF0000;
int ALERT_COLOR = 0xFFFF0000;
int TEXT_COLOR = 0xFF000000;
int TEXT_ALERT_COLOR = 0xFFFFFFFF;
int BACKGROUND_COLOR = 0xFFFFFFFF;
int BORDER_COLOR = 0xFFFF0000;
int ALERT_COLOR = 0xFFFF0000;
int TEXT_COLOR = 0xFF000000;
int TEXT_ALERT_COLOR = 0xFFFFFFFF;
int UNLIMITED_BORDER_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;
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);
}

View File

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

View File

@@ -105,7 +105,8 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View.
public EditBookmarkFragment() {}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
public void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, R.style.MwmTheme_FullScreenDialog);
}
@@ -184,10 +185,9 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View.
{
super.onStart();
Dialog dialog = getDialog();
if (dialog != null) {
dialog.getWindow().setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
if (dialog != null)
{
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}
// 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.Nullable;
import androidx.core.widget.NestedScrollView;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.ChartController;
import app.organicmaps.R;
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.util.UiUtils;
import app.organicmaps.util.Utils;
import com.google.android.material.textview.MaterialTextView;
import java.util.Objects;
public class ElevationProfileViewRenderer implements PlacePageStateListener

View File

@@ -14,7 +14,8 @@ public class OpenStateTextFormatter
return String.format(Locale.ROOT, "%02d:%02d", hour, minute);
int h = hour % 12;
if (h == 0) h = 12;
if (h == 0)
h = 12;
String ampm = (hour < 12) ? "AM" : "PM";
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);
}
static String buildAtLabel(
boolean opens,
boolean isToday,
String dayShort,
String time,
String opensAtLocalized,
String closesAtLocalized,
String opensDayAtLocalized,
String closesDayAtLocalized
)
static String buildAtLabel(boolean opens, boolean isToday, String dayShort, String time, String opensAtLocalized,
String closesAtLocalized, String opensDayAtLocalized, String closesDayAtLocalized)
{
if (isToday)
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
: 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;
}
};
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.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import app.organicmaps.MwmActivity;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
@@ -428,8 +427,9 @@ public class PlacePageView extends Fragment
private void updateBookmarkView()
{
boolean enabled = mMapObject.isBookmark() || mMapObject.isTrack();
updateViewFragment(PlacePageBookmarkFragment.class, BOOKMARK_FRAGMENT_TAG, R.id.place_page_bookmark_fragment,
mMapObject.isBookmark());
enabled);
}
private void updateTrackView()
@@ -714,12 +714,10 @@ public class PlacePageView extends Fragment
// map editing is disabled because the map is too old
mTvEditPlace.setEnabled(true);
mTvAddPlace.setEnabled(true);
mTvEditPlace.setOnClickListener((v) -> {
Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit);
});
mTvAddPlace.setOnClickListener((v) -> {
Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit);
});
mTvEditPlace.setOnClickListener(
(v) -> { Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit); });
mTvAddPlace.setOnClickListener(
(v) -> { Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit); });
CountryItem map = CountryItem.fill(countryId);
@@ -764,9 +762,7 @@ public class PlacePageView extends Fragment
mTvAddPlace.setTextColor(editButtonColor);
mTvEditPlace.setStrokeColor(ColorStateList.valueOf(editButtonColor));
mTvAddPlace.setStrokeColor(ColorStateList.valueOf(editButtonColor));
UiUtils.showIf(
UiUtils.isVisible(mEditPlace) || UiUtils.isVisible(mAddPlace),
mEditTopSpace);
UiUtils.showIf(UiUtils.isVisible(mEditPlace) || UiUtils.isVisible(mAddPlace), mEditTopSpace);
}
updateLinksView();
updateOpeningHoursView();
@@ -867,10 +863,9 @@ public class PlacePageView extends Fragment
}
// Get colours
final ForegroundColorSpan colorGreen =
new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_green));
final ForegroundColorSpan colorGreen = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_green));
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));
// Get next state info
@@ -896,13 +891,12 @@ public class PlacePageView extends Fragment
if (nextStateTime > 0 && nextStateTime < Long.MAX_VALUE / 2)
{
// NOTE: Timezone is currently device timezone. TODO: use feature-specific timezone.
nextChangeLocal = ZonedDateTime.ofInstant(
Instant.ofEpochSecond(nextStateTime), ZoneId.systemDefault()
);
nextChangeLocal = ZonedDateTime.ofInstant(Instant.ofEpochSecond(nextStateTime), ZoneId.systemDefault());
hasFiniteNextChange = true;
}
}
catch (Throwable ignored) {}
catch (Throwable ignored)
{}
}
if (!hasFiniteNextChange) // No valid next change
@@ -917,7 +911,7 @@ public class PlacePageView extends Fragment
}
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 shortHorizonOpening = !isOpen && minsToNextState >= 0 && minsToNextState <= SHORT_HORIZON_OPEN_MIN;
@@ -925,12 +919,12 @@ public class PlacePageView extends Fragment
if (shortHorizonClosing || shortHorizonOpening) // POI Opens/Closes in 60 mins • at 18:00
{
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);
openStateString.append(nextChangeFormatted, colorYellow, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
.append("") // Add spacer
.append(getString(R.string.at, localizedTimeString));
.append("") // Add spacer
.append(getString(R.string.at, localizedTimeString));
}
else
{
@@ -940,18 +934,16 @@ public class PlacePageView extends Fragment
final String closesDayAtStr = getString(R.string.closes_day_at); // "Closes %1$s at %2$s"
final boolean isToday =
OpenStateTextFormatter.isSameLocalDate(nextChangeLocal, ZonedDateTime.now(nextChangeLocal.getZone()));
OpenStateTextFormatter.isSameLocalDate(nextChangeLocal, ZonedDateTime.now(nextChangeLocal.getZone()));
// Full weekday name per design feedback.
final String dayName =
nextChangeLocal.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.getDefault());
final String dayName = nextChangeLocal.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.getDefault());
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);
final String atLabel =
OpenStateTextFormatter.buildAtLabel(false, isToday, dayName, localizedTimeString,
opensAtStr, closesAtStr, opensDayAtStr, closesDayAtStr);
final String atLabel = OpenStateTextFormatter.buildAtLabel(
false, isToday, dayName, localizedTimeString, opensAtStr, closesAtStr, opensDayAtStr, closesDayAtStr);
if (!TextUtils.isEmpty(atLabel))
openStateString.append("").append(atLabel);
@@ -960,9 +952,8 @@ public class PlacePageView extends Fragment
{
openStateString.append(getString(R.string.closed_now), colorRed, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
final String atLabel =
OpenStateTextFormatter.buildAtLabel(true, isToday, dayName, localizedTimeString,
opensAtStr, closesAtStr, opensDayAtStr, closesDayAtStr);
final String atLabel = OpenStateTextFormatter.buildAtLabel(
true, isToday, dayName, localizedTimeString, opensAtStr, closesAtStr, opensDayAtStr, closesDayAtStr);
if (!TextUtils.isEmpty(atLabel))
openStateString.append("").append(atLabel);

View File

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

View File

@@ -23,6 +23,7 @@ import app.organicmaps.R;
import app.organicmaps.sdk.bookmarks.data.Bookmark;
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
import app.organicmaps.sdk.bookmarks.data.MapObject;
import app.organicmaps.sdk.bookmarks.data.Track;
import app.organicmaps.sdk.util.StringUtils;
import app.organicmaps.util.UiUtils;
import app.organicmaps.util.Utils;
@@ -31,7 +32,8 @@ import app.organicmaps.widget.placepage.PlacePageViewModel;
import com.google.android.material.textview.MaterialTextView;
public class PlacePageBookmarkFragment extends Fragment implements View.OnClickListener, View.OnLongClickListener,
Observer<MapObject>, EditBookmarkFragment.EditBookmarkListener
Observer<MapObject>,
EditBookmarkFragment.EditBookmarkListener
{
private View mFrame;
private MaterialTextView mTvBookmarkNote;
@@ -41,6 +43,7 @@ public class PlacePageBookmarkFragment extends Fragment implements View.OnClickL
private PlacePageViewModel mViewModel;
private Bookmark currentBookmark;
private Track currentTrack;
@Nullable
@Override
@@ -88,7 +91,15 @@ public class PlacePageBookmarkFragment extends Fragment implements View.OnClickL
private void updateBookmarkDetails()
{
final String notes = currentBookmark.getBookmarkDescription();
String notes = null;
if (currentBookmark != null)
{
notes = currentBookmark.getBookmarkDescription();
}
if (currentTrack != null)
{
notes = currentTrack.getTrackDescription();
}
if (TextUtils.isEmpty(notes))
{
UiUtils.hide(mTvBookmarkNote);
@@ -120,8 +131,16 @@ public class PlacePageBookmarkFragment extends Fragment implements View.OnClickL
public void onClick(View v)
{
final FragmentActivity activity = requireActivity();
EditBookmarkFragment.editBookmark(currentBookmark.getCategoryId(), currentBookmark.getBookmarkId(), activity,
getChildFragmentManager(), PlacePageBookmarkFragment.this);
if (currentBookmark != null)
{
EditBookmarkFragment.editBookmark(currentBookmark.getCategoryId(), currentBookmark.getBookmarkId(), activity,
getChildFragmentManager(), PlacePageBookmarkFragment.this);
}
else if (currentTrack != null)
{
EditBookmarkFragment.editBookmark(currentTrack.getCategoryId(), currentTrack.getTrackId(), activity,
getChildFragmentManager(), PlacePageBookmarkFragment.this);
}
}
@Override
@@ -152,6 +171,11 @@ public class PlacePageBookmarkFragment extends Fragment implements View.OnClickL
currentBookmark = (Bookmark) mapObject;
updateBookmarkDetails();
}
if (mapObject != null && mapObject.isTrack())
{
currentTrack = (Track) mapObject;
updateBookmarkDetails();
}
}
@Override

View File

@@ -13,15 +13,13 @@ import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
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.sdk.Framework;
import app.organicmaps.sdk.bookmarks.data.ChargeSocketDescriptor;
import app.organicmaps.sdk.bookmarks.data.MapObject;
import app.organicmaps.widget.placepage.PlacePageViewModel;
import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.textview.MaterialTextView;
import java.text.DecimalFormat;
public class PlacePageChargeSocketsFragment extends Fragment implements Observer<MapObject>
@@ -96,8 +94,8 @@ public class PlacePageChargeSocketsFragment extends Fragment implements Observer
}
@SuppressLint("DiscouragedApi")
int resTypeId =
getResources().getIdentifier("charge_socket_" + socket.visualType(), "string", requireContext().getPackageName());
int resTypeId = getResources().getIdentifier("charge_socket_" + socket.visualType(), "string",
requireContext().getPackageName());
if (resTypeId != 0)
{
type.setText(resTypeId);
@@ -108,7 +106,8 @@ public class PlacePageChargeSocketsFragment extends Fragment implements Observer
DecimalFormat df = new DecimalFormat("#.##");
power.setText(getString(R.string.kw_label, df.format(socket.power())));
}
else if (socket.ignorePower()) {
else if (socket.ignorePower())
{
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.
default -> mMapObject.getMetadata(type);
};
// Add user names for social media if available
if (!TextUtils.isEmpty(title) && !title.equals(url) && !title.contains("/")) items.add(title);
// Add user names for social media if available
if (!TextUtils.isEmpty(title) && !title.equals(url) && !title.contains("/"))
items.add(title);
if (items.size() == 1)
PlacePageUtils.copyToClipboard(requireContext(), mFrame, items.get(0));

View File

@@ -41,5 +41,5 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_gravity="bottom|start"
android:background="?cardBackground"/>
android:background="?colorSurfaceContainerLow"/>
</FrameLayout>

View File

@@ -8,7 +8,6 @@
android:paddingStart="@dimen/margin_base"
android:paddingEnd="@dimen/margin_base"
android:gravity="center_vertical"
android:background="?clickableBackground"
android:orientation="horizontal">
<com.google.android.material.imageview.ShapeableImageView

View File

@@ -20,8 +20,8 @@
android:gravity="center"
android:layout_gravity="end|center_vertical"
android:background="?selectableItemBackgroundBorderless"
android:textSize="@dimen/text_size_toolbar"
android:padding="@dimen/margin_half"
android:textAppearance="@style/MwmTextAppearance.Toolbar.Title"
android:text="@string/editor_report_problem_send_button"/>
</com.google.android.material.appbar.MaterialToolbar>

View File

@@ -40,5 +40,5 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_gravity="bottom|center"
android:background="?cardBackground"/>
android:background="?colorSurfaceContainerLow"/>
</FrameLayout>

View File

@@ -4,6 +4,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
android:background="?cardBackground"
android:orientation="vertical">
<include
android:id="@+id/pp__preview"

View File

@@ -15,15 +15,8 @@
android:theme="@style/MwmWidget.ToolbarTheme"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/margin_half"
android:text="@string/editor_add_select_location"
android:textAppearance="@style/MwmTextAppearance.Toolbar.Title"/>
app:layout_constraintTop_toTopOf="parent"
app:title="@string/editor_add_select_location">
</com.google.android.material.appbar.MaterialToolbar>
<com.google.android.material.textview.MaterialTextView

View File

@@ -19,8 +19,8 @@
<string name="editor_zip_code">Postcode</string>
<string name="error_enter_correct_zip_code">Enter a valid postcode</string>
<plurals name="bookmarks_places">
<item quantity="one">%d bookmark</item>
<item quantity="other">%d bookmarks</item>
<item quantity="one">%d place</item>
<item quantity="other">%d places</item>
</plurals>
<plurals name="bookmarks_detect_message">
<item quantity="one">%d file was found. You can see it after conversion.</item>

View File

@@ -15,6 +15,7 @@
<color name="bg_cards">#FF3C4044</color>
<color name="bg_panel">@color/bg_window</color>
<color name="bg_primary_dark">#FF588157</color>
<color name="bg_app">#10140F</color>
<color name="bg_menu">#CC2D3237</color>

View File

@@ -73,11 +73,11 @@
<!-- "Add new bookmark list" dialog title -->
<string name="add_new_set">Add a New List</string>
<!-- Add Bookmark list dialog - hint when the list name is empty -->
<string name="bookmark_set_name">Bookmark List Name</string>
<string name="bookmark_set_name">List Name</string>
<!-- Should be used in the bookmarks-only context, see bookmarks_and_tracks if tracks are also implied. -->
<string name="bookmarks">Bookmarks</string>
<string name="bookmarks">Places</string>
<!-- "Bookmarks and Tracks" dialog title, also sync it with iphone/plist.txt -->
<string name="bookmarks_and_tracks">Bookmarks and Tracks</string>
<string name="bookmarks_and_tracks">Favorites</string>
<!-- Add bookmark dialog - bookmark name -->
<string name="name">Name</string>
<!-- Editor title above street and house number, duplicates [type.building.address] in types_strings.txt -->
@@ -156,18 +156,18 @@
<!-- Notes field in Bookmarks view -->
<string name="description">Notes</string>
<!-- Email Subject when sharing bookmark list -->
<string name="share_bookmarks_email_subject">CoMaps bookmarks were shared with you</string>
<string name="share_bookmarks_email_subject">My CoMaps Favorites</string>
<string name="share_bookmarks_email_body">Hello!
\n
\nAttached are my bookmarks; please open them in CoMaps. If you don\'t have it installed you can download it here: https://www.comaps.app/download/
\nAttached are my favorites; please open them in CoMaps. If you don\'t have it installed you can download it here: https://www.comaps.app/download/
\n
\nEnjoy travelling with CoMaps!</string>
<!-- message title of loading file -->
<string name="load_kmz_title">Loading Bookmarks</string>
<string name="load_kmz_title">Loading Favorites</string>
<!-- Kmz file successful loading -->
<string name="load_kmz_successful">Bookmarks loaded successfully! You can find them on the map or on the Bookmarks Manager screen.</string>
<string name="load_kmz_successful">Favorites loaded successfully! You can find them on the map or on the Favorites Manager screen.</string>
<!-- Kml file loading failed -->
<string name="load_kmz_failed">Failed to load bookmarks. The file may be corrupted or defective.</string>
<string name="load_kmz_failed">Failed to load favorites. The file may be corrupted or defective.</string>
<!-- Failed to recognize the format of a bookmarks or tracks file. -->
<string name="unknown_file_type">The file type is not recognized by the app:
\n%1$s</string>
@@ -541,7 +541,7 @@
<string name="minute">min</string>
<string name="day">d</string>
<string name="placepage_more_button">More</string>
<string name="placepage_edit_bookmark_button">Edit Bookmark</string>
<string name="placepage_edit_bookmark_button">Edit Saved Place</string>
<string name="placepage_personal_notes_hint">Personal notes (text or html)</string>
<string name="editor_reset_edits_message">Discard all local changes?</string>
<string name="editor_reset_edits_button">Discard changes</string>
@@ -635,17 +635,17 @@
<string name="dialog_error_storage_message">External storage is not accessible. The SD card may have been removed, damaged, or the file system is read-only. Please, check your SD card or contact us at support@comaps.app</string>
<string name="setting_emulate_bad_storage">Emulate bad storage</string>
<string name="error_enter_correct_name">Please enter a correct name</string>
<string name="bookmark_lists">Lists</string>
<string name="bookmark_lists">Favorite Lists</string>
<!-- Do not display all bookmark lists on the map -->
<string name="bookmark_lists_hide_all">Hide all</string>
<string name="bookmark_lists_show_all">Show all</string>
<plurals name="bookmarks_places">
<item quantity="one">%d bookmark</item>
<item quantity="other">%d bookmarks</item>
<item quantity="one">%d saved place</item>
<item quantity="other">%d saved places</item>
</plurals>
<string name="bookmarks_create_new_group">Create a new list</string>
<!-- Bookmark categories screen, button that opens folder selection dialog to import KML/KMZ/GPX/KMB files -->
<string name="bookmarks_import">Import Bookmarks and Tracks</string>
<string name="bookmarks_import">Import Favorites</string>
<string name="bookmarks_error_message_share_general">Unable to share due to an application error</string>
<string name="bookmarks_error_title_share_empty">Sharing error</string>
<string name="bookmarks_error_message_share_empty">Cannot share an empty list</string>
@@ -675,7 +675,7 @@
<string name="subway">Subway</string>
<string name="layers_title">Map Styles and Layers</string>
<string name="bookmarks_empty_list_title">This list is empty</string>
<string name="bookmarks_empty_list_message">To add a bookmark, tap a place on the map and then tap the star icon</string>
<string name="bookmarks_empty_list_message">To save a place, tap a place on the map and then tap the star icon</string>
<string name="category_desc_more">…more</string>
<string name="export_file">Export KMZ</string>
<string name="export_file_gpx">Export GPX</string>
@@ -730,7 +730,7 @@
<!-- max. 10 symbols, both iOS and Android -->
<string name="sort">Sort…</string>
<!-- Android, title, max 20-22 symbols -->
<string name="sort_bookmarks">Sort bookmarks</string>
<string name="sort_bookmarks">Sort favorites</string>
<!-- Android -->
<string name="by_default">By default</string>
<!-- Android -->
@@ -797,8 +797,10 @@
<string name="enable_show_on_lock_screen">Show on the lock screen</string>
<!-- Description in preferences -->
<string name="enable_show_on_lock_screen_description">When enabled, the app will work on the lockscreen even when the device is locked.</string>
<!-- Current language of the map! -->
<!-- Current language of the map -->
<string name="change_map_locale">Map language</string>
<!-- Local language -->
<string name="pref_maplanguage_local">Local Language</string>
<!-- OpenStreetMap text on splash screen -->
<string name="splash_subtitle">Map data from OpenStreetMap</string>
<!-- Telegram group url for the "?" About page -->
@@ -811,7 +813,7 @@
<string name="translated_om_site_url">https://comaps.app/</string>
<!-- Link to OSM wiki for Editor, Profile and About pages -->
<string name="osm_wiki_about_url">https://wiki.openstreetmap.org/wiki/About_OpenStreetMap</string>
<!-- A number of bookmarks and a number of tracks, separated by comma, like: 1 bookmark, 5 tracks -->
<!-- A number of bookmarks and a number of tracks, separated by comma, like: 1 saved place, 5 tracks -->
<string name="comma_separated_pair">%1$s, %2$s</string>
<!-- App Tip #00 -->
<string name="app_tip_00">Thank you for using our community-built maps!</string>
@@ -857,7 +859,7 @@
<string name="browser_not_available">Web browser is not available</string>
<string name="volume">Volume</string>
<!-- Bookmark categories screen, button that opens share dialog to export all bookmarks and tracks -->
<string name="bookmarks_export">Export all Bookmarks and Tracks</string>
<string name="bookmarks_export">Export all Places and Tracks</string>
<!-- button in (app) TTS settings, to open the system TTS settings. -->
<string name="pref_tts_open_system_settings">Speech synthesis system settings</string>
<!-- toast displayed when pressing the "Speech synthesis system settings" button, and the system settings aren't found. -->
@@ -889,7 +891,7 @@
<!-- Title for the "Stop Without Saving" action for the alert when saving a track recording. -->
<string name="continue_recording">Continue Recording</string>
<!-- Title for the alert when saving a track recording. -->
<string name="track_recording_alert_title">Save into Bookmarks and Tracks?</string>
<string name="track_recording_alert_title">Save into Favorites?</string>
<!-- Message for the toast when saving the track recording is finished but nothing to save. -->
<string name="track_recording_toast_nothing_to_save">Track is empty - nothing to save</string>
<!-- Error message when there are no File Manager apps installed to select a folder when importing Bookmarks and Tracks -->
@@ -903,13 +905,13 @@
<string name="pref_left_button_disable">Disable</string>
<!-- Settings "Backup" category: "Backup" title -->
<string name="pref_backup_title">Bookmarks and tracks backup</string>
<string name="pref_backup_title">Backup favorites</string>
<string name="pref_backup_summary">Automatically backup to a folder on your device</string>
<string name="pref_backup_now_title">Backup now</string>
<string name="pref_backup_now_summary">Create a backup immediately</string>
<string name="pref_backup_now_summary_progress">Backup in progress…</string>
<string name="pref_backup_now_summary_ok">Backup completed successfully</string>
<string name="pref_backup_now_summary_empty_lists">No bookmarks and tracks to backup</string>
<string name="pref_backup_now_summary_empty_lists">No places and tracks to backup</string>
<string name="pref_backup_now_summary_failed">Backup failed</string>
<string name="pref_backup_now_summary_folder_unavailable">The backup folder is not available</string>
<string name="pref_backup_status_summary_success">Last successful backup</string>
@@ -933,7 +935,7 @@
<string name="pedestrian">Pedestrian</string>
<string name="bicycle">Bicycle</string>
<string name="ruler">Ruler</string>
<string name="bookmark_color">Bookmark color</string>
<string name="bookmark_color">Color for Favorite</string>
<string name="about_help">About &amp; Help</string>
<string name="open_now">Open now</string>
<string name="closed_now">Closed now</string>

View File

@@ -98,16 +98,6 @@
<item name="android:textColorHint">@color/text_light_hint</item>
</style>
<style name="MwmTextAppearance.Toolbar.Title" parent="android:TextAppearance.Material.Widget.ActionBar.Title">
<item name="android:textSize">@dimen/text_size_toolbar</item>
<item name="android:textColor">@color/text_light</item>
<item name="android:textColorHint">@color/text_light_hint</item>
</style>
<style name="MwmTextAppearance.Toolbar.Title.Light">
<item name="android:textColor">@color/bg_cards</item>
</style>
<style name="MwmTextAppearance.NavMenu">
<item name="android:textStyle">bold</item>
</style>

View File

@@ -143,8 +143,7 @@
<item name="android:background">?colorPrimary</item>
<item name="android:displayOptions">homeAsUp|showTitle</item>
<item name="contentInsetStart">0dp</item>
<item name="android:titleTextAppearance">@style/MwmTextAppearance.Toolbar.Title</item>
<item name="titleTextAppearance">@style/MwmTextAppearance.Toolbar.Title</item>
<item name="titleTextColor">@color/text_light</item>
<item name="buttonGravity">center_vertical</item>
</style>
@@ -169,9 +168,7 @@
<item name="android:cacheColorHint">@android:color/transparent</item>
</style>
<style name="MwmWidget.TextView" parent="Widget.MaterialComponents.TextView">
<item name="android:background">@android:color/transparent</item>
</style>
<style name="MwmWidget.TextView" parent="Widget.MaterialComponents.TextView" />
<style name="MwmWidget.TextView.Item">
<item name="android:layout_width">match_parent</item>
@@ -290,13 +287,13 @@
</style>
<style name="MwmWidget.BottomSheetDialog" parent="Widget.Material3.BottomSheet.Modal">
<item name="backgroundTint">?cardBackground</item>
<item name="backgroundTint">?colorSurfaceContainerLow</item>
<item name="elevationOverlayEnabled">false</item>
<item name="shapeAppearance">@style/ShapeAppearance.Material3.LargeComponent</item>
</style>
<style name="MwmWidget.BottomSheet" parent="MwmWidget.BottomSheetDialog">
<item name="android:background">?cardBackground</item>
<item name="android:background">?colorSurfaceContainerLow</item>
<item name="behavior_hideable">false</item>
</style>

View File

@@ -7,6 +7,7 @@
<locale android:name="az" />
<locale android:name="be" />
<locale android:name="bg" />
<locale android:name="bn" />
<locale android:name="ca" />
<locale android:name="cs" />
<locale android:name="da" />
@@ -21,11 +22,16 @@
<locale android:name="fi" />
<locale android:name="fr" />
<locale android:name="fr-CA" />
<locale android:name="iw" />
<locale android:name="gl" />
<locale android:name="gsw" />
<locale android:name="he" />
<locale android:name="hi" />
<locale android:name="hu" />
<locale android:name="id" />
<locale android:name="in" />
<locale android:name="is" />
<locale android:name="it" />
<locale android:name="iw" />
<locale android:name="ja" />
<locale android:name="kw" />
<locale android:name="ko" />
@@ -34,16 +40,20 @@
<locale android:name="mr" />
<locale android:name="mt" />
<locale android:name="nb" />
<locale android:name="nb-NO" />
<locale android:name="nl" />
<locale android:name="pl" />
<locale android:name="pt" />
<locale android:name="pt-BR" />
<locale android:name="ro" />
<locale android:name="ru" />
<locale android:name="sl" />
<locale android:name="sk" />
<locale android:name="sr" />
<locale android:name="sr-Cyrl" />
<locale android:name="sr-Latn" />
<locale android:name="sv" />
<locale android:name="sw" />
<locale android:name="ta" />
<locale android:name="th" />
<locale android:name="tr" />
<locale android:name="uk" />

View File

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

View File

@@ -182,8 +182,7 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_DownloadResourcesLegacyActivity_
g_currentRequest.reset();
}
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_DownloadResourcesLegacyActivity_nativeResetMetaConfig(JNIEnv *,
jclass)
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_DownloadResourcesLegacyActivity_nativeResetMetaConfig(JNIEnv *, jclass)
{
auto & downloader = LegacyDownloader();
if (downloader)

View File

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

View File

@@ -18,7 +18,6 @@
#include <functional>
#include <memory>
#include <unordered_map>
#include <vector>
namespace
@@ -53,7 +52,7 @@ struct TBatchedData
jobject g_countryChangedListener = nullptr;
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;
storage::Storage & GetStorage()
@@ -589,8 +588,9 @@ JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeG
}
// static native boolean nativeIsMapTooOldToEdit(String countryId);
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeIsMapTooOldToEdit(JNIEnv *env, jclass clazz,
jstring country_id)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeIsMapTooOldToEdit(JNIEnv * env,
jclass clazz,
jstring country_id)
{
return GetStorage().IsMapTooOldToEdit(jni::ToNativeString(env, country_id));
}

View File

@@ -580,7 +580,8 @@ JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeGetMapObject
return static_cast<jint>(osm::Editor::Instance().GetFeatureStatus(g_editableMapObject.GetID()));
}
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeAreSomeFeatureChangesUploaded(JNIEnv * env, jclass clazz)
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_editor_Editor_nativeAreSomeFeatureChangesUploaded(JNIEnv * env,
jclass clazz)
{
return osm::Editor::Instance().AreSomeFeatureChangesUploaded(g_editableMapObject.GetID().m_mwmId,
g_editableMapObject.GetID().m_index);

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 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"}};
jfieldID stateField =

View File

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

View File

@@ -2,12 +2,10 @@ package app.organicmaps.sdk;
import android.content.Context;
import android.graphics.Bitmap;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Size;
import app.organicmaps.sdk.api.ParsedRoutingData;
import app.organicmaps.sdk.api.ParsedSearchRequest;
import app.organicmaps.sdk.api.RequestType;
@@ -26,7 +24,6 @@ import app.organicmaps.sdk.routing.RoutingRecommendationListener;
import app.organicmaps.sdk.routing.TransitRouteInfo;
import app.organicmaps.sdk.settings.SpeedCameraMode;
import app.organicmaps.sdk.util.Constants;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

View File

@@ -2,13 +2,11 @@ package app.organicmaps.sdk;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.annotation.NonNull;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ProcessLifecycleOwner;
import androidx.preference.PreferenceManager;
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
import app.organicmaps.sdk.bookmarks.data.Icon;
import app.organicmaps.sdk.downloader.Android7RootCertificateWorkaround;
@@ -28,7 +26,6 @@ import app.organicmaps.sdk.util.SharedPropertiesUtils;
import app.organicmaps.sdk.util.StorageUtils;
import app.organicmaps.sdk.util.log.Logger;
import app.organicmaps.sdk.util.log.LogsManager;
import java.io.IOException;
public final class OrganicMaps implements DefaultLifecycleObserver

View File

@@ -4,28 +4,30 @@ package app.organicmaps.sdk.bookmarks.data;
* represents the details of the socket available on a particular charging station
*
*/
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
* 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
*/
public String visualType() {
if (type.equals("typee")) {
return "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");
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
* 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
*/
public String visualType()
{
if (type.equals("typee"))
{
return "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.NonNull;
import androidx.annotation.Nullable;
import app.organicmaps.sdk.editor.data.Timespan;
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.res.Resources;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import app.organicmaps.sdk.R;
import java.text.DateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import app.organicmaps.sdk.R;
public final class DateUtils
{
private DateUtils() {}
@@ -44,7 +42,7 @@ public final class DateUtils
if (days == 1)
return resources.getString(R.string.yesterday).toLowerCase();
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)
return resources.getString(days < 14 ? R.string.week_ago : R.string.weeks_ago, Integer.toString(days / 7));
if (days < 365)

View File

@@ -43,9 +43,10 @@
<string name="type.leisure.adult_gaming_centre">Spielhalle für Erwachsene</string>
<string name="type.leisure.amusement_arcade">Spielhalle für Unterhaltungsspiele</string>
<string name="type.amenity.charging_station">Ladestation</string>
<string name="type.amenity.charging_station.bicycle">Fahrrad-Ladestation</string>
<string name="type.amenity.charging_station.motorcar">Kfz-Ladestation</string>
<string name="type.amenity.charging_station.motorcar.small">Kfz-Ladestation</string>
<string name="type.amenity.charging_station.bicycle">Fahrräder</string>
<string name="type.amenity.charging_station.motorcycle">Motorräder</string>
<string name="type.amenity.charging_station.motorcar">Autos</string>
<string name="type.amenity.charging_station.small">Begrenzte Kapazität</string>
<string name="type.amenity.childcare">Kindertagesstätte</string>
<string name="type.amenity.cinema">Kino</string>
<string name="type.leisure.bowling_alley">Bowlingbahn</string>

View File

@@ -53,9 +53,10 @@
<string name="type.leisure.adult_gaming_centre">Adult Gaming Centre</string>
<string name="type.leisure.amusement_arcade">Arcade</string>
<string name="type.amenity.charging_station">Charging Station</string>
<string name="type.amenity.charging_station.bicycle">Bicycle Charging Station</string>
<string name="type.amenity.charging_station.motorcar">Car Charging Station</string>
<string name="type.amenity.charging_station.motorcar.small">Car Charging Point</string>
<string name="type.amenity.charging_station.bicycle">Bicycles</string>
<string name="type.amenity.charging_station.motorcycle">Motorcycles</string>
<string name="type.amenity.charging_station.motorcar">Cars</string>
<string name="type.amenity.charging_station.small">Limited Capacity</string>
<string name="type.amenity.childcare">Nursery</string>
<string name="type.amenity.cinema">Cinema</string>
<string name="type.amenity.studio">Media Studio</string>
@@ -931,11 +932,11 @@
<string name="type.public_transport.platform">Platform</string>
<string name="type.railway">Railway</string>
<string name="type.railway.abandoned">Abandoned Railway</string>
<string name="type.railway.abandoned.bridge">Abandoned Railway Bridge</string>
<string name="type.railway.abandoned.tunnel">Abandoned Railway Tunnel</string>
<string name="type.railway.construction">Railway Construction</string>
<string name="type.railway.crossing">Railway Crossing</string>
<string name="type.railway.disused">Disused Railway</string>
<string name="type.railway.disused.bridge">Disused Railway Bridge</string>
<string name="type.railway.disused.tunnel">Disused Railway Tunnel</string>
<string name="type.railway.funicular">Funicular</string>
<string name="type.railway.funicular.bridge">Funicular Bridge</string>
<string name="type.railway.funicular.tunnel">Funicular Tunnel</string>
@@ -961,6 +962,7 @@
<string name="type.railway.rail.highspeed">High-Speed Railway</string>
<string name="type.railway.rail.tourism">Touristic Railway</string>
<string name="type.railway.rail.main">Railway</string>
<string name="type.railway.turntable">Railway Turntable</string>
<!-- Includes ordinary railway=rail w/o more specific usage= and service= tags. -->
<string name="type.railway.rail.branch">Railway Branch</string>
<!-- Non-passenger utility tracks: industrial, military, test. -->

View File

@@ -331,7 +331,9 @@
"amenity-car_wash": "4Autowaschanlage|Autowäsche",
"amenity-veterinary": "4Tierarzt|4Tierärztin|4Tierarztpraxis|4Tierpraxis|4Tierdoktor|5Hundearzt|5Katzenarzt|4Haustiere|U+2695",
"@charging_station": "4Ladestation|aufladen",
"amenity-charging_station-bicycle|@charging_station": "Fahrrad aufladen",
"amenity-charging_station-bicycle|@charging_station": "5Fahrradladestation|Fahrrad aufladen|E-Bike aufladen|Fahrrad laden|E-Bike laden",
"amenity-charging_station-motorcycle|@charging_station": "6Motorradladestation|Motorrad aufladen|Motorrad laden",
"amenity-charging_station-motorcar|@charging_station": "4Autoladestation|5Autoladegerät|Auto aufladen|Auto laden",
"amenity-childcare": "Kindertagesstätte|Kindergarten|Kinderbetreuung",
"amenity-bicycle_parking": "6Fahrradständer",
"amenity-waste_basket": "6Abfalleimer|4Mülleimer|4Restmüll|3Müll|4Müllkorb|U+1F6AE|U+1F5D1",
@@ -516,7 +518,6 @@
"attraction-amusement_ride|attraction-carousel|attraction-roller_coaster|attraction-maze|attraction-historic|attraction-big_wheel|attraction-bumper_car|@category_children": "4Attraktion|4Labyrinth",
"building-guardhouse": "4Wache",
"shop-lighting|@shop": "Leuchtmittel|Lampen|Leuchte",
"amenity-charging_station-motorcar|amenity-charging_station-motorcar-small|@charging_station": "4Autoladestation|5Autoladegerät|4Ladestation|4Ladegerät|U+1F50C|U+1FAAB|U+1F50B",
"amenity-mobile_money_agent": "6Mobile Money Vertretung|6Mobile Money|6Mobiles Geld",
"man_made-telescope|man_made-telescope-optical|man_made-telescope-radio|man_made-telescope-gamma": "4Teleskop",
"amenity-sailing_school": "5Segelschule|5Bootsschule|Bootsfahrschule",

View File

@@ -353,10 +353,11 @@
"man_made-observatory": "4Observatory",
"amenity-veterinary": "4Veterinary Doctor|3Veterinary|vet|veterinarian",
"amenity-animal_shelter": "6Animal Shelter",
"@charging_station": "4Charging Station|charging",
"@charging_station": "4Charging Station|charging|charger",
"amenity-charging_station|@charging_station": "",
"amenity-charging_station-bicycle|@charging_station": "4Bicycle Charging|4Bike Charging",
"amenity-charging_station-motorcar|amenity-charging_station-motorcar-small|@charging_station": "4Motorcar Charging|3Car Charging|Charger",
"amenity-charging_station-bicycle|@charging_station": "4Bicycle Charging Station|Bicycle Charging|Bike Charging",
"amenity-charging_station-motorcycle|@charging_station": "5Motorcycle Charging Station|Motorcycle Charging|Motorbike Charging",
"amenity-charging_station-motorcar|@charging_station": "3Car Charging Station|Motorcar Charging|Car Charging",
"amenity-childcare": "Nursery|4Child Care|childcare",
"amenity-bicycle_parking": "4Bicycle Parking|4Bike Parking",
"amenity-waste_basket": "4Trash Bin|4litter bin|5waste basket|bin",

View File

@@ -518,7 +518,7 @@
"amenity-toilets|toilets-yes|@category_toilet": "wc",
"leisure-sports_centre-sport-swimming": "4Centro de natación",
"amenity-police|@category_police": "Estación de policía|policía",
"amenity-charging_station-motorcar|amenity-charging_station-motorcar-small|@charging_station": "Cargador de autos|cargador de coches|cargador de carros|4Estación de carga|3Estación de carga|Cargador",
"amenity-charging_station-motorcar|@charging_station": "Cargador de autos|cargador de coches|cargador de carros|4Estación de carga|3Estación de carga|Cargador",
"amenity-sailing_school": "Escuela de vela|Escuela de navegación",
"amenity-flight_school": "Escuela de aviación|Escuela de aeronáutica|Escuela de pilotos|aeronáutica|vuelo|aviación",
"amenity-prep_school": "Propedéutico|Tutoría",

View File

@@ -486,7 +486,7 @@
"amenity-love_hotel": "Hôtel de passe|Hôtel de sexe|Hôtel pour adultes",
"healthcare-sample_collection": "Prélèvement d'échantillons",
"recycling-cardboard|@category_recycling": "5Recyclage de carton|Déchets de carton|Carton",
"amenity-charging_station-motorcar|amenity-charging_station-motorcar-small|@charging_station": "Chargeur automobile|Chargeur de voiture|Chargeur",
"amenity-charging_station-motorcar|@charging_station": "Chargeur automobile|Chargeur de voiture|Chargeur",
"shop-lighting|@shop": "4Lumières|Luminaires|4Lampes",
"office-security": "Bureau de sécurité",
"building-guardhouse": "Garde|poste de sécurité|poste de gardiennage",

View File

@@ -1 +1,543 @@
{}
{
"@category_eat": "",
"@category_food": "",
"@category_transport": "",
"@category_fuel": "",
"@category_parking": "",
"@category_shopping": "",
"@category_hotel": "",
"@category_tourism": "",
"@category_entertainment": "",
"@category_nightlife": "",
"@category_children": "",
"@category_atm": "",
"@category_rv": "",
"amenity-atm|@category_atm": "",
"@category_bank": "",
"@category_secondhand": "",
"amenity-bank|@category_bank": "",
"@category_recycling": "",
"amenity-bureau_de_change": "",
"amenity-studio": "",
"amenity-bar|amenity-pub|@category_eat|@category_nightlife": "",
"amenity-cafe|@category_eat": "",
"amenity-fast_food|@category_eat": "",
"amenity-restaurant|@category_eat": "",
"amenity-fuel|@category_fuel": "",
"@shop": "",
"shop-bakery|shop-pastry|@category_eat|@category_food|@shop": "",
"shop|@shop": "",
"shop-cannabis|@shop": "",
"shop-cosmetics|@category_shopping|@shop": "",
"shop-convenience|@category_food|@shop": "",
"shop-deli|@category_food|@shop": "",
"shop-farm|@category_food|@shop": "",
"shop-garden_centre|@shop": "",
"shop-grocery|@category_food|@shop": "",
"shop-health_food|@category_food|@shop": "",
"shop-hearing_aids|@shop": "",
"shop-mobile_phone|@shop": "",
"shop-florist|@shop": "",
"shop-butcher|@category_food|@shop": "",
"shop-furniture|@shop": "",
"shop-kitchen|@shop": "",
"shop-alcohol|@category_food|@shop": "",
"shop-books|@shop": "",
"shop-shoes|@category_shopping|@shop": "",
"shop-electronics|@shop": "",
"shop-hardware|shop-doityourself|@shop": "",
"shop-houseware|@shop": "",
"shop-jewelry|@category_shopping|@shop": "",
"shop-optician|@shop": "",
"shop-gift|@category_shopping|@shop": "",
"shop-beauty": "",
"shop-beauty-nails": "",
"shop-greengrocer|@category_food|@shop": "",
"shop-sports|@category_shopping|@shop": "",
"shop-supermarket|@category_food|@shop": "",
"shop-mall|@category_shopping|@shop": "",
"shop-department_store|@category_shopping|@shop": "",
"shop-beverages|@category_food|@shop": "",
"shop-computer|@shop": "",
"shop-confectionery|craft-confectionery|@category_food|@shop": "",
"shop-laundry": "",
"shop-toys|@category_children|@shop": "",
"amenity-marketplace|@category_food": "",
"amenity-mobile_money_agent": "",
"amenity-money_transfer": "",
"shop-clothes|@category_shopping|@shop": "",
"shop-caravan|@category_rv|@shop": "",
"shop-car|@shop": "",
"shop-bicycle|@shop": "",
"shop-kiosk": "",
"highway-bus_stop|@category_transport": "",
"railway-tram_stop|@category_transport": "",
"amenity-bus_station|@category_transport": "",
"railway-station|railway-halt|building-train_station|@category_transport": "",
"railway-station-funicular": "",
"railway-station-subway|@category_transport": "",
"amenity-ferry_terminal|@category_transport": "",
"amenity-taxi|@category_transport": "",
"amenity-townhall": "",
"tourism-attraction|@category_tourism": "",
"tourism-artwork": "",
"tourism-artwork-sculpture": "",
"tourism-artwork-statue": "",
"tourism-artwork-painting": "",
"tourism-viewpoint|@category_tourism": "",
"tourism-information": "",
"tourism-picnic_site|amenity-bbq|leisure-picnic_table": "",
"amenity-place_of_worship": "",
"amenity-place_of_worship-christian": "",
"amenity-place_of_worship-muslim": "",
"amenity-place_of_worship-buddhist": "",
"amenity-place_of_worship-hindu": "",
"amenity-place_of_worship-shinto": "",
"amenity-place_of_worship-jewish": "",
"amenity-place_of_worship-taoist": "",
"tourism-museum|@category_tourism": "",
"waterway-waterfall|@category_tourism": "",
"historic-archaeological_site|@category_tourism": "",
"historic-battlefield": "",
"historic-stone": "",
"historic-boundary_stone": "",
"historic-castle|@category_tourism": "",
"historic-city_gate|@category_tourism": "",
"historic-citywalls|@category_tourism": "",
"historic-fort|@category_tourism": "",
"historic-gallows|@category_tourism": "",
"historic-memorial|@category_tourism": "",
"historic-memorial-cross": "",
"historic-memorial-plaque": "",
"historic-memorial-sculpture|@category_tourism": "",
"historic-memorial-statue|@category_tourism": "",
"historic-memorial-stolperstein": "",
"historic-memorial-war_memorial|@category_tourism": "",
"historic-monument|@category_tourism": "",
"historic-pillory|@category_tourism": "",
"historic-cannon": "",
"historic-anchor": "",
"historic-ruins|@category_tourism": "",
"historic-mine": "",
"historic-ship|@category_tourism": "",
"historic-wreck": "",
"historic-locomotive|@category_tourism": "",
"historic-tank|@category_tourism": "",
"historic-aircraft|@category_tourism": "",
"historic-tomb|@category_tourism": "",
"man_made-cross": "",
"historic-wayside_cross": "",
"historic-wayside_shrine": "",
"leisure-dog_park": "",
"leisure-dance|@category_entertainment": "",
"leisure-garden": "",
"leisure-firepit": "",
"amenity-bench|amenity-bench-backless": "",
"amenity-boat_rental": "",
"amenity-bicycle_rental": "",
"amenity-bicycle_repair_station": "",
"amenity-car_sharing": "",
"amenity-car_rental": "",
"amenity-motorcycle_rental": "",
"amenity-cinema|@category_entertainment": "",
"leisure-bowling_alley|@category_entertainment": "",
"amenity-theatre|@category_entertainment": "",
"amenity-nightclub|@category_entertainment|@category_nightlife": "",
"amenity-brothel": "",
"amenity-love_hotel": "",
"@gambling": "",
"amenity-gambling|@gambling": "",
"amenity-casino|@category_entertainment|@category_nightlife|@gambling": "",
"leisure-adult_gaming_centre|@gambling": "",
"leisure-amusement_arcade|@category_entertainment": "",
"amenity-college": "",
"amenity-fire_station": "",
"amenity-fountain": "",
"amenity-grave_yard|landuse-cemetery": "",
"shop-funeral_directors": "",
"@category_hospital": "",
"amenity-hospital|@category_hospital": "",
"amenity-clinic|@category_hospital": "",
"amenity-doctors|@category_hospital": "",
"amenity-dentist": "",
"healthcare-laboratory": "",
"healthcare-physiotherapist": "",
"healthcare-alternative": "",
"healthcare-audiologist": "",
"healthcare-blood_donation": "",
"healthcare-optometrist": "",
"healthcare-podiatrist": "",
"healthcare-psychotherapist": "",
"healthcare-sample_collection": "",
"healthcare-speech_therapist": "",
"amenity-hunting_stand": "",
"amenity-kindergarten": "",
"amenity-library": "",
"amenity-parking|amenity-parking_entrance|@category_parking": "",
"@category_pharmacy": "",
"amenity-pharmacy|@category_pharmacy": "",
"@category_post": "",
"amenity-post_box|@category_post": "",
"amenity-post_office|post_office-post_partner|@category_post": "",
"amenity-vehicle_inspection": "",
"amenity-waste_disposal": "",
"amenity-recycling-centre|@category_recycling": "",
"amenity-recycling-container|amenity-recycling|@category_recycling": "",
"recycling-batteries|@category_recycling": "",
"recycling-clothes|@category_recycling": "",
"recycling-glass_bottles|@category_recycling": "",
"recycling-paper|@category_recycling": "",
"recycling-plastic|@category_recycling": "",
"recycling-plastic_bottles|@category_recycling": "",
"recycling-scrap_metal|@category_recycling": "",
"recycling-small_appliances|@category_recycling": "",
"recycling-cardboard|@category_recycling": "",
"recycling-cans|@category_recycling": "",
"recycling-shoes|@category_recycling": "",
"recycling-green_waste|@category_recycling": "",
"recycling-cartons|@category_recycling": "",
"amenity-sanitary_dump_station|@category_rv": "",
"amenity-school": "",
"amenity-shelter": "",
"amenity-shelter-basic_hut": "",
"amenity-shelter-lean_to": "",
"amenity-stripclub": "",
"amenity-telephone": "",
"@category_toilet": "",
"amenity-toilets|toilets-yes|@category_toilet": "",
"amenity-university": "",
"place-continent": "",
"place-country": "",
"place-city": "",
"place-town": "",
"place-city-capital": "",
"place-county": "",
"place-state": "",
"place-region": "",
"place-island|place-islet": "",
"place-suburb|place-quarter|place-neighbourhood|landuse-residential": "",
"place-hamlet": "",
"place-village": "",
"place-locality": "",
"place-farm": "",
"highway-raceway": "",
"highway-path|highway-footway|highway-steps|highway-cycleway": "",
"highway-pedestrian|highway-primary|highway-primary_link|highway-residential|highway-secondary|highway-secondary_link|highway-tertiary|highway-tertiary_link|highway-service|highway-road|highway-track|highway-trunk|highway-trunk_link|highway-living_street|highway-unclassified|highway-motorway_link|highway-motorway|highway-cycleway": "",
"highway-motorway_junction": "",
"highway-elevator": "",
"@mountain": "",
"natural-peak|@mountain": "",
"natural-saddle|mountain_pass": "",
"natural-strait": "",
"landuse-forest": "",
"leisure-park": "",
"tourism-aquarium|@category_tourism": "",
"tourism-hostel|@category_hotel": "",
"tourism-hotel|@category_hotel": "",
"tourism-guest_house|@category_hotel": "",
"tourism-motel|@category_hotel": "",
"tourism-alpine_hut|@category_hotel": "",
"shop-hairdresser": "",
"aeroway-aerodrome": "",
"leisure-stadium": "",
"leisure-playground|@category_children": "",
"leisure-sports_centre|leisure-sports_centre-sport-american_football|leisure-sports_centre-sport-archery|leisure-sports_centre-sport-athletics|leisure-sports_centre-sport-australian_football|leisure-sports_centre-sport-badminton|leisure-sports_centre-sport-baseball|leisure-sports_centre-sport-basketball|leisure-sports_centre-sport-beachvolleyball|leisure-sports_centre-sport-bowls|leisure-sports_centre-sport-climbing|leisure-sports_centre-sport-cricket|leisure-sports_centre-sport-curling|leisure-sports_centre-sport-equestrian|leisure-sports_centre-sport-field_hockey|leisure-sports_centre-sport-futsal|leisure-sports_centre-sport-golf|leisure-sports_centre-sport-gymnastics|leisure-sports_centre-sport-handball|leisure-sports_centre-sport-ice_hockey|leisure-sports_centre-sport-multi|leisure-sports_centre-sport-padel|leisure-sports_centre-sport-pelota|leisure-sports_centre-sport-scuba_diving|leisure-sports_centre-sport-shooting|leisure-sports_centre-sport-skateboard|leisure-sports_centre-sport-skiing|leisure-sports_centre-sport-soccer|leisure-sports_centre-sport-table_tennis|leisure-sports_centre-sport-tennis|leisure-sports_centre-sport-volleyball|leisure-sports_centre-sport-yoga": "",
"leisure-sports_centre-sport-swimming": "",
"leisure-golf_course": "",
"leisure-miniature_golf": "",
"leisure-escape_game": "",
"leisure-hackerspace": "",
"leisure-pitch": "",
"leisure-swimming_pool": "",
"leisure-swimming_pool-private": "",
"sport-american_football": "",
"sport-archery": "",
"sport-athletics": "",
"sport-australian_football": "",
"sport-baseball": "",
"sport-basketball": "",
"sport-beachvolleyball": "",
"sport-bowls": "",
"sport-chess": "",
"sport-cricket": "",
"sport-curling": "",
"sport-equestrian": "",
"sport-golf": "",
"sport-gymnastics": "",
"sport-handball": "",
"sport-scuba_diving": "",
"sport-shooting": "",
"sport-skateboard": "",
"sport-skiing": "",
"sport-soccer": "",
"sport-swimming": "",
"sport-table_tennis": "",
"sport-tennis": "",
"sport-padel": "",
"sport-volleyball": "",
"sport-9pin": "",
"sport-10pin": "",
"building": "",
"building-address": "",
"@category_police": "",
"amenity-police|@category_police": "",
"office-diplomatic": "",
"natural-bay": "",
"@category_water": "",
"amenity-drinking_water|drinking_water-yes|@category_water": "",
"natural-hot_spring|@category_water": "",
"natural-spring|@category_water": "",
"man_made-water_well|@category_water": "",
"amenity-water_point|@category_water|@category_rv": "",
"man_made-water_tap|@category_water": "",
"@waterbody": "",
"natural-water|@waterbody": "",
"natural-water-basin|landuse-basin|@waterbody": "",
"natural-water-pond|@waterbody": "",
"natural-water-lake|@waterbody": "",
"natural-water-reservoir|landuse-reservoir|@waterbody": "",
"waterway-river|waterway-stream|natural-water-river": "",
"waterway-canal": "",
"shop-car_repair": "",
"tourism-camp_site|@category_hotel": "",
"tourism-caravan_site|@category_rv||@category_hotel": "",
"office": "",
"office-company": "",
"office-government": "",
"office-lawyer": "",
"office-telecommunication": "",
"craft-beekeeper": "",
"craft-blacksmith": "",
"craft-brewery": "",
"craft-caterer": "",
"craft-carpenter": "",
"craft-confectionery": "",
"craft-electrician": "",
"craft-electronics_repair": "",
"craft-gardener": "",
"craft-grinding_mill": "",
"craft-handicraft": "",
"craft-hvac": "",
"craft-metal_construction": "",
"craft-key_cutter": "",
"craft-locksmith": "",
"craft-painter": "",
"craft-photographer": "",
"craft-plumber": "",
"craft-sawmill": "",
"craft-shoemaker": "",
"craft-winery": "",
"craft-tailor": "",
"area:highway-footway|area:highway-pedestrian|area:highway-steps|place-square": "",
"place-sea": "",
"place-ocean": "",
"@category_wifi": "",
"internet_access|internet_access-wlan|@category_wifi": "",
"natural-beach|natural-beach-sand|natural-beach-gravel|leisure-beach_resort": "",
"man_made-lighthouse": "",
"man_made-survey_point": "",
"man_made-flagpole": "",
"man_made-mast": "",
"man_made-communications_tower|man_made-tower-communication": "",
"man_made-petroleum_well": "",
"organic-only|organic-yes": "",
"shop-copyshop": "",
"shop-photo|@shop": "",
"shop-camera|@shop": "",
"shop-travel_agency": "",
"shop-outdoor|@shop": "",
"shop-dry_cleaning": "",
"shop-tyres|@shop": "",
"amenity-car_wash": "",
"man_made-telescope|man_made-telescope-optical|man_made-telescope-radio|man_made-telescope-gamma": "",
"man_made-observatory": "",
"amenity-veterinary": "",
"amenity-animal_shelter": "",
"@charging_station": "",
"amenity-charging_station|@charging_station": "",
"amenity-charging_station-bicycle|@charging_station": "",
"amenity-charging_station-motorcar|amenity-charging_station-motorcar-small|@charging_station": "",
"amenity-childcare": "",
"amenity-bicycle_parking": "",
"amenity-waste_basket": "",
"emergency-phone": "",
"leisure-fitness_centre": "",
"leisure-sauna": "",
"shop-car_repair-tyres|shop-car_repair": "",
"shop-chemist|@shop": "",
"shop-pet|@shop": "",
"tourism-zoo|@category_tourism|@category_children": "",
"attraction-animal": "",
"tourism-information-office|amenity-ranger_station|@category_tourism": "",
"tourism-information-visitor_centre|amenity-ranger_station|@category_tourism": "",
"amenity-community_centre": "",
"amenity-compressed_air": "",
"amenity-courthouse": "",
"amenity-vending_machine": "",
"amenity-vending_machine-cigarettes": "",
"amenity-vending_machine-coffee": "",
"amenity-vending_machine-condoms": "",
"amenity-vending_machine-drinks": "",
"amenity-vending_machine-food|@category_food": "",
"amenity-vending_machine-parking_tickets|@category_parking": "",
"amenity-vending_machine-public_transport_tickets|@category_transport": "",
"amenity-vending_machine-newspapers": "",
"amenity-vending_machine-sweets": "",
"amenity-vending_machine-excrement_bags": "",
"amenity-parcel_locker|@category_post": "",
"shop-outpost": "",
"amenity-vending_machine-fuel|@category_fuel": "",
"building-garage": "",
"highway-rest_area|highway-services": "",
"man_made-chimney": "",
"man_made-crane": "",
"man_made-tower|man_made-flare": "",
"shop-bookmaker|@gambling": "",
"shop-seafood|@category_food|@shop": "",
"shop-second_hand|@category_shopping|@shop|@category_secondhand": "",
"shop-charity|@shop|@category_secondhand": "",
"shop-ticket": "",
"shop-wine|@category_food|@shop": "",
"shop-car_parts|@shop": "",
"tourism-chalet|@category_hotel": "",
"tourism-information-board": "",
"tourism-information-map": "",
"tourism-information-tactile_map": "",
"tourism-information-guidepost": "",
"aerialway-station": "",
"aeroway-helipad": "",
"barrier-border_control": "",
"leisure-water_park|@category_tourism|@category_children": "",
"man_made-water_tower": "",
"man_made-windmill": "",
"natural-cave_entrance": "",
"natural-volcano|@mountain": "",
"office-estate_agent": "",
"waterway-lock_gate": "",
"amenity-public_bookcase": "",
"sport-climbing": "",
"sport-yoga": "",
"leisure-fitness_centre-sport-yoga": "",
"tourism-apartment|@category_hotel": "",
"leisure-resort|@category_hotel": "",
"amenity-biergarten|@category_eat|@category_nightlife": "",
"amenity-driving_school": "",
"amenity-sailing_school": "",
"amenity-flight_school": "",
"amenity-prep_school": "",
"amenity-music_school": "",
"amenity-language_school": "",
"amenity-ice_cream": "",
"amenity-internet_cafe": "",
"amenity-motorcycle_parking": "",
"amenity-parking_space-disabled|@category_parking": "",
"amenity-car_pooling|@category_parking": "",
"amenity-nursing_home": "",
"amenity-payment_terminal": "",
"amenity-payment_centre": "",
"amenity-public_bath": "",
"amenity-shower": "",
"emergency-access_point": "",
"emergency-assembly_point": "",
"emergency-life_ring": "",
"emergency-defibrillator": "",
"emergency-fire_hydrant": "",
"amenity-hydrant": "",
"emergency-lifeguard": "",
"emergency-mountain_rescue": "",
"leisure-fitness_station": "",
"office-insurance": "",
"office-ngo": "",
"shop-erotic|@shop": "",
"shop-beauty-day_spa": "",
"shop-massage": "",
"shop-motorcycle|@shop": "",
"shop-motorcycle_repair": "",
"shop-newsagent": "",
"shop-pawnbroker": "",
"shop-stationery|@shop": "",
"shop-tattoo": "",
"shop-variety_store|@category_shopping|@shop": "",
"shop-video|@shop": "",
"shop-video_games|@shop": "",
"tourism-wilderness_hut|@category_hotel": "",
"tourism-gallery|@category_tourism": "",
"tourism-theme_park|@category_tourism|@category_children": "",
"boundary-national_park|@category_tourism": "",
"leisure-nature_reserve|@category_tourism": "",
"natural-cape": "",
"natural-geyser": "",
"natural-glacier|@category_tourism": "",
"highway-ford": "",
"leisure-marina": "",
"leisure-indoor_play": "",
"piste:type-downhill|piste:type-nordic": "",
"amenity-events_venue": "",
"shop-chocolate|@category_food|@shop": "",
"shop-coffee|@category_food|@shop": "",
"shop-fabric|@shop": "",
"shop-money_lender": "",
"shop-music|@shop": "",
"shop-musical_instrument|@shop": "",
"shop-tea|@shop": "",
"shop-telecommunication|@shop": "",
"shop-antiques|@category_shopping|@shop|@category_secondhand": "",
"shop-art|@category_shopping|@shop": "",
"shop-baby_goods|@category_children|@shop": "",
"shop-bag|@category_shopping|@shop": "",
"shop-cheese|@category_food|@shop": "",
"shop-dairy|@category_food|@shop": "",
"shop-electrical|@shop": "",
"shop-fishing|@shop": "",
"shop-interior_decoration|@shop": "",
"shop-lighting|@shop": "",
"shop-lottery|@gambling": "",
"shop-medical_supply|@shop": "",
"shop-nutrition_supplements|@shop": "",
"shop-paint|@shop": "",
"shop-perfumery|@category_shopping|@shop": "",
"shop-sewing|@shop": "",
"shop-storage_rental": "",
"shop-tobacco|@shop": "",
"shop-trade|@shop": "",
"shop-watches|@category_shopping|@shop": "",
"shop-wholesale|@shop": "",
"leisure-track": "",
"leisure-bandstand": "",
"power-plant": "",
"power-generator-wind": "",
"shop-auction|@category_secondhand": "",
"shop-collector|@category_shopping|@category_secondhand": "",
"man_made-cairn": "",
"wheelchair-yes": "",
"amenity-social_facility": "",
"social_facility-soup_kitchen": "",
"social_facility-food_bank": "",
"amenity-food_sharing": "",
"amenity-give_box": "",
"leisure-sports_hall": "",
"amenity-arts_centre|@category_tourism": "",
"amenity-prison": "",
"amenity-exhibition_centre": "",
"shop-bathroom_furnishing|@shop": "",
"shop-bed|@shop": "",
"shop-boutique|@shop": "",
"amenity-food_court": "",
"shop-curtain|@shop": "",
"shop-gas|@shop": "",
"shop-pet_grooming": "",
"shop-hifi|@shop": "",
"amenity-conference_centre": "",
"shop-herbalist|@shop": "",
"shop-appliance|@shop": "",
"shop-agrarian|@shop": "",
"shop-fashion_accessories|@shop": "",
"amenity-waste_transfer_station": "",
"shop-carpet|@shop": "",
"shop-craft|@shop": "",
"shop-pasta|@shop": "",
"attraction-amusement_ride|attraction-carousel|attraction-roller_coaster|attraction-maze|attraction-historic|attraction-big_wheel|attraction-bumper_car|@category_children": "",
"amenity-luggage_locker": "",
"office-security": "",
"building-guardhouse": ""
}

View File

@@ -320,7 +320,7 @@
"amenity-veterinary": "4Veterinārārsts|vetārsts|vetklīnika|veterinārā klīnika",
"@charging_station": "4Uzlādes stacija|uzlāde",
"amenity-charging_station-bicycle|@charging_station": "4Velosipēdu uzlāde|Riteņu uzlāde|Ričuku uzlāde|Divriteņu uzlāde",
"amenity-charging_station-motorcar|amenity-charging_station-motorcar-small|@charging_station": "Automobiļu uzlāde|mašīnu uzlāde",
"amenity-charging_station-motorcar|@charging_station": "Automobiļu uzlāde|mašīnu uzlāde",
"amenity-childcare": "Bērnistaba",
"amenity-bicycle_parking": "4Velonovietne",
"amenity-waste_basket": "Atkritumu tvertne|4miskaste",

View File

@@ -330,7 +330,7 @@
"amenity-animal_shelter": "Приют для животных",
"@charging_station": "4Зарядная станция|зарядка|электрозарядка|зарядить",
"amenity-charging_station-bicycle|@charging_station": "4Велозарядка|Зарядка для велосипедов",
"amenity-charging_station-motorcar|amenity-charging_station-motorcar-small|@charging_station": "4Автозарядка",
"amenity-charging_station-motorcar|@charging_station": "4Автозарядка",
"amenity-childcare": "Детская комната|3ясли",
"amenity-bicycle_parking": "4Велопарковка|велостоянка",
"amenity-waste_basket": "3Урна|4Мусорная корзина",

View File

@@ -331,7 +331,7 @@
"amenity-veterinary": "4Veteriner",
"@charging_station": "Şarj İstasyonu|şarj etme",
"amenity-charging_station-bicycle|@charging_station": "4Bisiklet Şarjı",
"amenity-charging_station-motorcar|amenity-charging_station-motorcar-small|@charging_station": "4Otomobil Şarj Cihazı|4Araba Şarj Cihazı|4Araç Şarj Cihazı|3Trugo|4TOGG Şarj",
"amenity-charging_station-motorcar|@charging_station": "4Otomobil Şarj Cihazı|4Araba Şarj Cihazı|4Araç Şarj Cihazı|3Trugo|4TOGG Şarj",
"amenity-childcare": "Çocuk Yuvası|Kreş",
"amenity-bicycle_parking": "4Bisiklet park etme|bisiklet park",
"amenity-waste_basket": "Çöp Kutusu",

View File

@@ -148,11 +148,11 @@
<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://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>
<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>
&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>
<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>
<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>
<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>
<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>
<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>
<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>
&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>
<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>
&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>
<p lang="en">Beyond OpenStreetMap, we also use a few other open data sources to improve our map data:</p>

View File

@@ -1167,6 +1167,9 @@
<type id="tourism-information-map">
<include field="name" />
</type>
<type id="tourism-information-tactile_map">
<include field="name" />
</type>
<type id="tourism-information-guidepost">
</type>
<!-- Too generic to add -->

View File

@@ -302,7 +302,7 @@ railway|crossing;197;
boundary|national_park;198;
deprecated:natural|wood|deciduous:01.2020;[natural=wood][wood=deciduous],[natural=wood][leaf_type=deciduous],[natural=wood][leaf_cycle=deciduous];x;name;int_name;199;landuse|forest|deciduous
waterway|dam;200;
amenity|charging_station|motorcar|small;[amenity=charging_station][motorcar?][!capacity],[amenity=charging_station][motorcar?][capacity=1],[amenity=charging_station][motorcar?][capacity=2];;name;int_name;201;
amenity|charging_station|small;[amenity=charging_station][motorcar?][!capacity],[amenity=charging_station][motorcar?][capacity=1],[amenity=charging_station][motorcar?][capacity=2],[amenity=charging_station][!capacity],[amenity=charging_station][capacity=1],[amenity=charging_station][capacity=2],;;name;int_name;201;
leisure|golf_course;202;
highway|service|bridge;[highway=service][bridge?];;name;int_name;203;
# ~250K usages.
@@ -351,7 +351,7 @@ sport|basketball;242;
amenity|cinema;243;
amenity|theatre;244;
sport|chess;245;
deprecated:railway|spur:06.2023;246;x
railway|turntable;246;
aerialway|station;247;
landuse|brownfield;248;
aeroway|apron;249;
@@ -403,15 +403,14 @@ place|farm;294;
deprecated:boundary|administrative|11:04.2024;[boundary=administrative][admin_level=11];x;name;int_name;295;
waterway|weir;296;
highway|secondary|tunnel;[highway=secondary][tunnel?];;name;int_name;297;
# TODO: its a mismapping likely, if there is a bridge structure still, then it should be railway=disused.
railway|abandoned|bridge;[railway=abandoned][bridge?];;name;int_name;298;
railway|disused|bridge;[railway=disused][bridge?],[railway=abandoned][bridge?];;name;int_name;298;
man_made|lighthouse;299;
deprecated:highway|path|demanding_mountain_hiking:04.2024;[highway=path][sac_scale=demanding_mountain_hiking];x;name;int_name;300;highway|path|difficult
amenity|charging_station|motorcycle;[amenity=charging_station][motorcycle?];;name;int_name;300;
man_made|storage_tank;301;
man_made|silo;302;
power|generator;303;
highway|pedestrian|bridge;[highway=pedestrian][bridge?];;name;int_name;304;
amenity|charging_station|motorcar;[amenity=charging_station][motorcar?][capacity?];;name;int_name;305;
amenity|charging_station|motorcar;[amenity=charging_station][motorcar?][capacity?],[amenity=charging_station][motorcar?];;name;int_name;305;
natural|saddle;306;
mountain_pass;[mountain_pass];;name;int_name;307;
highway|raceway;308;
@@ -420,7 +419,7 @@ highway|primary_link|bridge;[highway=primary_link][bridge?];;name;int_name;310;
man_made|tower|communication;[man_made=tower][tower:type=communication];;name;int_name;311;
sport|equestrian;312;
tourism|information|office;[tourism=information][information=office];;name;int_name;313;
deprecated:highway|footway|hiking:04.2024;[highway=footway][sac_scale=hiking];x;name;int_name;314;highway|path
amenity|charging_station|carless;[amenity=charging_station][motorcar=not],[amenity=charging_station][motorcar=no];;name;int_name;314;
aeroway|gate;315;
# TODO: railway=preserved is deprecated in OSM, recommended mapping is railway:preserved=yes + railway=*
railway|preserved;316;
@@ -511,8 +510,7 @@ railway|rail|spur|tunnel;[railway=rail][service=spur][!usage][tunnel?];;name;int
highway|secondary_link|bridge;[highway=secondary_link][bridge?];;name;int_name;397;
railway|tram|tunnel;[railway=tram][tunnel?];;name;int_name;398;
railway|rail|tourism;[railway=rail][usage=tourism][!service];;name;int_name;399;
# TODO: its a mismapping likely, if there is a tunnel structure still, then it should be railway=disused.
railway|abandoned|tunnel;[railway=abandoned][tunnel?];;name;int_name;400;
railway|disused|tunnel;[railway=disused][tunnel?],[railway=abandoned][tunnel?];;name;int_name;400;
area:highway|living_street;401;
piste:type|sled;402;
leisure|beach_resort;403;
@@ -1193,7 +1191,7 @@ shop|tyres;1064;
craft|beekeeper;1065;
amenity|car_wash;1066;
amenity|veterinary;1067;
amenity|charging_station;1068;
amenity|charging_station;[amenity=charging_station];;name;int_name;1068;
amenity|childcare;1069;
craft|blacksmith;1070;
amenity|bicycle_parking;1071;
Can't render this file because it contains an unexpected character in line 7 and column 16.

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -559,8 +559,9 @@ area|z15-[amenity=marketplace],
area|z15-[office=diplomatic],
area|z15-[amenity=vehicle_inspection],
area|z15-[amenity=car_wash],
area|z15-[amenity=charging_station][motorcar?],
area|z15-[amenity=fuel],
area|z15-[amenity=charging_station][motorcar?],
area|z16-[amenity=charging_station],
area|z15-[amenity=motorcycle_parking],
area|z15-[amenity=bicycle_parking],
{fill-opacity: 1; fill-color: @general_area;}

View File

@@ -2399,18 +2399,28 @@ node|z17-[amenity=fuel],
node|z18-[amenity=fuel],
{font-size: 11;}
node|z15-[amenity=charging_station][motorcar?],
node|z16-[amenity=charging_station][motorcycle?],
node|z16-[amenity=charging_station][bicycle?],
node|z16-[amenity=charging_station][motorcar=not],
node|z16-[amenity=charging_station],
{icon-image: charging_station-small-m.svg;}
node|z14[amenity=charging_station][motorcar?][capacity?],
{icon-image: charging_station-s.svg;}
node|z15-[amenity=charging_station][motorcar?][capacity?],
{icon-image: charging_station-m.svg;}
node|z14[amenity=charging_station][motorcar?][!capacity],
node|z14[amenity=charging_station][motorcar?][capacity=1],
node|z14[amenity=charging_station][motorcar?][capacity=2],
{icon-image: none;}
node|z15-[amenity=charging_station][motorcar?][!capacity],
node|z15-[amenity=charging_station][motorcar?][capacity=1],
node|z15-[amenity=charging_station][motorcar?][capacity=2],
node|z16-[amenity=charging_station],
{icon-image: charging-point-m.svg;}
{icon-image: charging_station-small-m.svg;}
node|z14[amenity=charging_station][motorcar?][capacity?],
{icon-image: charging-station-s.svg;}
node|z15-[amenity=charging_station][motorcar?][capacity?],
{icon-image: charging-station-m.svg;}
node|z14[amenity=charging_station][motorcar?][capacity?],
node|z14[amenity=charging_station][motorcar?],
{text-offset: 1;font-size: 10;icon-min-distance: 20;}
node|z15[amenity=charging_station][motorcar?],
{icon-min-distance: 20;}

View File

@@ -1198,6 +1198,7 @@ line|z15-[railway=preserved],
line|z16-[railway=miniature],
line|z16-[railway=disused],
line|z16-[railway=abandoned],
line|z17-[railway=turntable],
{color: @railway; opacity: 0.7;}
line|z13-[railway=light_rail][!tunnel],
@@ -1216,14 +1217,14 @@ line|z13-[railway=subway][bridge?]::bridgewhite,
line|z13-[railway=light_rail][bridge?]::bridgewhite,
line|z15-[railway=preserved][bridge?]::bridgewhite,
line|z16-[railway=miniature][bridge?]::bridgewhite,
line|z16-[railway=abandoned][bridge?]::bridgewhite,
line|z16-[railway=disused][bridge?]::bridgewhite,
{casing-linecap: butt;casing-color:@bridge_background;casing-opacity: 0.8;}
line|z16-[railway=rail][bridge?]::bridgeblack,
line|z16-[railway=subway][bridge?]::bridgeblack,
line|z16-[railway=light_rail][bridge?]::bridgeblack,
line|z16-[railway=preserved][bridge?]::bridgeblack,
line|z16-[railway=miniature][bridge?]::bridgeblack,
line|z16-[railway=abandoned][bridge?]::bridgeblack,
line|z16-[railway=disused][bridge?]::bridgeblack,
{casing-linecap: butt;casing-color:@bridge_casing;casing-opacity: 0.7;}
/* 9.1 RAIL 11-22 ZOOM */
@@ -1374,13 +1375,16 @@ line|z18-[railway=light_rail][!tunnel]::dash,
line|z15-[railway=preserved],
line|z16-[railway=miniature],
line|z16-[railway=abandoned],
line|z16-[railway=disused],
{width: 1.6;dashes: 6.3,6.3;}
line|z15-[railway=construction],
line|z16-[railway=disused],
line|z16-[railway=abandoned],
{width: 1;dashes: 1.8,5.4;}
line|z17-[railway=turntable],
{width: 1.6;}
/* 9.2 Rail tunnel 14-22 ZOOM */
line|z12[railway=rail][tunnel?],
@@ -1430,21 +1434,21 @@ line|z16[railway=subway][bridge?]::bridgewhite,
line|z16[railway=light_rail][bridge?]::bridgewhite,
line|z16[railway=preserved][bridge?]::bridgewhite,
line|z16[railway=miniature][bridge?]::bridgewhite,
line|z16[railway=abandoned][bridge?]::bridgewhite,
line|z16[railway=disused][bridge?]::bridgewhite,
{casing-width-add: 1.6;}
line|z17[railway=rail][bridge?]::bridgewhite,
line|z17[railway=subway][bridge?]::bridgewhite,
line|z17[railway=light_rail][bridge?]::bridgewhite,
line|z17[railway=preserved][bridge?]::bridgewhite,
line|z17[railway=miniature][bridge?]::bridgewhite,
line|z17[railway=abandoned][bridge?]::bridgewhite,
line|z17[railway=disused][bridge?]::bridgewhite,
{casing-width-add: 2.3;}
line|z18-[railway=rail][bridge?]::bridgewhite,
line|z18-[railway=subway][bridge?]::bridgewhite,
line|z18-[railway=light_rail][bridge?]::bridgewhite,
line|z18-[railway=preserved][bridge?]::bridgewhite,
line|z18-[railway=miniature][bridge?]::bridgewhite,
line|z18-[railway=abandoned][bridge?]::bridgewhite,
line|z18-[railway=disused][bridge?]::bridgewhite,
{casing-width-add: 3.5;}
line|z16[railway=rail][bridge?]::bridgeblack,
@@ -1452,21 +1456,21 @@ line|z16[railway=subway][bridge?]::bridgeblack,
line|z16[railway=light_rail][bridge?]::bridgeblack,
line|z16[railway=preserved][bridge?]::bridgeblack,
line|z16[railway=miniature][bridge?]::bridgeblack,
line|z16[railway=abandoned][bridge?]::bridgeblack,
line|z16[railway=disused][bridge?]::bridgeblack,
{casing-width-add: 2.2;}
line|z17[railway=rail][bridge?]::bridgeblack,
line|z17[railway=subway][bridge?]::bridgeblack,
line|z17[railway=light_rail][bridge?]::bridgeblack,
line|z17[railway=preserved][bridge?]::bridgeblack,
line|z17[railway=miniature][bridge?]::bridgeblack,
line|z17[railway=abandoned][bridge?]::bridgeblack,
line|z17[railway=disused][bridge?]::bridgeblack,
{casing-width-add: 3;}
line|z18-[railway=rail][bridge?]::bridgeblack,
line|z18-[railway=subway][bridge?]::bridgeblack,
line|z18-[railway=light_rail][bridge?]::bridgeblack,
line|z18-[railway=preserved][bridge?]::bridgeblack,
line|z18-[railway=miniature][bridge?]::bridgeblack,
line|z18-[railway=abandoned][bridge?]::bridgeblack,
line|z18-[railway=disused][bridge?]::bridgeblack,
{casing-width-add: 4.4;}
/* 9.4 Monorail 14-22 ZOOM */

View File

@@ -85,8 +85,12 @@ landuse-cemetery-christian # area z10- (also has icon z
=== 180
amenity-car_wash # area z15- (also has icon z17-, caption(optional) z17-)
amenity-charging_station # area z16- (also has icon z16-, caption(optional) z16-)
amenity-charging_station-bicycle # area z16- (also has icon z16-, caption(optional) z16-)
amenity-charging_station-carless # area z16- (also has icon z16-, caption(optional) z16-)
amenity-charging_station-motorcar # area z15- (also has icon z14-, caption(optional) z14-)
amenity-charging_station-motorcar-small # area z15- (also has icon z16-, caption(optional) z16-)
amenity-charging_station-motorcycle # area z16- (also has icon z16-, caption(optional) z16-)
amenity-charging_station-small # area z15- (also has icon z15-, caption(optional) z16-)
amenity-courthouse # area z15- (also has icon z17-, caption(optional) z17-)
amenity-fire_station # area z15- (also has icon z16-, caption(optional) z17-)
amenity-fuel # area z15- (also has icon z14-, caption(optional) z14-)

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