Compare commits

..

24 Commits

Author SHA1 Message Date
x7z4w
89bcc9894d [android] Do not crash on unknown types
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-10-19 12:27:20 +02:00
Jean-Baptiste
96d51dfcf9 [editor] Support more postcode format
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2025-10-19 10:40:25 +02:00
Yannik Bloscheck
cf1432cbf7 Remove speed cameras in Germany
Signed-off-by: Yannik Bloscheck <git@yannikbloscheck.com>
2025-10-19 09:32:20 +02:00
x7z4w
9ae005ac56 [map] Don't save routing viewport
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-10-19 09:30:02 +02:00
x7z4w
bdf9a335ae [tools] Add txt to JSON categories conversion
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-10-18 20:14:20 +00:00
Codeberg Translate
422b14d31a [strings] Update from Codeberg Translate
Co-authored-by: Codeberg Translate <translate@codeberg.org>
Co-authored-by: Fjuro <fjuro@alius.cz>
Co-authored-by: Prefill add-on <noreply-addon-prefill@weblate.org>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: dobridabar <dobridabar@noreply.codeberg.org>
Co-authored-by: matheusgomesms <matheusgomesms@noreply.codeberg.org>
Co-authored-by: patepelo <patepelo@noreply.codeberg.org>
Co-authored-by: summoner <summoner@noreply.codeberg.org>
Translation: CoMaps/Android - Map Feature Types
Translation: CoMaps/Android UI Strings
Translation: CoMaps/Countries and regions names
Translation: CoMaps/Search synonyms / aliases
Translation: CoMaps/iOS - Map Feature Types
Translation: CoMaps/iOS UI Strings
2025-10-18 18:41:37 +00:00
x7z4w
ee30622940 [editor] Support Andorra postcodes
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-10-18 20:05:24 +02:00
Jean-Baptiste
1e931c81d2 [android] Re-enable socket cardview and improve dialog
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2025-10-18 19:48:34 +02:00
x7z4w
517cfb656a [strings] steps -> stairs
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-10-18 19:45:18 +02:00
x7z4w
7b1a4ed7ac nit
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-10-18 18:02:38 +02:00
x7z4w
8926a9fe16 Update data/faq.html
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-10-18 18:02:38 +02:00
Jean-Baptiste
bdadd2689c Update sentence
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2025-10-18 18:02:38 +02:00
x7z4w
c399d5e415 Update data/faq.html
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-10-18 18:02:38 +02:00
x7z4w
7feeb6eca6 Update data/faq.html
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-10-18 18:02:38 +02:00
Jean-Baptiste
547ff5795e Updata FAQ about Android version
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2025-10-18 18:02:38 +02:00
Jean-Baptiste
de5b61fde0 Update links in copyright file
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2025-10-18 17:57:20 +02:00
x7z4w
59bbea44a5 [styles] Sync vehicle label colors
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-10-18 17:55:42 +02:00
Jean-Baptiste
9ca9704bd9 [android] Improve tools texts
Signed-off-by: Jean-Baptiste jeanbaptiste.charron@outlook.fr
Co-authored-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
Co-committed-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2025-10-18 14:24:01 +02:00
Jean-Baptiste
d283fd41ae [android] Improve colors in navigation UI
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2025-10-18 08:55:35 +02:00
Codeberg Translate
f81eff2e33 [strings] Update from Codeberg Translate
Co-authored-by: 2lab <2lab@noreply.codeberg.org>
Co-authored-by: Codeberg Translate <translate@codeberg.org>
Co-authored-by: Edgarsons <edgarsons@noreply.codeberg.org>
Co-authored-by: JanezPavelZebovec <janezpavelzebovec@noreply.codeberg.org>
Co-authored-by: Outbreak2096 <outbreak2096@noreply.codeberg.org>
Co-authored-by: Prefill add-on <noreply-addon-prefill@weblate.org>
Co-authored-by: Priit Jõerüüt <jrtcdbrg@noreply.codeberg.org>
Co-authored-by: Ricky-Tigg <ricky-tigg@noreply.codeberg.org>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate Translation Memory <noreply-mt-weblate-translation-memory@weblate.org>
Co-authored-by: gedankenstuecke <gedankenstuecke@noreply.codeberg.org>
Co-authored-by: ghose <ghose@noreply.codeberg.org>
Co-authored-by: javnik <javnik@noreply.codeberg.org>
Co-authored-by: map-per <map-per@noreply.codeberg.org>
Co-authored-by: ovl-005 <ovl-005@noreply.codeberg.org>
Co-authored-by: potatofury <potatofury@noreply.codeberg.org>
Co-authored-by: summoner <summoner@noreply.codeberg.org>
Co-authored-by: teletext <teletext@noreply.codeberg.org>
Co-authored-by: x7z4w <x7z4w@noreply.codeberg.org>
Translate-URL: https://translate.codeberg.org/projects/comaps/fdroid-app-description/
Translation: CoMaps/Android - Map Feature Types
Translation: CoMaps/Android UI Strings
Translation: CoMaps/Android UI Strings (SDK)
Translation: CoMaps/Apple AppStore description
Translation: CoMaps/Countries and regions names
Translation: CoMaps/F-Droid app description
Translation: CoMaps/Google Play and Huawei AppGallery descriptions
Translation: CoMaps/Search synonyms / aliases
Translation: CoMaps/iOS - Map Feature Types
Translation: CoMaps/iOS Plurals
Translation: CoMaps/iOS UI Strings
2025-10-17 19:09:32 +00:00
Jean-Baptiste
1d7cf5ae39 [android] Improve phone item view
Signed-off-by: Jean-Baptiste <jeanbaptiste.charron@outlook.fr>
2025-10-17 17:54:28 +02:00
Yannik Bloscheck
0efe782325 [ios] Fix search bar background for POI categories
Signed-off-by: Yannik Bloscheck <git@yannikbloscheck.com>
2025-10-17 15:54:07 +02:00
x7z4w
a1e45b5837 [build] Fix World links
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-10-17 12:11:30 +02:00
x7z4w
7a03dd7cf6 [editor] Fix warning
Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
2025-10-17 12:11:00 +02:00
144 changed files with 851 additions and 8461 deletions

View File

@@ -0,0 +1 @@
Лесна навигация - Открийте повече от вашето пътуване - Подкрепен от общността

View File

@@ -0,0 +1 @@
CoMaps - Хайкинг, Велосипед, Пътуване без Интернет

View File

@@ -1,4 +1,4 @@
这是一个由社区主导、以 OpenStreetMap 数据为基础的免费开源地图应用建立在我们对运营透明、隐私安全和非营利性的承诺之上。CoMaps 是 Organic Maps 的分叉/衍生产品,而 Organic Maps 则是 Maps.ME 的分叉。
这是一个由社区主导、以 OpenStreetMap 数据为基础的自由开源地图应用建立在我们对运营透明、隐私安全和非营利性的承诺之上。CoMaps 是 Organic Maps 的分叉/衍生产品,而 Organic Maps 则是 Maps.ME 的分叉。
如需了解此项目诞生的原因及未来方向,请访问 <b><i>codeberg.org/comaps</i></b>。
加入以上社区,和大家一起打造最优质的地图应用
@@ -10,7 +10,7 @@
‣ <b>尊重隐私</b>:开发者们在设计 CoMaps 时优先考虑的是保护用户隐私。CoMaps 无法识别用户身份、无法跟踪用户活动也无法收集个人信息。此外CoMaps 不会也不能显示任何广告。
‣ <b>简洁精致</b>:轻便易用、不出差错的基本功能。
‣ <b>节省电池电量和空间</b>:不会像其他导航应用那样耗电。精简的地图可以节省宝贵的手机空间。
‣ <b>由社区合作创建的免费应用</b>:如同您一样的用户通过向 OpenStreetMap 添加地点、测试功能并提供反馈、无私地贡献自己的编程技能和资金,协力开发了 CoMaps。
‣ <b>自由且社区共建</b>:如同您一样的用户通过向 OpenStreetMap 添加地点、测试功能并提供反馈、无私地贡献自己的编程技能和资金,协力开发了 CoMaps。
‣ <b>决策问责、财务透明、非营利性、完全开源。</b>
<b>主要功能</b>
@@ -25,7 +25,7 @@
• 地铁交通图层和路线指示
• 轨迹记录
• 以 KML、KMZ 和 GPX 格式导出和导入书签和轨迹
选择天暗后自动开启的黑暗模式
深色模式,适配夜间使用场景
• 使用基本的内置编辑器来编辑 OpenStreetMap 地点,帮助大家改进地图数据
<b>自由在此</b>

View File

@@ -0,0 +1 @@
Лесна навигация - Открийте повече от вашето пътуване - Подкрепен от общността

View File

@@ -0,0 +1 @@
CoMaps - Пътуване с Приватност

View File

@@ -0,0 +1,36 @@
Skupnostno vodena brezplačna in odprtokodna aplikacija za zemljevide, ki temelji na podatkih OpenStreetMap, ter je okrepljena z zavezanostjo k transparentnosti, zasebnosti, in ostajanju neprofitne organizacije.
Pridružite se skupnosti in pomagajte ustvariti najboljšo aplikacijo za zemljevide.
• Uporabljajte aplikacijo in jo priporočajte drugim.
• Podajte povratne informacije in poročajte o težavah.
• Posodobite podatke zemljevida v aplikaciji ali na spletni strani OpenStreetMap.
<i>Vaše povratne informacije in 5-zvezdične ocene so najboljša podpora za nas!</i>
‣ <b>Preprostost in izpopolnjenost</b>: bistvene, enostavne za uporabo funkcije, ki preprosto delujejo.
‣ <b>Osredotočena na delovanje brez internetne povezave</b>: načrtujte in navigirajte svoje potovanje v tujini brez potrebe po mobilni povezavi, iščite točke na poti med daljšo pohodniško turo, itd. Vse funkcije aplikacije so zasnovane za delovanje brez internetne povezave.
‣ <b>Spoštovanje zasebnosti</b>: aplikacija je zasnovana z mislijo na zasebnost ne identificira ljudi, ne sledi in ne zbira osebnih podatkov. Brez oglasov.
‣ <b>Varčuje z baterijo in prostorom</b>: ne izčrpava baterije kot druge navigacijske aplikacije. Kompaktni zemljevidi varčujejo dragoceni prostor na vašem telefonu.
‣ <b>Brezplačna in ustvarjena s pomočjo skupnosti</b>: ljudje, kot ste vi, so pomagali ustvariti aplikacijo z dodajanjem krajev v OpenStreetMap, testiranjem in dajanjem povratnih informacij o funkcijah ter prispevanjem svojih razvojnih veščin in denarja.
‣ <b>Odprto in pregledno odločanje in finance, neprofitna in popolnoma odprtokodna aplikacija.
<b>Glavne značilnosti</b>:
• Podrobni zemljevidi z mesti, ki niso na voljo v Google Maps, ki jih lahko prenesete
• Način za uporabo na prostem z označenimi pohodniškimi potmi, kampi, vodnimi viri, vrhovi, višinskimi krivuljami itd.
• Pešpoti in kolesarske poti
• Zanimivosti, kot so restavracije, bencinske črpalke, hoteli, trgovine, znamenitosti in še veliko več
• Iskanje po imenu, naslovu ali kategoriji zanimivih točk
• Navigacija z glasovnimi napovedmi za hojo, kolesarjenje ali vožnjo
• Z enim dotikom dodajte svoje priljubljene kraje v zaznamke
• Članki iz Wikipedije za uporabo brez internetne povezave
• Plast podzemne železnice in navodila za pot
• Sledenje poti
• Izvoz in uvoz zaznamkov in poti v formatih KML, KMZ, GPX
• Temni način za uporabo ponoči
• Izboljšajte zemljevidne podatke za vse z uporabo vgrajenega osnovnega urejevalnika.
• Podpora za Android Auto.
Prijavite težave z aplikacijo, predlagajte ideje in se pridružite naši skupnosti na spletni strani <b><i>comaps.app</i></b>.
<b>Svoboda je tu</b>
Odkrijte svojo pot, raziskujte svet z zasebnostjo in skupnostjo v ospredju!

View File

@@ -0,0 +1 @@
CoMaps - Navigacija z zasebnostjo

View File

@@ -1,4 +1,4 @@
这是一个由社区主导、以 OpenStreetMap 数据为基础的免费开源地图应用,建立在我们对运营透明、隐私安全和非营利性的承诺之上。
这是一个由社区主导、以 OpenStreetMap 数据为基础的自由开源地图应用,建立在我们对运营透明、隐私安全和非营利性的承诺之上。
加入社区,和大家一起打造最优质的地图应用
• 使用 CoMaps 的同时也分享推荐给周围的人
@@ -11,7 +11,7 @@
‣ <b>以提供离线服务为核心</b>:无需移动网络即可规划和导航您的海外旅行,郊外远足时仍可搜索航点等等。所有功能均可离线使用。
‣ <b>尊重隐私</b>:开发者们在设计 CoMaps 时优先考虑的是保护用户隐私。CoMaps 无法识别用户身份、无法跟踪用户活动也无法收集个人信息。此外CoMaps 不会也不能显示任何广告。
‣ <b>节省电池电量和空间</b>:不会像其他导航应用那样耗电。精简的地图可以节省宝贵的手机空间。
‣ <b>由社区合作创建的免费应用</b>:如同您一样的用户通过向 OpenStreetMap 添加地点、测试功能并提供反馈、无私地贡献自己的编程技能和资金,协力开发了 CoMaps。
‣ <b>自由且社区共建</b>:如同您一样的用户通过向 OpenStreetMap 添加地点、测试功能并提供反馈、无私地贡献自己的编程技能和资金,协力开发了 CoMaps。
‣ <b>决策问责、财务透明、非营利性、完全开源。</b>
<b>主要功能</b>
@@ -26,7 +26,7 @@
• 地铁交通图层和路线指示
• 轨迹记录
• 以 KML、KMZ 和 GPX 格式导出和导入书签和轨迹
选择天暗后自动开启的黑暗模式
深色模式,适配夜间使用场景
• 使用基本的内置编辑器来编辑 OpenStreetMap 地点,帮助大家改进地图数据
• 支持 Android Auto

View File

@@ -500,13 +500,6 @@
android:stopWithTask="false"
/>
<service android:name=".location.LocationSharingService"
android:foregroundServiceType="location"
android:exported="false"
android:enabled="true"
android:stopWithTask="false"
/>
<service
android:name=".downloader.DownloaderService"
android:foregroundServiceType="dataSync"

View File

@@ -426,32 +426,19 @@ public class MwmActivity extends BaseMwmFragmentActivity
private void shareMyLocation()
{
final Location loc = MwmApplication.from(this).getLocationHelper().getSavedLocation();
if (loc == null)
if (loc != null)
{
dismissLocationErrorDialog();
mLocationErrorDialog = new MaterialAlertDialogBuilder(MwmActivity.this, R.style.MwmTheme_AlertDialog)
.setMessage(R.string.unknown_current_position)
.setCancelable(true)
.setPositiveButton(R.string.ok, null)
.setOnDismissListener(dialog -> mLocationErrorDialog = null)
.show();
SharingUtils.shareLocation(this, loc);
return;
}
SharingUtils.shareLocation(this, loc);
}
public void onLocationSharingStateChanged(boolean isSharing)
{
mMapButtonsViewModel.setLocationSharingState(isSharing);
MapButtonsController mapButtonsController =
(MapButtonsController) getSupportFragmentManager().findFragmentById(R.id.map_buttons);
if (mapButtonsController != null)
mapButtonsController.updateMenuBadge();
// Update share location button color in navigation menu
if (mNavigationController != null)
mNavigationController.refreshShareLocationColor();
dismissLocationErrorDialog();
mLocationErrorDialog = new MaterialAlertDialogBuilder(MwmActivity.this, R.style.MwmTheme_AlertDialog)
.setMessage(R.string.unknown_current_position)
.setCancelable(true)
.setPositiveButton(R.string.ok, null)
.setOnDismissListener(dialog -> mLocationErrorDialog = null)
.show();
}
private void showDownloader(boolean openDownloaded)
@@ -1696,13 +1683,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
mMapButtonsViewModel.setLayoutMode(MapButtonsController.LayoutMode.regular);
refreshLightStatusBar();
Utils.keepScreenOn(Config.isKeepScreenOnEnabled(), getWindow());
// Stop location sharing when navigation ends
if (app.organicmaps.location.LocationSharingManager.getInstance().isSharing())
{
app.organicmaps.location.LocationSharingManager.getInstance().stopSharing();
onLocationSharingStateChanged(false);
}
}
@Override

View File

@@ -1,200 +0,0 @@
package app.organicmaps.api;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.organicmaps.sdk.util.log.Logger;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
* HTTP API client for location sharing server.
* Sends encrypted location updates to the server.
*/
public class LocationSharingApiClient
{
private static final String TAG = LocationSharingApiClient.class.getSimpleName();
private static final int CONNECT_TIMEOUT_MS = 10000;
private static final int READ_TIMEOUT_MS = 10000;
private final String mServerBaseUrl;
private final String mSessionId;
private final Executor mExecutor;
public interface Callback
{
void onSuccess();
void onFailure(@NonNull String error);
}
public LocationSharingApiClient(@NonNull String serverBaseUrl, @NonNull String sessionId)
{
mServerBaseUrl = serverBaseUrl.endsWith("/") ? serverBaseUrl : serverBaseUrl + "/";
mSessionId = sessionId;
mExecutor = Executors.newSingleThreadExecutor();
}
/**
* Create a new session on the server.
* @param callback Result callback
*/
public void createSession(@Nullable Callback callback)
{
mExecutor.execute(() -> {
try
{
String url = mServerBaseUrl + "api/v1/session";
String requestBody = "{\"sessionId\":\"" + mSessionId + "\"}";
int responseCode = postJson(url, requestBody);
if (responseCode >= 200 && responseCode < 300)
{
Logger.d(TAG, "Session created successfully: " + mSessionId);
if (callback != null)
callback.onSuccess();
}
else
{
String error = "Server returned error: " + responseCode;
Logger.w(TAG, error);
if (callback != null)
callback.onFailure(error);
}
}
catch (IOException e)
{
Logger.e(TAG, "Failed to create session", e);
if (callback != null)
callback.onFailure(e.getMessage());
}
});
}
/**
* Update location on the server with encrypted payload.
* @param encryptedPayloadJson Encrypted payload JSON (from native code)
* @param callback Result callback
*/
public void updateLocation(@NonNull String encryptedPayloadJson, @Nullable Callback callback)
{
mExecutor.execute(() -> {
try
{
String url = mServerBaseUrl + "api/v1/location/" + mSessionId;
int responseCode = postJson(url, encryptedPayloadJson);
if (responseCode >= 200 && responseCode < 300)
{
Logger.d(TAG, "Location updated successfully");
if (callback != null)
callback.onSuccess();
}
else
{
String error = "Server returned error: " + responseCode;
Logger.w(TAG, error);
if (callback != null)
callback.onFailure(error);
}
}
catch (IOException e)
{
Logger.e(TAG, "Failed to update location", e);
if (callback != null)
callback.onFailure(e.getMessage());
}
});
}
/**
* End the session on the server.
*/
public void endSession()
{
mExecutor.execute(() -> {
try
{
String url = mServerBaseUrl + "api/v1/session/" + mSessionId;
deleteRequest(url);
Logger.d(TAG, "Session ended: " + mSessionId);
}
catch (IOException e)
{
Logger.e(TAG, "Failed to end session", e);
}
});
}
/**
* Send a POST request with JSON body.
* @param urlString URL to send request to
* @param jsonBody JSON request body
* @return HTTP response code
* @throws IOException on network error
*/
private int postJson(@NonNull String urlString, @NonNull String jsonBody) throws IOException
{
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
try
{
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setRequestProperty("Accept", "application/json");
connection.setConnectTimeout(CONNECT_TIMEOUT_MS);
connection.setReadTimeout(READ_TIMEOUT_MS);
connection.setDoOutput(true);
// Write body
byte[] bodyBytes = jsonBody.getBytes(StandardCharsets.UTF_8);
connection.setFixedLengthStreamingMode(bodyBytes.length);
try (OutputStream os = connection.getOutputStream())
{
os.write(bodyBytes);
os.flush();
}
return connection.getResponseCode();
}
finally
{
connection.disconnect();
}
}
/**
* Send a DELETE request.
* @param urlString URL to send request to
* @return HTTP response code
* @throws IOException on network error
*/
private int deleteRequest(@NonNull String urlString) throws IOException
{
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
try
{
connection.setRequestMethod("DELETE");
connection.setConnectTimeout(CONNECT_TIMEOUT_MS);
connection.setReadTimeout(READ_TIMEOUT_MS);
return connection.getResponseCode();
}
finally
{
connection.disconnect();
}
}
}

View File

@@ -113,9 +113,6 @@ public class PhoneListAdapter extends RecyclerView.Adapter<PhoneListAdapter.View
deleteButton = itemView.findViewById(R.id.delete_icon);
deleteButton.setOnClickListener(this);
// TODO: setting icons from code because icons defined in layout XML are white.
deleteButton.setImageResource(R.drawable.ic_delete);
((ShapeableImageView) itemView.findViewById(R.id.phone_icon)).setImageResource(R.drawable.ic_phone);
}
public void setPosition(int position)

View File

@@ -1,131 +0,0 @@
package app.organicmaps.location;
import android.util.Base64;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.json.JSONException;
import org.json.JSONObject;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* AES-256-GCM encryption/decryption for location data.
*/
public class LocationCrypto
{
private static final String ALGORITHM = "AES/GCM/NoPadding";
private static final int GCM_IV_LENGTH = 12; // 96 bits
private static final int GCM_TAG_LENGTH = 128; // 128 bits
/**
* Encrypt plaintext JSON using AES-256-GCM.
* @param base64Key Base64-encoded 256-bit key
* @param plaintextJson JSON string to encrypt
* @return JSON string with encrypted payload: {"iv":"...","ciphertext":"...","authTag":"..."}
*/
@Nullable
public static String encrypt(@NonNull String base64Key, @NonNull String plaintextJson)
{
try
{
// Decode the base64 key
byte[] key = Base64.decode(base64Key, Base64.NO_WRAP);
if (key.length != 32) // 256 bits
{
android.util.Log.e("LocationCrypto", "Invalid key size: " + key.length);
return null;
}
// Generate random IV
byte[] iv = new byte[GCM_IV_LENGTH];
new SecureRandom().nextBytes(iv);
// Create cipher
Cipher cipher = Cipher.getInstance(ALGORITHM);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
GCMParameterSpec gcmSpec = new GCMParameterSpec(GCM_TAG_LENGTH, iv);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmSpec);
// Encrypt
byte[] plaintext = plaintextJson.getBytes(StandardCharsets.UTF_8);
byte[] ciphertextWithTag = cipher.doFinal(plaintext);
// Split ciphertext and auth tag
// In GCM mode, doFinal() returns ciphertext + tag
int ciphertextLength = ciphertextWithTag.length - (GCM_TAG_LENGTH / 8);
byte[] ciphertext = new byte[ciphertextLength];
byte[] authTag = new byte[GCM_TAG_LENGTH / 8];
System.arraycopy(ciphertextWithTag, 0, ciphertext, 0, ciphertextLength);
System.arraycopy(ciphertextWithTag, ciphertextLength, authTag, 0, authTag.length);
// Build JSON response
JSONObject result = new JSONObject();
result.put("iv", Base64.encodeToString(iv, Base64.NO_WRAP));
result.put("ciphertext", Base64.encodeToString(ciphertext, Base64.NO_WRAP));
result.put("authTag", Base64.encodeToString(authTag, Base64.NO_WRAP));
return result.toString();
}
catch (Exception e)
{
android.util.Log.e("LocationCrypto", "Encryption failed", e);
return null;
}
}
/**
* Decrypt encrypted payload using AES-256-GCM.
* @param base64Key Base64-encoded 256-bit key
* @param encryptedPayloadJson JSON string with format: {"iv":"...","ciphertext":"...","authTag":"..."}
* @return Decrypted plaintext JSON string
*/
@Nullable
public static String decrypt(@NonNull String base64Key, @NonNull String encryptedPayloadJson)
{
try
{
// Parse encrypted payload
JSONObject payload = new JSONObject(encryptedPayloadJson);
byte[] iv = Base64.decode(payload.getString("iv"), Base64.NO_WRAP);
byte[] ciphertext = Base64.decode(payload.getString("ciphertext"), Base64.NO_WRAP);
byte[] authTag = Base64.decode(payload.getString("authTag"), Base64.NO_WRAP);
// Decode the base64 key
byte[] key = Base64.decode(base64Key, Base64.NO_WRAP);
if (key.length != 32) // 256 bits
{
android.util.Log.e("LocationCrypto", "Invalid key size: " + key.length);
return null;
}
// Combine ciphertext and auth tag for GCM decryption
byte[] ciphertextWithTag = new byte[ciphertext.length + authTag.length];
System.arraycopy(ciphertext, 0, ciphertextWithTag, 0, ciphertext.length);
System.arraycopy(authTag, 0, ciphertextWithTag, ciphertext.length, authTag.length);
// Create cipher
Cipher cipher = Cipher.getInstance(ALGORITHM);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
GCMParameterSpec gcmSpec = new GCMParameterSpec(GCM_TAG_LENGTH, iv);
cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmSpec);
// Decrypt
byte[] plaintext = cipher.doFinal(ciphertextWithTag);
return new String(plaintext, StandardCharsets.UTF_8);
}
catch (Exception e)
{
android.util.Log.e("LocationCrypto", "Decryption failed", e);
return null;
}
}
}

View File

@@ -1,220 +0,0 @@
package app.organicmaps.location;
import android.app.Dialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentManager;
import app.organicmaps.R;
import app.organicmaps.util.SharingUtils;
/**
* Dialog for starting/stopping live location sharing and managing the share URL.
*/
public class LocationSharingDialog extends DialogFragment
{
private static final String TAG = LocationSharingDialog.class.getSimpleName();
@Nullable
private TextView mStatusText;
@Nullable
private TextView mShareUrlText;
@Nullable
private Button mStartStopButton;
@Nullable
private Button mCopyButton;
@Nullable
private Button mShareButton;
private LocationSharingManager mManager;
public static void show(@NonNull FragmentManager fragmentManager)
{
LocationSharingDialog dialog = new LocationSharingDialog();
dialog.show(fragmentManager, TAG);
}
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState)
{
mManager = LocationSharingManager.getInstance();
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
View view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_location_sharing, null);
initViews(view);
updateUI();
builder.setView(view);
builder.setTitle(R.string.location_sharing_title);
builder.setNegativeButton(R.string.close, (dialog, which) -> dismiss());
return builder.create();
}
private void initViews(@NonNull View root)
{
mStatusText = root.findViewById(R.id.status_text);
mShareUrlText = root.findViewById(R.id.share_url_text);
mStartStopButton = root.findViewById(R.id.start_stop_button);
mCopyButton = root.findViewById(R.id.copy_button);
mShareButton = root.findViewById(R.id.share_button);
if (mStartStopButton != null)
{
mStartStopButton.setOnClickListener(v -> {
if (mManager.isSharing())
stopSharing();
else
startSharing();
});
}
if (mCopyButton != null)
{
mCopyButton.setOnClickListener(v -> copyUrl());
}
if (mShareButton != null)
{
mShareButton.setOnClickListener(v -> shareUrl());
}
}
private void updateUI()
{
boolean isSharing = mManager.isSharing();
if (mStatusText != null)
{
mStatusText.setText(isSharing
? R.string.location_sharing_status_active
: R.string.location_sharing_status_inactive);
}
if (mShareUrlText != null)
{
String url = mManager.getShareUrl();
if (url != null && isSharing)
{
mShareUrlText.setText(url);
mShareUrlText.setVisibility(View.VISIBLE);
}
else
{
mShareUrlText.setVisibility(View.GONE);
}
}
if (mStartStopButton != null)
{
mStartStopButton.setText(isSharing
? R.string.location_sharing_stop
: R.string.location_sharing_start);
}
// Show/hide copy and share buttons
int visibility = isSharing ? View.VISIBLE : View.GONE;
if (mCopyButton != null)
mCopyButton.setVisibility(visibility);
if (mShareButton != null)
mShareButton.setVisibility(visibility);
}
private void startSharing()
{
String shareUrl = mManager.startSharing();
if (shareUrl != null)
{
Toast.makeText(requireContext(),
R.string.location_sharing_started,
Toast.LENGTH_SHORT).show();
updateUI();
// Notify the activity
if (getActivity() instanceof app.organicmaps.MwmActivity)
{
((app.organicmaps.MwmActivity) getActivity()).onLocationSharingStateChanged(true);
}
// Auto-copy URL to clipboard
copyUrlToClipboard(shareUrl);
}
else
{
Toast.makeText(requireContext(),
R.string.location_sharing_failed_to_start,
Toast.LENGTH_LONG).show();
}
}
private void stopSharing()
{
mManager.stopSharing();
Toast.makeText(requireContext(),
R.string.location_sharing_stopped,
Toast.LENGTH_SHORT).show();
updateUI();
// Notify the activity
if (getActivity() instanceof app.organicmaps.MwmActivity)
{
((app.organicmaps.MwmActivity) getActivity()).onLocationSharingStateChanged(false);
}
}
private void copyUrl()
{
String url = mManager.getShareUrl();
if (url != null)
{
copyUrlToClipboard(url);
}
}
private void copyUrlToClipboard(@NonNull String url)
{
ClipboardManager clipboard = (ClipboardManager)
requireContext().getSystemService(Context.CLIPBOARD_SERVICE);
if (clipboard != null)
{
ClipData clip = ClipData.newPlainText("Location Share URL", url);
clipboard.setPrimaryClip(clip);
Toast.makeText(requireContext(),
R.string.location_sharing_url_copied,
Toast.LENGTH_SHORT).show();
}
}
private void shareUrl()
{
String url = mManager.getShareUrl();
if (url == null)
return;
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, getString(R.string.location_sharing_share_message, url));
startActivity(Intent.createChooser(shareIntent, getString(R.string.location_sharing_share_url)));
}
}

View File

@@ -1,205 +0,0 @@
package app.organicmaps.location;
import android.content.Context;
import android.content.Intent;
import android.os.BatteryManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import app.organicmaps.MwmApplication;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.util.Config;
import app.organicmaps.sdk.util.log.Logger;
/**
* Singleton manager for live location sharing functionality.
* Coordinates between LocationHelper, RoutingController, and LocationSharingService.
*/
public class LocationSharingManager
{
private static final String TAG = LocationSharingManager.class.getSimpleName();
private static LocationSharingManager sInstance;
@Nullable
private String mSessionId;
@Nullable
private String mEncryptionKey;
@Nullable
private String mShareUrl;
private boolean mIsSharing = false;
private final Context mContext;
private LocationSharingManager()
{
mContext = MwmApplication.sInstance;
}
@NonNull
public static synchronized LocationSharingManager getInstance()
{
if (sInstance == null)
sInstance = new LocationSharingManager();
return sInstance;
}
/**
* Start live location sharing.
* @return Share URL that can be sent to others
*/
@Nullable
public String startSharing()
{
if (mIsSharing)
{
Logger.w(TAG, "Location sharing already active");
return mShareUrl;
}
// Generate session credentials via native code
String[] credentials = nativeGenerateSessionCredentials();
if (credentials == null || credentials.length != 2)
{
Logger.e(TAG, "Failed to generate session credentials");
return null;
}
mSessionId = credentials[0];
mEncryptionKey = credentials[1];
// Generate share URL using configured server
String serverUrl = Config.LocationSharing.getServerUrl();
mShareUrl = nativeGenerateShareUrl(mSessionId, mEncryptionKey, serverUrl);
if (mShareUrl == null)
{
Logger.e(TAG, "Failed to generate share URL");
return null;
}
mIsSharing = true;
// Start foreground service
Intent intent = new Intent(mContext, LocationSharingService.class);
intent.putExtra(LocationSharingService.EXTRA_SESSION_ID, mSessionId);
intent.putExtra(LocationSharingService.EXTRA_ENCRYPTION_KEY, mEncryptionKey);
intent.putExtra(LocationSharingService.EXTRA_SERVER_URL, serverUrl);
intent.putExtra(LocationSharingService.EXTRA_UPDATE_INTERVAL, Config.LocationSharing.getUpdateInterval());
mContext.startForegroundService(intent);
Logger.i(TAG, "Location sharing started, session ID: " + mSessionId);
return mShareUrl;
}
/**
* Stop live location sharing.
*/
public void stopSharing()
{
if (!mIsSharing)
{
Logger.w(TAG, "Location sharing not active");
return;
}
// Stop foreground service
Intent intent = new Intent(mContext, LocationSharingService.class);
mContext.stopService(intent);
mIsSharing = false;
mSessionId = null;
mEncryptionKey = null;
mShareUrl = null;
Logger.i(TAG, "Location sharing stopped");
}
public boolean isSharing()
{
return mIsSharing;
}
@Nullable
public String getShareUrl()
{
return mShareUrl;
}
@Nullable
public String getSessionId()
{
return mSessionId;
}
public void setUpdateIntervalSeconds(int seconds)
{
Config.LocationSharing.setUpdateInterval(seconds);
}
public int getUpdateIntervalSeconds()
{
return Config.LocationSharing.getUpdateInterval();
}
public void setServerBaseUrl(@NonNull String url)
{
Config.LocationSharing.setServerUrl(url);
}
@NonNull
public String getServerBaseUrl()
{
return Config.LocationSharing.getServerUrl();
}
/**
* Get current battery level (0-100).
*/
public int getBatteryLevel()
{
BatteryManager bm = (BatteryManager) mContext.getSystemService(Context.BATTERY_SERVICE);
if (bm == null)
return 100;
return bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
}
/**
* Check if currently navigating with an active route.
*/
public boolean isNavigating()
{
return RoutingController.get().isNavigating();
}
// Native methods (implemented in JNI)
/**
* Generate new session credentials (ID and encryption key).
* @return Array of [sessionId, encryptionKey]
*/
@Nullable
private static native String[] nativeGenerateSessionCredentials();
/**
* Generate shareable URL from credentials.
* @param sessionId Session ID (UUID)
* @param encryptionKey Base64-encoded encryption key
* @param serverBaseUrl Server base URL
* @return Share URL
*/
@Nullable
private static native String nativeGenerateShareUrl(String sessionId, String encryptionKey, String serverBaseUrl);
/**
* Encrypt location payload.
* @param encryptionKey Base64-encoded encryption key
* @param payloadJson JSON payload to encrypt
* @return Encrypted payload JSON (with iv, ciphertext, authTag) or null on failure
*/
@Nullable
public static native String nativeEncryptPayload(String encryptionKey, String payloadJson);
}

View File

@@ -1,146 +0,0 @@
package app.organicmaps.location;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import app.organicmaps.MwmActivity;
import app.organicmaps.R;
import app.organicmaps.sdk.routing.RoutingInfo;
import java.util.Locale;
/**
* Helper for creating and updating location sharing notifications.
*/
public class LocationSharingNotification
{
public static final String CHANNEL_ID = "LOCATION_SHARING";
private static final String CHANNEL_NAME = "Live Location Sharing";
private final Context mContext;
private final NotificationManagerCompat mNotificationManager;
public LocationSharingNotification(@NonNull Context context)
{
mContext = context;
mNotificationManager = NotificationManagerCompat.from(context);
createNotificationChannel();
}
private void createNotificationChannel()
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
return;
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID,
CHANNEL_NAME,
NotificationManager.IMPORTANCE_LOW); // Low importance = no sound/vibration
channel.setDescription("Notifications for active live location sharing");
channel.setShowBadge(false);
channel.enableLights(false);
channel.enableVibration(false);
NotificationManager nm = mContext.getSystemService(NotificationManager.class);
if (nm != null)
nm.createNotificationChannel(channel);
}
/**
* Build notification for location sharing service.
* @param stopIntent PendingIntent to stop sharing
* @return Notification object
*/
@NonNull
public Notification buildNotification(@NonNull PendingIntent stopIntent)
{
return buildNotification(stopIntent, null);
}
/**
* Build notification with copy URL action.
* @param stopIntent PendingIntent to stop sharing
* @param copyUrlIntent PendingIntent to copy URL (optional)
* @return Notification object
*/
@NonNull
public Notification buildNotification(
@NonNull PendingIntent stopIntent,
@Nullable PendingIntent copyUrlIntent)
{
Intent notificationIntent = new Intent(mContext, MwmActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
mContext,
0,
notificationIntent,
PendingIntent.FLAG_IMMUTABLE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_share)
.setContentIntent(pendingIntent)
.setOngoing(true)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setShowWhen(false)
.setAutoCancel(false);
// Title
builder.setContentTitle(mContext.getString(R.string.location_sharing_active));
// No subtitle - keep it simple
// Copy URL action button (if provided)
if (copyUrlIntent != null)
{
builder.addAction(
R.drawable.ic_share,
mContext.getString(R.string.location_sharing_copy_url),
copyUrlIntent);
}
// Stop action button
builder.addAction(
R.drawable.ic_close,
mContext.getString(R.string.location_sharing_stop),
stopIntent);
// Set foreground service type for Android 10+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{
builder.setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE);
}
return builder.build();
}
/**
* Update existing notification.
* @param notificationId Notification ID
* @param notification Updated notification
*/
public void updateNotification(int notificationId, @NonNull Notification notification)
{
mNotificationManager.notify(notificationId, notification);
}
/**
* Cancel notification.
* @param notificationId Notification ID
*/
public void cancelNotification(int notificationId)
{
mNotificationManager.cancel(notificationId);
}
}

View File

@@ -1,366 +0,0 @@
package app.organicmaps.location;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import app.organicmaps.MwmActivity;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.api.LocationSharingApiClient;
import app.organicmaps.sdk.location.LocationHelper;
import app.organicmaps.sdk.location.LocationListener;
import app.organicmaps.sdk.routing.RoutingController;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.util.log.Logger;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Locale;
/**
* Foreground service for live GPS location sharing.
* Monitors location updates and posts encrypted data to server at regular intervals.
*/
public class LocationSharingService extends Service implements LocationListener
{
private static final String TAG = LocationSharingService.class.getSimpleName();
private static final int NOTIFICATION_ID = 0x1002; // Unique ID for location sharing
// Intent extras
public static final String EXTRA_SESSION_ID = "session_id";
public static final String EXTRA_ENCRYPTION_KEY = "encryption_key";
public static final String EXTRA_SERVER_URL = "server_url";
public static final String EXTRA_UPDATE_INTERVAL = "update_interval";
// Actions for notification buttons
private static final String ACTION_STOP = "app.organicmaps.ACTION_STOP_LOCATION_SHARING";
private static final String ACTION_COPY_URL = "app.organicmaps.ACTION_COPY_LOCATION_URL";
@Nullable
private String mSessionId;
@Nullable
private String mEncryptionKey;
@Nullable
private String mServerUrl;
private int mUpdateIntervalSeconds = 20;
@Nullable
private Location mLastLocation;
private long mLastUpdateTimestamp = 0;
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final Runnable mUpdateTask = this::processLocationUpdate;
@Nullable
private LocationSharingApiClient mApiClient;
@Nullable
private LocationSharingNotification mNotificationHelper;
@Override
public void onCreate()
{
super.onCreate();
Logger.i(TAG, "Service created");
mNotificationHelper = new LocationSharingNotification(this);
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId)
{
if (intent == null)
{
Logger.w(TAG, "Null intent, stopping service");
stopSelf();
return START_NOT_STICKY;
}
// Handle stop action from notification
if (ACTION_STOP.equals(intent.getAction()))
{
Logger.i(TAG, "Stop action received from notification");
LocationSharingManager.getInstance().stopSharing();
stopSelf();
return START_NOT_STICKY;
}
// Handle copy URL action from notification
if (ACTION_COPY_URL.equals(intent.getAction()))
{
Logger.i(TAG, "Copy URL action received from notification");
String shareUrl = LocationSharingManager.getInstance().getShareUrl();
if (shareUrl != null)
{
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
android.content.ClipData clip = android.content.ClipData.newPlainText("Location Share URL", shareUrl);
clipboard.setPrimaryClip(clip);
android.widget.Toast.makeText(this, R.string.location_sharing_url_copied, android.widget.Toast.LENGTH_SHORT).show();
}
return START_STICKY;
}
// Extract session info
mSessionId = intent.getStringExtra(EXTRA_SESSION_ID);
mEncryptionKey = intent.getStringExtra(EXTRA_ENCRYPTION_KEY);
mServerUrl = intent.getStringExtra(EXTRA_SERVER_URL);
mUpdateIntervalSeconds = intent.getIntExtra(EXTRA_UPDATE_INTERVAL, 20);
if (mSessionId == null || mEncryptionKey == null || mServerUrl == null)
{
Logger.e(TAG, "Missing session info, stopping service");
stopSelf();
return START_NOT_STICKY;
}
// Initialize API client
mApiClient = new LocationSharingApiClient(mServerUrl, mSessionId);
// Create session on server
mApiClient.createSession(new LocationSharingApiClient.Callback()
{
@Override
public void onSuccess()
{
Logger.i(TAG, "Session created on server");
}
@Override
public void onFailure(@NonNull String error)
{
Logger.w(TAG, "Failed to create session on server: " + error);
}
});
// Start foreground with notification
Notification notification = mNotificationHelper != null
? mNotificationHelper.buildNotification(getStopIntent(), getCopyUrlIntent())
: buildFallbackNotification();
startForeground(NOTIFICATION_ID, notification);
// Register for location updates
LocationHelper locationHelper = MwmApplication.sInstance.getLocationHelper();
locationHelper.addListener(this);
Logger.i(TAG, "Service started for session: " + mSessionId);
return START_STICKY;
}
@Override
public void onDestroy()
{
Logger.i(TAG, "Service destroyed");
// Unregister location listener
LocationHelper locationHelper = MwmApplication.sInstance.getLocationHelper();
locationHelper.removeListener(this);
// Cancel pending updates
mHandler.removeCallbacks(mUpdateTask);
// Send session end to server (optional)
if (mApiClient != null && mSessionId != null)
mApiClient.endSession();
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent)
{
return null; // Not a bound service
}
// LocationHelper.LocationListener implementation
@Override
public void onLocationUpdated(@NonNull Location location)
{
mLastLocation = location;
// No need to update notification - it's simple and static now
// Schedule update if needed
scheduleUpdate();
}
// Private methods
private void scheduleUpdate()
{
long now = System.currentTimeMillis();
long timeSinceLastUpdate = (now - mLastUpdateTimestamp) / 1000; // Convert to seconds
if (timeSinceLastUpdate >= mUpdateIntervalSeconds)
{
// Remove any pending updates
mHandler.removeCallbacks(mUpdateTask);
// Execute immediately
mHandler.post(mUpdateTask);
}
}
private void processLocationUpdate()
{
if (mLastLocation == null || mEncryptionKey == null || mApiClient == null)
return;
// Check battery level
int batteryLevel = getBatteryLevel();
if (batteryLevel < 10)
{
Logger.w(TAG, "Battery level too low (" + batteryLevel + "%), stopping sharing");
LocationSharingManager.getInstance().stopSharing();
stopSelf();
return;
}
// Build payload JSON
JSONObject payload = buildPayloadJson(mLastLocation, batteryLevel);
if (payload == null)
return;
// Encrypt payload
String encryptedJson = LocationCrypto.encrypt(mEncryptionKey, payload.toString());
if (encryptedJson == null)
{
Logger.e(TAG, "Failed to encrypt payload");
return;
}
// Send to server
mApiClient.updateLocation(encryptedJson, new LocationSharingApiClient.Callback()
{
@Override
public void onSuccess()
{
Logger.d(TAG, "Location update sent successfully");
mLastUpdateTimestamp = System.currentTimeMillis();
}
@Override
public void onFailure(@NonNull String error)
{
Logger.w(TAG, "Failed to send location update: " + error);
}
});
}
@Nullable
private JSONObject buildPayloadJson(@NonNull Location location, int batteryLevel)
{
try
{
JSONObject json = new JSONObject();
json.put("timestamp", System.currentTimeMillis() / 1000); // Unix timestamp
json.put("lat", location.getLatitude());
json.put("lon", location.getLongitude());
json.put("accuracy", location.getAccuracy());
if (location.hasSpeed())
json.put("speed", location.getSpeed());
if (location.hasBearing())
json.put("bearing", location.getBearing());
// Check if navigating
RoutingInfo routingInfo = getNavigationInfo();
if (routingInfo != null && routingInfo.distToTarget != null)
{
json.put("mode", "navigation");
// Calculate ETA (current time + time remaining)
if (routingInfo.totalTimeInSeconds > 0)
{
long etaTimestamp = (System.currentTimeMillis() / 1000) + routingInfo.totalTimeInSeconds;
json.put("eta", etaTimestamp);
}
// Distance remaining in meters
if (routingInfo.distToTarget != null)
{
json.put("distanceRemaining", routingInfo.distToTarget.mDistance);
}
}
else
{
json.put("mode", "standalone");
}
json.put("batteryLevel", batteryLevel);
return json;
}
catch (JSONException e)
{
Logger.e(TAG, "Failed to build payload JSON", e);
return null;
}
}
@Nullable
private RoutingInfo getNavigationInfo()
{
if (!RoutingController.get().isNavigating())
return null;
return RoutingController.get().getCachedRoutingInfo();
}
private int getBatteryLevel()
{
BatteryManager bm = (BatteryManager) getSystemService(BATTERY_SERVICE);
if (bm == null)
return 100;
return bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
}
@NonNull
private PendingIntent getStopIntent()
{
Intent stopIntent = new Intent(this, LocationSharingService.class);
stopIntent.setAction(ACTION_STOP);
return PendingIntent.getService(this, 0, stopIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
}
@NonNull
private PendingIntent getCopyUrlIntent()
{
Intent copyIntent = new Intent(this, LocationSharingService.class);
copyIntent.setAction(ACTION_COPY_URL);
return PendingIntent.getService(this, 1, copyIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
}
@NonNull
private Notification buildFallbackNotification()
{
Intent notificationIntent = new Intent(this, MwmActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent,
PendingIntent.FLAG_IMMUTABLE);
return new NotificationCompat.Builder(this, LocationSharingNotification.CHANNEL_ID)
.setContentTitle(getString(R.string.location_sharing_active))
.setSmallIcon(R.drawable.ic_share)
.setContentIntent(pendingIntent)
.setOngoing(true)
.build();
}
}

View File

@@ -322,8 +322,7 @@ public class MapButtonsController extends Fragment
mBadgeDrawable.setVisible(count > 0);
BadgeUtils.attachBadgeDrawable(mBadgeDrawable, menuButton);
final boolean isTrackRecording = TrackRecorder.nativeIsTrackRecordingEnabled();
updateMenuBadge(isTrackRecording);
updateMenuBadge(TrackRecorder.nativeIsTrackRecordingEnabled());
}
public void updateLayerButton()

View File

@@ -16,7 +16,6 @@ public class MapButtonsViewModel extends ViewModel
private final MutableLiveData<SearchWheel.SearchOption> mSearchOption = new MutableLiveData<>();
private final MutableLiveData<Boolean> mTrackRecorderState =
new MutableLiveData<>(TrackRecorder.nativeIsTrackRecordingEnabled());
private final MutableLiveData<Boolean> mLocationSharingState = new MutableLiveData<>(false);
public MutableLiveData<Boolean> getButtonsHidden()
{
@@ -87,14 +86,4 @@ public class MapButtonsViewModel extends ViewModel
{
return mTrackRecorderState;
}
public void setLocationSharingState(boolean state)
{
mLocationSharingState.setValue(state);
}
public MutableLiveData<Boolean> getLocationSharingState()
{
return mLocationSharingState;
}
}

View File

@@ -205,11 +205,6 @@ public class NavigationController implements TrafficManager.TrafficCallback, Nav
mNavMenu.refreshTts();
}
public void refreshShareLocationColor()
{
mNavMenu.updateShareLocationColor();
}
@Override
public void onEnabled()
{

View File

@@ -26,10 +26,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import app.organicmaps.MwmActivity;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.location.LocationSharingDialog;
import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.bookmarks.data.DistanceAndAzimut;
import app.organicmaps.sdk.routing.RouteMarkData;
@@ -146,9 +144,6 @@ final class RoutingBottomMenuController implements View.OnClickListener
mActionButton.setOnClickListener(this);
View actionSearchButton = actionFrame.findViewById(R.id.btn__search_point);
actionSearchButton.setOnClickListener(this);
View shareLocationButton = actionFrame.findViewById(R.id.btn__share_location);
if (shareLocationButton != null)
shareLocationButton.setOnClickListener(this);
mActionIcon = mActionButton.findViewById(R.id.iv__icon);
UiUtils.hide(mAltitudeChartFrame, mActionFrame);
mListener = listener;
@@ -477,11 +472,6 @@ final class RoutingBottomMenuController implements View.OnClickListener
final RouteMarkType pointType = (RouteMarkType) mActionMessage.getTag();
mListener.onSearchRoutePoint(pointType);
}
else if (id == R.id.btn__share_location)
{
if (mContext instanceof MwmActivity)
LocationSharingDialog.show(((MwmActivity) mContext).getSupportFragmentManager());
}
else if (id == R.id.btn__manage_route)
mListener.onManageRouteOpen();
else if (id == R.id.btn__save)

View File

@@ -8,7 +8,6 @@ import android.os.Bundle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.EditTextPreference;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
@@ -74,7 +73,6 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La
initScreenSleepEnabledPrefsCallbacks();
initShowOnLockScreenPrefsCallbacks();
initLeftButtonPrefs();
initLocationSharingPrefsCallbacks();
}
private void initLeftButtonPrefs()
@@ -544,29 +542,6 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La
category.removePreference(preference);
}
private void initLocationSharingPrefsCallbacks()
{
// Server URL preference
final EditTextPreference serverUrlPref = getPreference(getString(R.string.pref_location_sharing_server_url));
serverUrlPref.setText(Config.LocationSharing.getServerUrl());
serverUrlPref.setSummary(Config.LocationSharing.getServerUrl());
serverUrlPref.setOnPreferenceChangeListener((preference, newValue) -> {
String url = (String) newValue;
Config.LocationSharing.setServerUrl(url);
serverUrlPref.setSummary(url);
return true;
});
// Update interval preference
final ListPreference intervalPref = getPreference(getString(R.string.pref_location_sharing_update_interval));
intervalPref.setValue(String.valueOf(Config.LocationSharing.getUpdateInterval()));
intervalPref.setOnPreferenceChangeListener((preference, newValue) -> {
int seconds = Integer.parseInt((String) newValue);
Config.LocationSharing.setUpdateInterval(seconds);
return true;
});
}
@Override
public void onLanguageSelected(Language language)
{

View File

@@ -5,7 +5,6 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import app.organicmaps.R;
import app.organicmaps.location.LocationSharingDialog;
import app.organicmaps.sdk.routing.RoutingInfo;
import app.organicmaps.sdk.sound.TtsPlayer;
import app.organicmaps.sdk.util.DateUtils;
@@ -27,7 +26,6 @@ public class NavMenu
private final View mHeaderFrame;
private final ShapeableImageView mTts;
private final ShapeableImageView mShareLocation;
private final MaterialTextView mEtaValue;
private final MaterialTextView mEtaAmPm;
private final MaterialTextView mTimeHourValue;
@@ -99,16 +97,12 @@ public class NavMenu
mRouteProgress = bottomFrame.findViewById(R.id.navigation_progress);
// Bottom frame buttons
mShareLocation = bottomFrame.findViewById(R.id.share_location);
mShareLocation.setOnClickListener(v -> onShareLocationClicked());
ShapeableImageView mSettings = bottomFrame.findViewById(R.id.settings);
mSettings.setOnClickListener(v -> onSettingsClicked());
mTts = bottomFrame.findViewById(R.id.tts_volume);
mTts.setOnClickListener(v -> onTtsClicked());
MaterialButton stop = bottomFrame.findViewById(R.id.stop);
stop.setOnClickListener(v -> onStopClicked());
updateShareLocationColor();
}
private void onStopClicked()
@@ -116,22 +110,6 @@ public class NavMenu
mNavMenuListener.onStopClicked();
}
private void onShareLocationClicked()
{
LocationSharingDialog.show(mActivity.getSupportFragmentManager());
// Update color after dialog is shown (in case state changes)
mShareLocation.postDelayed(this::updateShareLocationColor, 500);
}
public void updateShareLocationColor()
{
final boolean isLocationSharing = app.organicmaps.location.LocationSharingManager.getInstance().isSharing();
final int color = isLocationSharing
? androidx.core.content.ContextCompat.getColor(mActivity, R.color.active_location_sharing)
: app.organicmaps.util.ThemeUtils.getColor(mActivity, R.attr.iconTint);
mShareLocation.setImageTintList(android.content.res.ColorStateList.valueOf(color));
}
private void onSettingsClicked()
{
mNavMenuListener.onSettingsClicked();

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/base_accent"/>
<solid android:color="@color/bg_primary"/>
<corners android:radius="4dp"/>
</shape>

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<!-- Location pin with share icon -->
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z"/>
<!-- Share arrows (smaller, overlaid) -->
<path
android:fillColor="@android:color/white"
android:pathData="M18,16l-3,3v-2H9v-2h6v-2z"
android:fillAlpha="0.8"/>
</vector>

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="12dp" />
<solid android:color="@color/active_location_sharing" />
</shape>

View File

@@ -24,7 +24,7 @@
app:layout_constraintTop_toBottomOf="@+id/statutbar"
app:layout_constraintStart_toEndOf="@+id/nav_next_turn_container"
android:clickable="true"
app:cardBackgroundColor="?colorSecondary">
app:cardBackgroundColor="?colorPrimary">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/nav_street_height"
@@ -37,7 +37,7 @@
android:maxLines="2"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:textColor="?android:textColorPrimaryInverse"
android:textColor="@android:color/white"
tools:text="Sample street name.\nLong looooooooong!!!!"/>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
@@ -73,12 +73,13 @@
android:theme="?navigationTheme"
android:layout_width="@dimen/nav_next_turn_sign"
android:layout_height="@dimen/nav_next_turn_sign"
app:tint="?iconTint"
app:tint="@android:color/white"
tools:background="#400000FF"/>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/circle_exit"
style="@style/MwmWidget.TextView.NavNextTurn.Exit"
android:textColor="@android:color/white"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
@@ -93,6 +94,7 @@
android:layout_marginBottom="@dimen/nav_next_turn_bottom"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:textColor="@android:color/white"
tools:text="9999 ft"/>
</LinearLayout>
@@ -130,7 +132,7 @@
app:layout_constraintTop_toBottomOf="@id/street_frame"
app:lanesActiveLaneTintColor="?navLaneArrowActiveColor"
app:lanesInactiveLaneTintColor="?navLaneArrowInactiveColor"
app:lanesBackgroundColor="?colorSecondary"
app:lanesBackgroundColor="?colorPrimary"
app:lanesCornerRadius="@dimen/margin_quarter"
app:lanesEditModeLanesCount="10"
tools:visibility="visible" />

View File

@@ -25,8 +25,7 @@
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:layout_weight="1"
android:layout_height="wrap_content"
app:endIconMode="clear_text">
android:layout_height="wrap_content">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/edit_socket_power"
@@ -46,9 +45,7 @@
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:layout_weight="1"
android:layout_height="wrap_content"
app:endIconMode="clear_text"
>
android:layout_height="wrap_content">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/edit_socket_count"

View File

@@ -1,83 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- Status Text -->
<TextView
android:id="@+id/status_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textColor="?android:textColorPrimary"
android:paddingBottom="8dp"
tools:text="Location sharing is not active" />
<!-- Description -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/location_sharing_description"
android:textSize="14sp"
android:textColor="?android:textColorSecondary"
android:paddingBottom="16dp" />
<!-- Share URL (visible only when sharing) -->
<TextView
android:id="@+id/share_url_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12sp"
android:textColor="?android:textColorPrimary"
android:fontFamily="monospace"
android:background="?android:selectableItemBackground"
android:padding="12dp"
android:textIsSelectable="true"
android:visibility="gone"
tools:visibility="visible"
tools:text="https://live.organicmaps.app/live/abc123def456" />
<!-- Button Row -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="end"
android:paddingTop="16dp">
<!-- Copy Button -->
<Button
android:id="@+id/copy_button"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/location_sharing_copy_url"
android:visibility="gone"
tools:visibility="visible" />
<!-- Share Button -->
<Button
android:id="@+id/share_button"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/location_sharing_share_url"
android:visibility="gone"
android:layout_marginStart="8dp"
tools:visibility="visible" />
<!-- Start/Stop Button -->
<Button
android:id="@+id/start_stop_button"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
tools:text="Start Sharing" />
</LinearLayout>
</LinearLayout>

View File

@@ -64,8 +64,7 @@
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/cv__charging_station"
style="@style/MwmWidget.Editor.CardView"
android:visibility="gone">
style="@style/MwmWidget.Editor.CardView">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -195,7 +194,7 @@
android:layout_marginTop="@dimen/margin_quarter"
android:gravity="center_vertical"
android:textAppearance="@style/MwmTextAppearance.Body1"
tools:text="Italian, russian, russian, russian, russian, russian, russian, russian, russian"
tools:text="italian, russian, coffee_shop, sandwich, dessert, cake, regional, sausage, sandwich, breakfast, pizza"
app:drawableEndCompat="@drawable/ic_arrow_down" />
<View
android:layout_width="match_parent"

View File

@@ -6,7 +6,7 @@
android:layout_height="@dimen/height_item_oneline"
android:background="?clickableBackground"
android:paddingStart="@dimen/margin_half_plus"
android:paddingEnd="@dimen/margin_half">
android:paddingEnd="@dimen/margin_half_plus">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/phone_icon"
@@ -15,14 +15,15 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toStartOf="@+id/phone_input"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_phone"/>
app:srcCompat="@drawable/ic_phone"
tools:ignore="ContentDescription" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/phone_input"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_half"
android:layout_marginEnd="@dimen/margin_half"
android:layout_toStartOf="@id/delete_icon"
android:textColorHint="?android:textColorSecondary"
app:layout_constraintBottom_toBottomOf="parent"
@@ -41,13 +42,11 @@
android:id="@+id/delete_icon"
style="@style/MwmWidget.Editor.MetadataIcon"
android:layout_marginStart="@dimen/margin_half"
android:layout_marginTop="@dimen/margin_half"
android:layout_marginEnd="@dimen/margin_half"
android:layout_marginBottom="@dimen/margin_half"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_delete" />
app:layout_constraintStart_toEndOf="@+id/phone_input"
app:srcCompat="@drawable/ic_delete"
tools:ignore="ContentDescription" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -58,7 +58,7 @@
android:textStyle="italic"
android:maxLines="2"
android:ellipsize="end"
tools:text="Russia, Moscow &amp; Central, Moscow"/>
tools:text="1, Rue des Carrières, Québec, G1R 4P5"/>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/distance"

View File

@@ -43,17 +43,6 @@
android:paddingEnd="@dimen/nav_bottom_gap"
tools:background="#300000FF">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/share_location"
android:layout_width="0dp"
android:layout_height="@dimen/nav_icon_size"
android:layout_weight="0.2"
android:background="?selectableItemBackgroundBorderless"
android:scaleType="center"
android:contentDescription="@string/location_sharing_title"
app:srcCompat="@drawable/ic_share"
app:tint="?iconTint" />
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/tts_volume"
android:layout_width="0dp"

View File

@@ -24,7 +24,7 @@
android:elevation="@dimen/nav_elevation"
app:layout_constraintTop_toBottomOf="@+id/statutbar"
android:clickable="true"
app:cardBackgroundColor="?colorSecondary">
app:cardBackgroundColor="?colorPrimary">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -39,7 +39,7 @@
android:minHeight="60dp"
android:layout_gravity="center_vertical"
android:gravity="center"
android:textColor="?android:textColorPrimaryInverse"
android:textColor="@android:color/white"
tools:text="Sample street name.\nLong looooooooong!!!!"/>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
@@ -75,7 +75,7 @@
android:theme="?navigationTheme"
android:layout_width="@dimen/nav_next_turn_sign"
android:layout_height="@dimen/nav_next_turn_sign"
app:tint="?iconTint"
app:tint="@android:color/white"
tools:background="#400000FF"/>
<com.google.android.material.textview.MaterialTextView
@@ -84,6 +84,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="@android:color/white"
tools:text="9"/>
</FrameLayout>
@@ -95,6 +96,7 @@
android:layout_marginBottom="@dimen/nav_next_turn_bottom"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:textColor="@android:color/white"
tools:text="9999 ft"/>
</LinearLayout>

View File

@@ -57,27 +57,4 @@
app:srcCompat="@drawable/ic_location_crosshair"
tools:tint="?colorSecondary"/>
</LinearLayout>
<LinearLayout
android:id="@+id/btn__share_location"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:background="?clickableBackground"
tools:visibility="visible">
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_marginBottom="@dimen/margin_half"
android:layout_marginTop="@dimen/margin_half"
android:background="?dividerHorizontal"/>
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/iv__share_location_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_base"
app:srcCompat="@drawable/ic_share"
app:tint="?colorSecondary"
android:contentDescription="@string/location_sharing_title"/>
</LinearLayout>
</LinearLayout>

View File

@@ -349,7 +349,7 @@
<string name="search_history_text">Преглед на последните търсения.</string>
<string name="clear_search">Изчистване на историята на търсенията</string>
<string name="p2p_your_location">Вашето местоположение</string>
<string name="p2p_start">Начало</string>
<string name="p2p_start">Почна</string>
<string name="p2p_from_here">Маршрут от</string>
<string name="p2p_to_here">Маршрут към</string>
<string name="p2p_only_from_current">Навигацията е възможна само от текущото ви местоположение.</string>

View File

@@ -884,4 +884,8 @@
<string name="error_invalid_number">Neplatné číslo</string>
<string name="charge_socket_count">Počet</string>
<string name="unknown_count">neznámé</string>
<string name="offline_explanation_text">Pro prohlížení a navigaci v dané oblasti je nutné si stáhnout mapu.\nStáhněte si mapy oblastí, které chcete navštívit.</string>
<string name="editor_place_doesnt_exist_description">Popište, jak místo vypadá nyní a pošlete poznámku o chybě komunitě OpenStreetMap</string>
<string name="avoid_steps">Vyhnout se schodům</string>
<string name="offline_explanation_title">Offline mapy</string>
</resources>

View File

@@ -871,4 +871,25 @@
<string name="hours_confirmed_time_ago">Bestätigt %s</string>
<string name="pref_tts_no_system_tts_short">Kein Text-zu-Sprache-Modul gefunden, überprüfe die App-Einstellungen</string>
<string name="avoid_steps">Treppen vermeiden</string>
<string name="editor_place_doesnt_exist_description">Beschreibe wie der Ort jetzt aussieht um eine Fehlermeldung an die OpenStreetMap Community zu senden</string>
<string name="offline_explanation_title">Offline Karten</string>
<string name="offline_explanation_text">Um die Gegend anzusehen, muss eine Karte heruntergeladen werden.\nLaden Sie Karten für die Gebiete herunter, die Sie bereisen möchten.</string>
<string name="charge_socket_type2">Typ 2 (ohne Kabel)</string>
<string name="charge_socket_type2_cable">Typ 2 (mit Kabel)</string>
<string name="charge_socket_type2_combo">Typ 2 Combo</string>
<string name="charge_socket_type1">Typ 1</string>
<string name="charge_socket_nacs">NACS</string>
<string name="unknown_socket_type">Unbekannter Anschluss</string>
<string name="unknow_socket_type">Unbekannter Anschluss</string>
<string name="edit_socket_info_tooltip">Neue Anschlüsse erstellen oder Existierende bearbeiten.</string>
<string name="charging_station_available_sockets">Verfügbare Anschlüsse</string>
<string name="charge_socket_unknown_other">Andere oder unbekannt</string>
<string name="charge_socket_power">Leistung (kW)</string>
<string name="editor_socket">Anschluss bearbeiten</string>
<string name="error_value_must_be_positive">Wert muss positiv sein</string>
<string name="unknown_power_output">unbekannt</string>
<string name="charge_socket_chademo">CHAdeMO</string>
<string name="charge_socket_count">Anzahl</string>
<string name="unknown_count">unbekannt</string>
<string name="error_invalid_number">ungültige Zahl</string>
</resources>

View File

@@ -886,4 +886,15 @@
<string name="charge_socket_count">Recuento</string>
<string name="charge_socket_power">Potencia (kW)</string>
<string name="unknown_count">desconocido</string>
<string name="avoid_steps">Evitar escalones</string>
<string name="unknown_socket_type">enchufe desconocido</string>
<string name="unknow_socket_type">enchufe desconocido</string>
<string name="edit_socket_info_tooltip">Crear nuevo enchufe o editar existentes.</string>
<string name="charging_station_available_sockets">Enchufes disponibles</string>
<string name="charge_socket_unknown_other">Otros o desconocido</string>
<string name="editor_socket">Editar enchufe</string>
<string name="error_value_must_be_positive">El valor debe ser positivo</string>
<string name="error_invalid_number">Número inválido</string>
<string name="offline_explanation_title">Mapas Offline</string>
<string name="offline_explanation_text">Se debe descargar un mapa para ver y navegar el área\nDescarga mapas de las áreas que quieras navegar.</string>
</resources>

View File

@@ -884,4 +884,8 @@
<string name="error_value_must_be_positive">Sisestuse väärtus peab olema positiitve</string>
<string name="unknown_count">tundmatu</string>
<string name="error_invalid_number">Vigane number</string>
<string name="editor_place_doesnt_exist_description">Kirjelda selle koha praegust välimust ja lisa veamärge OpenStreetMapi kogukonnale</string>
<string name="avoid_steps">Väldi treppe</string>
<string name="offline_explanation_title">Ilma võrguühenduseta toimivad kaardid</string>
<string name="offline_explanation_text">Selles piirkonnas liikumiseks ja teekonna juhatamiseks pead vajaliku kaardi alla laadima.\nVali allalaaditav kaart selle piirkonna kohta.</string>
</resources>

View File

@@ -27,7 +27,7 @@
<!-- A dialog title, that warns a user that Precise Location is disabled and suggests to turn it on -->
<string name="limited_accuracy">Rajoitettu tarkkuus</string>
<!-- A dialog text, that warns a user that Precise Location is disabled and suggests to turn it on -->
<string name="precise_location_is_disabled_long_text">Tarkan navigoinnin varmistamiseksi ota käyttöön tarkka sijainti asetuksista</string>
<string name="precise_location_is_disabled_long_text">Tarkan navigoinnin varmistamiseksi ota Tarkka sijainti käyttöön asetuksissa</string>
<!-- View and button titles for accessibility -->
<string name="zoom_to_country">Näytä kartalla</string>
<!-- Message to display at the center of the screen when the country download has failed -->
@@ -164,9 +164,9 @@
<!-- Warning message when doing search around current position -->
<string name="unknown_current_position">Sijaintiasi ei ole vielä määritetty</string>
<!-- Alert message that we can't run Map Storage settings due to some reasons. -->
<string name="cant_change_this_setting">Kartan tallennusasetukset ovat poissa käytöstä</string>
<string name="cant_change_this_setting">Valitettavasti karttatallennustilaasetukset ovat tällä hetkellä poissa käytöstä</string>
<!-- Alert message that downloading is in progress. -->
<string name="downloading_is_active">Kartan lataus käynnissä</string>
<string name="downloading_is_active">Kartan lataus on parhaillaan käynnissä</string>
<!-- Share my position using SMS, %1$@ contains om:// and %2$@ https://comaps.app link WITHOUT NAME. @NOTE non-ascii symbols in the link will result in max 70 characters SMS instead of 140. -->
<string name="my_position_share_sms">Hei, katso sijaintini CoMaps-sovelluksessa! %1$s tai %2$s Eikö sinulla ole vielä offline-karttoja? Lataa ne täältä: https://www.comaps.app/download/</string>
<!-- Subject for emailed bookmark -->
@@ -342,16 +342,16 @@
<string name="dialog_routing_location_turn_on">Ota sijaintipalvelut käyttöön</string>
<string name="dialog_routing_location_unknown_turn_on">Tämänhetkisiä GPS-koordinaatteja ei löydy. Ota sijaintipalvelut käyttöön reitin laskemista varten.</string>
<string name="dialog_routing_unable_locate_route">Reitin paikannus ei onnistu</string>
<string name="dialog_routing_cant_build_route">Reitin luonti ei onnistu</string>
<string name="dialog_routing_cant_build_route">Reittiä ei voi luoda</string>
<string name="dialog_routing_change_start_or_end">Muuta aloituskohtaa tai määränpäätä.</string>
<string name="dialog_routing_change_start">Muuta aloituskohtaa</string>
<string name="dialog_routing_start_not_determined">Reittiä ei luotu. Aloituskohdan paikannus ei onnistu.</string>
<string name="dialog_routing_select_closer_start">Valitse lähempänä tietä oleva aloituskohta.</string>
<string name="dialog_routing_change_end">Muuta määränpäätä</string>
<string name="dialog_routing_end_not_determined">Reittiä ei luotu. Määränpään paikannus ei onnistu.</string>
<string name="dialog_routing_select_closer_end">Valitse lähempänä tietä oleva määränpää</string>
<string name="dialog_routing_change_intermediate">Välipisteen paikallistaminen ei onnistunut</string>
<string name="dialog_routing_intermediate_not_determined">Siirrä välipistettä</string>
<string name="dialog_routing_select_closer_end">Valitse lähempänä tietä sijaitseva määränpää</string>
<string name="dialog_routing_change_intermediate">Välikohtaa ei voi paikantaa</string>
<string name="dialog_routing_intermediate_not_determined">Säädä välikohtaasi</string>
<string name="dialog_routing_system_error">Järjestelmävirhe</string>
<string name="dialog_routing_application_error">Reittiä ei voi luoda sovellusvirheen vuoksi</string>
<string name="dialog_routing_try_again">Yritä uudelleen</string>
@@ -367,7 +367,7 @@
<string name="hide">Piilota</string>
<string name="categories">Luokat</string>
<string name="history">Historia</string>
<string name="search_not_found">Pahoittelut, hakutuloksia ei ole</string>
<string name="search_not_found">Hups, tuloksia ei löytynyt</string>
<!-- The message when user did not find anything in the search. -->
<string name="search_not_found_query">Lataa alue, jolta etsit, tai yritä lisätä läheisen kaupungin tai kylän nimi.</string>
<string name="search_history_title">Hakuhistoria</string>
@@ -379,7 +379,7 @@
<string name="p2p_start">Aloita</string>
<string name="p2p_from_here">Lähtöpaikka</string>
<string name="p2p_to_here">Reitin loppupiste</string>
<string name="p2p_only_from_current">Navigointi onnistuu vain nykyisestä sijainnistasi</string>
<string name="p2p_only_from_current">Navigointi on käytettävissä vain nykyisestä sijainnistasi</string>
<string name="p2p_reroute_from_current">Haluatko valita vaihtoehtoisen reitin?</string>
<!-- Edit open hours/set time and minutes dialog -->
<string name="next_button">Seuraava</string>
@@ -451,7 +451,7 @@
<string name="common_check_internet_connection_dialog">Varmista, että laitteesi on yhteydessä Internetiin</string>
<string name="downloader_no_space_title">Ei tarpeeksi tilaa</string>
<string name="downloader_no_space_message">Poista tarpeeton data</string>
<string name="editor_login_error_dialog">Kirjautumisvirhe</string>
<string name="editor_login_error_dialog">Sisäänkirjautumisvirhe</string>
<string name="editor_profile_changes">Vahvistetut karttamuutokset</string>
<string name="editor_focus_map_on_location">Aseta risti paikan tai yrityksen sijaintiin vetämällä karttaa.</string>
<string name="editor_edit_place_title">Muokkaus</string>
@@ -471,7 +471,7 @@
<!-- Downloaded 10 **of** 20 <- it is that "of" -->
<string name="downloader_of">%1$d/%2$d</string>
<string name="download_over_mobile_header">Lataa käyttämällä puhelinverkkoyhteyttä?</string>
<string name="download_over_mobile_message">Tämä vaihtoehto saattaa olla huomattavasti kalliimpi tietyillä sopimuksilla tai roaming-yhteydellä</string>
<string name="download_over_mobile_message">Tämä vaihtoehto saattaa olla huomattavasti kalliimpi tietyillä sopimuksilla tai verkkovierailunyhteydellä</string>
<string name="error_enter_correct_house_number">Syötä oikea talon numero</string>
<!-- Error message in Editor when a user tries to set the number of floors for a building higher than %d floors -->
<string name="error_enter_correct_storey_number">Kerrosten määrä saa olla korkeintaan %d</string>
@@ -492,7 +492,7 @@
<string name="editor_category_unsuitable_title">Etkö löydä sopivaa luokkaa?</string>
<string name="editor_category_unsuitable_text">CoMaps mahdollistaa vain yksinkertaisten pisteluokkien lisäämisen, eli ei kaupunkeja, teitä, järviä, rakennusten ääriviivoja jne. Lisää tällaiset luokat suoraan <a href="https://www.openstreetmap.org">OpenStreetMap.org</a>. Tarkista <a href="https://www.comaps.app/support/advanced-map-editing/">oppaastamme</a> yksityiskohtaiset ohjeet vaihe vaiheelta.</string>
<string name="downloader_no_downloaded_maps_title">Et ole ladannut yhtään karttaa</string>
<string name="downloader_no_downloaded_maps_message">Lataa karttoja löytääksesi paikkoja ja navigoidaksesi offline-tilassa</string>
<string name="downloader_no_downloaded_maps_message">Lataa karttoja ei-verkkotilassa etsimistä ja navigoimista varten</string>
<string name="current_location_unknown_error_title">Nykyinen sijainti on tuntematon</string>
<!-- abbreviation for kilometers per hour -->
<string name="kilometers_per_hour">km/h</string>
@@ -523,8 +523,8 @@
<!-- Displayed when saving some edits to the map to warn against publishing personal data -->
<string name="editor_share_to_all_dialog_title">Haluatko lähettää sen kaikille käyttäjille?</string>
<!-- Dialog before publishing the modifications to the public map. -->
<string name="editor_share_to_all_dialog_message_1">Varmista, ettet syöttänyt henkilökohtaisia tietojasi</string>
<string name="editor_share_to_all_dialog_message_2">OpenStreetMap-editorit tarkistavat muutokset ja ottavat sinuun yhteyttä, jos heillä on kysyttävää</string>
<string name="editor_share_to_all_dialog_message_1">Varmista, ettet ole syöttänyt yksityisiä tai henkilökohtaisia tietoja</string>
<string name="editor_share_to_all_dialog_message_2">OpenStreetMap-muokkaimet tarkistavat muutokset ja ottavat sinuun yhteyttä, jos niillä on kysyttävää</string>
<string name="navigation_stop_button">Lopeta</string>
<!-- Shown as toast when starting the recent track recording -->
<string name="track_recording">Reitin kirjaaminen</string>
@@ -538,7 +538,7 @@
<string name="mobile_data_option_not_today">Älä käytä tänään</string>
<string name="mobile_data">Mobiili-internet</string>
<!-- NOTE to translators: please synchronize your translation with the English one. -->
<string name="mobile_data_description">Mobiili-internet vaaditaan paikkojen lisätietojen, kuten valokuvien, hintojen ja arvioiden näyttämiseen</string>
<string name="mobile_data_description">Mobiili-internet vaaditaan karttapäivitysilmoituksiin ja muokkausten lataamiseen ulospäin</string>
<string name="mobile_data_option_never">Älä käytä koskaan</string>
<string name="mobile_data_option_ask">Kysy aina</string>
<string name="traffic_update_maps_text">Liikennetietojen näyttämiseksi kartat on päivitettävä</string>
@@ -621,7 +621,7 @@
<!-- Speed camera settings menu option - Never warn (about speedcams) -->
<string name="pref_tts_speedcams_never">Älä koskaan varoita</string>
<string name="power_managment_title">Virransäästötila</string>
<string name="power_managment_description">Yritä vähentää virrankulutusta toiminnallisuuden kustannuksella</string>
<string name="power_managment_description">Yritä vähentää virrankulutusta joidenkin toimintojen kustannuksella</string>
<string name="power_managment_setting_never">Ei koskaan</string>
<string name="power_managment_setting_auto">Automaattinen</string>
<string name="power_managment_setting_manual_max">Täysi virransäästö</string>
@@ -635,7 +635,7 @@
<string name="avoid_ferry">Vältä lautan käyttöä</string>
<string name="avoid_motorways">Vältä moottoritietä</string>
<string name="unable_to_calc_alert_title">Reittiä ei voi luoda</string>
<string name="unable_to_calc_alert_subtitle">Valitettavasti emme voineet luoda reittiä valituilla vaihtoehdoilla. Tämä voi johtua reittiasetuksista tai OpenStreetMap:n puuttuvista tiedoista. Vaihda reititysasetuksia ja yritä uudelleen.</string>
<string name="unable_to_calc_alert_subtitle">Reittiä ei löytynyt. Tämä voi johtua reititysasetuksistasi tai puutteellisista OpenStreetMap-tiedoista. Muuta reititysvaihtoehtoja ja yritä uudelleen.</string>
<string name="define_to_avoid_btn">Määritä vältettävät tiet</string>
<string name="change_driving_options_btn">Reititysvalinnat ovat päällä</string>
<string name="toll_road">Maksullinen tie</string>
@@ -870,4 +870,24 @@
<string name="hours_confirmed_time_ago">Vahvistettu %s</string>
<string name="existence_confirmed_time_ago">Olemassaolo vahvistettu %s</string>
<string name="pref_tts_no_system_tts_short">Tekstistä puheeksi -moottoria ei löytynyt, tarkista sovelluksen asetukset</string>
<string name="unknown_power_output">tuntematon</string>
<string name="charge_socket_count">Lukumäärä</string>
<string name="unknown_count">tuntematon</string>
<string name="error_invalid_number">Ei kelvollinen numero</string>
<string name="offline_explanation_title">Ei-verkkotilassa olevat kartat</string>
<string name="editor_place_doesnt_exist_description">Kuvaile, miltä paikka näyttää nyt, lähettääksesi virheilmoituksen OpenStreetMap-yhteisölle</string>
<string name="avoid_steps">Vältä portaita</string>
<string name="charge_socket_type2">Tyyppi 2 (ei kaapelia)</string>
<string name="charge_socket_type2_cable">Tyyppi 2 (w/ -kaapeli)</string>
<string name="charge_socket_type2_combo">Tyyppi 2 combo</string>
<string name="charge_socket_type1">Tyyppi 1</string>
<string name="unknown_socket_type">tuntematon pistoke</string>
<string name="unknow_socket_type">tuntematon pistoke</string>
<string name="edit_socket_info_tooltip">Luo uusia pistokkeita tai muokkaa olemassa olevia.</string>
<string name="charging_station_available_sockets">Saatavilla olevat pistokkeet</string>
<string name="charge_socket_unknown_other">Muu tai tuntematon</string>
<string name="charge_socket_power">Teho (kW)</string>
<string name="editor_socket">Muokkaa pistoketta</string>
<string name="error_value_must_be_positive">Arvon on oltava positiivinen</string>
<string name="offline_explanation_text">Alueen katseluun ja navigointiin tarvitaan kartta.\nLataa karttoja alueille, joille haluat matkustaa.</string>
</resources>

View File

@@ -622,4 +622,8 @@
<string name="charging_station_available_sockets">Enganches dispoñibles</string>
<string name="charge_socket_unknown_other">Outro ou descoñecido</string>
<string name="unknow_socket_type">engache descoñecido</string>
<string name="editor_place_doesnt_exist_description">Describe a aparencia do lugar para enviar unha nota co erro á comunidade OpenStreetMap</string>
<string name="avoid_steps">Evitar pasos</string>
<string name="offline_explanation_title">Mapas sen conexión</string>
<string name="offline_explanation_text">Hai que descargar un mapa para ver e navegar polo área.\nDescarga os mapas para as zonas polas que vas viaxar.</string>
</resources>

View File

@@ -52,11 +52,11 @@
<string name="disconnect_usb_cable">A CoMaps használatához válassza le az USB-kábelt vagy helyezze be a memóriakártyát</string>
<!-- Used in DownloadResources startup screen -->
<string name="not_enough_free_space_on_sdcard">Az alkalmazás használatához először szabadítson fel némi helyet az SD-kártyán/USB-tárolón</string>
<string name="download_resources">Mielőtt elkezdené használni az alkalmazást, töltse le az áttekintő világtérképet az eszközre. \nEz %s tárhelyet fog igénybe venni.</string>
<string name="download_resources">Mielőtt elkezdené használni az alkalmazást, töltse le az áttekintő világtérképet az eszközére.\nEz %s tárhelyet fog igénybe venni.</string>
<string name="download_resources_continue">Ugrás a térképre</string>
<string name="downloading_country_can_proceed">%1$s (%2$s) letöltése. Most már\ntovábbléphet a térképre.</string>
<string name="download_country_ask">Letölti a következőt: %1$s? (%2$s)</string>
<string name="update_country_ask">Frissíti a következőt: %1$s? (%2$s)</string>
<string name="download_country_ask">Biztosan letölti a következőt: %1$s? (%2$s)</string>
<string name="update_country_ask">Biztosan frissíti a következőt: %1$s? (%2$s)</string>
<!-- REMOVE THIS STRING AFTER REFACTORING -->
<string name="pause">Szüneteltetés</string>
<!-- REMOVE THIS STRING AFTER REFACTORING -->
@@ -88,7 +88,7 @@
<!-- Free space out of total storage size in Maps Storage settings, e.g. "300 MB free of 2 GB" -->
<string name="maps_storage_free_size">%1$s szabad terület ennyiből: %2$s</string>
<!-- Question dialog for transferring maps from one storage to another -->
<string name="move_maps">Áthelyezi a térképeket?</string>
<string name="move_maps">Biztosan áthelyezi a térképeket?</string>
<!-- Error moving map files from one storage to another -->
<string name="move_maps_error">Hiba történt a térképfájlok áthelyezésekor</string>
<!-- Ask user to wait several minutes (some long process in modal dialog). -->
@@ -225,7 +225,7 @@
<string name="placepage_distance">Távolság</string>
<string name="search_show_on_map">Megtekintés a térképen</string>
<!-- Text in menu -->
<string name="website">Honlap</string>
<string name="website">Webhely</string>
<!-- Text in About menu, opens CoMaps news website -->
<string name="news">Hírek</string>
<!-- Settings: Send feedback button and dialog title -->
@@ -245,9 +245,9 @@
<!-- Text in menu + Button in the main Help dialog -->
<string name="report_a_bug">Hibajelentés</string>
<!-- Toast text when compass calibration may improve the correctness of the current position arrow -->
<string name="compass_calibration_recommended">Javítsa a nyíl irányát a telefon nyolcas mozgatásával az iránytű kalibrálásához.</string>
<string name="compass_calibration_recommended">Javítsa a nyíl irányát az eszköz nyolcas mozgatásával az iránytű kalibrálásához.</string>
<!-- Toast text when compass calibration may improve the correctness of the current position arrow -->
<string name="compass_calibration_required">Mozgassa a telefont egy nyolcas mozdulattal az iránytű kalibrálásához és a nyíl irányának rögzítéséhez a térképen.</string>
<string name="compass_calibration_required">Mozgassa az eszközt egy nyolcas mozdulattal az iránytű kalibrálásához és a nyíl irányának rögzítéséhez a térképen.</string>
<!-- Toast text when user hides UI with a long tap anywhere on the map -->
<string name="long_tap_toast">Érintse meg újra hosszan a térképet a kezelőfelület megjelenítéséhez</string>
<!-- Update all button text -->
@@ -266,7 +266,7 @@
<!-- Displayed in a dialog that appears when a user tries to delete a map while the app is in the follow route mode -->
<string name="downloader_delete_map_while_routing_dialog">A térkép törléséhez állítsa le a navigációt</string>
<!-- PointsInDifferentMWM -->
<string name="routing_failed_cross_mwm_building">Útvonalakat csak akkor lehet készíteni, ha teljesen rajta vannak egy térképen.</string>
<string name="routing_failed_cross_mwm_building">Csak olyan útvonalakat lehet létrehozni, amelyek teljes egészében egy régió térképén belül helyezkednek el.</string>
<!-- Context menu item for downloader. -->
<string name="downloader_download_map">Térkép letöltése</string>
<!-- Item status in downloader. -->
@@ -284,7 +284,7 @@
<!-- Text for routing error dialog -->
<string name="routing_download_maps_along">Összes térkép letöltése az útvonal mentén</string>
<!-- Text for routing error dialog -->
<string name="routing_requires_all_map">Az útvonal létrehozásához le kell töltenie és frissítenie kell az összes térképet az Ön tartózkodási helyétől a célig.</string>
<string name="routing_requires_all_map">Az útvonal létrehozásához le kell töltenie és frissítenie kell az összes térképet a saját tartózkodási helyétől a célig.</string>
<!-- Text for routing error dialog -->
<string name="routing_not_enough_space">Nincs elegendő tárhely</string>
<!-- location service disabled -->
@@ -325,10 +325,10 @@
<string name="blue_gray">Kékes szürke</string>
<!-- SECTION: Routing dialogs strings -->
<string name="dialog_routing_disclaimer_title">Az útvonal követésekor vegye figyelembe az alábbiakat:</string>
<string name="dialog_routing_disclaimer_priority"> Az útviszonyok, a közlekedési szabályok és a jelzőtáblák mindig elsőbbséget élveznek a navigációs útmutatással szemben;</string>
<string name="dialog_routing_disclaimer_precision"> A térkép pontatlan lehet és a javasolt útvonal lehetséges, hogy nem mindig a legoptimálisabb módja a célállomás elérésének;</string>
<string name="dialog_routing_disclaimer_recommendations"> A javasolt útvonalakat csupán ajánlottként kell tekinteni;</string>
<string name="dialog_routing_disclaimer_borders"> Legyen óvatos az útvonalakkal a határzónákban: az alkalmazásunk által létrehozott útvonalak néha nem engedélyezett helyeken léphetik át az országhatárokat.</string>
<string name="dialog_routing_disclaimer_priority">- Az útviszonyok, a közlekedési szabályok és a jelzőtáblák mindig elsőbbséget élveznek a navigációs útmutatással szemben;</string>
<string name="dialog_routing_disclaimer_precision">- A térkép pontatlan lehet és a javasolt útvonal lehetséges, hogy nem mindig a legoptimálisabb módja a célállomás elérésének;</string>
<string name="dialog_routing_disclaimer_recommendations">- A javasolt útvonalakat csak ajánlásként kell értelmezni;</string>
<string name="dialog_routing_disclaimer_borders">- Legyen óvatos az útvonalakkal a határzónákban: az alkalmazásunk által létrehozott útvonalak néha nem engedélyezett helyeken léphetik át az országhatárokat.</string>
<string name="dialog_routing_disclaimer_beware">Mindig maradjon éber és vezessen biztonságosan az utakon!</string>
<string name="dialog_routing_check_gps">Ellenőrizze a GPS-jelet</string>
<string name="dialog_routing_error_location_not_found">Nem sikerült létrehozni az útvonalat. A jelenlegi GPS-koordináták nem azonosíthatók.</string>
@@ -347,13 +347,13 @@
<string name="dialog_routing_change_intermediate">Nem sikerült meghatározni a köztes helyet</string>
<string name="dialog_routing_intermediate_not_determined">Pontosítsa a köztes helyet</string>
<string name="dialog_routing_system_error">Rendszerhiba</string>
<string name="dialog_routing_application_error">Az alkalmazás hibája miatt nem lehet létrehozni az útvonalat</string>
<string name="dialog_routing_application_error">Egy alkalmazáshiba miatt nem lehet létrehozni az útvonalat</string>
<string name="dialog_routing_try_again">Próbálja meg újra</string>
<string name="not_now">Most nem</string>
<string name="dialog_routing_download_and_build_cross_route">Szeretné letölteni a térképet, és egynél több térképen átívelő, optimálisabb útvonalat létrehozni?</string>
<string name="dialog_routing_download_cross_route">Töltsön le további térképeket, hogy egy jobb útvonalat hozzon létre, amely keresztezi ennek a térképnek a határait.</string>
<string name="dialog_routing_download_and_build_cross_route">Szeretné letölteni a térképet és létrehozni egy optimálisabb útvonalat, amely több térképet is igényel?</string>
<string name="dialog_routing_download_cross_route">Töltsön le további térképeket, hogy jobb útvonalat állíthasson össze, amely átlép a ennek a térképnek a határain.</string>
<!-- SECTION: Strings for downloading map from search -->
<string name="search_without_internet_advertisement">Az útvonalak kereséséhez és létrehozásához, töltse le a térképet és többé nem lesz szüksége internetkapcsolatra.</string>
<string name="search_without_internet_advertisement">Az útvonalak keresésének és létrehozásának megkezdéséhez, töltse le a térképet. Ezután már nem lesz szüksége internetkapcsolatra.</string>
<string name="search_select_map">Térkép kiválasztása</string>
<!-- «Show» context menu -->
<string name="show">Megjelenítés</string>
@@ -393,7 +393,7 @@
<string name="editor_example_values">Példaértékek</string>
<string name="editor_correct_mistake">Hiba javítása</string>
<string name="editor_add_select_location">Hely kiválasztása</string>
<string name="editor_report_problem_desription_1">Írja le részletesen a problémát, hogy az OpenStreetMap csapata kijavíthassa.</string>
<string name="editor_report_problem_desription_1">Írja le részletesen a problémát, hogy az OpenStreetMap közössége kijavíthassa.</string>
<string name="editor_report_problem_desription_2">Vagy javítsa ki Ön itt: https://www.openstreetmap.org/</string>
<string name="editor_report_problem_send_button">Küldés</string>
<string name="editor_report_problem_title">Hibajegy</string>
@@ -409,11 +409,11 @@
<string name="closed">Zárva</string>
<string name="edit_opening_hours">Nyitvatartás szerkesztése</string>
<string name="no_osm_account">Nem rendelkezik még felhasználói fiókkal az OpenStreetMapen?</string>
<string name="register_at_openstreetmap">Regisztráció az OpenStreetMap oldalon</string>
<string name="register_at_openstreetmap">Regisztráció az OpenStreetMapen</string>
<string name="login">Bejelentkezés</string>
<!-- Status message indicating that user did not login to OSM profile yet. -->
<string name="not_signed_in">Nincs bejelentkezve</string>
<string name="login_osm">Jelentkezzen be az OpenStreetMap fiókjába</string>
<string name="login_osm">Jelentkezzen be az OpenStreetMapbe</string>
<string name="logout">Kijelentkezés</string>
<string name="edit_place">Hely szerkesztése</string>
<string name="add_language">Nyelv hozzáadása</string>
@@ -453,7 +453,7 @@
<!-- Text in About and OSM Login screens. First %@ is replaced by a local, human readable date. -->
<string name="osm_presentation">A közösségi OpenStreetMap adatok frissítésének időpontja: %s. Tudjon meg többet a térkép szerkesztéséről és frissítéséről az OpenStreetMap.org oldalon</string>
<!-- OSM explanation on Android login screen -->
<string name="login_osm_presentation">Az OpenStreetMap.org (OSM) egy közösségi projekt, amelynek célja egy ingyenes és nyílt térkép létrehozása. Ez a CoMaps alkalmazás térképadatainak fő forrása, és a Wikipédiához hasonlóan működik. Helyeket adhat hozzá vagy szerkeszthet, és azok világszerte felhasználók milliói számára válnak elérhetővé. \nCsatlakozzon a közösséghez, és segítsen jobb térképet készíteni mindenki számára!</string>
<string name="login_osm_presentation">Az OpenStreetMap.org (OSM) egy közösségi projekt, amelynek célja egy ingyenes és szabad térkép létrehozása. Ez a CoMaps alkalmazás térképadatainak fő forrása, és a Wikipédiához hasonlóan működik. Helyeket adhat hozzá vagy szerkeszthet, és azok világszerte felhasználók milliói számára válnak elérhetővé.\nCsatlakozzon a közösséghez, és segítsen jobb térképet készíteni mindenki számára!</string>
<string name="login_to_make_edits_visible">Hozzon létre egy OpenStreetMap-fiókot vagy jelentkezzen be, hogy közzétehesse a térképszerkesztéseit a világ számára</string>
<!-- Downloaded 10 **of** 20 <- it is that "of" -->
<string name="downloader_of">%1$d / %2$d</string>
@@ -496,7 +496,7 @@
<string name="editor_place_doesnt_exist">A hely nem létezik</string>
<!-- Phone number error message -->
<string name="error_enter_correct_phone">Adjon megy egy érvényes telefonszámot</string>
<string name="error_enter_correct_web">Adjon meg egy érvényes weboldalcímet</string>
<string name="error_enter_correct_web">Adjon meg egy érvényes webcímet</string>
<string name="error_enter_correct_email">Adjon meg egy érvényes e-mail-címet</string>
<string name="placepage_add_place_button">Hely hozzáadása az OpenStreetMap adatbázisához</string>
<!-- Displayed when saving some edits to the map to warn against publishing personal data -->
@@ -524,12 +524,12 @@
<string name="big_font">Betűméret növelése a térképen</string>
<string name="traffic_update_app">Frissítse a CoMaps alkalmazást</string>
<!-- "traffic" as in "road congestion" -->
<string name="traffic_data_unavailable">Forgalmi adatok nem állnak rendelkezésre</string>
<string name="traffic_data_unavailable">Nem állnak rendelkezésre forgalmi adatok</string>
<string name="enable_logging">Naplózás engedélyezése</string>
<!-- Settings: "Send general feedback" button -->
<string name="feedback_general">Általános visszajelzés</string>
<string name="prefs_languages_information">Az CoMaps TTS-rendszert használ a hangnavigációhoz. Sok androidos eszköz használja a Google TTS-t; töltse le vagy frissítse a Google Play áruházból (https://play.google.com/store/apps/details?id=com.google.android.tts)</string>
<string name="prefs_languages_information_off">Egyes nyelveknél másik beszédszintetizátort vagy további nyelvi csomagot kell telepítenie az alkalmazás-áruházból (Google Play, Galaxy Store, App Gallery, FDroid). \nNyissa meg az eszköz beállításait → Nyelv és bevitel → Beszéd → Szöveg-beszéd átalakító kimenet. \nItt kezelheti a beszédszintézis beállításokat (például: nyelvi csomag letöltése a kapcsolat nélküli használathoz) és másik szövegfelolvasót jelölhet ki.</string>
<string name="prefs_languages_information_off">Egyes nyelveknél másik beszédszintetizátort vagy további nyelvi csomagot kell telepítenie az alkalmazás-áruházból (Google Play, Galaxy Store, App Gallery, FDroid).\nNyissa meg az eszköz beállításait → Nyelv és bevitel → Beszéd → Szöveg-beszéd átalakító kimenet.\nItt kezelheti a beszédszintézis beállításokat (például: nyelvi csomag letöltése a kapcsolat nélküli használathoz) és másik szövegfelolvasót jelölhet ki.</string>
<string name="prefs_languages_information_off_link">Ebben az útmutatóban további tájékoztatást talál</string>
<string name="transliteration_title">Átírás latin betűkre</string>
<string name="learn_more">Tudjon meg többet</string>
@@ -556,7 +556,7 @@
<string name="bookmarks_create_new_group">Új lista létrehozása</string>
<!-- Bookmark categories screen, button that opens folder selection dialog to import KML/KMZ/GPX/KMB files -->
<string name="bookmarks_import">Könyvjelzők és nyomvonalak importálása</string>
<string name="bookmarks_error_message_share_general">Nem lehet megosztani egy alkalmazáshiba miatt</string>
<string name="bookmarks_error_message_share_general">Egy alkalmazáshiba miatt nem lehet megosztani</string>
<string name="bookmarks_error_title_share_empty">Megosztási hiba</string>
<string name="bookmarks_error_message_share_empty">Üres lista nem osztható meg</string>
<string name="bookmarks_error_title_empty_list_name">A név nem lehet üres</string>
@@ -594,7 +594,7 @@
<!-- this text will be shown in application notification preferences opposite checkbox which enable/disable downloader notifications. Devices on Android 8+ are affected. -->
<string name="notification_channel_downloader">Térképletöltő</string>
<!-- "Speed cameras" settings menu option (should be short! no more than 47-50 chars) to warn a driver if there is a risk of exceeding the speed limit -->
<string name="pref_tts_speedcams_auto">Gyorshajtáskor figyelmeztessen</string>
<string name="pref_tts_speedcams_auto">Figyelmeztetés gyorshajtáskor</string>
<!-- Speed camera settings menu option - Always warn (about speedcams) -->
<string name="pref_tts_speedcams_always">Mindig figyelmeztessen</string>
<!-- Speed camera settings menu option - Never warn (about speedcams) -->
@@ -602,7 +602,7 @@
<string name="power_managment_title">Energiatakarékos mód</string>
<string name="power_managment_description">Megpróbálja csökkenteni az energiafelhasználást bizonyos funkciók rovására</string>
<string name="power_managment_setting_never">Soha</string>
<string name="power_managment_setting_auto">Amikor az akkumulátor lemerül</string>
<string name="power_managment_setting_auto">Alacsony akkumulátorszinten</string>
<string name="power_managment_setting_manual_max">Mindig</string>
<string name="enable_logging_warning_message">Engedélyezze ideiglenesen ezt a beállítást, hogy rögzíthesse és elküldhesse nekünk a problémájával kapcsolatos részletes diagnosztikai naplókat a „Névjegy és súgó” képernyő „Hibajelentés” funkciójával. A naplók tartalmazhatnak helyadatokat.</string>
<string name="driving_options_title">Útvonaltervezési beállítások</string>
@@ -707,15 +707,15 @@
<!-- App tip #01 -->
<string name="app_tip_01">Adományaival és támogatásával létrehozhatjuk a világ legjobb térképes alkalmazását!</string>
<!-- App tip #02 -->
<string name="app_tip_02">Tetszik az alkalmazásunk? Adományozzon, hogy támogassa a fejlesztést! Mégsem tetszik? Jelezze felénk, hogy miért nem, és mi kijavítjuk!</string>
<string name="app_tip_02">Tetszik az alkalmazásunk? Adományozzon, hogy támogassa a fejlesztést! - Mégsem tetszik? Jelezze felénk, hogy miért nem, és mi kijavítjuk!</string>
<!-- App tip #03 -->
<string name="app_tip_03">Ha ismer egy szoftverfejlesztőt, megkérheti őt egy olyan funkció megvalósítására, amelyre szüksége van.</string>
<!-- App tip #04 -->
<string name="app_tip_04">Koppintson a térképen bárhová, hogy bármit kiválaszthasson. Hosszú koppintással elrejtheti és visszahozhatja a felületet.</string>
<!-- App tip #05 -->
<string name="app_tip_05">Tudja, hogy kijelölheti pozícióját a térképen?</string>
<string name="app_tip_05">Tudta, hogy a térképen kiválaszthatja a jelenlegi tartózkodási helyét?</string>
<!-- App tip #06 -->
<string name="app_tip_06">Segítsen lefordítani az alkalmazást az Ön nyelvére.</string>
<string name="app_tip_06">Segítsen lefordítani az alkalmazást a saját nyelvére.</string>
<!-- App tip #07 -->
<string name="app_tip_07">Ezt az alkalmazást néhány lelkes közreműködő és a közösség fejleszteti.</string>
<!-- App tip #08 -->
@@ -723,17 +723,17 @@
<!-- App tip #09 -->
<string name="app_tip_09">A fő célunk az, hogy gyors, az adatvédelemre fókuszáló, könnyen használható térképeket készítsünk, amelyeket szeretni fog.</string>
<!-- Text on the Android Auto or CarPlay placeholder screen that maps are displayed on the phone screen -->
<string name="car_used_on_the_phone_screen">Ön most a CoMaps alkalmazást használja a telefon képernyőjén</string>
<string name="car_used_on_the_phone_screen">Ön most a CoMaps alkalmazást használja az eszköz képernyőjén</string>
<!-- Text on the phone placeholder screen that maps are displayed on the car screen -->
<string name="car_used_on_the_car_screen">Ön most a CoMaps alkalmazást használja az autó képernyőjén</string>
<!-- Displayed on the phone screen. Android Auto connected -->
<string name="aa_connected_title">Ön már kapcsolódva van az Android Auto rendszerhez</string>
<!-- Displayed on the phone screen. Button to display maps on the phone screen instead of a car -->
<string name="car_continue_on_the_phone">Folytatás telefonon</string>
<string name="car_continue_on_the_phone">Folytatás az eszközön</string>
<!-- Displayed on the Android Auto or CarPlay screen. Button to display maps on the car screen instead of a phone. Must be no more than 18 symbols! -->
<string name="car_continue_in_the_car">Az autó képernyőjére</string>
<!-- Ask user to grant location permissions -->
<string name="aa_location_permissions_request">A CoMaps alkalmazásnak szüksége van a helymeghatározáshoz való hozzáférésre. Ha biztonságos, ellenőrizze az értesítést a telefonján.</string>
<string name="aa_location_permissions_request">A CoMaps alkalmazásnak szüksége van a helymeghatározáshoz való hozzáférésre. Ha biztonságos, ellenőrizze az értesítést az eszközén.</string>
<!-- Notification title for permission request from AA. -->
<string name="aa_request_permission_notification">Ennek az alkalmazásnak szüksége van az Ön engedélyére</string>
<!-- The text in the activity for location permission request. -->
@@ -768,7 +768,7 @@
<!-- To indicate if restaurant or other place has outdoor seating -->
<string name="outdoor_seating">Kiülős helyek</string>
<!-- Disclaimer summary shown when Power Saving Mode is enabled -->
<string name="power_save_dialog_summary">A legpontosabb navigáció érdekében javasoljuk az energiatakarékos üzemmód kikapcsolását a telefon akkumulátor-beállításaiban.</string>
<string name="power_save_dialog_summary">A legpontosabb navigáció érdekében javasoljuk az energiatakarékos üzemmód kikapcsolását az eszköz akkumulátor-beállításaiban.</string>
<!-- Prompt to start recording a track. -->
<string name="start_track_recording">Nyomvonal rögzítése</string>
<!-- Prompt for stopping a track recording. -->
@@ -780,7 +780,7 @@
<!-- Title for the alert when saving a track recording. -->
<string name="track_recording_alert_title">Menti a könyvjelzők és nyomvonalak közé?</string>
<!-- Message for the toast when saving the track recording is finished but nothing to save. -->
<string name="track_recording_toast_nothing_to_save">A nyomvonal üres nincs mit menteni</string>
<string name="track_recording_toast_nothing_to_save">A nyomvonal üres - nincs mit menteni</string>
<!-- Error message when there are no File Manager apps installed to select a folder when importing Bookmarks and Tracks -->
<string name="error_no_file_manager_app">Nem lehet megjeleníteni a mappaválasztó párbeszédpanelt, mert nincs megfelelő alkalmazás telepítve az eszközén. Telepítsen egy fájlkezelő alkalmazást, és próbálja meg újra.</string>
<string name="choose_color">Válasszon színt</string>
@@ -817,7 +817,7 @@
<string name="panoramax">Panoramax kép</string>
<string name="app_site_url">https://comaps.app/hu/</string>
<string name="saved">Mentett</string>
<string name="about_headline">Közösség által működtetett nyílt projekt</string>
<string name="about_headline">Közösség által működtetett szabad projekt</string>
<string name="closed_now">Jelenleg zárva</string>
<string name="existence_confirmed_time_ago">A létezése ellenőrizve és megerősítve: %s</string>
<string name="hours_confirmed_time_ago">Megerősítve: %s</string>
@@ -869,5 +869,19 @@
<string name="charge_socket_nacs">NACS (Észak-Amerikai töltőszabvány)</string>
<string name="charge_socket_chademo">Gyors töltési szabvány Japán autókhoz</string>
<string name="unknown_socket_type">ismeretlen aljzat</string>
<string name="unknown_power_output">ismeretlen áramkimenet</string>
<string name="unknown_power_output">ismeretlen</string>
<string name="editor_place_doesnt_exist_description">Írja le, hogy jelenleg hogyan néz ki a hely, a hibaüzenet elküldéséhez az OpenStreetMap közösségnek</string>
<string name="avoid_steps">Lépcsők elkerülése</string>
<string name="unknow_socket_type">ismeretlen aljzat</string>
<string name="edit_socket_info_tooltip">Új aljzatok létrehozása vagy a meglévők szerkesztése.</string>
<string name="charging_station_available_sockets">Elérhető aljzatok</string>
<string name="charge_socket_unknown_other">Egyéb vagy ismeretlen aljzat</string>
<string name="charge_socket_count">Darabszám</string>
<string name="charge_socket_power">Teljesítmény (kW)</string>
<string name="editor_socket">Aljzat szerkesztése</string>
<string name="unknown_count">ismeretlen</string>
<string name="error_value_must_be_positive">Az érték csak pozitív egész szám lehet</string>
<string name="error_invalid_number">Érvénytelen szám</string>
<string name="offline_explanation_title">Offline térképek</string>
<string name="offline_explanation_text">A terület megtekintéséhez és az azon való navigálásához egy térképet kell letölteni.\nTöltsön le térképeket azokra a területekre, ahová utazni szeretne.</string>
</resources>

View File

@@ -824,4 +824,9 @@
<string name="edit_socket_info_tooltip">Pievienot jaunas ligzdas vai labot esošās.</string>
<string name="unknow_socket_type">nezināma ligzda</string>
<string name="unknown_count">nezināms</string>
<string name="offline_explanation_title">Bezsaistes kartes</string>
<string name="offline_explanation_text">Ir nepieciešams lejupielādēt karti, lai apskatītu un pārvietotos apgabalā.\nJālejupielādē apgabalu, kuros vēlies ceļot, kartes.</string>
<string name="avoid_steps">Izvairīties no pakāpieniem</string>
<string name="editor_place_doesnt_exist_description">Jāapraksta, kā vieta tagad izskatās, lai nosūtītu kļūdas piezīmi OpenStreetMap kopienai</string>
<string name="unknown_socket_type">nezināma ligzda</string>
</resources>

View File

@@ -21,7 +21,7 @@
<!-- View and button titles for accessibility, please also edit it in iphone/plist.txt -->
<string name="search">Søk</string>
<!-- Search box placeholder text; Used when searching on the map itself, not when searching for a map -->
<string name="search_map">Søk kart</string>
<string name="search_map">Søk kartet</string>
<!-- Location services are disabled by user alert - message -->
<string name="location_is_disabled_long_text">Du har for øyeblikket deaktivert alle posisjonstjenester for denne enheten eller applikasjonen. Slå dem på i «Innstillinger».</string>
<!-- A dialog title, that warns a user that Precise Location is disabled and suggests to turn it on -->
@@ -31,7 +31,7 @@
<!-- View and button titles for accessibility -->
<string name="zoom_to_country">Vis på kartet</string>
<!-- Message to display at the center of the screen when the country download has failed -->
<string name="country_status_download_failed">Laster ned mislyktes</string>
<string name="country_status_download_failed">Nedlasting mislyktes</string>
<!-- Button text for the button under the country_status_download_failed message -->
<string name="try_again">Prøv på nytt</string>
<string name="about_menu_title">Om CoMaps</string>
@@ -46,12 +46,12 @@
<!-- Text in About screen -->
<string name="about_developed_by_enthusiasts">Fullstendig åpen kildekode, ikke for profitt, gjennomsiktige beslutningsprosesser og finanser.</string>
<!-- The button that opens system location settings -->
<string name="location_settings">Innstillinger for plassering</string>
<string name="location_settings">Posisjonsinnstillinger</string>
<string name="close">Lukk</string>
<string name="unsupported_phone">En maskinvareakselerert OpenGL kreves. Dessverre støttes ikke enheten din.</string>
<string name="download">Last ned</string>
<!-- Used in DownloadResources startup screen -->
<string name="disconnect_usb_cable">Koble fra USB-kabelen eller sett inn minnekortet for å bruke CoMaps</string>
<string name="disconnect_usb_cable">Koble fra USB-kabelen eller sett inn minnekort for å bruke CoMaps</string>
<!-- Used in DownloadResources startup screen -->
<string name="not_enough_free_space_on_sdcard">Frigjør plass på SD-kortet/USB-enheten først for å bruke appen</string>
<string name="download_resources">Før du begynner å bruke appen, last ned oversiktskartet over verden til enheten din.\nDet vil bruke %s lagringsplass.</string>
@@ -66,9 +66,9 @@
<!-- Show popup notification on top of the map when country download has failed. -->
<string name="download_country_failed">Nedlasting av %s mislyktes</string>
<!-- "Add new bookmark list" dialog title -->
<string name="add_new_set">Legg til nytt sett</string>
<string name="add_new_set">Legg til en ny liste</string>
<!-- Add Bookmark list dialog - hint when the list name is empty -->
<string name="bookmark_set_name">Bokmerk settnavn</string>
<string name="bookmark_set_name">Bokmerkelistenavn</string>
<!-- Should be used in the bookmarks-only context, see bookmarks_and_tracks if tracks are also implied. -->
<string name="bookmarks">Bokmerker</string>
<!-- "Bookmarks and Tracks" dialog title, also sync it with iphone/plist.txt -->
@@ -86,11 +86,11 @@
<!-- Detailed description of Maps Storage settings button -->
<string name="maps_storage_summary">Velg lagringsmappe for de nedlastede kartene</string>
<!-- E.g. "Downloaded maps: 500Mb" in Maps Storage settings -->
<string name="maps_storage_downloaded">Kart</string>
<string name="maps_storage_downloaded">Nedlastede kart</string>
<!-- Free space out of total storage size in Maps Storage settings, e.g. "300 MB free of 2 GB" -->
<string name="maps_storage_free_size">%1$s ledig av %2$s</string>
<!-- Question dialog for transferring maps from one storage to another -->
<string name="move_maps">Flytt kart?</string>
<string name="move_maps">Flytte kart?</string>
<!-- Error moving map files from one storage to another -->
<string name="move_maps_error">Kunne ikke flytte kart</string>
<!-- Ask user to wait several minutes (some long process in modal dialog). -->
@@ -149,13 +149,13 @@
<string name="description">Merknader</string>
<!-- Email Subject when sharing bookmark list -->
<string name="share_bookmarks_email_subject">Delte CoMaps-bokmerker</string>
<string name="share_bookmarks_email_body">Hei! \n \nVedlagt er mine bokmerker fra CoMaps-appen. Åpne de dersom du har CoMaps installert. Har du ikke har det, last ned appen til iOS eller Android ved å trykke på denne linken: https://www.comaps.app/download/ \n \nNyt reisen med CoMaps!</string>
<string name="share_bookmarks_email_body">Hei! \n \nVedlagt er mine bokmerker; åpne dem i CoMaps. Har du ikke installert appen kan du laste ned her: https://www.comaps.app/download/ \n \nGod reise med CoMaps!</string>
<!-- message title of loading file -->
<string name="load_kmz_title">Laster inn bokmerker</string>
<!-- Kmz file successful loading -->
<string name="load_kmz_successful">Bokmerkene ble lastet inn! Du finner dem på kartet eller på skjermen «Bokmerkeadministrasjon».</string>
<string name="load_kmz_successful">Bokmerkene ble lastet inn! Du finner dem på kartet eller på skjermen Bokmerkehåndtering.</string>
<!-- Kml file loading failed -->
<string name="load_kmz_failed">Opplasting av bokmerker mislyktes. Filen kan være skadet eller defekt.</string>
<string name="load_kmz_failed">Mislyktes i å laste inn bokmerker. Filen kan være skadet eller defekt.</string>
<!-- Failed to recognize the format of a bookmarks or tracks file. -->
<string name="unknown_file_type">Filtypen gjenkjennes ikke av appen: \n%1$s</string>
<!-- Failed to open a bookmarks or tracks file in CoMaps. -->
@@ -277,7 +277,7 @@
<!-- Context menu item for downloader. -->
<string name="downloader_download_map">Last ned kartet</string>
<!-- Item status in downloader. -->
<string name="downloader_retry">Gjenta</string>
<string name="downloader_retry">Prøv igjen</string>
<!-- Item in context menu. -->
<string name="downloader_delete_map">Slett kart</string>
<!-- Item in context menu. -->
@@ -289,11 +289,11 @@
<!-- Preference title -->
<!-- Preference description -->
<!-- Text for routing error dialog -->
<string name="routing_download_maps_along">Last ned kart langs ruten</string>
<string name="routing_download_maps_along">Last ned alle kartene langs ruten din</string>
<!-- Text for routing error dialog -->
<string name="routing_requires_all_map">Når du skal opprette en rute må du ha oppdatert alle kartene fra ditt ståsted til din destinasjon.</string>
<string name="routing_requires_all_map">For å opprette en rute må alle kartene fra posisjonen din til målet ditt lastes ned og oppdateres.</string>
<!-- Text for routing error dialog -->
<string name="routing_not_enough_space">Ikke nok ledig minne</string>
<string name="routing_not_enough_space">Ikke nok plass</string>
<!-- location service disabled -->
<string name="enable_location_services">Aktiver posisjonstjenester</string>
<string name="save">Lagre</string>
@@ -339,15 +339,15 @@
<string name="dialog_routing_disclaimer_beware">Kjør trygt!</string>
<string name="dialog_routing_check_gps">Sjekk GPS-signal</string>
<string name="dialog_routing_error_location_not_found">Ingen rute ble opprettet. Nåværende GPS-koordinater ble ikke funnet.</string>
<string name="dialog_routing_location_turn_wifi">Sjekk GPS-signalet. Resultatet blir mer nøyaktig når du bruker wi-fi.</string>
<string name="dialog_routing_location_turn_on">Aktiver stedstjenester</string>
<string name="dialog_routing_location_unknown_turn_on">Nåværende GPS-koordinater ble ikke funnet. Aktiver stedstjenester for å beregne en rute.</string>
<string name="dialog_routing_location_turn_wifi">Sjekk GPS-signalet. Bruk av Wi-Fi vil forbedre posisjonsnøyaktigheten.</string>
<string name="dialog_routing_location_turn_on">Aktiver posisjonstjenester</string>
<string name="dialog_routing_location_unknown_turn_on">Nåværende GPS-koordinater ble ikke funnet. Aktiver posisjonstjenester for å beregne en rute.</string>
<string name="dialog_routing_unable_locate_route">Kunne ikke finne rute</string>
<string name="dialog_routing_cant_build_route">Kan ikke opprette rute</string>
<string name="dialog_routing_change_start_or_end">Endre startpunkt eller bestemmelsessted.</string>
<string name="dialog_routing_change_start">Endre startpunkt</string>
<string name="dialog_routing_start_not_determined">Ingen rute ble opprettet. Startpunktet ble ikke funnet.</string>
<string name="dialog_routing_select_closer_start">Velg et startpunkt som er i nærheten av en vei.</string>
<string name="dialog_routing_select_closer_start">Velg et startpunkt nærmere en vei.</string>
<string name="dialog_routing_change_end">Endre bestemmelsessted</string>
<string name="dialog_routing_end_not_determined">Ingen rute ble opprettet. Bestemmelsesstedet ble ikke funnet.</string>
<string name="dialog_routing_select_closer_end">Velg et bestemmelsessted som er nærmere en vei</string>
@@ -358,9 +358,9 @@
<string name="dialog_routing_try_again">Vennligst prøv igjen</string>
<string name="not_now">Ikke nå</string>
<string name="dialog_routing_download_and_build_cross_route">Vil du laste ned kartet og lage en mer optimal rute som går over flere kart?</string>
<string name="dialog_routing_download_cross_route">Last ned kartet for å opprette en mer optimal rute som går utenfor dette kartet.</string>
<string name="dialog_routing_download_cross_route">Last ned ytterligere kart for å opprette en bedre rute som krysser grensene til dette kartet.</string>
<!-- SECTION: Strings for downloading map from search -->
<string name="search_without_internet_advertisement">Last vennligst ned kartet for å begynne å søke og opprette ruter - så slipper du i fremtiden å være avhengig av å ha internettforbindelse.</string>
<string name="search_without_internet_advertisement">Last ned kartet for å begynne å søke og opprette ruter. Etter det trenger du ikke lenger en internettforbindelse.</string>
<string name="search_select_map">Velg kartet</string>
<!-- «Show» context menu -->
<string name="show">Vis</string>
@@ -374,20 +374,20 @@
<string name="search_history_title">Søkehistorikk</string>
<string name="search_history_text">Vis de siste søkene dine</string>
<string name="clear_search">Tøm søkehistorikk</string>
<string name="p2p_your_location">Din beliggenhet</string>
<string name="p2p_your_location">Din posisjon</string>
<string name="p2p_start">Start</string>
<string name="p2p_from_here">Fra</string>
<string name="p2p_from_here">Rute fra</string>
<string name="p2p_to_here">Rute til</string>
<string name="p2p_only_from_current">Navigering er kun tilgjengelig fra din gjeldende posisjon</string>
<string name="p2p_reroute_from_current">Vil du vi skal planlegge en rute fra din nåværende posisjon?</string>
<string name="p2p_reroute_from_current">Vil du planlegge en rute fra din nåværende posisjon?</string>
<!-- Edit open hours/set time and minutes dialog -->
<string name="next_button">Neste</string>
<!-- Tab title in the Edit Opening Hours time picker -->
<string name="editor_time_from">Fra</string>
<!-- Tab title in the Edit Opening Hours time picker -->
<string name="editor_time_to">Til</string>
<string name="editor_time_add">Legg til tidsrom</string>
<string name="editor_time_delete">Slett tidsrom</string>
<string name="editor_time_add">Legg til tidsplan</string>
<string name="editor_time_delete">Slett tidsplan</string>
<!-- Text for allday switch. -->
<string name="editor_time_allday">Hele dagen (24 timer)</string>
<string name="editor_time_open">Åpen</string>
@@ -407,12 +407,12 @@
<string name="editor_report_problem_no_place_title">Stedet finnes ikke</string>
<string name="editor_report_problem_under_construction_title">Stengt pga. vedlikehold</string>
<string name="editor_report_problem_duplicate_place_title">Duplisert sted</string>
<string name="autodownload">Automatisk nedlasting</string>
<string name="autodownload">Last ned kart automatisk</string>
<!-- Place Page opening hours text -->
<string name="daily">Daglig</string>
<string name="twentyfour_seven">Dag og natt</string>
<string name="day_off_today">Fridag i dag</string>
<string name="day_off">Fridag</string>
<string name="day_off_today">Stengt i dag</string>
<string name="day_off">Stengt</string>
<string name="opens_in">Åpner om %s</string>
<string name="closes_in">Stenger om %s</string>
<string name="closed">Stengt</string>
@@ -442,10 +442,10 @@
<string name="select_cuisine">Velg kjøkken</string>
<!-- login text field -->
<string name="editor_add_phone">Legg til telefon</string>
<string name="level">Gulv</string>
<string name="level">Etasje</string>
<string name="downloader_delete_map_dialog">Alle dine kartredigeringer vil slettes sammen med kartet</string>
<string name="downloader_update_maps">Oppdater kart</string>
<string name="downloader_mwm_migration_dialog">For å opprette en reiserute må du oppdatere alle kartene og deretter planlegge reiseruten på nytt.</string>
<string name="downloader_mwm_migration_dialog">For å opprette en rute må du oppdatere alle kartene og deretter planlegge ruten på nytt.</string>
<string name="downloader_search_field_hint">Finn kartet</string>
<string name="common_check_internet_connection_dialog">Sørg for at enheten din er koblet til Internett</string>
<string name="downloader_no_space_title">Ikke nok plass</string>
@@ -473,9 +473,9 @@
<string name="download_over_mobile_message">Dette kan være veldig dyrt med enkelte abonnementer eller ved roaming</string>
<string name="error_enter_correct_house_number">Skriv riktig husnummer</string>
<!-- Error message in Editor when a user tries to set the number of floors for a building higher than %d floors -->
<string name="error_enter_correct_storey_number">Rediger bygningen med maks. %d etasjer</string>
<string name="error_enter_correct_storey_number">Antallet etasjer må ikke overstige %d</string>
<string name="editor_zip_code">Postnummer</string>
<string name="error_enter_correct_zip_code">Angi riktig postnummer</string>
<string name="error_enter_correct_zip_code">Angi et gyldig postnummer</string>
<!-- Title for OSM note section in the editor -->
<string name="editor_other_info">Merknad til OpenStreetMap-frivillige (valgfritt)</string>
<!-- Hint of the input field in the OSM note section of the editor -->
@@ -501,23 +501,23 @@
<string name="day">d</string>
<string name="placepage_more_button">Mer</string>
<string name="placepage_edit_bookmark_button">Rediger bokmerke</string>
<string name="placepage_personal_notes_hint">Personlige notater (text or html)</string>
<string name="editor_reset_edits_message">Nullstille alle lokale endringer?</string>
<string name="editor_reset_edits_button">Nullstill</string>
<string name="editor_remove_place_message">Fjerne et tilføyd sted?</string>
<string name="editor_remove_place_button">Fjern</string>
<string name="placepage_personal_notes_hint">Personlige notater (tekst eller html)</string>
<string name="editor_reset_edits_message">Forkaste alle lokale endringer?</string>
<string name="editor_reset_edits_button">Forkast</string>
<string name="editor_remove_place_message">Slette tillagt sted?</string>
<string name="editor_remove_place_button">Slett</string>
<string name="editor_place_doesnt_exist">Sted finnes ikke</string>
<!-- Error message for "Place doesn't exist" dialog when comment is empty -->
<string name="delete_place_empty_comment_error">Forklar hvorfor stedet skal slettes</string>
<!-- Phone number error message -->
<string name="error_enter_correct_phone">Skriv riktig telefonnummer</string>
<string name="error_enter_correct_phone">Angi et gyldig telefonnummer</string>
<string name="error_enter_correct_web">Oppgi en gyldig nettadresse</string>
<string name="error_enter_correct_email">Oppgi en gyldig epostadresse</string>
<string name="error_enter_correct_facebook_page">Skriv inn en gyldig Facebook-adresse, -konto eller -side</string>
<string name="error_enter_correct_instagram_page">Skriv inn en gyldig Instagram-adresse eller -kontonavn</string>
<string name="error_enter_correct_twitter_page">Skriv inn en gyldig Twitter-adresse eller -brukernavn</string>
<string name="error_enter_correct_vk_page">Skriv inn en gyldig VK-adresse eller -kontonavn</string>
<string name="error_enter_correct_line_page">Skriv inn en gyldig LINE-adresse eller -ID</string>
<string name="error_enter_correct_facebook_page">Angi en gyldig Facebook-adresse, konto eller sidenavn</string>
<string name="error_enter_correct_instagram_page">Angi et gyldig Instagram-brukernavn eller nettadresse</string>
<string name="error_enter_correct_twitter_page">Angi et gyldig Twitter-brukernavn eller nettadresse</string>
<string name="error_enter_correct_vk_page">Angi et gyldig VK-brukernavn eller nettadresse</string>
<string name="error_enter_correct_line_page">Angi en gyldig LINE-ID eller nettadresse</string>
<string name="placepage_add_place_button">Legg til sted i OpenStreetMap</string>
<!-- Displayed when saving some edits to the map to warn against publishing personal data -->
<string name="editor_share_to_all_dialog_title">Vil du sende det til alle brukere?</string>
@@ -526,7 +526,7 @@
<string name="editor_share_to_all_dialog_message_2">OpenStreetMap-redaktører vil sjekke endringene og kontakte deg hvis de har spørsmål</string>
<string name="navigation_stop_button">Stopp</string>
<!-- Shown as toast when starting the recent track recording -->
<string name="track_recording">Registrere sporet</string>
<string name="track_recording">Tar opp sporet</string>
<!-- For the first routing -->
<string name="accept">Godta</string>
<!-- For the first routing -->
@@ -541,14 +541,14 @@
<string name="mobile_data_option_never">Aldri bruk</string>
<string name="mobile_data_option_ask">Alltid spør</string>
<string name="traffic_update_maps_text">For å vise trafikkdata må kartene være oppdaterte</string>
<string name="big_font">Forstørr skriften på kartet</string>
<string name="big_font">Øk størrelsen på kartpåskrifter</string>
<string name="traffic_update_app">Vennligst oppdater CoMaps</string>
<!-- "traffic" as in "road congestion" -->
<string name="traffic_data_unavailable">Trafikkdata er ikke tilgjengelig</string>
<string name="enable_logging">Aktiver loggføring</string>
<!-- Settings: "Send general feedback" button -->
<string name="feedback_general">Generell tilbakemelding</string>
<string name="prefs_languages_information">Vi bruker system TTS for stemmeveiledning. Mange Android-enheter bruker Google TTS, Du kan laste ned eller oppdatere via Google Play (https://play.google.com/store/apps/details?id=com.google.android.tts)</string>
<string name="prefs_languages_information">Vi bruker system-TTS for taleveiledning. Mange Android-enheter bruker Google TTS, du kan laste ned eller oppdatere via Google Play (https://play.google.com/store/apps/details?id=com.google.android.tts)</string>
<string name="prefs_languages_information_off">For enkelte språk er det nødvendig å installere en annen talesyntese eller en ekstra språkpakke fra appbutikken (Google Play, Galaxy Store, App Gallery, FDroid). \nGå til enhetens innstillinger → Språk og input → Tale → Tekst til tale output. \nHer kan du administrere innstillingene for talesyntese (for eksempel laste ned språkpakke for offline bruk) og velge en annen tekst-til-tale-motor.</string>
<string name="prefs_languages_information_off_link">Les denne veiledningen for mer informasjon</string>
<string name="transliteration_title">Omskrivning til latin</string>
@@ -557,10 +557,10 @@
<string name="routing_add_start_point">Bruk søk eller trykk på kartet for å legge til et startpunkt for ruten</string>
<!-- User selected the start of a route by pressing Route From. Now the destination of a route should be selected using search or by tapping on the map and then pressing "Route To". -->
<string name="routing_add_finish_point">Bruk søk eller trykk på kartet for å legge til et destinasjonspunkt</string>
<string name="planning_route_manage_route">Administrere rute</string>
<string name="button_plan">Planlegge</string>
<string name="planning_route_manage_route">Håndter rute</string>
<string name="button_plan">Planlegg</string>
<string name="placepage_remove_stop">Fjern stopp</string>
<string name="placepage_add_stop">Angi stopp</string>
<string name="placepage_add_stop">Legg til stopp</string>
<string name="dialog_error_storage_title">Problemer med tilgang til lagring</string>
<string name="dialog_error_storage_message">Ekstern lagring er ikke tilgjengelig. Sannsynligvis er SD-kortet fjernet eller skadet eller så er filsystemet skrivebeskyttet. Undersøk og kontakt oss på support@comaps.app</string>
<string name="setting_emulate_bad_storage">Emulere skadet lagring</string>
@@ -586,19 +586,19 @@
<string name="bookmarks_error_message_list_name_already_taken">Vennligst velg et annet navn</string>
<string name="please_wait">Vennligst vent…</string>
<string name="phone_number">Telefonnummer</string>
<string name="profile">OpenStreetMap profil</string>
<string name="profile">OpenStreetMap-profil</string>
<plurals name="bookmarks_detect_message">
<item quantity="one">%d fil funnet. Du vil se den etter konverteringen.</item>
<item quantity="other">%d filer funnet. Du vil se dem etter konverteringen.</item>
</plurals>
<string name="restore">Restaurere</string>
<string name="restore">Gjenopprett</string>
<plurals name="tracks">
<item quantity="one">%d sti</item>
<item quantity="other">%d stier</item>
<item quantity="one">%d spor</item>
<item quantity="other">%d spor</item>
</plurals>
<!-- Settings privacy group in settings screen -->
<string name="privacy">Personvern</string>
<string name="privacy_policy">Personvernpolitikk</string>
<string name="privacy_policy">Personvernpraksis</string>
<string name="terms_of_use">Bruksbetingelser</string>
<string name="button_layer_traffic">Trafikk</string>
<string name="subway">T-bane</string>
@@ -610,9 +610,9 @@
<string name="export_file_gpx">Eksporter GPX</string>
<string name="delete_list">Slett liste</string>
<string name="speedcams_alert_title">Fartskamera</string>
<string name="place_description_title">Plasser beskrivelse</string>
<string name="place_description_title">Stedsbeskrivelse</string>
<!-- this text will be shown in application notification preferences opposite checkbox which enable/disable downloader notifications. Devices on Android 8+ are affected. -->
<string name="notification_channel_downloader">Nedlast kart</string>
<string name="notification_channel_downloader">Kartnedlasting</string>
<!-- "Speed cameras" settings menu option (should be short! no more than 47-50 chars) to warn a driver if there is a risk of exceeding the speed limit -->
<string name="pref_tts_speedcams_auto">For å advare deg mot fartsovertredelser</string>
<!-- Speed camera settings menu option - Always warn (about speedcams) -->
@@ -622,21 +622,21 @@
<string name="power_managment_title">Strømsparemodus</string>
<string name="power_managment_description">Prøv å redusere strømforbruket på bekostning av noen funksjoner</string>
<string name="power_managment_setting_never">Aldri</string>
<string name="power_managment_setting_auto">Automatisk</string>
<string name="power_managment_setting_manual_max">Maksimum strømsparing</string>
<string name="enable_logging_warning_message">Alternativet slår på logging for diagnostiske formål. Det kan være nyttig for våre supportpersonale som feilsøker problemer med appen. Aktiver dette alternativet bare på forespørsel fra CoMaps-brukerstøtte.</string>
<string name="driving_options_title">Kjørealternativer</string>
<string name="power_managment_setting_auto">Ved lavt batterinivå</string>
<string name="power_managment_setting_manual_max">Alltid</string>
<string name="enable_logging_warning_message">Aktiver dette alternativet midlertidig for å registrere og manuelt sende detaljerte diagnostiske loggfiler om problemet ditt til oss ved bruk av \"Rapporter en feil\" i Hjelp-dialogen. Loggfiler kan inkludere posisjonsinfo.</string>
<string name="driving_options_title">Rutingalternativer</string>
<!-- Recommended length for CarPlay and Android Auto is around 25-27 characters -->
<string name="avoid_tolls">Unngå bompenger</string>
<!-- Recommended length for CarPlay and Android Auto is around 25-27 characters -->
<string name="avoid_unpaved">Unngå uasfalterte veier</string>
<!-- Recommended length for CarPlay and Android Auto is around 25-27 characters -->
<string name="avoid_ferry">Unngå fergeoverganger</string>
<string name="avoid_motorways">Unngå motorveien</string>
<string name="avoid_ferry">Unngå ferger</string>
<string name="avoid_motorways">Unngå motorveier</string>
<string name="unable_to_calc_alert_title">Kan ikke beregne rute</string>
<string name="unable_to_calc_alert_subtitle">Kan ikke finne en rute. Dette kan skyldes dine rutealternativer eller ufullstendige OpenStreetMap-data. Endre dine rutealternativer og prøv igjen.</string>
<string name="define_to_avoid_btn">Definer veier som skal unngås</string>
<string name="change_driving_options_btn">Kjørealternativer aktivert</string>
<string name="change_driving_options_btn">Rutingalternativer aktivert</string>
<string name="toll_road">Bompengevei</string>
<string name="unpaved_road">Uasfaltert vei</string>
<string name="ferry_crossing">Fergeovergang</string>
@@ -655,9 +655,9 @@
<string name="trip_finished">Du har ankommet!</string>
<string name="ok">Ok</string>
<!-- max. 10 symbols, both iOS and Android -->
<string name="sort">Sortere</string>
<string name="sort">Sorter…</string>
<!-- Android, title, max 20-22 symbols -->
<string name="sort_bookmarks">Sortere merker</string>
<string name="sort_bookmarks">Sorter bokmerker</string>
<!-- Android -->
<string name="by_default">Som standard</string>
<!-- Android -->
@@ -668,8 +668,8 @@
<string name="by_date">Etter dato</string>
<!-- Android -->
<string name="by_name">Etter navn</string>
<string name="week_ago_sorttype">For en uke siden</string>
<string name="month_ago_sorttype">For en måned siden</string>
<string name="week_ago_sorttype">En uke siden</string>
<string name="month_ago_sorttype">En måned siden</string>
<string name="moremonth_ago_sorttype">Mer enn en måned siden</string>
<string name="moreyear_ago_sorttype">Mer enn ett år siden</string>
<string name="near_me_sorttype">Nær meg</string>
@@ -686,15 +686,15 @@
<string name="buildings">Bygninger</string>
<string name="money">Penger</string>
<string name="shops">Butikker</string>
<string name="parkings">Parkeringer</string>
<string name="parkings">Parkering</string>
<string name="fuel_places">Bensinstasjoner</string>
<string name="medicine">Medisin</string>
<string name="search_in_the_list">Søk på lista</string>
<string name="religious_places">Hellige steder</string>
<string name="select_list">Velge liste</string>
<string name="transit_not_found">T-bane navigasjon er ikke tilgjengelig i denne regionen ennå</string>
<string name="dialog_pedestrian_route_is_long_header">T-bane rute ikke funnet</string>
<string name="dialog_pedestrian_route_is_long_message">Velg utgangspunkt eller destinasjon som befinner seg nærmere en T-bane stasjon</string>
<string name="select_list">Velg liste</string>
<string name="transit_not_found">T-bane-navigasjon er ikke tilgjengelig i denne regionen ennå</string>
<string name="dialog_pedestrian_route_is_long_header">T-banerute ikke funnet</string>
<string name="dialog_pedestrian_route_is_long_message">Velg startpunkt eller endepunkt nærmere en T-banestasjon</string>
<string name="button_layer_isolines">Høydekurver</string>
<string name="isolines_activation_error_dialog">Aktivering av høydekurver krever nedlasting av kartdata for dette området</string>
<string name="isolines_location_error_dialog">Høydekurver er ikke tilgjengelige i dette området ennå</string>
@@ -715,14 +715,14 @@
<!-- Used in DownloadResources startup screen -->
<string name="connection_failure">Tilkoblingsfeil</string>
<!-- Used in DownloadResources startup screen -->
<string name="disconnect_usb_cable_title">Fjern USB-kabelen</string>
<string name="disconnect_usb_cable_title">Frakoble USB-kabel</string>
<string name="enable_keep_screen_on">Behold skjermen på</string>
<!-- Description in preferences -->
<string name="enable_keep_screen_on_description">Når dette er aktivert, vil skjermen alltid være på når kartet vises.</string>
<!-- A preference title; keep short! -->
<string name="enable_show_on_lock_screen">Vis på låseskjerm</string>
<!-- Description in preferences -->
<string name="enable_show_on_lock_screen_description">Når dette er aktivert trenger du ikke låse opp enheten hver gang når appen kjører.</string>
<string name="enable_show_on_lock_screen_description">Når dette er aktivert, fungerer appen på låseskjermen selv når enheten er låst.</string>
<!-- Current language of the map! -->
<string name="change_map_locale">Kart-språk</string>
<!-- OpenStreetMap text on splash screen -->
@@ -807,7 +807,7 @@
<!-- Message for the toast when saving the track recording is finished but nothing to save. -->
<string name="track_recording_toast_nothing_to_save">Ruten er tom - ingenting å lagre</string>
<!-- Error message when there are no File Manager apps installed to select a folder when importing Bookmarks and Tracks -->
<string name="error_no_file_manager_app">Kan ikke vise dialogboksen for mappevalg fordi ingen passende app er installert på enheten din. Installer en filbehandler-app og prøv på nytt</string>
<string name="error_no_file_manager_app">Kan ikke vise dialogboksen for mappevalg fordi ingen egnet app er installert på enheten din. Installer en filbehandler-app og prøv på nytt.</string>
<string name="choose_color">Velg farge</string>
<string name="edit_track">Rediger ruten</string>
<string name="uri_open_location_failed">Ingen app installert som kan åpne stedet</string>
@@ -862,4 +862,15 @@
<string name="pref_backup_history_title">Antall sikkerhetskopier som skal beholdes</string>
<string name="dialog_report_error_missing_folder">Den valgte sikkerhetskopiplasseringen er ikke tilgjengelig eller skrivbar. Velg en annen plassering.</string>
<string name="share_track">Del spor</string>
<string name="editor_place_doesnt_exist_description">Beskriv hvordan stedet ser ut nå for å sende en feilmelding til OpenStreetMap-fellesskapet</string>
<string name="avoid_steps">Unngå trapper</string>
<string name="offline_explanation_title">Offline-kart</string>
<string name="offline_explanation_text">Et kart må lastes ned for å vise og navigere i området.\nLast ned kart for områdene du vil reise til.</string>
<string name="error_invalid_number">Ugyldig tall</string>
<string name="error_value_must_be_positive">Verdien må være positiv</string>
<string name="unknown_power_output">ukjent</string>
<string name="charge_socket_count">Antall</string>
<string name="unknown_count">ukjent</string>
<string name="error_enter_correct_fediverse_page">Angi et gyldig Mastodon-brukernavn eller nettadresse</string>
<string name="error_enter_correct_bluesky_page">Angi et gyldig Bluesky-brukernavn eller nettadresse</string>
</resources>

View File

@@ -33,7 +33,7 @@
<color name="button_accent_text_disabled">#4CFFFFFF</color>
<!-- LanesView -->
<color name="nav_lane_arrow_active">@color/black_primary</color>
<color name="nav_lane_arrow_active">@color/white_primary</color>
<color name="elevation_profile_dot_enabled">#FF9600</color>
<color name="elevation_profile">@color/base_accent</color>

View File

@@ -48,7 +48,7 @@
<item name="navNextTurnFrame">@drawable/bg_nav_next_turn</item>
<item name="navNextNextTurnFrame">@drawable/bg_nav_next_next_turn</item>
<item name="navLanesBackgroundColor">@color/base_accent</item>
<item name="navLanesBackgroundColor">@color/bg_primary</item>
<item name="navLaneArrowActiveColor">@color/nav_lane_arrow_active</item>
<item name="navLaneArrowInactiveColor">@color/nav_lane_arrow_inactive</item>

View File

@@ -538,7 +538,7 @@
<string name="mobile_data_option_not_today">Nie stosuj dzisiaj</string>
<string name="mobile_data">Dane mobilne</string>
<!-- NOTE to translators: please synchronize your translation with the English one. -->
<string name="mobile_data_description">Dane mobilne są wymagane do powiadomień o aktualizacji map i wyświetlania dokładniejszych informacji o miejscach i zakładkach.</string>
<string name="mobile_data_description">Dane mobilne są wymagane do powiadomień o aktualizacji map i wysyłania edycji</string>
<string name="mobile_data_option_never">Nigdy nie stosuj</string>
<string name="mobile_data_option_ask">Zawsze pytaj</string>
<string name="traffic_update_maps_text">Aby wyświetlić dane o ruchu, muszą zostać zaktualizowane mapy.</string>
@@ -642,7 +642,7 @@
<string name="avoid_motorways">Unikaj autostrad</string>
<string name="unable_to_calc_alert_title">Brak możliwości zbudowania trasy</string>
<string name="unable_to_calc_alert_subtitle">Nie udało się znaleźć trasy. Może to być spowodowane ustawieniami nawigacji lub niekompletnymi danymi OpenStreetMap. Zmień opcje nawigacji i spróbuj ponownie.</string>
<string name="define_to_avoid_btn">Dostosuj ścieżkę objazdu</string>
<string name="define_to_avoid_btn">Dostosuj omijane typy dróg</string>
<string name="change_driving_options_btn">Ustawienia objazdu są włączone</string>
<string name="toll_road">Droga płatna</string>
<string name="unpaved_road">Droga gruntowa</string>
@@ -877,4 +877,26 @@
<string name="existence_confirmed_time_ago">Istnienie potwierdzone %s</string>
<string name="osm_note_hint">Ewentualnie zostaw notatkę dla społeczności OpenStreetMap, żeby ktoś inny mógł dodać lub poprawić to miejsce.</string>
<string name="osm_note_toast">Notatka zostanie wysłana do OpenStreetMap</string>
<string name="offline_explanation_title">Mapy Offline</string>
<string name="offline_explanation_text">Aby przeglądać i nawigować po okolicy potrzebujesz pobrać mapę.\nPobierz mapy obszarów, po których chcesz podróżować.</string>
<string name="editor_place_doesnt_exist_description">Opisz jak to miejsce wygląda teraz, aby wysłać zgłoszenie do społeczności OpenStreetMap</string>
<string name="avoid_steps">Unikaj schodów</string>
<string name="unknown_power_output">nieznana</string>
<string name="charge_socket_type2">Typ 2 (bez kabla)</string>
<string name="charge_socket_type2_cable">Typ 2 (z kablem)</string>
<string name="charge_socket_type2_combo">Typ 2 combo</string>
<string name="charge_socket_type1">Typ 1</string>
<string name="charge_socket_nacs">NACS</string>
<string name="charge_socket_chademo">CHAdeMO</string>
<string name="unknown_socket_type">nieznane gniazdo</string>
<string name="unknow_socket_type">nieznane gniazdo</string>
<string name="edit_socket_info_tooltip">Stwórz nowe gniazda lub edytuj już istniejące.</string>
<string name="charging_station_available_sockets">Dostępne gniazda</string>
<string name="charge_socket_unknown_other">Inne lub nieznane</string>
<string name="charge_socket_count">Liczba</string>
<string name="charge_socket_power">Moc (kW)</string>
<string name="editor_socket">Edytuj gniazdo</string>
<string name="unknown_count">nieznana</string>
<string name="error_value_must_be_positive">Wartość musi być dodatnia</string>
<string name="error_invalid_number">Nieprawidłowa liczba</string>
</resources>

View File

@@ -72,7 +72,7 @@
<!-- "Bookmarks and Tracks" dialog title, also sync it with iphone/plist.txt -->
<string name="bookmarks_and_tracks">Locuri preferate și trasee</string>
<!-- Add bookmark dialog - bookmark name -->
<string name="name">Denumire</string>
<string name="name">Nume</string>
<!-- Editor title above street and house number, duplicates [type.building.address] in types_strings.txt -->
<string name="address">Adresă</string>
<!-- Add Bookmark dialog/Bookmark list; Bookmarks dialog/Bookmark list cell. -->

View File

@@ -533,4 +533,103 @@
<string name="app_tip_08">Enostavno lahko popravite in izboljšate kartografske podatke.</string>
<string name="app_tip_09">Naš cilj je ustvariti učinkovite in enostavne zemljevide, ki spoštujejo zasebnost in vam koristijo.</string>
<string name="car_used_on_the_phone_screen">CoMaps zdaj uporabljate na zaslonu telefona</string>
<string name="error_invalid_number">Neveljavno število</string>
<string name="offline_explanation_title">Zemljevidi brez povezave</string>
<string name="offline_explanation_text">Zemljevid morate prenesti, da ga lahko ogledujete in se po njem usmerjate.\nPrenesite zemljevide za območja, kjer želite potovati.</string>
<string name="google_play_services">Googleova združena lokacijska storitev</string>
<string name="create">ustvari</string>
<string name="editor_place_doesnt_exist_description">Opišite, kako to mesto izgleda sedaj, da pošljete obvestilo skupnosti OpenStreetMap</string>
<string name="prefs_languages_information_off">Za nekatere jezike boste morali namestiti sintetizator govora ali dodatni jezikovni paket iz trgovine z aplikacijami (Google Play, Galaxy Store, App Gallery, FDroid). \nOdprite nastavitve naprave → Jezik in vnos → Govor → Izhod besedila v govor. \nTukaj lahko upravljate nastavitve za sintezo govora (na primer prenesete jezikovni paket za uporabo brez povezave) in izberete drug gonilnik za pretvorbo besedila v govor.</string>
<string name="category_desc_more">… več</string>
<string name="avoid_steps">Izogni se stopnicam</string>
<string name="translated_om_site_url">https://comaps.app/</string>
<string name="osm_wiki_about_url">https://wiki.openstreetmap.org/wiki/About_OpenStreetMap</string>
<string name="car_used_on_the_car_screen">Trenutno uporabljate CoMaps na zaslonu vozila</string>
<string name="aa_connected_title">Trenutno ste povezani z Android Auto</string>
<string name="car_continue_on_the_phone">Nadaljuj na telefonu</string>
<string name="car_continue_in_the_car">Na zaslon vozila</string>
<string name="aa_location_permissions_request">CoMaps potrebuje dostop do lokacije. Ko bo varno, preverite obvestila na vašem telefonu.</string>
<string name="aa_request_permission_notification">To orodje potrebuje vaše dovoljenje</string>
<string name="aa_request_permission_activity_text">CoMaps v Android Auto za učinkovito delovanje potrebuje lokacijska dovoljenja</string>
<string name="aa_grant_permissions">Podeli dovoljenja</string>
<string name="button_layer_outdoor">Na prostem</string>
<string name="browser_not_available">Spletni brskalnik ni na voljo</string>
<string name="volume">Glasnost</string>
<string name="bookmarks_export">Izvozi vse zaznamke in sledi</string>
<string name="pref_tts_open_system_settings">Sistemske nastavitve sintetizatorja govora</string>
<string name="pref_tts_no_system_tts">Nastavitve za sintezo govora niso bile najdene. Ali ste prepričani, da vaša naprava to podpira?</string>
<string name="drive_through">Vožnja skozi</string>
<string name="clear_the_search">Počisti iskanje</string>
<string name="website_menu">Povezava do menija</string>
<string name="view_menu">Oglej si meni</string>
<string name="open_in_app">Odpri v drugem orodju</string>
<string name="self_service">Samopostrežno</string>
<string name="select_option">Izberi možnost</string>
<string name="outdoor_seating">Sedišča na prostem</string>
<string name="power_save_dialog_summary">Za kar najbolj natančno navigacijo priporočamo, da v nastavitvah baterije telefona onemogočite varčevanje z energijo.</string>
<string name="start_track_recording">Snemaj sled</string>
<string name="stop_track_recording">Ustavi snemanje sledi</string>
<string name="stop_without_saving">Ustavi brez shranjevanja</string>
<string name="continue_recording">Nadaljuj snemanje</string>
<string name="track_recording_alert_title">Shrani med Zaznamke in sledi?</string>
<string name="track_recording_toast_nothing_to_save">Sled je prazna ničesar ni za shraniti</string>
<string name="error_no_file_manager_app">Pogovornega okna za izbiro mape ni mogoče prikazati, ker na vaši napravi ni nameščenega ustreznega orodja. Namestite upravitelja datotek in poskusite znova.</string>
<string name="choose_color">Izberi barvo</string>
<string name="edit_track">Uredi sled</string>
<string name="uri_open_location_failed">Ni nameščenega orodja, ki bi lahko odprlo zemljepisni položaj</string>
<string name="nav_auto">Samodejno v potnem usmerjanju</string>
<string name="zoom_in">Približaj</string>
<string name="zoom_out">Oddalji</string>
<string name="pref_left_button_title">Nastavitev levega gumba</string>
<string name="pref_backup_title">Varnostno kopiranje zaznamkov in sledi</string>
<string name="pref_backup_summary">Samodejno varnostno kopiraj v mapo na vaši napravi</string>
<string name="pref_backup_now_title">Ustvari varnostno kopijo zdaj</string>
<string name="pref_left_button_disable">Onemogoči</string>
<string name="pref_backup_now_summary_progress">Varnostno kopiranje se izvaja …</string>
<string name="pref_backup_now_summary">Nemudoma ustvari varnostno kopijo</string>
<string name="pref_backup_now_summary_ok">Varnostno kopiranje uspešno izvedeno</string>
<string name="pref_backup_now_summary_empty_lists">Ni zaznamkov in sledi za varnostno kopiranje</string>
<string name="pref_backup_now_summary_failed">Varnostno kopiranje je spodletelo</string>
<string name="pref_backup_now_summary_folder_unavailable">Mapa za varnostno kopijo ni na voljo</string>
<string name="pref_backup_status_summary_success">Zadnje uspešno kopiranje</string>
<string name="pref_backup_location_title">Mesto varnostne kopije</string>
<string name="pref_backup_location_summary_initial">Prosimo, najprej izberite mapo in podelite dovoljenja</string>
<string name="pref_backup_history_title">Število varnostnih kopij, ki jih je treba hraniti</string>
<string name="pref_backup_interval_title">Samodejno varnostno kopiranje</string>
<string name="backup_interval_manual_only">Izklopljeno (samo ročno)</string>
<string name="dialog_report_error_missing_folder">Izbrano mesto za varnostno kopijo ni na voljo ali vanjo ni mogoče pisati. Izberite drugo mesto.</string>
<string name="backup_interval_every_day">Dnevno</string>
<string name="backup_interval_every_week">Tedensko</string>
<string name="dialog_report_error_with_logs">Prosimo, pošljite nam poročilo o napaki:\n - \"Omogoči beleženje\" v nastavitvah\n - poustvarite težavo\n - na zaslonu »O programu in Pomoč« pritisnite gumb »Prijavi napako« in jo pošljite po e-pošti ali klepetu\n - onemogoči beleženje</string>
<string name="route_type">Vrsta poti</string>
<string name="vehicle">Vozilo</string>
<string name="pedestrian">Za pešce</string>
<string name="bookmark_color">Barva zaznamka</string>
<string name="about_help">O programu in Pomoč</string>
<string name="open_now">Trenutno odprto</string>
<string name="closed_now">Trenutno zaprto</string>
<string name="at">ob %s</string>
<string name="share_track">Deli sled</string>
<string name="delete_track_dialog_title">Izbriši %s?</string>
<string name="pref_tts_no_system_tts_short">Nobeno orodje za pretvorbo besedila v govor ni bilo najdeno, preverite nastavitve aplikacije</string>
<string name="charge_socket_type2">Vrsta 2 (brezžično)</string>
<string name="charge_socket_type2_combo">Vrsta 2 kombinirano</string>
<string name="charge_socket_type1">Vrsta 1</string>
<string name="charge_socket_nacs">NACS (severnoameriško polnilno omrežje)</string>
<string name="charge_socket_chademo">CHAdeMO (japonski standard za polnjenje vozil)</string>
<string name="unknown_socket_type">neznana vtičnica</string>
<string name="unknow_socket_type">neznana vtičnica</string>
<string name="edit_socket_info_tooltip">Ustvari nove vtičnice ali uredi obstoječe.</string>
<string name="charging_station_available_sockets">Razpoložljive vtičnice</string>
<string name="charge_socket_unknown_other">Druge ali neznane</string>
<string name="charge_socket_count">Število</string>
<string name="charge_socket_power">Moč (kW)</string>
<string name="editor_socket">Uredi vtičnico</string>
<string name="unknown_count">neznano</string>
<string name="error_value_must_be_positive">Vrednosti mora biti pozitivna</string>
<string name="charge_socket_type2_cable">Vrsta 2 (s kablom)</string>
<string name="clear">Počisti</string>
<string name="bicycle">Kolo</string>
<string name="unknown_power_output">neznano</string>
<string name="ruler">Ravnilo</string>
</resources>

View File

@@ -27,7 +27,7 @@
<!-- A dialog title, that warns a user that Precise Location is disabled and suggests to turn it on -->
<string name="limited_accuracy">Begränsad noggrannhet</string>
<!-- A dialog text, that warns a user that Precise Location is disabled and suggests to turn it on -->
<string name="precise_location_is_disabled_long_text">För att säkerställa korrekt navigering aktiverar du Precise Location i inställningarna.</string>
<string name="precise_location_is_disabled_long_text">Aktivera Exakt Plats i inställningarna för att säkerställa korrekt navigering</string>
<!-- View and button titles for accessibility -->
<string name="zoom_to_country">Visa på kartan</string>
<!-- Message to display at the center of the screen when the country download has failed -->
@@ -36,13 +36,13 @@
<string name="try_again">Försök igen</string>
<string name="about_menu_title">Om CoMaps</string>
<!-- Text in About screen -->
<string name="about_proposition_1">Inga annonser, ingen spårning, ingen datainsamling</string>
<string name="about_proposition_1">Lättanvändlig och finslipad</string>
<!-- Text in About screen -->
<string name="about_proposition_2">Låg batteriförbrukning, fungerar utan uppkoppling</string>
<string name="about_proposition_2">Integritetsfokuserad och fri från annonser</string>
<!-- Text in About screen -->
<string name="about_proposition_3">• Offline, snabb och kompakt</string>
<!-- Text in About screen -->
<string name="about_developed_by_enthusiasts">Öppen källkod-app skapad av entusiaster och frivilliga.</string>
<string name="about_developed_by_enthusiasts">Fullständigt öppen källkod, icke-vinstdrivande, transparent beslutsfattande och ekonomi.</string>
<!-- The button that opens system location settings -->
<string name="location_settings">Platsinställningar</string>
<string name="close">Stäng</string>

View File

@@ -146,7 +146,7 @@
<string name="category_rv">房车设施</string>
<!-- SECTION: Other translations -->
<!-- Notes field in Bookmarks view -->
<string name="description"></string>
<string name="description"></string>
<!-- Email Subject when sharing bookmark list -->
<string name="share_bookmarks_email_subject">已与您分享 CoMaps 书签</string>
<string name="share_bookmarks_email_body">您好! \n \n附件是我的书签请在 CoMaps 中打开。如果您没有安装 CoMaps可以在这里下载: https://www.comaps.app/download/ \n \n祝您使用 CoMaps 旅行愉快!</string>
@@ -473,7 +473,7 @@
<!-- Text in About and OSM Login screens. First %@ is replaced by a local, human readable date. -->
<string name="osm_presentation">截至 %s 的社区创建的 OpenStreetMap 数据。请访问 OpenStreetMap.org 以了解有关如何编辑和更新地图的信息</string>
<!-- OSM explanation on Android login screen -->
<string name="login_osm_presentation">OpenStreetMap.orgOSM是一个构建免费开放地图的社区项目。它是 CoMaps 中地图数据的主要来源,其工作原理类似于维基百科。您可以添加或编辑地点,可供全世界数以百万计的用户使用并受益。\n加入OSM,让我们共绘更优质的地图吧!</string>
<string name="login_osm_presentation">OpenStreetMap.orgOSM是一个构建自由开放地图的社区项目。它是 CoMaps 中地图数据的主要来源,其工作原理类似于维基百科。您可以添加或编辑地点,可供全世界数以百万计的用户使用并受益。\n加入社区,让我们共绘更优质的地图吧!</string>
<string name="login_to_make_edits_visible">创建 OpenStreetMap 账号或登录,向全世界发布您编辑的地图</string>
<!-- Downloaded 10 **of** 20 <- it is that "of" -->
<string name="downloader_of">%1$d / %2$d</string>
@@ -485,14 +485,14 @@
<string name="editor_zip_code">邮政编码</string>
<string name="error_enter_correct_zip_code">输入有效的邮政编码</string>
<!-- Title for OSM note section in the editor -->
<string name="editor_other_info">OpenStreetMap 志愿者须知(可选</string>
<string name="editor_other_info">OpenStreetMap 志愿者注记(选填</string>
<!-- Hint of the input field in the OSM note section of the editor -->
<string name="editor_note_hint">描述地图上的错误或无法使用 CoMaps 编辑的内容</string>
<!-- Information about OSM at the top of the editing page -->
<string name="editor_about_osm">您的编辑内容将上传到公共<a href="https://wiki.openstreetmap.org/wiki/Zh-hans:关于">OpenStreetMap</a>数据库。请勿添加个人或受版权保护的信息。</string>
<string name="editor_more_about_osm">关于 OpenStreetMap 的更多信息</string>
<string name="editor_osm_history">您的编辑历史</string>
<string name="editor_osm_notes">您的地图数据说明</string>
<string name="editor_osm_notes">您的地图数据注记</string>
<string name="editor_operator">操作员</string>
<!-- To indicate the operator of ATMs, bicycle rentals, electric vehicle charging stations... -->
<string name="operator">操作员: %s</string>
@@ -509,7 +509,7 @@
<string name="day"></string>
<string name="placepage_more_button">更多</string>
<string name="placepage_edit_bookmark_button">编辑书签</string>
<string name="placepage_personal_notes_hint">个人注(文字或 html</string>
<string name="placepage_personal_notes_hint">个人注(文字或 html</string>
<string name="editor_reset_edits_message">重置所有本地更改?</string>
<string name="editor_reset_edits_button">重置</string>
<string name="editor_remove_place_message">删除已添加的地点?</string>
@@ -866,8 +866,8 @@
<string name="closed_now">已歇业</string>
<string name="open_now">营业中</string>
<string name="at">%s</string>
<string name="osm_note_hint">或者,也可以给 OpenStreetMap 社区留,以便其他人可以在此添加或修复地点。</string>
<string name="osm_note_toast">将发送至 OpenStreetMap</string>
<string name="osm_note_hint">或者,也可以给 OpenStreetMap 社区留下注记,以便其他人可以在此添加或修复地点。</string>
<string name="osm_note_toast">将发送至 OpenStreetMap</string>
<string name="existence_confirmed_time_ago">已于%s确认地点存在</string>
<string name="delete_track_dialog_title">是否删除%s</string>
<string name="hours_confirmed_time_ago">已于%s确认</string>
@@ -891,4 +891,8 @@
<string name="unknown_count">未知</string>
<string name="error_value_must_be_positive">值必须为正数</string>
<string name="error_invalid_number">无效的数字</string>
<string name="editor_place_doesnt_exist_description">描述该地点的现状,以便向 OpenStreetMap 社区发送错误注记</string>
<string name="avoid_steps">避开台阶</string>
<string name="offline_explanation_title">离线地图</string>
<string name="offline_explanation_text">需要下载地图才能查看并在该区域内导航。\n请为您计划前往的区域下载地图。</string>
</resources>

View File

@@ -50,21 +50,4 @@
<item>8</item>
<item>10</item>
</string-array>
<!-- Location Sharing Update Intervals -->
<string-array name="location_sharing_intervals">
<item>5 seconds</item>
<item>10 seconds</item>
<item>20 seconds</item>
<item>30 seconds</item>
<item>60 seconds</item>
</string-array>
<string-array name="location_sharing_interval_values">
<item>5</item>
<item>10</item>
<item>20</item>
<item>30</item>
<item>60</item>
</string-array>
</resources>

View File

@@ -124,7 +124,6 @@
<color name="elevation_profile">@color/base_accent</color>
<color name="active_track_recording">#0057ff</color>
<color name="active_location_sharing">#FF9500</color>
<color name="material_calendar_surface_dark">#929292</color>
<color name="notification_warning">#FFC22219</color>

View File

@@ -210,9 +210,6 @@
<!-- Length of track in cell that describes route -->
<string name="length">Length</string>
<string name="share_my_location">Share My Location</string>
<string name="stop_sharing_my_location">Stop Sharing My Location</string>
<string name="share_location_coordinates">Share Current Coordinates</string>
<string name="share_location_live">Start Live Location Sharing</string>
<!-- Settings general group in settings screen -->
<string name="prefs_group_general">General settings</string>
<!-- Settings information group in settings screen -->
@@ -679,7 +676,7 @@
<!-- Recommended length for CarPlay and Android Auto is around 25-27 characters -->
<string name="avoid_ferry">Avoid ferries</string>
<string name="avoid_motorways">Avoid freeways</string>
<string name="avoid_steps">Avoid steps</string>
<string name="avoid_steps">Avoid stairs</string>
<string name="unable_to_calc_alert_title">Unable to calculate route</string>
<string name="unable_to_calc_alert_subtitle">A route could not be found. This may be caused by your routing options or incomplete OpenStreetMap data. Please change your routing options and retry.</string>
<string name="define_to_avoid_btn">Define roads to avoid</string>

View File

@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Location Sharing -->
<string name="location_sharing_title">Live Location Sharing</string>
<string name="location_sharing_start">Start Sharing</string>
<string name="location_sharing_stop">Stop Sharing</string>
<string name="location_sharing_active">Sharing live location</string>
<string name="location_sharing_status_active">Your location is being shared</string>
<string name="location_sharing_status_inactive">Location sharing is not active</string>
<!-- Notification -->
<string name="location_sharing_notification_text">Your live location is being shared</string>
<string name="location_sharing_tap_to_view">Tap to view in app</string>
<string name="location_sharing_eta">ETA: %s</string>
<string name="location_sharing_remaining">remaining</string>
<string name="location_sharing_accuracy">Accuracy: %s</string>
<string name="location_sharing_accuracy_high">high</string>
<string name="location_sharing_accuracy_medium">medium</string>
<string name="location_sharing_accuracy_low">low</string>
<string name="location_sharing_waiting_for_location">Waiting for location…</string>
<!-- Messages -->
<string name="location_sharing_started">Location sharing started</string>
<string name="location_sharing_stopped">Location sharing stopped</string>
<string name="location_sharing_failed_to_start">Failed to start location sharing</string>
<string name="location_sharing_url_copied">Share URL copied to clipboard</string>
<string name="location_sharing_share_message">Follow my live location: %s</string>
<!-- Dialog -->
<string name="location_sharing_description">Share your real-time location with end-to-end encryption. Only people with the link can view your location.</string>
<string name="location_sharing_copy_url">Copy Link</string>
<string name="location_sharing_share_url">Share Link</string>
<!-- Using existing close string from main strings.xml -->
<!-- Settings -->
<string name="pref_location_sharing_category">Live Location Sharing</string>
<string name="pref_location_sharing_update_interval">Update interval</string>
<string name="pref_location_sharing_update_interval_summary">How often to send location updates</string>
<string name="pref_location_sharing_server_url">Server URL</string>
<string name="pref_location_sharing_server_url_summary">Location sharing server endpoint</string>
</resources>

View File

@@ -47,7 +47,7 @@
<item name="navNextTurnFrame">@drawable/bg_nav_next_turn</item>
<item name="navNextNextTurnFrame">@drawable/bg_nav_next_next_turn</item>
<item name="navLanesBackgroundColor">@color/base_accent</item>
<item name="navLanesBackgroundColor">@color/bg_primary</item>
<item name="navLaneArrowActiveColor">@color/nav_lane_arrow_active</item>
<item name="navLaneArrowInactiveColor">@color/nav_lane_arrow_inactive</item>

View File

@@ -159,27 +159,6 @@
</intent>
</PreferenceScreen>
</androidx.preference.PreferenceCategory>
<androidx.preference.PreferenceCategory
android:key="@string/pref_location_sharing_category"
android:title="@string/location_sharing_title"
android:order="5">
<EditTextPreference
android:key="@string/pref_location_sharing_server_url"
android:title="@string/pref_location_sharing_server_url"
app:singleLineTitle="false"
android:summary="@string/pref_location_sharing_server_url_summary"
android:defaultValue="https://live.organicmaps.app"
android:order="1"/>
<ListPreference
android:key="@string/pref_location_sharing_update_interval"
android:title="@string/pref_location_sharing_update_interval"
app:singleLineTitle="false"
android:summary="@string/pref_location_sharing_update_interval_summary"
android:entries="@array/location_sharing_intervals"
android:entryValues="@array/location_sharing_interval_values"
android:defaultValue="20"
android:order="2"/>
</androidx.preference.PreferenceCategory>
<androidx.preference.PreferenceCategory
android:key="@string/pref_privacy"
android:title="@string/privacy"

View File

@@ -53,7 +53,6 @@ set(SRC
app/organicmaps/sdk/editor/OpeningHours.cpp
app/organicmaps/sdk/editor/OsmOAuth.cpp
app/organicmaps/sdk/Framework.cpp
app/organicmaps/location/LocationSharingJni.cpp
app/organicmaps/sdk/isolines/IsolinesManager.cpp
app/organicmaps/sdk/LocationState.cpp
app/organicmaps/sdk/Map.cpp
@@ -95,7 +94,6 @@ target_include_directories(${PROJECT_NAME} PRIVATE .)
target_link_libraries(${PROJECT_NAME}
# CoMaps libs
map
location_sharing
# ge0
# tracking
# routing

View File

@@ -1,76 +0,0 @@
#include "app/organicmaps/sdk/core/jni_helper.hpp"
#include "location_sharing/location_sharing_types.hpp"
#include "location_sharing/crypto_util.hpp"
#include "base/logging.hpp"
#include <jni.h>
using namespace location_sharing;
extern "C"
{
// Generate session credentials
JNIEXPORT jobjectArray JNICALL
Java_app_organicmaps_location_LocationSharingManager_nativeGenerateSessionCredentials(
JNIEnv * env, jclass)
{
SessionCredentials creds = SessionCredentials::Generate();
// Create String array [sessionId, encryptionKey]
jobjectArray result = env->NewObjectArray(2, env->FindClass("java/lang/String"), nullptr);
if (!result)
{
LOG(LERROR, ("Failed to create result array"));
return nullptr;
}
jstring sessionId = jni::ToJavaString(env, creds.sessionId);
jstring encryptionKey = jni::ToJavaString(env, creds.encryptionKey);
env->SetObjectArrayElement(result, 0, sessionId);
env->SetObjectArrayElement(result, 1, encryptionKey);
env->DeleteLocalRef(sessionId);
env->DeleteLocalRef(encryptionKey);
return result;
}
// Generate share URL
JNIEXPORT jstring JNICALL
Java_app_organicmaps_location_LocationSharingManager_nativeGenerateShareUrl(
JNIEnv * env, jclass, jstring jSessionId, jstring jEncryptionKey, jstring jServerBaseUrl)
{
std::string sessionId = jni::ToNativeString(env, jSessionId);
std::string encryptionKey = jni::ToNativeString(env, jEncryptionKey);
std::string serverBaseUrl = jni::ToNativeString(env, jServerBaseUrl);
SessionCredentials creds(sessionId, encryptionKey);
std::string shareUrl = creds.GenerateShareUrl(serverBaseUrl);
return jni::ToJavaString(env, shareUrl);
}
// Encrypt payload
JNIEXPORT jstring JNICALL
Java_app_organicmaps_location_LocationSharingManager_nativeEncryptPayload(
JNIEnv * env, jclass, jstring jEncryptionKey, jstring jPayloadJson)
{
std::string encryptionKey = jni::ToNativeString(env, jEncryptionKey);
std::string payloadJson = jni::ToNativeString(env, jPayloadJson);
auto encryptedOpt = crypto::EncryptAes256Gcm(encryptionKey, payloadJson);
if (!encryptedOpt.has_value())
{
LOG(LERROR, ("Encryption failed"));
return nullptr;
}
std::string resultJson = encryptedOpt->ToJson();
return jni::ToJavaString(env, resultJson);
}
} // extern "C"

View File

@@ -88,7 +88,7 @@ public class Metadata implements Parcelable
if (type.mMetaType == metaType)
return type;
throw new IllegalArgumentException("Illegal metaType: " + metaType);
return -1;
}
public int toInt()
@@ -102,6 +102,9 @@ public class Metadata implements Parcelable
public void addMetadata(int metaType, String metaValue)
{
final MetadataType type = MetadataType.fromInt(metaType);
if (type == -1)
return;
mMetadataMap.put(type, metaValue);
}

View File

@@ -515,46 +515,6 @@ public final class Config
}
}
public static class LocationSharing
{
interface Keys
{
String SERVER_URL = "LocationSharingServerUrl";
String UPDATE_INTERVAL = "LocationSharingUpdateInterval";
}
public interface Defaults
{
String SERVER_URL = "https://live.organicmaps.app";
int UPDATE_INTERVAL = 20; // seconds
int UPDATE_INTERVAL_MIN = 5;
int UPDATE_INTERVAL_MAX = 60;
}
@NonNull
public static String getServerUrl()
{
return getString(Keys.SERVER_URL, Defaults.SERVER_URL);
}
public static void setServerUrl(@NonNull String url)
{
setString(Keys.SERVER_URL, url);
}
public static int getUpdateInterval()
{
return getInt(Keys.UPDATE_INTERVAL, Defaults.UPDATE_INTERVAL);
}
public static void setUpdateInterval(int seconds)
{
if (seconds < Defaults.UPDATE_INTERVAL_MIN || seconds > Defaults.UPDATE_INTERVAL_MAX)
seconds = Defaults.UPDATE_INTERVAL;
setInt(Keys.UPDATE_INTERVAL, seconds);
}
}
private static native boolean nativeHasConfigValue(String name);
private static native boolean nativeDeleteConfigValue(String name);
private static native boolean nativeGetBoolean(String name, boolean defaultValue);

View File

@@ -1259,4 +1259,19 @@
<string name="type.barrier.cycle_barrier">Sykkelbarriere</string>
<string name="type.highway.ladder">Stige</string>
<string name="type.barrier.guard_rail">Autovern</string>
<string name="type.piste_type.sled">Akebakke</string>
<string name="type.piste_type.sled.area">Akebakke</string>
<string name="type.man_made.pipeline">Rørledning</string>
<string name="type.man_made.survey_point">Landmålingspunkt</string>
<string name="type.man_made.cairn">Varde</string>
<string name="type.man_made">Menneskeskapt</string>
<string name="type.landuse.retail">Butikkområde</string>
<string name="type.landuse.quarry">Steinbrudd</string>
<string name="type.landuse.military">Militært område</string>
<string name="type.landuse.industrial">Industriområde</string>
<string name="type.barrier.retaining_wall">Støttemur</string>
<string name="type.recycling.cartons">Kartonger</string>
<string name="type.recycling.green_waste">Organisk avfall</string>
<string name="type.recycling.cans">Bokser</string>
<string name="type.recycling.cardboard">Papp</string>
</resources>

View File

@@ -431,7 +431,6 @@
<string name="type.highway.pedestrian.area">Obszar deptaka</string>
<!-- These translations are used for all type.highway.*.bridge. -->
<string name="type.highway.pedestrian.bridge">Most dla pieszych</string>
<string name="type.highway.pedestrian.square">Plac</string>
<!-- These translations are used for all type.highway.*.tunnel. -->
<string name="type.highway.pedestrian.tunnel">Tunel dla pieszych</string>
@@ -1395,4 +1394,7 @@
<string name="type.amenity.ranger_station">Budynek obsługi parku</string>
<string name="type.power.portal">Portal elektroenergetyczny</string>
<string name="type.office.security">Biuro ochrony</string>
<string name="type.shop.lighting">Sklep oświetleniowy</string>
<string name="type.barrier.wicket_gate">Furtka</string>
<string name="type.leisure.escape_game">Escape Room</string>
</resources>

View File

@@ -15,23 +15,23 @@
<string name="type.amenity.bbq">Grătar</string>
<string name="type.amenity.bench">Banchetă</string>
<string name="type.amenity.bicycle_parking">Parcare biciclete</string>
<string name="type.amenity.bicycle_rental">Închiriere de biciclete</string>
<string name="type.amenity.bicycle_rental">Închiriere biciclete</string>
<string name="type.amenity.biergarten">Berărie</string>
<string name="type.amenity.brothel">Bordel</string>
<string name="type.amenity.bureau_de_change">Schimb valutar</string>
<string name="type.amenity.bus_station">Gara de autobuz</string>
<string name="type.amenity.bus_station">Autogară</string>
<string name="type.amenity.cafe">Cafenea</string>
<string name="type.amenity.car_rental">Închiriere mașini</string>
<string name="type.amenity.motorcycle_rental">Închiriere motociclete</string>
<string name="type.amenity.car_wash">Spălătorie Auto</string>
<string name="type.amenity.casino">Casinou</string>
<string name="type.amenity.casino">Cazinou</string>
<string name="type.amenity.gambling">Jocuri de noroc</string>
<string name="type.leisure.adult_gaming_centre">Centru de jocuri pentru adulți</string>
<string name="type.leisure.amusement_arcade">Arcadă</string>
<string name="type.amenity.charging_station">Stație încărcare</string>
<string name="type.amenity.charging_station.bicycle">Stație de încărcare pentru biciclete</string>
<string name="type.amenity.charging_station.motorcar">Stație de încărcare autoturisme</string>
<string name="type.amenity.childcare">De îngrijire a copilului</string>
<string name="type.amenity.childcare">Creșă</string>
<string name="type.leisure.bowling_alley">Popicărie</string>
<string name="type.amenity.clinic">Clinică</string>
<string name="type.amenity.college">Colegiu</string>
@@ -1177,7 +1177,7 @@
<string name="type.aeroway.runway">Pistă</string>
<string name="type.aeroway.taxiway">Cale de rulare</string>
<string name="type.aeroway.terminal">Terminal</string>
<string name="type.amenity.bar">Bară</string>
<string name="type.amenity.bar">Bar</string>
<string name="type.amenity.bicycle_parking.covered">Parcare acoperită pentru biciclete</string>
<string name="type.amenity.love_hotel">Hotel cu ora</string>
<string name="type.amenity.studio">Garsonieră</string>

View File

@@ -2,4 +2,5 @@
<resources>
<string name="core_my_position">Moj položaj</string>
<string name="core_my_places">Moji kraji</string>
<string name="gb">GB</string>
</resources>

View File

@@ -5,4 +5,5 @@
<string name="type.addr_interpolation">Naslov/blok</string>
<string name="type.aerialway.cable_car">Žičnica</string>
<string name="type.cuisine.noodles">Nudli</string>
<string name="type.addr_interpolation.even">Naslov/Blok</string>
</resources>

View File

@@ -178,7 +178,7 @@
<string name="type.amenity.vending_machine.sweets">Аутомат за слаткише</string>
<string name="type.amenity.vending_machine.excrement_bags">Кесе за псећи измет</string>
<string name="type.amenity.parcel_locker">Пакетомат</string>
<string name="type.amenity.vehicle_inspection">Контрола возила</string>
<string name="type.amenity.vehicle_inspection">Технички преглед возила</string>
<string name="type.amenity.vending_machine.fuel">Пумпа за гориво</string>
<string name="type.amenity.veterinary">Ветеринар</string>
<string name="type.amenity.waste_basket">Канта за смеће</string>
@@ -1243,7 +1243,7 @@
<string name="type.tourism">Туризам</string>
<string name="type.tourism.aquarium">Акваријум</string>
<!-- Typically serviced, staff is present and food is available (compared to wilderness_hut). -->
<string name="type.tourism.alpine_hut">Планинарска колиба</string>
<string name="type.tourism.alpine_hut">Планинарски дом</string>
<string name="type.tourism.apartment">Апартман</string>
<string name="type.tourism.artwork">Уметничка скулптура</string>
<string name="type.tourism.artwork.architecture">Архитектонско уметничко дело</string>

View File

@@ -101,6 +101,13 @@ if [ -z "$SKIP_MAP_DOWNLOAD" ]; then
rm -f WorldCoasts.mwm; ln -s "$WORLD_PATH2" WorldCoasts.mwm
fi
if [ ! -f "World.mwm" ]; then
ln -s "$WORLD_PATH" World.mwm
fi
if [ ! -f "WorldCoasts.mwm" ]; then
ln -s "$WORLD_PATH2" WorldCoasts.mwm
fi
popd
else
echo "Skipping world map download..."

View File

@@ -463,5 +463,6 @@
"shop-alcohol|@category_food|@shop": "Магазин за алкохол|4алкохол|5спиртни напитки|U+1F377",
"shop-caravan|@category_rv|@shop": "Автокъща за кемпери|кемпери|каравани|къщи на колела",
"leisure-dance|@category_entertainment": "Зала за танци|Танцово училище|Танцова школа|танци",
"leisure-firepit": "4Огнище"
"leisure-firepit": "4Огнище",
"amenity-arts_centre|@category_tourism": "3Арт център|Център за изкуства"
}

View File

@@ -408,5 +408,6 @@
"shop-hearing_aids|@shop": "Aparelhos Auditivos",
"railway-station-funicular": "Funicular",
"historic-citywalls|@category_tourism": "Muralha da Cidade",
"historic-fort|@category_tourism": "Fortaleza"
"historic-fort|@category_tourism": "Fortaleza",
"historic-battlefield": "Campo de batalha"
}

View File

@@ -146,11 +146,11 @@
<p lang="uk"><strong>CoMaps</strong> був би неможливим без щедрої участі таких проектів:</p>
<ul class="license-list">
<li><a href="http://antigrain.com/">Anti-Grain Geometry</a><br>&copy; 2002&ndash;2005 Maxim Shemanarev; <a href="#agg-license" class="license">License</a></li>
<li><a href="https://agg.sourceforge.net/antigrain.com/index.html">Anti-Grain Geometry</a><br>&copy; 2002&ndash;2005 Maxim Shemanarev; <a href="#agg-license" class="license">License</a></li>
<li><a href="http://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="http://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>;
<a href="#bsd3-license" class="license">BSD License</a></li>
@@ -167,7 +167,7 @@
<li><a href="https://github.com/thisistherk/fast_obj">fast_obj</a><br>
&copy; 2013 thisistherk; <a href="#mit-license" class="license">MIT License</a></li>
<li><a href="http://www.freetype.org">FreeType</a><br>
<li><a href="https://www.freetype.org">FreeType</a><br>
&copy; 2013 The FreeType Project; <a href="#freetype-license" class="license">FTL</a></li>
<li><a href="https://stephenberry.github.io/glaze/">glaze</a><br>
@@ -176,16 +176,16 @@
<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="http://www.g-truc.net/project-0016.html">GLM</a><br>
<li><a href="https://www.g-truc.net/project-0016.html">GLM</a><br>
&copy; 2005&ndash;2014 G-Truc Creation; <a href="#mit-license" class="license">MIT License</a></li>
<li><a href="http://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="http://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="http://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>
@@ -197,7 +197,7 @@
<li><a href="https://github.com/google/protobuf">Protobuf</a><br>
&copy; 2014 Google Inc.; <a href="#bsd3-license" class="license">BSD License</a></li>
<li><a href="http://pugixml.org/">Pugixml</a><br>
<li><a href="https://pugixml.org/">Pugixml</a><br>
&copy; 2006-2015 Arseny Kapoulkine; <a href="#mit-license" class="license">MIT License</a></li>
<li><a href="https://github.com/ot/succinct">succinct library</a><br>
@@ -212,7 +212,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="http://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>
@@ -282,22 +282,22 @@
<p lang="uk">Ми також користувалися такими чудовими шрифтами для написів на карті:</p>
<ul class="license-list">
<li><a href="https://www.google.com/fonts/specimen/Roboto">Roboto</a><br>
<li><a href="https://fonts.google.com/specimen/Roboto">Roboto</a><br>
&copy; 2015 Christian Robertson; <a href="#apache2-license" class="license">Apache License</a></li>
<li><a href="http://www.droidfonts.com/droidfonts/">Droid Sans Fallback</a><br>
<li><a href="https://www.droidfonts.com/droidfonts/">Droid Sans Fallback</a><br>
&copy; Ascender Corporation; <a href="#apache2-license" class="license">Apache License</a></li>
<li><a href="http://dejavu-fonts.org/">DejaVu Sans</a><br>
<li><a href="https://dejavu-fonts.org/">DejaVu Sans</a><br>
&copy; 2003 Bitstream Inc., &copy; 2006 Tavmjong Bah; <a href="#dejavufonts-license" class="license">License</a></li>
<li><a href="https://sites.google.com/site/chrisfynn2/home/fonts/jomolhari">Jomolhari</a><br>
<li><a href="https://fonts.google.com/specimen/Jomolhari">Jomolhari</a><br>
&copy; Christopher Fynn; <a href="#sil-license" class="license">OFL</a></li>
<li><a href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;id=padauk">Padauk</a><br>
<li><a href="https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;id=padauk">Padauk</a><br>
&copy; 2011 SIL International; <a href="#sil-license" class="license">OFL</a></li>
<li><a href="http://www.khmeros.info/en/fonts">Khmer OS</a><br>
<li><a href="https://www.khmeros.info/en/fonts">Khmer OS</a><br>
&copy; 2005 Danh Hong, &copy; 2005 Open Forum of Cambodia; <a href="#lgpl21-license" class="license">LGPL</a></li>
<li>Code2000 Font<br>
@@ -312,7 +312,7 @@
<li><a href="https://github.com/FortAwesome/Font-Awesome">Font Awesome Free</a><br>
&copy; 2021 Fonticons, Inc.; <a href="#cc-by-4" class="license">CC BY 4.0 License</a></li>
<li><a href="http://www.evericons.com/">Evericon</a><br>
<li><a href="https://www.evericons.com/">Evericon</a><br>
&copy; 2018 Aleksey Popov; <a href="#cc0-1" class="license">CC0 1.0 Universal</a>.</li>
<li><a href="https://github.com/Remix-Design/remixicon">Remixicon</a><br>

View File

@@ -1937,7 +1937,7 @@
"Latvia Description":"Riia, Daugavpils, Liepāja",
"Lebanon Description":"Beirut, Zaḩlah, Siidon",
"Liberia Description":"Monrovia, Sanniquellie, Fish Town City",
"Libya Description":"Tripoli, Benghazi, Misrata",
"Libya Description":"Tripoli, Benghazi, Mişrātah",
"Liechtenstein Description":"Vaduz, Schaan, Triesen",
"Lithuania_East Description":"Vilnius, Kaunas, Alytus",
"Lithuania_West Description":"Klaipėda, Šiauliai, Panevėžys",
@@ -1946,7 +1946,7 @@
"Madagascar Description":"Antananarivo, Toamasina, Fianarantsoa",
"Malawi Description":"Lilongwe, Blantyre, Mzuzu",
"Malaysia Description":"Kuala Lumpur, Petaling Jaya, Kota Kinabalu",
"Maldives Description":"Feridhoo, Malé, Dhiggiri",
"Maldives Description":"Malé, Feridhoo, Dhiggiri",
"Mali Description":"Bamako, Koulikoro, Ségou",
"Malta Description":"Valletta, Victoria, Zebbug",
"Marshall Islands Description":"Majuro, Jelter, Ebeye",
@@ -1958,27 +1958,27 @@
"Mexico_Central_West Description":"Guadalajara, Aguascalientes, Zapopan",
"Mexico_Chihuahua Description":"Ciudad Juárez, Chihuahua, Ciudad Acuña",
"Mexico_East Description":"Mérida, Villahermosa, Cancún",
"Mexico_Mexico Description":"Mexico City, Puebla, Cuautitlán Izcalli",
"Mexico_Sonora Description":"Hermosillo, Ciudad Obregon, Heroica Nogales",
"Mexico_Mexico Description":"México, Puebla, Cuautitlán Izcalli",
"Mexico_Sonora Description":"Hermosillo, Ciudad Obregón, Nogales",
"Mexico_South Description":"León, Querétaro, Acapulco",
"Moldova Description":"Chișinău, Tiraspol, Bălți",
"Monaco Description":"Monaco, Monaco",
"Mongolia Description":"Ulaanbaatar, Khovd, Erdenet",
"Montenegro Description":"Podgorica, Niksic, Tuzi",
"Mongolia Description":"Ulaanbaatar, Hovd, Erdenet",
"Montenegro Description":"Podgorica, Nikšić, Tuzi",
"Montserrat Description":"Brades, Salem",
"Morocco_Doukkala-Abda Description":"Casablanca, Marrakesh, Safi",
"Morocco_Rabat-Sale-Zemmour-Zaer Description":"Fez, Rabat, Salé",
"Morocco_Southern Description":"Meknès, Agadir, Oujda",
"Morocco_Western Sahara Description":"Laayoune, Guelmim, Assa",
"Morocco_Doukkala-Abda Description":"Casablanca, Marrakech, Safi",
"Morocco_Rabat-Sale-Zemmour-Zaer Description":"Fès, Rabat, Salé",
"Morocco_Southern Description":"Meknes, Agadir, Oujda",
"Morocco_Western Sahara Description":"El Aaiún, Guelmim, Assa",
"Mozambique Description":"Maputo, Matola, Praia de Bilene",
"Myanmar Description":"Yangon, Naypyidaw, Mandalay",
"Nagorno-Karabakh Description":"Khankendi, Shusha, Lachin",
"Nagorno-Karabakh Description":"Xankəndi, Şuşa, Laçın",
"Namibia Description":"Windhoek, Opuwo, Eenhana",
"Nauru Description":"Yaren, Buada, Orro",
"Nepal_Kathmandu Description":"Katmandu, Patan",
"Nepal_Madhyamanchal Description":"Bharatpur, Birganj",
"Nepal_Purwanchal Description":"Sarang Pada, Campa Bazzar, Kerkha Bazar",
"Nepal_West Description":"Butwal, Pokhara, Nepalgunj Sub Metropolitan City",
"Nepal_West Description":"Butwal, Pokhara, Nepalgunj",
"Netherlands_Drenthe Description":"Assen, Emmen, Hoogeveen",
"Netherlands_Flevoland Description":"Almere, Lelystad, Dronten",
"Netherlands_Friesland Description":"Leeuwarden, Drachten, Sneek",
@@ -2012,7 +2012,7 @@
"Nigeria_North Description":"Kano, Maiduguri, Sokoto",
"Nigeria_South Description":"Lagos, Ibadan, Abuja",
"Niue Description":"Alofi, Liku, Lakepa",
"North Korea Description":"Pyongyang, Hamhung, Nampo",
"North Korea Description":"Pyongyang, Hamhŭng, Namp'o",
"Norway_Central Description":"Oslo, Sandvika, Drammen",
"Norway_Hedmark Description":"Brumunddal, Hamar, Elverum",
"Norway_Hordaland Description":"Bergen, Leirvik, Vossevangen",
@@ -2029,7 +2029,7 @@
"Oman Description":"Muscat, Al Khasal, As Suwaiq",
"Pakistan Description":"Karachi, Lahore, Faisalabad",
"Palau Description":"Melekeok, Palau, Koror",
"Palestine Description":"Gaza, Modi'in Illit, Nablus",
"Palestine Description":"Gaza, Petlemm, Nablus",
"Panama Description":"Panama, Santiago de Veraguas, Colón",
"Papua New Guinea Description":"Port Moresby, Lae, Vanimo",
"Paraguay Description":"Asuncion, San Lorenzo, Ciudad del Este",

View File

@@ -4,7 +4,7 @@
"Alabama":"Alabama",
"Albania":"Albánia",
"Algeria":"Algéria",
"Algeria_Central":"Algéria - Közép",
"Algeria_Central":"Algéria - közép",
"Algeria_Coast":"Algéria - észak",
"Andorra":"Andorra",
"Angola":"Angola",
@@ -103,7 +103,7 @@
"California":"Kalifornia",
"Cambodia":"Kambodzsa",
"Cameroon":"Kamerun",
"Cameroon_Central":"Kamerun - Közép",
"Cameroon_Central":"Kamerun - közép",
"Cameroon_West":"Kamerun - nyugat",
"Campo de Hielo Sur":"Dél-patagóniai jégmező",
"Canada":"Kanada",
@@ -112,7 +112,7 @@
"Canada_Alberta_North":"Alberta - észak",
"Canada_Alberta_South":"Alberta - dél",
"Canada_British Columbia":"Brit Columbia",
"Canada_British Columbia_Central":"Brit Columbia - Közép",
"Canada_British Columbia_Central":"Brit Columbia - közép",
"Canada_British Columbia_Far_North":"Brit Columbia - kelet",
"Canada_British Columbia_Islands":"Vancouver-sziget",
"Canada_British Columbia_North":"Brit Columbia - nyugat",
@@ -804,7 +804,7 @@
"Russia_Altai Krai":"Altaji határterület",
"Russia_Altai Republic":"Altaji Köztársaság",
"Russia_Amur Oblast":"Amuri terület",
"Russia_Arkhangelsk Oblast_Central":"Arhangelszki terület - Közép",
"Russia_Arkhangelsk Oblast_Central":"Arhangelszki terület - közép",
"Russia_Arkhangelsk Oblast_North":"Arhangelszki terület - észak",
"Russia_Astrakhan Oblast":"Asztraháni terület",
"Russia_Bashkortostan":"Baskír Köztársaság",
@@ -1211,10 +1211,10 @@
"Brazil_South Region_West":"Déli régió - nyugat",
"Bulgaria_East":"Bulgária - kelet",
"Bulgaria_West":"Bulgária - nyugat",
"Chile_Central":"Chile - Közép",
"Chile_Central":"Chile - közép",
"Congo-Kinshasa_Kivu":"Kivu",
"Congo-Kinshasa_West":"Kongó - nyugat",
"Croatia_Central":"Horvátország - Közép",
"Croatia_Central":"Horvátország - közép",
"Croatia_West":"Horvátország - nyugat",
"Ecuador_East":"Ecuador - kelet",
"Ecuador_West":"Ecuador - nyugat",
@@ -1285,7 +1285,7 @@
"Switzerland_Espace Mittelland_East":"Espace Mittelland kelet",
"Taiwan_North":"Tajvan észak",
"Taiwan_South":"Tajvan dél",
"Thailand_Central":"Thaiföld - Közép",
"Thailand_Central":"Thaiföld - közép",
"Turkey_Central Anatolia Region_Ankara":"Közép-Anatólia - Ankara",
"Turkey_Central Anatolia Region_Kayseri":"Közép-Anatólia - Kayseri",
"Turkey_Marmara Region_Bursa":"Márvány-tengeri régió - Bursa",

View File

@@ -646,7 +646,7 @@
"Kingdom of Lesotho":"Лесото",
"Kiribati":"Кирибати",
"Kuwait":"Кувейт",
"Kyrgyzstan":"Киргизия",
"Kyrgyzstan":"Кыргызстан",
"Laos":"Лаос",
"Latvia":"Латвия",
"Lebanon":"Ливан",
@@ -1817,7 +1817,7 @@
"Isle of Man Description":"Дуглас",
"Israel Description":"Тель-Авив-Яффа, Герцлия, Модиин-Маккабим-Реут",
"Italy_Abruzzo Description":"Пескара",
"Italy_Aosta Valley Description":"Аоста, Аоста",
"Italy_Aosta Valley Description":"Куарт, Аоста",
"Italy_Apulia Description":"Бари, Таранто, Фоджа",
"Italy_Basilicata Description":"Потенца, Матера",
"Italy_Calabria Description":"Реджо-ди-Калабрия, Катандзаро, Козенца",
@@ -1839,21 +1839,21 @@
"Italy_Liguria Description":"Генуя, Специя, Специя",
"Italy_Lombardy_Bergamo Description":"Бергамо",
"Italy_Lombardy_Brescia Description":"Бреша",
"Italy_Lombardy_Como Description":"Комо, Комо",
"Italy_Lombardy_Cremona Description":"Кремона, Кремона",
"Italy_Lombardy_Como Description":"Комо, Канту",
"Italy_Lombardy_Cremona Description":"Кремона, Трескоре-Кремаско",
"Italy_Lombardy_Lecco Description":"Лекко",
"Italy_Lombardy_Lodi Description":"Лоди",
"Italy_Lombardy_Mantua Description":"Мантуя, Мантуя",
"Italy_Lombardy_Mantua Description":"Мантуя, Судзара",
"Italy_Lombardy_Milan Description":"Милан",
"Italy_Lombardy_Monza and Brianza Description":"Монца",
"Italy_Lombardy_Pavia Description":"Павия",
"Italy_Lombardy_Sondrio Description":"Сондрио, Сондрио",
"Italy_Lombardy_Sondrio Description":"Сондрио, Морбеньо",
"Italy_Lombardy_Varese Description":"Бусто-Арсицио, Варезе",
"Italy_Marche Description":"Анкона, Пезаро",
"Italy_Molise Description":"Кампобассо",
"Italy_Piemont_Alessandria Description":"Алессандрия, Нови-Лигуре",
"Italy_Piemont_Asti Description":"Асти",
"Italy_Piemont_Biella Description":"Бьелла",
"Italy_Piemont_Biella Description":"Бьелла, Коссато",
"Italy_Piemont_Cuneo Description":"Кунео",
"Italy_Piemont_Novara Description":"Новара",
"Italy_Piemont_Torino Description":"Турин, Риволи",
@@ -1975,7 +1975,7 @@
"Nagorno-Karabakh Description":"Ханкенди, Шуша, Лачин",
"Namibia Description":"Виндхук, Опуво, Ээнхана",
"Nauru Description":"Yaren, Buada, Orro",
"Nepal_Kathmandu Description":"Катманду, Катманду",
"Nepal_Kathmandu Description":"Катманду, Патан",
"Nepal_Madhyamanchal Description":"Бхаратпур, Биргандж",
"Nepal_Purwanchal Description":"Sarang pada, Campa bazzar, Kerkha bajar",
"Nepal_West Description":"Покхара",
@@ -2330,7 +2330,7 @@
"US_Georgia_Macon Description":"Grovetown, Perry, Byron",
"US_Georgia_North Description":"Emerson, Jefferson, Cartersville",
"US_Georgia_South Description":"De Soto, Santa Claus, Pearson",
"US_Guam Description":"Dededo Flea (Market), Tumon Golf Driving Range, San José",
"US_Guam Description":"Dededo Flea Market, Tumon Golf Driving Range, San José",
"US_Hawaii Description":"Хило",
"US_Idaho_North Description":"Huetter, Peck, Hayden",
"US_Idaho_South Description":"Arco, Middleton, Greenleaf",
@@ -2470,7 +2470,7 @@
"Ukraine_Rivne Oblast Description":"Ровно, Вараш (Кузнецовск), Дубно",
"Ukraine_Sumy Oblast Description":"Сумы, Конотоп, Шостка",
"Ukraine_Ternopil Oblast Description":"Тернополь, Чортков, Кременец",
"Ukraine_Vinnytsia Oblast Description":"Винница, Жмеринка",
"Ukraine_Vinnytsia Oblast Description":"Винница, Ворошиловка, Жмеринка",
"Ukraine_Volyn Oblast Description":"Луцк, Ковель, Нововолынск",
"Ukraine_Zakarpattia Oblast Description":"Ужгород, Мукачево, Хуст",
"Ukraine_Zaporizhia Oblast Description":"Запорожье, Мелитополь, Бердянск",

View File

@@ -568,8 +568,8 @@
"Italy_Sardinia":"Sardinien",
"Italy_Sicily":"Sicilien",
"Italy_Trentino-Alto Adige Sudtirol":"Trentino-Alto Adige",
"Italy_Tuscany_Grosseto":"Toscana — Grosseto",
"Italy_Tuscany_Massa e Carrara":"Toscana — Massa-Carrara",
"Italy_Tuscany_Grosseto":"Toscana — Sydost",
"Italy_Tuscany_Massa e Carrara":"Toscana — Nordost",
"Italy_Umbria":"Umbrien",
"Italy_Veneto":"Veneto",
"Italy_Veneto_Belluno":"Belluno",

View File

@@ -1673,123 +1673,57 @@ CoMaps 的地理位置数据共享应该是启用的。</p>
<dd lang="en">
<p>Default battery optimization settings on Samsung, Huawei, Google, Xiaomi, OnePlus, Meizu, Asus, Wiko, Lenovo, Oppo, Vivo, Realme, Sony, Motorola, HTC and other devices may stop or kill CoMaps app in the background.</p>
<p>This is especially true for modern Android versions:</p>
<ul>
<li>Android 14</li>
<li>Android 13</li>
<li>Android 12</li>
<li>Android 11</li>
</ul>
<p>This is especially true for versions Android 11 and higher</p>
<p>The exact steps on how to make CoMaps (and other apps) work in the background are listed here: https://dontkillmyapp.com/</p>
</dd>
<dd lang="ru">
<p>Настройки оптимизации батареи по умолчанию на устройствах Samsung, Huawei, Google, Xiaomi, OnePlus, Meizu, Asus, Wiko, Lenovo, Oppo, Vivo, Realme, Sony, Motorola, HTC и других могут остановить или закрыть приложение CoMaps в фоновом режиме.</p>
<p>Это особенно актуально для современных версий Android:</p>
<ul>
<li>Android 14</li>
<li>Android 13</li>
<li>Android 12</li>
<li>Android 11</li>
</ul>
<p>Это особенно актуально для версий Android 11 и выше.</p>
<p>На этом сайте описано, как настроить работу в фоновом режиме для CoMaps и других приложений: https://dontkillmyapp.com/</p>
</dd><dd lang="de">
<p>Die Standardeinstellungen zur Akkuoptimierung auf Samsung, Huawei, Google, Xiaomi, OnePlus, Meizu, Asus, Wiko, Lenovo, Oppo, Vivo, Realme, Sony, Motorola, HTC und anderen Geräten können die CoMaps-App im Hintergrund stoppen oder beenden.</p>
<p>Dies gilt insbesondere für moderne Android-Versionen:</p>
<ul>
<li>Android 14</li>
<li>Android 13</li>
<li>Android 12</li>
<li>Android 11</li>
</ul>
<p>Dies gilt insbesondere für Versionen Android 11 und höher</p>
<p>Die genauen Schritte, wie man CoMaps (und andere Apps) im Hintergrund zum Laufen bringt, sind hier aufgeführt: https://dontkillmyapp.com/</p>
</dd><dd lang="es">
<p>La configuración predeterminada de optimización de la batería en Samsung, Huawei, Google, Xiaomi, OnePlus, Meizu, Asus, Wiko, Lenovo, Oppo, Vivo, Realme, Sony, Motorola, HTC y otros dispositivos puede detener o cerrar la aplicación CoMaps en segundo plano.</p>
<p>Esto ocurre especialmente en las versiones modernas de Android:</p>
<ul>
<li>Android 14</li>
<li>Android 13</li>
<li>Android 12</li>
<li>Android 11</li>
</ul>
<p>Esto es especialmente cierto para las versiones de Android 11 y superior</p>
<p>Los pasos exactos sobre cómo hacer que CoMaps (y otras aplicaciones) funcionen en segundo plano se enumeran aquí (en inglés): https://dontkillmyapp.com/</p>
</dd><dd lang="fr">
<p>Les paramètres d'optimisation de la batterie par défaut sur Samsung, Huawei, Google, Xiaomi, OnePlus, Meizu, Asus, Wiko, Lenovo, Oppo, Vivo, Realme, Sony, Motorola, HTC et d'autres appareils peuvent arrêter ou tuer l'application CoMaps en arrière-plan.</p>
<p>Cela est particulièrement vrai pour les versions modernes d'Android :</p>
<ul>
<li>Android 14</li>
<li>Android 13</li>
<li>Android 12</li>
<li>Android 11</li>
</ul>
<p>Cela est particulièrement vrai pour les versions Android 11 et supérieures</p>
<p>Les étapes exactes pour faire fonctionner CoMaps (et d'autres applications) en arrière-plan sont listées ici : https://dontkillmyapp.com/</p>
</dd><dd lang="pl">
<p>Domyślne ustawienia optymalizacji baterii na urządzeniach Samsung, Huawei, Google, Xiaomi, OnePlus, Meizu, Asus, Wiko, Lenovo, Oppo, Vivo, Realme, Sony, Motorola, HTC i innych, mogą zatrzymać aplikację CoMaps działającą w tle.</p>
<p>Dotyczy to zwłaszcza nowoczesnych wersji Androida:</p>
<ul>
<li>Android 14</li>
<li>Android 13</li>
<li>Android 12</li>
<li>Android 11</li>
</ul>
<p>Dotyczy to szczególnie wersji Android 11 i wyższych</p>
<p>Dokładne kroki, jak sprawić, by CoMaps (i inne aplikacje) działały w tle, są wymienione tutaj: https://dontkillmyapp.com/</p>
</dd><dd lang="pt">
<p>As definições predefinidas de otimização da bateria na Samsung, Huawei, Google, Xiaomi, OnePlus, Meizu, Asus, Wiko, Lenovo, Oppo, Vivo, Realme, Sony, Motorola, HTC e outros dispositivos podem parar ou encerrar a aplicação CoMaps em segundo plano.</p>
<p>Isso acontece especialmente nas versões mais modernas do Android:</p>
<ul>
<li>Android 14</li>
<li>Android 13</li>
<li>Android 12</li>
<li>Android 11</li>
</ul>
<p>Isso é especialmente verdadeiro para as versões Android 11 e superior</p>
<p>Os passos exatos sobre como fazer com que o CoMaps (e outras aplicações) funcionem em segundo plano estão listados aqui: https://dontkillmyapp.com/</p>
</dd><dd lang="pt-BR">
<p>As configurações padrão de otimização da bateria na Samsung, Huawei, Google, Xiaomi, OnePlus, Meizu, Asus, Wiko, Lenovo, Oppo, Vivo, Realme, Sony, Motorola, HTC e outros dispositivos podem interromper ou fechar o aplicativo CoMaps em segundo plano.</p>
<p>Isso acontece especialmente nas versões mais modernas do Android:</p>
<ul>
<li>Android 14</li>
<li>Android 13</li>
<li>Android 12</li>
<li>Android 11</li>
</ul>
<p>Isso é especialmente verdadeiro para as versões Android 11 e superiores</p>
<p>O passo-a-passo sobre como fazer o CoMaps (e outros aplicativos) funcionar em segundo plano pode ser encontrado aqui: https://dontkillmyapp.com/</p>
</dd><dd lang="tr">
<p>Samsung, Huawei, Google, Xiaomi, OnePlus, Meizu, Asus, Wiko, Lenovo, Oppo, Vivo, Realme, Sony, Motorola, HTC ve diğer cihazlardaki varsayılan pil optimizasyon ayarları arka planda CoMaps uygulamasını durdurabilir veya öldürebilir.</p>
<p>Bu durum özellikle modern Android sürümleri için geçerlidir:</p>
<ul>
<li>Android 14</li>
<li>Android 13</li>
<li>Android 12</li>
<li>Android 11</li>
</ul>
<p>Bu özellikle Android 11 ve üstü sürümler için geçerlidir</p>
<p>CoMaps'ın (ve diğer uygulamaların) arka planda nasıl çalışacağına ilişkin tam adımlar burada listelenmiştir: https://dontkillmyapp.com/</p>
</dd><dd lang="uk">
<p>Стандартні налаштування оптимізації роботи акумулятора на пристроях Samsung, Huawei, Google, Xiaomi, OnePlus, Meizu, Asus, Wiko, Lenovo, Oppo, Vivo, Realme, Sony, Motorola, HTC та інших пристроях можуть зупиняти або закривати додаток CoMaps у фоновому режимі.</p>
<p>Це особливо актуально для сучасних версій Android:</p>
<ul>
<li>Android 14</li>
<li>Android 13</li>
<li>Android 12</li>
<li>Android 11</li>
</ul>
<p>Особливо це стосується версій Android 11 і вище</p>
<p>На цьому сайті описано, як налаштувати роботу у фоновому режимі для CoMaps та інших додатків: https://dontkillmyapp.com/</p>
</dd><dd lang="zh">
<p>三星、华为、谷歌、小米、OnePlus、美图、华硕、Wiko、联想、Oppo、Vivo、Realme、索尼、摩托罗拉、HTC 和其他设备上的默认电池优化设置可能会在后台停止或杀死CoMaps应用程序。</p>
<p>现代安卓版本尤其如此</p>
<ul>
<li>安卓 14</li>
<li>安卓 13</li>
<li>安卓 12</li>
<li>安卓 11</li>
</ul>
<p>对于 Android 11 及更高版本来说尤其如此</p>
<p>如何让CoMaps和其他应用程序在后台工作的具体步骤在此列出https://dontkillmyapp.com/</p>
</dd>

View File

@@ -168,12 +168,12 @@
@building_label: #737373;
@poi_label: #666666;
@subway_label: #555555;
@shop_label: #8C5F93;
@food_label: #BB9342;
@culture_label: #7F5933;
@hotel_label: #6D544C;
@healthcare_label: #C15746;
@industry_label: #717065;
@shop_label: #6B425C;
@food_label: #8C491C;
@culture_label: #6E4426;
@hotel_label: #614A43;
@healthcare_label: #983E44;
@industry_label: #51585E;
@public_transport_label: #2F6499;
/* 6.4 Road labels */

View File

@@ -145,7 +145,7 @@
@hotel_label: #54413B;
@healthcare_label: #A6454B;
@industry_label: #494F54;
@public_transport_label: #1F4366;
@public_transport_label: #234B73;
/* ROADS LABELS */
@shield_text: #000000;

View File

@@ -1,136 +0,0 @@
import Foundation
/// API client for location sharing server
class LocationSharingApiClient {
private let serverBaseUrl: String
private let sessionId: String
private let session: URLSession
private static let connectTimeout: TimeInterval = 10
private static let requestTimeout: TimeInterval = 10
init(serverBaseUrl: String, sessionId: String) {
self.serverBaseUrl = serverBaseUrl.hasSuffix("/") ? serverBaseUrl : serverBaseUrl + "/"
self.sessionId = sessionId
let config = URLSessionConfiguration.default
config.timeoutIntervalForRequest = Self.requestTimeout
config.timeoutIntervalForResource = Self.connectTimeout
self.session = URLSession(configuration: config)
}
// MARK: - API Methods
/// Create session on server
func createSession(completion: ((Bool, String?) -> Void)? = nil) {
let urlString = "\(serverBaseUrl)api/v1/session"
guard let url = URL(string: urlString) else {
completion?(false, "Invalid URL")
return
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let body: [String: Any] = ["sessionId": sessionId]
guard let jsonData = try? JSONSerialization.data(withJSONObject: body) else {
completion?(false, "Failed to serialize JSON")
return
}
request.httpBody = jsonData
let task = session.dataTask(with: request) { data, response, error in
if let error = error {
NSLog("Create session error: \(error.localizedDescription)")
completion?(false, error.localizedDescription)
return
}
guard let httpResponse = response as? HTTPURLResponse else {
completion?(false, "Invalid response")
return
}
if (200..<300).contains(httpResponse.statusCode) {
NSLog("Session created: \(self.sessionId)")
completion?(true, nil)
} else {
completion?(false, "Server error: \(httpResponse.statusCode)")
}
}
task.resume()
}
/// Update location on server with encrypted payload
func updateLocation(encryptedPayload: String, completion: ((Bool, String?) -> Void)? = nil) {
let urlString = "\(serverBaseUrl)api/v1/location/\(sessionId)"
guard let url = URL(string: urlString) else {
completion?(false, "Invalid URL")
return
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = encryptedPayload.data(using: .utf8)
let task = session.dataTask(with: request) { data, response, error in
if let error = error {
NSLog("Update location error: \(error.localizedDescription)")
completion?(false, error.localizedDescription)
return
}
guard let httpResponse = response as? HTTPURLResponse else {
completion?(false, "Invalid response")
return
}
if (200..<300).contains(httpResponse.statusCode) {
completion?(true, nil)
} else {
completion?(false, "Server error: \(httpResponse.statusCode)")
}
}
task.resume()
}
/// End session on server
func endSession(completion: ((Bool, String?) -> Void)? = nil) {
let urlString = "\(serverBaseUrl)api/v1/session/\(sessionId)"
guard let url = URL(string: urlString) else {
completion?(false, "Invalid URL")
return
}
var request = URLRequest(url: url)
request.httpMethod = "DELETE"
let task = session.dataTask(with: request) { data, response, error in
if let error = error {
NSLog("End session error: \(error.localizedDescription)")
completion?(false, error.localizedDescription)
return
}
guard let httpResponse = response as? HTTPURLResponse else {
completion?(false, "Invalid response")
return
}
if (200..<300).contains(httpResponse.statusCode) {
NSLog("Session ended: \(self.sessionId)")
completion?(true, nil)
} else {
completion?(false, "Server error: \(httpResponse.statusCode)")
}
}
task.resume()
}
}

View File

@@ -1,31 +0,0 @@
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/// Objective-C++ bridge to C++ location sharing functionality
@interface LocationSharingBridgeObjC : NSObject
/// Generate new session credentials
/// @return Array of [sessionId, encryptionKey]
+ (NSArray<NSString *> *)generateSessionCredentials;
/// Generate share URL from credentials
+ (nullable NSString *)generateShareUrlWithSessionId:(NSString *)sessionId
encryptionKey:(NSString *)encryptionKey
serverBaseUrl:(NSString *)serverBaseUrl;
/// Encrypt payload using AES-256-GCM
/// @param key Base64-encoded encryption key
/// @param plaintext JSON payload to encrypt
/// @return Encrypted JSON (with iv, ciphertext, authTag) or nil on failure
+ (nullable NSString *)encryptPayloadWithKey:(NSString *)key plaintext:(NSString *)plaintext;
/// Decrypt payload using AES-256-GCM
/// @param key Base64-encoded encryption key
/// @param encryptedJson Encrypted JSON (with iv, ciphertext, authTag)
/// @return Decrypted plaintext or nil on failure
+ (nullable NSString *)decryptPayloadWithKey:(NSString *)key encryptedJson:(NSString *)encryptedJson;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,77 +0,0 @@
#import "LocationSharingBridge.h"
#include "location_sharing/location_sharing_types.hpp"
#include "location_sharing/crypto_util.hpp"
#include "base/logging.hpp"
#import <Foundation/Foundation.h>
using namespace location_sharing;
@implementation LocationSharingBridgeObjC
+ (NSArray<NSString *> *)generateSessionCredentials
{
SessionCredentials creds = SessionCredentials::Generate();
NSString * sessionId = [NSString stringWithUTF8String:creds.sessionId.c_str()];
NSString * encryptionKey = [NSString stringWithUTF8String:creds.encryptionKey.c_str()];
return @[sessionId, encryptionKey];
}
+ (NSString *)generateShareUrlWithSessionId:(NSString *)sessionId
encryptionKey:(NSString *)encryptionKey
serverBaseUrl:(NSString *)serverBaseUrl
{
std::string sessionIdStr = [sessionId UTF8String];
std::string encryptionKeyStr = [encryptionKey UTF8String];
std::string serverBaseUrlStr = [serverBaseUrl UTF8String];
SessionCredentials creds(sessionIdStr, encryptionKeyStr);
std::string shareUrl = creds.GenerateShareUrl(serverBaseUrlStr);
return [NSString stringWithUTF8String:shareUrl.c_str()];
}
+ (NSString *)encryptPayloadWithKey:(NSString *)key plaintext:(NSString *)plaintext
{
std::string keyStr = [key UTF8String];
std::string plaintextStr = [plaintext UTF8String];
auto encryptedOpt = crypto::EncryptAes256Gcm(keyStr, plaintextStr);
if (!encryptedOpt.has_value())
{
LOG(LERROR, ("Encryption failed"));
return nil;
}
std::string resultJson = encryptedOpt->ToJson();
return [NSString stringWithUTF8String:resultJson.c_str()];
}
+ (NSString *)decryptPayloadWithKey:(NSString *)key encryptedJson:(NSString *)encryptedJson
{
std::string keyStr = [key UTF8String];
std::string encryptedJsonStr = [encryptedJson UTF8String];
// Parse encrypted JSON
auto encryptedPayloadOpt = EncryptedPayload::FromJson(encryptedJsonStr);
if (!encryptedPayloadOpt.has_value())
{
LOG(LERROR, ("Failed to parse encrypted JSON"));
return nil;
}
auto decryptedOpt = crypto::DecryptAes256Gcm(keyStr, *encryptedPayloadOpt);
if (!decryptedOpt.has_value())
{
LOG(LERROR, ("Decryption failed"));
return nil;
}
return [NSString stringWithUTF8String:decryptedOpt->c_str()];
}
@end

View File

@@ -1,200 +0,0 @@
import Foundation
import UIKit
import UserNotifications
import CoreLocation
/// Manages notifications for location sharing
@objc class LocationSharingNotifier: NSObject {
@objc static let shared = LocationSharingNotifier()
private let notificationCenter = UNUserNotificationCenter.current()
private var reminderTimer: Timer?
private static let activeNotificationId = "location_sharing_active"
private static let reminderNotificationId = "location_sharing_reminder"
private static let categoryId = "LOCATION_SHARING"
private override init() {
super.init()
setupNotificationCategories()
}
// MARK: - Setup
private func setupNotificationCategories() {
// Define stop action
let stopAction = UNNotificationAction(
identifier: "STOP_SHARING",
title: "Stop Sharing",
options: [.destructive])
// Define category
let category = UNNotificationCategory(
identifier: Self.categoryId,
actions: [stopAction],
intentIdentifiers: [],
options: [])
notificationCenter.setNotificationCategories([category])
}
// MARK: - Authorization
func requestAuthorization(completion: @escaping (Bool) -> Void) {
notificationCenter.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
if let error = error {
NSLog("Notification authorization error: \(error)")
}
completion(granted)
}
}
// MARK: - Active Notification
/// Schedule persistent notification while sharing is active
func scheduleActiveNotification() {
requestAuthorization { [weak self] granted in
guard granted else { return }
self?.showActiveNotification()
}
// Schedule reminder notifications every 10 minutes
scheduleReminderNotifications()
}
private func showActiveNotification() {
let content = UNMutableNotificationContent()
content.title = "Location Sharing Active"
content.body = "Your live location is being shared. Tap to view or stop."
content.sound = nil // Silent notification
content.categoryIdentifier = Self.categoryId
// Add badge
content.badge = 1
let request = UNNotificationRequest(
identifier: Self.activeNotificationId,
content: content,
trigger: nil) // Immediate
notificationCenter.add(request) { error in
if let error = error {
NSLog("Failed to schedule active notification: \(error)")
}
}
}
/// Update notification with current location info
func updateNotification(location: CLLocation) {
let content = UNMutableNotificationContent()
content.title = "Location Sharing Active"
// Format accuracy
let accuracyText = formatAccuracy(location.horizontalAccuracy)
content.body = "Sharing your location (accuracy: \(accuracyText))"
content.sound = nil
content.categoryIdentifier = Self.categoryId
content.badge = 1
let request = UNNotificationRequest(
identifier: Self.activeNotificationId,
content: content,
trigger: nil)
notificationCenter.add(request)
}
// MARK: - Reminder Notifications
private func scheduleReminderNotifications() {
// Cancel existing reminders
notificationCenter.removePendingNotificationRequests(withIdentifiers: [Self.reminderNotificationId])
// Schedule timer to show reminder every 10 minutes
reminderTimer?.invalidate()
reminderTimer = Timer.scheduledTimer(
withTimeInterval: 600, // 10 minutes
repeats: true) { [weak self] _ in
self?.showReminderNotification()
}
}
private func showReminderNotification() {
let content = UNMutableNotificationContent()
content.title = "Location Sharing Reminder"
content.body = "Your location is still being shared. Tap to stop if needed."
content.sound = .default
content.categoryIdentifier = Self.categoryId
let request = UNNotificationRequest(
identifier: Self.reminderNotificationId,
content: content,
trigger: nil)
notificationCenter.add(request) { error in
if let error = error {
NSLog("Failed to schedule reminder notification: \(error)")
}
}
}
// MARK: - Cancel
func cancelNotifications() {
// Cancel all location sharing notifications
notificationCenter.removePendingNotificationRequests(
withIdentifiers: [Self.activeNotificationId, Self.reminderNotificationId])
notificationCenter.removeDeliveredNotifications(
withIdentifiers: [Self.activeNotificationId, Self.reminderNotificationId])
// Stop reminder timer
reminderTimer?.invalidate()
reminderTimer = nil
// Clear badge
UIApplication.shared.applicationIconBadgeNumber = 0
}
// MARK: - Helpers
private func formatAccuracy(_ accuracy: Double) -> String {
if accuracy < 10 {
return "high"
} else if accuracy < 50 {
return "medium"
} else {
return "low"
}
}
}
// MARK: - Live Activities (iOS 16.1+)
#if canImport(ActivityKit)
import ActivityKit
@available(iOS 16.1, *)
extension LocationSharingNotifier {
/// Start Live Activity for location sharing
func startLiveActivity() {
// TODO: Implement Live Activity
// This would show persistent UI on lock screen and Dynamic Island
// Requires defining ActivityAttributes and ActivityConfiguration
NSLog("Live Activity support would be implemented here for iOS 16.1+")
}
/// Update Live Activity with current location
func updateLiveActivity(location: CLLocation, eta: TimeInterval?, distance: Int?) {
// TODO: Update Live Activity content
}
/// End Live Activity
func endLiveActivity() {
// TODO: End Live Activity
}
}
#endif

View File

@@ -1,252 +0,0 @@
import Foundation
import CoreLocation
import UIKit
/// Service managing the location sharing lifecycle
@objc class LocationSharingService: NSObject {
@objc static let shared = LocationSharingService()
private var locationManager: CLLocationManager?
private var apiClient: LocationSharingApiClient?
private let session = LocationSharingSession.shared
private var updateTimer: Timer?
// Battery monitoring
private var batteryLevelObserver: NSObjectProtocol?
private override init() {
super.init()
setupSession()
}
deinit {
stopSharing()
}
// MARK: - Public API
/// Start sharing location
@objc func startSharing() -> String? {
let config = LocationSharingConfig()
guard let shareUrl = session.start(with: config) else {
NSLog("Failed to start location sharing session")
return nil
}
// Initialize API client
guard let credentials = session.credentials else {
return nil
}
apiClient = LocationSharingApiClient(
serverBaseUrl: config.serverBaseUrl,
sessionId: credentials.sessionId)
// Request location authorization if needed
setupLocationManager()
requestLocationAuthorization()
// Start location updates
startLocationUpdates()
// Setup battery monitoring
setupBatteryMonitoring()
// Send session creation to server
apiClient?.createSession()
NSLog("Location sharing service started")
return shareUrl
}
/// Stop sharing location
@objc func stopSharing() {
// Stop location updates
stopLocationUpdates()
// Stop battery monitoring
stopBatteryMonitoring()
// End session on server
apiClient?.endSession()
apiClient = nil
// Stop session
session.stop()
NSLog("Location sharing service stopped")
}
/// Check if currently sharing
@objc var isSharing: Bool {
return session.state == .active
}
/// Get current share URL
@objc var shareUrl: String? {
return session.shareUrl
}
// MARK: - Location Management
private func setupLocationManager() {
if locationManager == nil {
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.desiredAccuracy = kCLLocationAccuracyBest
locationManager?.allowsBackgroundLocationUpdates = true
locationManager?.pausesLocationUpdatesAutomatically = false
locationManager?.showsBackgroundLocationIndicator = true
}
}
private func requestLocationAuthorization() {
guard let manager = locationManager else { return }
let status = CLLocationManager.authorizationStatus()
switch status {
case .notDetermined:
manager.requestWhenInUseAuthorization()
case .authorizedWhenInUse:
manager.requestAlwaysAuthorization()
case .authorizedAlways:
break
case .denied, .restricted:
NSLog("Location authorization denied or restricted")
session.onError?("Location permission required")
@unknown default:
break
}
}
private func startLocationUpdates() {
locationManager?.startUpdatingLocation()
// Also monitor significant location changes for battery efficiency
locationManager?.startMonitoringSignificantLocationChanges()
}
private func stopLocationUpdates() {
locationManager?.stopUpdatingLocation()
locationManager?.stopMonitoringSignificantLocationChanges()
}
// MARK: - Battery Monitoring
private func setupBatteryMonitoring() {
UIDevice.current.isBatteryMonitoringEnabled = true
batteryLevelObserver = NotificationCenter.default.addObserver(
forName: UIDevice.batteryLevelDidChangeNotification,
object: nil,
queue: .main) { [weak self] _ in
self?.updateBatteryLevel()
}
// Initial battery level
updateBatteryLevel()
}
private func stopBatteryMonitoring() {
if let observer = batteryLevelObserver {
NotificationCenter.default.removeObserver(observer)
batteryLevelObserver = nil
}
UIDevice.current.isBatteryMonitoringEnabled = false
}
private func updateBatteryLevel() {
let level = Int(UIDevice.current.batteryLevel * 100)
if level >= 0 {
session.updateBatteryLevel(level)
}
}
// MARK: - Session Setup
private func setupSession() {
session.onStateChange = { [weak self] state in
self?.handleStateChange(state)
}
session.onError = { error in
NSLog("Location sharing error: \(error)")
}
session.onPayloadReady = { [weak self] data in
self?.sendPayloadToServer(data)
}
}
private func handleStateChange(_ state: LocationSharingState) {
switch state {
case .active:
LocationSharingNotifier.shared.scheduleActiveNotification()
case .inactive:
LocationSharingNotifier.shared.cancelNotifications()
case .error:
LocationSharingNotifier.shared.cancelNotifications()
default:
break
}
}
// MARK: - Server Communication
private func sendPayloadToServer(_ data: Data) {
guard let jsonString = String(data: data, encoding: .utf8) else {
NSLog("Failed to convert payload to string")
return
}
apiClient?.updateLocation(encryptedPayload: jsonString) { success, error in
if success {
NSLog("Location update sent successfully")
} else {
NSLog("Failed to send location update: \(error ?? "unknown error")")
}
}
}
}
// MARK: - CLLocationManagerDelegate
extension LocationSharingService: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
// Update session with new location
session.updateLocation(location)
// Update notification with current location
LocationSharingNotifier.shared.updateNotification(location: location)
// TODO: Check if navigation is active and update navigation info
// This would integrate with the routing framework
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
NSLog("Location manager error: \(error.localizedDescription)")
session.onError?(error.localizedDescription)
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .authorizedAlways, .authorizedWhenInUse:
if isSharing {
startLocationUpdates()
}
case .denied, .restricted:
session.onError?("Location permission denied")
stopSharing()
default:
break
}
}
}

View File

@@ -1,317 +0,0 @@
import Foundation
import CoreLocation
/// Session state for location sharing
@objc enum LocationSharingState: Int {
case inactive
case starting
case active
case paused
case stopping
case error
}
/// Mode for location sharing
enum LocationSharingMode {
case standalone // GPS only
case navigation // GPS + ETA + distance
}
/// Configuration for location sharing session
struct LocationSharingConfig {
var updateIntervalSeconds: Int = 20
var includeDestinationName: Bool = true
var includeBatteryLevel: Bool = true
var lowBatteryThreshold: Int = 10
// Default from LOCATION_SHARING_SERVER_URL in private.h
// Can be overridden by user settings
var serverBaseUrl: String = "https://live.organicmaps.app"
}
/// Session credentials
struct LocationSharingCredentials {
let sessionId: String
let encryptionKey: String
/// Generate share URL from credentials
func generateShareUrl(serverBaseUrl: String) -> String {
let combined = "\(sessionId):\(encryptionKey)"
guard let data = combined.data(using: .utf8) else { return "" }
let base64 = data.base64EncodedString()
.replacingOccurrences(of: "+", with: "-")
.replacingOccurrences(of: "/", with: "_")
.replacingOccurrences(of: "=", with: "")
var url = serverBaseUrl
if !url.hasSuffix("/") {
url += "/"
}
url += "live/\(base64)"
return url
}
/// Generate new random credentials
static func generate() -> LocationSharingCredentials {
let sessionId = UUID().uuidString
let encryptionKey = Self.generateRandomKey()
return LocationSharingCredentials(sessionId: sessionId, encryptionKey: encryptionKey)
}
private static func generateRandomKey() -> String {
var bytes = [UInt8](repeating: 0, count: 32)
_ = SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes)
return Data(bytes).base64EncodedString()
}
}
/// Location payload structure
struct LocationPayload {
var timestamp: TimeInterval
var latitude: Double
var longitude: Double
var accuracy: Double
var speed: Double?
var bearing: Double?
var mode: LocationSharingMode = .standalone
var eta: TimeInterval?
var distanceRemaining: Int?
var destinationName: String?
var batteryLevel: Int?
init(location: CLLocation) {
self.timestamp = Date().timeIntervalSince1970
self.latitude = location.coordinate.latitude
self.longitude = location.coordinate.longitude
self.accuracy = location.horizontalAccuracy
if location.speed >= 0 {
self.speed = location.speed
}
if location.course >= 0 {
self.bearing = location.course
}
}
func toJSON() -> [String: Any] {
var json: [String: Any] = [
"timestamp": Int(timestamp),
"lat": latitude,
"lon": longitude,
"accuracy": accuracy
]
if let speed = speed {
json["speed"] = speed
}
if let bearing = bearing {
json["bearing"] = bearing
}
json["mode"] = mode == .navigation ? "navigation" : "standalone"
if mode == .navigation {
if let eta = eta {
json["eta"] = Int(eta)
}
if let distanceRemaining = distanceRemaining {
json["distanceRemaining"] = distanceRemaining
}
if let destinationName = destinationName {
json["destinationName"] = destinationName
}
}
if let batteryLevel = batteryLevel {
json["batteryLevel"] = batteryLevel
}
return json
}
}
/// Main location sharing session manager
@objc class LocationSharingSession: NSObject {
// Singleton instance
@objc static let shared = LocationSharingSession()
// State
private(set) var state: LocationSharingState = .inactive
private(set) var credentials: LocationSharingCredentials?
private(set) var config: LocationSharingConfig = LocationSharingConfig()
private(set) var shareUrl: String?
// Current payload
private var currentPayload: LocationPayload?
private var lastUpdateTimestamp: TimeInterval = 0
// Callbacks
var onStateChange: ((LocationSharingState) -> Void)?
var onError: ((String) -> Void)?
var onPayloadReady: ((Data) -> Void)?
private override init() {
super.init()
}
/// Start location sharing session
@objc func start(with config: LocationSharingConfig) -> String? {
if state != .inactive {
NSLog("Location sharing already active, stopping previous session")
stop()
}
setState(.starting)
self.config = config
self.credentials = LocationSharingCredentials.generate()
self.lastUpdateTimestamp = 0
guard let credentials = self.credentials else {
onError?("Failed to generate credentials")
setState(.error)
return nil
}
self.shareUrl = credentials.generateShareUrl(serverBaseUrl: config.serverBaseUrl)
NSLog("Location sharing session started: \(credentials.sessionId)")
setState(.active)
return shareUrl
}
/// Stop location sharing session
@objc func stop() {
if state == .inactive {
return
}
setState(.stopping)
NSLog("Location sharing session stopped")
currentPayload = nil
credentials = nil
shareUrl = nil
lastUpdateTimestamp = 0
setState(.inactive)
}
/// Update location
func updateLocation(_ location: CLLocation) {
guard state == .active else {
NSLog("Cannot update location - session not active")
return
}
currentPayload = LocationPayload(location: location)
processLocationUpdate()
}
/// Update navigation info
func updateNavigationInfo(eta: TimeInterval, distanceRemaining: Int, destinationName: String?) {
guard state == .active, currentPayload != nil else { return }
currentPayload?.mode = .navigation
currentPayload?.eta = eta
currentPayload?.distanceRemaining = distanceRemaining
if config.includeDestinationName, let name = destinationName {
currentPayload?.destinationName = name
}
}
/// Clear navigation info
func clearNavigationInfo() {
currentPayload?.mode = .standalone
currentPayload?.eta = nil
currentPayload?.distanceRemaining = nil
currentPayload?.destinationName = nil
}
/// Update battery level
func updateBatteryLevel(_ level: Int) {
guard state == .active else { return }
if config.includeBatteryLevel {
currentPayload?.batteryLevel = level
}
// Stop if battery too low
if level < config.lowBatteryThreshold {
NSLog("Battery level too low (\(level)%), stopping location sharing")
onError?("Battery level too low")
stop()
}
}
// MARK: - Private methods
private func setState(_ newState: LocationSharingState) {
if state == newState {
return
}
NSLog("Location sharing state: \(state.rawValue) -> \(newState.rawValue)")
state = newState
onStateChange?(newState)
}
private func processLocationUpdate() {
guard shouldSendUpdate() else { return }
guard let encryptedData = createEncryptedPayload() else {
onError?("Failed to create encrypted payload")
return
}
lastUpdateTimestamp = Date().timeIntervalSince1970
onPayloadReady?(encryptedData)
}
private func shouldSendUpdate() -> Bool {
guard currentPayload != nil else { return false }
let now = Date().timeIntervalSince1970
let timeSinceLastUpdate = now - lastUpdateTimestamp
return timeSinceLastUpdate >= Double(config.updateIntervalSeconds)
}
private func createEncryptedPayload() -> Data? {
guard let payload = currentPayload,
let credentials = credentials else {
return nil
}
let json = payload.toJSON()
guard let jsonData = try? JSONSerialization.data(withJSONObject: json),
let jsonString = String(data: jsonData, encoding: .utf8) else {
NSLog("Failed to serialize payload to JSON")
return nil
}
// Call native encryption (via bridge)
guard let encryptedJson = LocationSharingBridge.encryptPayload(
key: credentials.encryptionKey,
plaintext: jsonString) else {
NSLog("Encryption failed")
return nil
}
return encryptedJson.data(using: .utf8)
}
}
/// Swift wrapper for LocationSharingBridgeObjC
extension LocationSharingBridge {
static func encryptPayload(key: String, plaintext: String) -> String? {
return LocationSharingBridgeObjC.encryptPayload(withKey: key, plaintext: plaintext)
}
}

View File

@@ -493,7 +493,7 @@
/* Place Page link to Wikimedia Commons. */
"wikimedia_commons" = "Общомедия";
"p2p_your_location" = "Вашето местоположение";
"p2p_start" = "Начало";
"p2p_start" = "Почна";
"p2p_from_here" = "Маршрут от";
"p2p_to_here" = "Маршрут към";
"p2p_only_from_current" = "Навигацията е възможна само от текущото ви местоположение.";

View File

@@ -1097,5 +1097,7 @@
"pref_maplanguage_local" = "Místní jazyk";
"existence_confirmed_time_ago" = "Existence potvrzena %@";
"hours_confirmed_time_ago" = "Potvrzeno %@";
"offline_explanation_text" = "Pro prohlížení a navigaci v dané oblasti je nutné stáhnout mapu.\nStáhnout mapy oblastí, které chcete navštívit.";
"offline_explanation_text" = "Pro prohlížení a navigaci v dané oblasti je nutné si stáhnout mapu.\nStáhněte si mapy oblastí, které chcete navštívit.";
"offline_explanation_title" = "Offline mapy";
"avoid_steps" = "Vyhnout se schodům";
"editor_place_doesnt_exist_description" = "Popište, jak místo vypadá nyní a pošlete poznámku o chybě komunitě OpenStreetMap";

View File

@@ -1099,3 +1099,5 @@
"existence_confirmed_time_ago" = "Existenz bestätigt %@";
"hours_confirmed_time_ago" = "Bestätigt %@";
"offline_explanation_title" = "Offline Karten";
"offline_explanation_text" = "Um die Gegend anzusehen, muss eine Karte heruntergeladen werden.\nLaden Sie Karten für die Gebiete herunter, die Sie bereisen möchten.";
"editor_place_doesnt_exist_description" = "Beschreibe wie der Ort jetzt aussieht um eine Fehlermeldung an die OpenStreetMap Community zu senden";

View File

@@ -846,7 +846,7 @@
"avoid_unpaved" = "Avoid unpaved roads";
/* Recommended length for CarPlay and Android Auto is around 25-27 characters */
"avoid_steps" = "Avoid steps";
"avoid_steps" = "Avoid stairs";
"avoid_ferry" = "Avoid ferries";
"avoid_motorways" = "Avoid motorways";
"unable_to_calc_alert_title" = "Unable to calculate route";

View File

@@ -869,7 +869,7 @@
"avoid_unpaved" = "Avoid unpaved roads";
/* Recommended length for CarPlay and Android Auto is around 25-27 characters */
"avoid_steps" = "Avoid steps";
"avoid_steps" = "Avoid stairs";
"avoid_ferry" = "Avoid ferries";
"avoid_motorways" = "Avoid freeways";
"unable_to_calc_alert_title" = "Unable to calculate route";

View File

@@ -1,58 +0,0 @@
/* Location Sharing */
/* Title for location sharing feature */
"location_sharing_title" = "Live Location Sharing";
/* Start sharing button */
"location_sharing_start" = "Start Sharing";
/* Stop sharing button */
"location_sharing_stop" = "Stop Sharing";
/* Location sharing active status */
"location_sharing_active" = "Sharing location";
/* Status message when sharing is active */
"location_sharing_status_active" = "Your location is being shared";
/* Status message when sharing is inactive */
"location_sharing_status_inactive" = "Location sharing is not active";
/* Description text explaining the feature */
"location_sharing_description" = "Share your real-time location with end-to-end encryption. Only people with the link can view your location.";
/* Copy link button */
"location_sharing_copy_url" = "Copy Link";
/* Share link button */
"location_sharing_share_url" = "Share Link";
/* Close button */
"close" = "Close";
/* Success message when sharing started */
"location_sharing_started" = "Location sharing started";
/* Success message when sharing stopped */
"location_sharing_stopped" = "Location sharing stopped";
/* Error message when failed to start */
"location_sharing_failed_to_start" = "Failed to start location sharing";
/* Success message when URL copied */
"location_sharing_url_copied" = "Share URL copied to clipboard";
/* Share message template */
"location_sharing_share_message" = "Follow my live location: %@";
/* Notification title */
"location_sharing_notification_title" = "Location Sharing Active";
/* Notification body */
"location_sharing_notification_body" = "Your live location is being shared. Tap to view or stop.";
/* Reminder notification title */
"location_sharing_reminder_title" = "Location Sharing Reminder";
/* Reminder notification body */
"location_sharing_reminder_body" = "Your location is still being shared. Tap to stop if needed.";

View File

@@ -1097,3 +1097,6 @@
"pref_maplanguage_local" = "Idioma local";
"existence_confirmed_time_ago" = "Existencia confirmada %@";
"hours_confirmed_time_ago" = "Confirmado %@";
"offline_explanation_text" = "Se debe descargar un mapa para ver y navegar el área\nDescarga mapas de las áreas que quieras navegar.";
"offline_explanation_title" = "Mapas Offline";
"avoid_steps" = "Evitar escalones";

View File

@@ -1097,3 +1097,5 @@
"hours_confirmed_time_ago" = "Kontrollitud %@";
"offline_explanation_text" = "Selles piirkonnas liikumiseks ja teekonna juhatamiseks pead vajaliku kaardi alla laadima.\nVali allalaaditav kaart selle piirkonna kohta.";
"offline_explanation_title" = "Ilma võrguühenduseta toimivad kaardid";
"avoid_steps" = "Väldi treppe";
"editor_place_doesnt_exist_description" = "Kirjelda selle koha praegust välimust ja lisa veamärge OpenStreetMapi kogukonnale";

View File

@@ -325,7 +325,7 @@
"report_incorrect_map_bug" = "Ilmoita tai korjaa virheelliset karttatiedot";
/* Button in the About screen */
"volunteer" = "Auta parantamaan CoMapsia";
"volunteer" = "Tee vapaaehtoistyötä ja paranna CoMapsia";
/* "Social media" section header in the About screen */
"follow_us" = "Ota yhteyttä";
@@ -826,7 +826,7 @@
"avoid_ferry" = "Vältä lautan käyttöä";
"avoid_motorways" = "Vältä moottoritietä";
"unable_to_calc_alert_title" = "Reittiä ei voi luoda";
"unable_to_calc_alert_subtitle" = "Valitettavasti emme voineet luoda reittiä valituilla vaihtoehdoilla. Vaihda asetuksia ja yritä uudelleen";
"unable_to_calc_alert_subtitle" = "Reittiä ei löytynyt. Tämä voi johtua reititysasetuksistasi tai puutteellisista OpenStreetMap-tiedoista. Muuta reititysvaihtoehtoja ja yritä uudelleen.";
"define_to_avoid_btn" = "Määritä vältettävät tiet";
"change_driving_options_btn" = "Reititysvalinnat ovat päällä";
"toll_road" = "Maksullinen tie";
@@ -984,7 +984,7 @@
"app_tip_09" = "Päätavoitteemme on rakentaa nopeita, yksityisyyteen keskittyviä, helppokäyttöisiä karttoja, joista pidät.";
/* Text on the Android Auto or CarPlay placeholder screen that maps are displayed on the phone screen */
"car_used_on_the_phone_screen" = "Käytät nyt puhelimen näytöllä CoMaps -palvelua.";
"car_used_on_the_phone_screen" = "Käytät nyt CoMapsia puhelimen näytöllä";
/* Text on the phone placeholder screen that maps are displayed on the car screen */
"car_used_on_the_car_screen" = "Käytät nyt CoMaps auton näytöllä";
@@ -1039,10 +1039,10 @@
"icloud_synchronization_error_alert_title" = "iCloud-synkronoinnin epäonnistuminen";
/* iCloud error message: Failed to synchronize due to connection error */
"icloud_synchronization_error_connection_error" = "Virhe: Synkronointi epäonnistui yhteysvirheen vuoksi.";
"icloud_synchronization_error_connection_error" = "Virhe: Synkronointi epäonnistui yhteysvirheen vuoksi";
/* iCloud error message: Failed to synchronize due to iCloud quota exceeded */
"icloud_synchronization_error_quota_exceeded" = "Virhe: iCloud-kiintiön ylittymisen vuoksi synkronointi epäonnistui.";
"icloud_synchronization_error_quota_exceeded" = "Virhe: iCloud-kiintiön ylittymisen vuoksi synkronointi epäonnistui";
/* iCloud error message: iCloud is not available */
"icloud_synchronization_error_cloud_is_unavailable" = "Virhe: iCloud ei ole käytettävissä";
@@ -1097,3 +1097,7 @@
"pref_maplanguage_local" = "Paikallinen kieli";
"existence_confirmed_time_ago" = "Olemassaolo varmistettu %@";
"hours_confirmed_time_ago" = "Varmistettu %@";
"offline_explanation_text" = "Alueen katseluun ja navigointiin tarvitaan kartta.\nLataa karttoja alueille, joille haluat matkustaa.";
"offline_explanation_title" = "Ei-verkkotilassa olevat kartat";
"avoid_steps" = "Vältä portaita";
"editor_place_doesnt_exist_description" = "Kuvaile, miltä paikka näyttää nyt, lähettääksesi virheilmoituksen OpenStreetMap-yhteisölle";

View File

@@ -589,3 +589,7 @@
"pref_maplanguage_local" = "Local Language";
"hours_confirmed_time_ago" = "Confirmed %@";
"existence_confirmed_time_ago" = "Existence confirmed %@";
"offline_explanation_text" = "Hai que descargar un mapa para ver e navegar polo área.\nDescarga os mapas para as zonas polas que vas viaxar.";
"offline_explanation_title" = "Mapas sen conexión";
"avoid_steps" = "Evitar pasos";
"editor_place_doesnt_exist_description" = "Describe a aparencia do lugar para enviar unha nota co erro á comunidade OpenStreetMap";

View File

@@ -256,7 +256,7 @@
"search_show_on_map" = "Megtekintés a térképen";
/* Text in menu */
"website" = "Honlap";
"website" = "Webhely";
/* Text in About menu, opens CoMaps news website */
"news" = "Hírek";
@@ -365,7 +365,7 @@
"downloader_delete_map_while_routing_dialog" = "Állítsa le a navigációt a térkép törléséhez.";
/* PointsInDifferentMWM */
"routing_failed_cross_mwm_building" = "Útvonalakat csak akkor lehet készíteni, ha teljesen rajta vannak egy térképen.";
"routing_failed_cross_mwm_building" = "Csak olyan útvonalakat lehet létrehozni, amelyek teljes egészében egy régió térképén belül helyezkednek el.";
/* Context menu item for downloader. */
"downloader_download_map" = "Térkép letöltése";
@@ -380,7 +380,7 @@
"routing_download_maps_along" = "Összes térkép letöltése az útvonal mentén";
/* Text for routing error dialog */
"routing_requires_all_map" = "Az útvonal létrehozásához le kell töltenie és frissítenie kell az összes térképet az Ön tartózkodási helyétől a célig.";
"routing_requires_all_map" = "Az útvonal létrehozásához le kell töltenie és frissítenie kell az összes térképet a saját tartózkodási helyétől a célig.";
/* bookmark button text */
"bookmark" = "könyvjelző";
@@ -435,10 +435,10 @@
/* blue gray color */
"blue_gray" = "Kékes szürke";
"dialog_routing_disclaimer_title" = "Az útvonal követésekor vegye figyelembe az alábbiakat:";
"dialog_routing_disclaimer_priority" = " Az útviszonyok, a közlekedési szabályok és a jelzőtáblák mindig elsőbbséget élveznek a navigációs útmutatással szemben;";
"dialog_routing_disclaimer_precision" = " A térkép pontatlan lehet és a javasolt útvonal lehetséges, hogy nem mindig a legoptimálisabb módja a célállomás elérésének;";
"dialog_routing_disclaimer_recommendations" = " A javasolt útvonalakat csupán ajánlottként kell tekinteni;";
"dialog_routing_disclaimer_borders" = " Legyen óvatos az útvonalakkal a határzónákban: az alkalmazásunk által létrehozott útvonalak néha nem engedélyezett helyeken léphetik át az országhatárokat.";
"dialog_routing_disclaimer_priority" = "- Az útviszonyok, a közlekedési szabályok és a jelzőtáblák mindig elsőbbséget élveznek a navigációs útmutatással szemben;";
"dialog_routing_disclaimer_precision" = "- A térkép pontatlan lehet és a javasolt útvonal lehetséges, hogy nem mindig a legoptimálisabb módja a célállomás elérésének;";
"dialog_routing_disclaimer_recommendations" = "- A javasolt útvonalakat csak ajánlásként kell értelmezni;";
"dialog_routing_disclaimer_borders" = "- Legyen óvatos az útvonalakkal a határzónákban: az alkalmazásunk által létrehozott útvonalak néha nem engedélyezett helyeken léphetik át az országhatárokat.";
"dialog_routing_disclaimer_beware" = "Mindig maradjon éber és vezessen biztonságosan az utakon!";
"dialog_routing_check_gps" = "Ellenőrizze a GPS-jelet";
"dialog_routing_error_location_not_found" = "Nem sikerült létrehozni az útvonalat. A jelenlegi GPS-koordináták nem azonosíthatók.";
@@ -460,8 +460,8 @@
"dialog_routing_system_error" = "Rendszerhiba";
"dialog_routing_application_error" = "Nem lehet létrehozni az útvonalat egy alkalmazáshiba miatt.";
"dialog_routing_try_again" = "Próbálja meg újra";
"dialog_routing_download_and_build_cross_route" = "Szeretné letölteni a térképet, és egynél több térképen átívelő, optimálisabb útvonalat létrehozni?";
"dialog_routing_download_cross_route" = "Töltsön le további térképeket, hogy egy jobb útvonalat hozzon létre, amely keresztezi ennek a térképnek a határait.";
"dialog_routing_download_and_build_cross_route" = "Szeretné letölteni a térképet és létrehozni egy optimálisabb útvonalat, amely több térképet is igényel?";
"dialog_routing_download_cross_route" = "Töltsön le további térképeket, hogy jobb útvonalat állíthasson össze, amely átlép a ennek a térképnek a határain.";
/* «Show» context menu */
"show" = "Megjelenítés";
@@ -685,7 +685,7 @@
/* Phone number error message */
"error_enter_correct_phone" = "Adjon megy egy érvényes telefonszámot";
"error_enter_correct_web" = "Adjon meg egy érvényes weboldalcímet";
"error_enter_correct_web" = "Adjon meg egy érvényes webcímet";
"error_enter_correct_email" = "Adjon meg egy érvényes e-mail-címet";
"refresh" = "Frissítés";
"placepage_add_place_button" = "Hely hozzáadása az OpenStreetMap adatbázisához";
@@ -729,7 +729,7 @@
"traffic_update_app_message" = "A forgalmi adatok megjelenítéséhez frissíteni kell az alkalmazást.";
/* "traffic" as in "road congestion" */
"traffic_data_unavailable" = "Forgalmi adatok nem állnak rendelkezésre";
"traffic_data_unavailable" = "Nem állnak rendelkezésre forgalmi adatok";
"enable_logging" = "Naplózás engedélyezése";
"log_file_size" = "Naplófájl mérete: %@";
"transliteration_title" = "Átírás latin betűkre";
@@ -766,7 +766,7 @@
"downloader_percent" = "%@ (%@ / %@)";
"downloader_process" = "%@ letöltése…";
"downloader_applying" = "%@ alkalmazása…";
"bookmarks_error_message_share_general" = "Nem lehet megosztani egy alkalmazáshiba miatt";
"bookmarks_error_message_share_general" = "Egy alkalmazáshiba miatt nem lehet megosztani";
"bookmarks_error_title_share_empty" = "Megosztási hiba";
"bookmarks_error_message_share_empty" = "Üres lista nem osztható meg";
"bookmarks_error_message_empty_list_name" = "Adja meg a lista nevét";
@@ -795,7 +795,7 @@
"place_description_title" = "Hely ismertetése";
/* "Speed cameras" settings menu option (should be short! no more than 47-50 chars) to warn a driver if there is a risk of exceeding the speed limit */
"pref_tts_speedcams_auto" = "Gyorshajtáskor figyelmeztessen";
"pref_tts_speedcams_auto" = "Figyelmeztetés gyorshajtáskor";
/* Speed camera settings menu option - Always warn (about speedcams) */
"pref_tts_speedcams_always" = "Mindig figyelmeztessen";
@@ -805,7 +805,7 @@
"power_managment_title" = "Energiatakarékos mód";
"power_managment_description" = "Megpróbálja csökkenteni az energiafelhasználást bizonyos funkciók rovására.";
"power_managment_setting_never" = "Soha";
"power_managment_setting_auto" = "Amikor az akkumulátor lemerül";
"power_managment_setting_auto" = "Alacsony akkumulátorszinten";
"power_managment_setting_manual_max" = "Mindig";
"enable_logging_warning_message" = "Engedélyezze ideiglenesen ezt a beállítást, hogy rögzíthesse és elküldhesse nekünk a problémájával kapcsolatos részletes diagnosztikai naplókat a „Névjegy és súgó” képernyő „Hibajelentés” funkciójával. A naplók tartalmazhatnak helyadatokat.";
"driving_options_title" = "Útvonaltervezési beállítások";
@@ -954,7 +954,7 @@
"app_tip_01" = "Adományaival és támogatásával létrehozhatjuk a világ legjobb térképes alkalmazását!";
/* App tip #02 */
"app_tip_02" = "Tetszik az alkalmazásunk? Adományozzon, hogy támogassa a fejlesztést! Mégsem tetszik? Jelezze felénk, hogy miért nem, és mi kijavítjuk!";
"app_tip_02" = "Tetszik az alkalmazásunk? Adományozzon, hogy támogassa a fejlesztést! - Mégsem tetszik? Jelezze felénk, hogy miért nem, és mi kijavítjuk!";
/* App tip #03 */
"app_tip_03" = "Ha ismer egy szoftverfejlesztőt, megkérheti őt egy olyan funkció megvalósítására, amelyre szüksége van.";
@@ -963,10 +963,10 @@
"app_tip_04" = "Koppintson a térképen bárhová, hogy bármit kiválaszthasson. Hosszú koppintással elrejtheti és visszahozhatja a felületet.";
/* App tip #05 */
"app_tip_05" = "Tudja, hogy kijelölheti pozícióját a térképen?";
"app_tip_05" = "Tudta, hogy a térképen kiválaszthatja a jelenlegi tartózkodási helyét?";
/* App tip #06 */
"app_tip_06" = "Segítsen lefordítani az alkalmazást az Ön nyelvére.";
"app_tip_06" = "Segítsen lefordítani az alkalmazást a saját nyelvére.";
/* App tip #07 */
"app_tip_07" = "Ezt az alkalmazást néhány lelkes közreműködő és a közösség fejleszteti.";
@@ -978,13 +978,13 @@
"app_tip_09" = "A fő célunk az, hogy gyors, az adatvédelemre fókuszáló, könnyen használható térképeket készítsünk, amelyeket szeretni fog.";
/* Text on the Android Auto or CarPlay placeholder screen that maps are displayed on the phone screen */
"car_used_on_the_phone_screen" = "Ön most a CoMaps alkalmazást használja a telefon képernyőjén";
"car_used_on_the_phone_screen" = "Ön most a CoMaps alkalmazást használja az eszköz képernyőjén";
/* Text on the phone placeholder screen that maps are displayed on the car screen */
"car_used_on_the_car_screen" = "Ön most a CoMaps alkalmazást használja az autó képernyőjén";
/* Displayed on the phone screen. Button to display maps on the phone screen instead of a car */
"car_continue_on_the_phone" = "Folytatás telefonon";
"car_continue_on_the_phone" = "Folytatás az eszközön";
/* Displayed on the Android Auto or CarPlay screen. Button to display maps on the car screen instead of a phone. Must be no more than 18 symbols! */
"car_continue_in_the_car" = "Az autó képernyőjére";
@@ -1081,15 +1081,19 @@
"track_recording_alert_title" = "Menti a könyvjelzők és nyomvonalak közé?";
/* Message for the toast when saving the track recording is finished but nothing to save. */
"track_recording_toast_nothing_to_save" = "A nyomvonal üres nincs mit menteni";
"track_recording_toast_nothing_to_save" = "A nyomvonal üres - nincs mit menteni";
"edit_track" = "Nyomvonal szerkesztése";
"osm_profile_view_notes" = "Jegyzetek megtekintése";
"osm_profile_view_edit_history" = "Szerkesztési előzmények megtekintése";
"about_proposition_3" = "Átlátható és nem profitorientált";
"about_headline" = "Közösség által működtetett nyílt projekt";
"about_headline" = "Közösség által működtetett szabad projekt";
"pref_mapappearance_title" = "A térkép megjelenése";
"pref_maplanguage_title" = "A térkép nyelve";
"transliteration_title_disabled_summary" = "Letiltva, ha mindig a helyi nyelvet használja a térképen";
"pref_maplanguage_local" = "A helyi nyelv";
"existence_confirmed_time_ago" = "A létezése ellenőrizve és megerősítve %@";
"hours_confirmed_time_ago" = "Ellenőrizve és megerősítve %@";
"offline_explanation_text" = "A terület megtekintéséhez és az azon való navigálásához egy térképet kell letölteni.\nTöltsön le térképeket azokra a területekre, ahová utazni szeretne.";
"offline_explanation_title" = "Offline térképek";
"avoid_steps" = "Lépcsők elkerülése";
"editor_place_doesnt_exist_description" = "Írja le, hogy jelenleg hogyan néz ki a hely, a hibaüzenet elküldéséhez az OpenStreetMap közösségnek";

View File

@@ -1093,3 +1093,7 @@
"pref_maplanguage_local" = "Vietējā valoda";
"existence_confirmed_time_ago" = "Pastāvēšana apstiprināta %@";
"hours_confirmed_time_ago" = "Apstiprināts %@";
"offline_explanation_text" = "Ir nepieciešams lejupielādēt karti, lai apskatītu un pārvietotos apgabalā.\nJālejupielādē apgabalu, kuros vēlies ceļot, kartes.";
"offline_explanation_title" = "Bezsaistes kartes";
"avoid_steps" = "Izvairīties no pakāpieniem";
"editor_place_doesnt_exist_description" = "Jāapraksta, kā vieta tagad izskatās, lai nosūtītu kļūdas piezīmi OpenStreetMap kopienai";

View File

@@ -40,7 +40,7 @@
"country_status_download_without_size" = "Last ned kart";
/* Message to display at the center of the screen when the country download has failed */
"country_status_download_failed" = "Laster ned mislyktes";
"country_status_download_failed" = "Nedlasting mislyktes";
/* Text in About screen */
"about_headline" = "Åpent prosjekt drevet av felleskapet";
@@ -57,10 +57,10 @@
"continue_button" = "Fortsett";
/* "Add new bookmark list" dialog title */
"add_new_set" = "Legg til nytt sett";
"add_new_set" = "Legg til en ny liste";
/* Add Bookmark list dialog - hint when the list name is empty */
"bookmark_set_name" = "Bokmerk settnavn";
"bookmark_set_name" = "Bokmerkelistenavn";
/* "Bookmark Lists" dialog title */
"bookmark_sets" = "Bokmerk sett";
@@ -157,10 +157,10 @@
"load_kmz_title" = "Laster inn bokmerker";
/* Kmz file successful loading */
"load_kmz_successful" = "Bokmerkene ble lastet inn! Du finner dem på kartet eller på skjermen «Bokmerkeadministrasjon».";
"load_kmz_successful" = "Bokmerkene ble lastet inn! Du finner dem på kartet eller på skjermen Bokmerkehåndtering.";
/* Kml file loading failed */
"load_kmz_failed" = "Opplasting av bokmerker mislyktes. Filen kan være skadet eller defekt.";
"load_kmz_failed" = "Mislyktes i å laste inn bokmerker. Filen kan være skadet eller defekt.";
/* resource for context menu */
"edit" = "Rediger";
@@ -374,16 +374,16 @@
"downloader_download_map" = "Last ned kartet";
/* Item status in downloader. */
"downloader_retry" = "Gjenta";
"downloader_retry" = "Prøv igjen";
/* Item in context menu. */
"downloader_delete_map" = "Slett kart";
/* Text for routing error dialog */
"routing_download_maps_along" = "Last ned kart langs ruten";
"routing_download_maps_along" = "Last ned alle kartene langs ruten din";
/* Text for routing error dialog */
"routing_requires_all_map" = "Når du skal opprette en rute må du ha oppdatert alle kartene fra ditt ståsted til din destinasjon.";
"routing_requires_all_map" = "For å opprette en rute må alle kartene fra posisjonen din til målet ditt lastes ned og oppdateres.";
/* bookmark button text */
"bookmark" = "bokmerk";
@@ -445,16 +445,16 @@
"dialog_routing_disclaimer_beware" = "Kjør trygt!";
"dialog_routing_check_gps" = "Sjekk GPS-signal";
"dialog_routing_error_location_not_found" = "Ingen rute ble opprettet. Nåværende GPS-koordinater ble ikke funnet.";
"dialog_routing_location_turn_wifi" = "Sjekk GPS-signalet. Resultatet blir mer nøyaktig når du bruker wi-fi.";
"dialog_routing_location_turn_on" = "Aktiver stedstjenester";
"dialog_routing_location_unknown_turn_on" = "Nåværende GPS-koordinater ble ikke funnet. Aktiver stedstjenester for å beregne en rute.";
"dialog_routing_location_turn_wifi" = "Sjekk GPS-signalet. Bruk av Wi-Fi vil forbedre posisjonsnøyaktigheten.";
"dialog_routing_location_turn_on" = "Aktiver posisjonstjenester";
"dialog_routing_location_unknown_turn_on" = "Nåværende GPS-koordinater ble ikke funnet. Aktiver posisjonstjenester for å beregne en rute.";
"dialog_routing_download_files" = "Last ned nødvendige filer";
"dialog_routing_download_and_update_all" = "Last ned og oppdater all kart- og ruteinformasjon langs den foreslåtte veien for å beregne ruten.";
"dialog_routing_unable_locate_route" = "Kunne ikke finne rute";
"dialog_routing_change_start_or_end" = "Endre startpunkt eller bestemmelsessted.";
"dialog_routing_change_start" = "Endre startpunkt";
"dialog_routing_start_not_determined" = "Ingen rute ble opprettet. Startpunktet ble ikke funnet.";
"dialog_routing_select_closer_start" = "Velg et startpunkt som er i nærheten av en vei.";
"dialog_routing_select_closer_start" = "Velg et startpunkt nærmere en vei.";
"dialog_routing_change_end" = "Endre bestemmelsessted";
"dialog_routing_end_not_determined" = "Ingen rute ble opprettet. Bestemmelsesstedet ble ikke funnet.";
"dialog_routing_select_closer_end" = "Velg et bestemmelsessted som er i nærheten av en vei.";
@@ -464,7 +464,7 @@
"dialog_routing_application_error" = "En applikasjonsfeil førte til at ruten ikke kunne opprettes.";
"dialog_routing_try_again" = "Vennligst prøv igjen";
"dialog_routing_download_and_build_cross_route" = "Vil du laste ned kartet og lage en mer optimal rute som går over flere kart?";
"dialog_routing_download_cross_route" = "Last ned kartet for å opprette en mer optimal rute som går utenfor dette kartet.";
"dialog_routing_download_cross_route" = "Last ned ytterligere kart for å opprette en bedre rute som krysser grensene til dette kartet.";
/* «Show» context menu */
"show" = "Vis";
@@ -495,14 +495,14 @@
/* Place Page link to Wikimedia Commons. */
"wikimedia_commons" = "Wikimedia Commons";
"p2p_your_location" = "Din beliggenhet";
"p2p_your_location" = "Din posisjon";
"p2p_start" = "Start";
"p2p_from_here" = "Fra";
"p2p_from_here" = "Rute fra";
"p2p_to_here" = "Rute til";
"p2p_only_from_current" = "Navigering er kun tilgjengelig fra din nåværende beliggenhet.";
"p2p_reroute_from_current" = "Vil du vi skal planlegge en rute fra din nåværende posisjon?";
"editor_time_add" = "Legg til tidsrom";
"editor_time_delete" = "Slett tidsrom";
"p2p_reroute_from_current" = "Vil du planlegge en rute fra din nåværende posisjon?";
"editor_time_add" = "Legg til tidsplan";
"editor_time_delete" = "Slett tidsplan";
/* Text for allday switch. */
"editor_time_allday" = "Hele dagen (24 timer)";
@@ -518,7 +518,7 @@
"editor_done_dialog_1" = "Du har endret verdenskartet. Ikke skjul denne! Fortell vennene dine, og rediger det sammen.";
"share_with_friends" = "Del med venner";
"editor_report_problem_send_button" = "Send";
"autodownload" = "Automatisk nedlasting";
"autodownload" = "Last ned kart automatisk";
/* Place Page opening hours text */
"closed_now" = "Lukket nå";
@@ -526,8 +526,8 @@
/* Place Page opening hours text */
"daily" = "Daglig";
"twentyfour_seven" = "Dag og natt";
"day_off_today" = "Fridag i dag";
"day_off" = "Fridag";
"day_off_today" = "Stengt i dag";
"day_off" = "Stengt";
"today" = "I dag";
"opens_tomorrow_at" = "Åpner i morgen klokka %@";
"opens_dayoftheweek_at" = "Åpner %1$@ klokka %2$@";
@@ -581,7 +581,7 @@
/* login text field */
"email_or_username" = "E-postadresse eller brukernavn";
"phone" = "Telefon";
"level" = "Gulv";
"level" = "Etasje";
"please_note" = "Vær oppmerksom på at";
"downloader_delete_map_dialog" = "Alle endringer i kartet vil slettes sammen med kartet.";
"downloader_update_maps" = "Oppdater kart";
@@ -618,9 +618,9 @@
"editor_storey_number" = "Antall etasjer (maks. %d)";
/* Error message in Editor when a user tries to set the number of floors for a building higher than %d floors */
"error_enter_correct_storey_number" = "Rediger bygningen med maks. %d etasjer";
"error_enter_correct_storey_number" = "Antallet etasjer må ikke overstige %d";
"editor_zip_code" = "Postnummer";
"error_enter_correct_zip_code" = "Angi riktig postnummer";
"error_enter_correct_zip_code" = "Angi et gyldig postnummer";
/* Place Page title for long tap */
"core_placepage_unknown_place" = "Kartpunkt";
@@ -675,19 +675,19 @@
"placepage_call_button" = "Ring";
"placepage_edit_bookmark_button" = "Rediger bokmerke";
"placepage_bookmark_name_hint" = "Bokmerkenavn";
"placepage_personal_notes_hint" = "Personlige notater (text or html)";
"placepage_personal_notes_hint" = "Personlige notater (tekst eller html)";
"placepage_delete_bookmark_button" = "Slett bokmerke";
"editor_edits_sent_message" = "Notatet ditt vil bli sendt til OpenStreetMap";
"editor_comment_hint" = "Kommentar…";
"editor_reset_edits_message" = "Nullstille alle lokale endringer?";
"editor_reset_edits_button" = "Nullstill";
"editor_remove_place_message" = "Fjerne et tilføyd sted?";
"editor_remove_place_button" = "Fjern";
"editor_reset_edits_message" = "Forkaste alle lokale endringer?";
"editor_reset_edits_button" = "Forkast";
"editor_remove_place_message" = "Slette tillagt sted?";
"editor_remove_place_button" = "Slett";
"editor_place_doesnt_exist" = "Sted finnes ikke";
"text_more_button" = "…mer";
/* Phone number error message */
"error_enter_correct_phone" = "Skriv riktig telefonnummer";
"error_enter_correct_phone" = "Angi et gyldig telefonnummer";
"error_enter_correct_web" = "Oppgi en gyldig nettadresse";
"error_enter_correct_email" = "Oppgi en gyldig epostadresse";
"refresh" = "Oppdatere";
@@ -726,7 +726,7 @@
"mobile_data_option_never" = "Aldri bruk";
"mobile_data_option_ask" = "Alltid spør";
"traffic_update_maps_text" = "For å vise trafikkdata må kartene i appen være oppdaterte.";
"big_font" = "Forstørr skriften på kartet";
"big_font" = "Øk størrelsen på kartpåskrifter";
/* "traffic" as in road congestion */
"traffic_update_app_message" = "Du må oppdatere applikasjonen for å kunne se trafikkdata.";
@@ -745,11 +745,11 @@
/* User selected the start of a route by pressing Route From. Now the destination of a route should be selected using search or by tapping on the map and then pressing "Route To". */
"routing_add_finish_point" = "Bruk søk eller trykk på kartet for å legge til et destinasjonspunkt";
"planning_route_manage_route" = "Administrere rute";
"button_plan" = "Planlegge";
"planning_route_manage_route" = "Håndter rute";
"button_plan" = "Planlegg";
"placepage_remove_stop" = "Fjern stopp";
"planning_route_remove_title" = "Dra hit for å fjerne";
"placepage_add_stop" = "Angi stopp";
"placepage_add_stop" = "Legg til stopp";
"start_from_my_position" = "Start fra";
/* Title for button when a route was saved. */
@@ -775,13 +775,13 @@
"bookmarks_error_message_empty_list_name" = "Vennligst skriv inn listenavnet";
"bookmarks_error_title_list_name_already_taken" = "Dette navnet er allerede tatt";
"bookmarks_error_title_list_name_too_long" = "Dette navnet er for langt";
"profile" = "OpenStreetMap profil";
"profile" = "OpenStreetMap-profil";
"bookmarks_detect_title" = "Nye filer oppdaget";
"button_convert" = "Konvertere";
"bookmarks_convert_error_title" = "Feil";
"bookmarks_convert_error_message" = "Noen filer ble ikke konvertert.";
"restore" = "Restaurere";
"privacy_policy" = "Personvernpolitikk";
"restore" = "Gjenopprett";
"privacy_policy" = "Personvernpraksis";
"terms_of_use" = "Bruksbetingelser";
"button_layer_subway" = "T-bane";
"layers_title" = "Kartstiler og -lag";
@@ -795,7 +795,7 @@
"tags_loading_error_subtitle" = "Det oppsto en feil under lasting av emneknagger, prøv igjen";
"download_button" = "Last ned";
"speedcams_alert_title" = "Fartskamera";
"place_description_title" = "Plasser beskrivelse";
"place_description_title" = "Stedsbeskrivelse";
/* "Speed cameras" settings menu option (should be short! no more than 47-50 chars) to warn a driver if there is a risk of exceeding the speed limit */
"pref_tts_speedcams_auto" = "For å advare deg mot fartsovertredelser";
@@ -808,10 +808,10 @@
"power_managment_title" = "Strømsparemodus";
"power_managment_description" = "Når automatisk modus er valgt, begynner programmet å deaktivere batteridriftfunksjonene avhengig av det nåværende batterinivået";
"power_managment_setting_never" = "Aldri";
"power_managment_setting_auto" = "Automatisk";
"power_managment_setting_manual_max" = "Maksimum strømsparing";
"enable_logging_warning_message" = "Alternativet slår på logging for diagnostiske formål. Det kan være nyttig for våre supportpersonale som feilsøker problemer med appen. Aktiver dette alternativet bare på forespørsel fra CoMaps-brukerstøtte.";
"driving_options_title" = "Kjørealternativer";
"power_managment_setting_auto" = "Ved lavt batterinivå";
"power_managment_setting_manual_max" = "Alltid";
"enable_logging_warning_message" = "Aktiver dette alternativet midlertidig for å registrere og manuelt sende detaljerte diagnostiske loggfiler om problemet ditt til oss ved bruk av \"Rapporter en feil\" i Hjelp-dialogen. Loggfiler kan inkludere posisjonsinfo.";
"driving_options_title" = "Rutingalternativer";
/* Recommended length for CarPlay and Android Auto is around 25-27 characters */
"avoid_tolls" = "Unngå bompenger";
@@ -820,12 +820,12 @@
"avoid_unpaved" = "Unngå uasfalterte veier";
/* Recommended length for CarPlay and Android Auto is around 25-27 characters */
"avoid_ferry" = "Unngå fergeoverganger";
"avoid_motorways" = "Unngå motorveien";
"avoid_ferry" = "Unngå ferger";
"avoid_motorways" = "Unngå motorveier";
"unable_to_calc_alert_title" = "Kan ikke beregne rute";
"unable_to_calc_alert_subtitle" = "Kan ikke finne en rute. Dette kan skyldes dine rutealternativer eller ufullstendige OpenStreetMap-data. Endre dine rutealternativer og prøv igjen.";
"define_to_avoid_btn" = "Definer veier som skal unngås";
"change_driving_options_btn" = "Kjørealternativer aktivert";
"change_driving_options_btn" = "Rutingalternativer aktivert";
"toll_road" = "Bompengevei";
"unpaved_road" = "Uasfaltert vei";
"ferry_crossing" = "Fergeovergang";
@@ -872,7 +872,7 @@
"carplay_roundabout_exit" = "%@ avkjøring";
/* max. 10 symbols, both iOS and Android */
"sort" = "Sortere…";
"sort" = "Sorter…";
/* iOS */
"sort_default" = "Sortere som standard";
@@ -880,8 +880,8 @@
"sort_distance" = "Sortere etter avstand";
"sort_date" = "Sortere etter dato";
"sort_name" = "Sorter etter navn";
"week_ago_sorttype" = "For en uke siden";
"month_ago_sorttype" = "For en måned siden";
"week_ago_sorttype" = "En uke siden";
"month_ago_sorttype" = "En måned siden";
"moremonth_ago_sorttype" = "Mer enn en måned siden";
"moreyear_ago_sorttype" = "Mer enn ett år siden";
"near_me_sorttype" = "Nær meg";
@@ -897,14 +897,14 @@
"buildings" = "Bygninger";
"money" = "Penger";
"shops" = "Butikker";
"parkings" = "Parkeringer";
"parkings" = "Parkering";
"fuel_places" = "Bensinstasjoner";
"medicine" = "Medisin";
"search_in_the_list" = "Søk på lista";
"religious_places" = "Hellige steder";
"transit_not_found" = "T-bane navigasjon er ikke tilgjengelig i denne regionen ennå";
"dialog_pedestrian_route_is_long_header" = "T-bane rute ikke funnet";
"dialog_pedestrian_route_is_long_message" = "Velg utgangspunkt eller destinasjon som befinner seg nærmere en T-bane stasjon";
"transit_not_found" = "T-bane-navigasjon er ikke tilgjengelig i denne regionen ennå";
"dialog_pedestrian_route_is_long_header" = "T-banerute ikke funnet";
"dialog_pedestrian_route_is_long_message" = "Velg startpunkt eller endepunkt nærmere en T-banestasjon";
"button_layer_isolines" = "Høydekurver";
"isolines_activation_error_dialog" = "Aktivering av høydekurver krever nedlasting av kartdata for dette området";
"isolines_location_error_dialog" = "Høydekurver er ikke tilgjengelige i dette området ennå";
@@ -1095,3 +1095,7 @@
"pref_maplanguage_local" = "Lokalt Språk";
"existence_confirmed_time_ago" = "Existence confirmed %@";
"hours_confirmed_time_ago" = "Confirmed %@";
"offline_explanation_text" = "Et kart må lastes ned for å vise og navigere i området.\nLast ned kart for områdene du vil reise til.";
"offline_explanation_title" = "Offline-kart";
"avoid_steps" = "Unngå trapper";
"editor_place_doesnt_exist_description" = "Beskriv hvordan stedet ser ut nå for å sende en feilmelding til OpenStreetMap-fellesskapet";

View File

@@ -139,11 +139,11 @@
"type.recycling.plastic_bottles" = "Plastflasker";
"type.recycling.scrap_metal" = "Metallavfall";
"type.recycling.small_appliances" = "Elektronisk avfall";
"type.recycling.cardboard" = "Cardboard";
"type.recycling.cans" = "Cans";
"type.recycling.cardboard" = "Papp";
"type.recycling.cans" = "Bokser";
"type.recycling.shoes" = "Sko";
"type.recycling.green_waste" = "Green/Organic Waste";
"type.recycling.cartons" = "Cartons";
"type.recycling.green_waste" = "Organisk avfall";
"type.recycling.cartons" = "Kartonger";
"type.amenity.restaurant" = "Restaurant";
"type.amenity.sanitary_dump_station" = "Holding Tank Dump Station";
"type.amenity.school" = "Skole";
@@ -206,7 +206,7 @@
"type.barrier.hedge" = "Hekk";
"type.barrier.kissing_gate" = "Port";
"type.barrier.lift_gate" = "Bom";
"type.barrier.retaining_wall" = "Retaining Wall";
"type.barrier.retaining_wall" = "Støttemur";
"type.barrier.stile" = "Gjerdeklyver";
"type.barrier.turnstile" = "Rotasjonsport";
"type.barrier.swing_gate" = "Bom";
@@ -675,17 +675,17 @@
"type.landuse.grass" = "Plen";
"type.landuse.greenfield" = "Greenfield";
"type.landuse.greenhouse_horticulture" = "Greenhouse";
"type.landuse.industrial" = "Industrial Area";
"type.landuse.industrial" = "Industriområde";
"type.landuse.landfill" = "Land-deponi";
"type.landuse.meadow" = "Eng";
"type.landuse.military" = "Military Area";
"type.landuse.military" = "Militært område";
"type.landuse.orchard" = "Orchard";
"type.landuse.quarry" = "Quarry";
"type.landuse.quarry" = "Steinbrudd";
"type.landuse.railway" = "Jernbaneområde";
"type.landuse.recreation_ground" = "Rekreasjonsområde";
"type.landuse.reservoir" = "Vann";
"type.landuse.residential" = "Boligområde";
"type.landuse.retail" = "Retail Area";
"type.landuse.retail" = "Butikkområde";
"type.landuse.salt_pond" = "Salt Pond";
"type.landuse.village_green" = "Land";
"type.landuse.vineyard" = "Vineyard";
@@ -724,17 +724,17 @@
"type.leisure.track.area" = "Track";
"type.leisure.water_park" = "Vannpark";
"type.leisure.beach_resort" = "Beach Resort";
"type.man_made" = "Man Made";
"type.man_made" = "Menneskeskapt";
"type.man_made.breakwater" = "Molo";
"type.man_made.cairn" = "Cairn";
"type.man_made.cairn" = "Varde";
"type.man_made.chimney" = "Fabrikkpipe";
"type.man_made.cutline" = "Cutline";
"type.man_made.survey_point" = "Survey Point";
"type.man_made.survey_point" = "Landmålingspunkt";
"type.man_made.flagpole" = "Flaggstang";
"type.man_made.lighthouse" = "Fyr";
"type.man_made.mast" = "Mast";
"type.man_made.pier" = "Pir";
"type.man_made.pipeline" = "Pipeline";
"type.man_made.pipeline" = "Rørledning";
"type.man_made.pipeline.overground" = "Overground Pipeline";
"type.man_made.silo" = "Silo";
"type.man_made.storage_tank" = "Storage Tank";
@@ -1437,8 +1437,8 @@
"type.piste_type.downhill.novice" = "Downhill Ski Run";
"type.piste_type.downhill.novice.area" = "Downhill Ski Run";
"type.piste_type.nordic" = "Langrennsløype";
"type.piste_type.sled" = "Sledding Piste";
"type.piste_type.sled.area" = "Sledding Piste";
"type.piste_type.sled" = "Akebakke";
"type.piste_type.sled.area" = "Akebakke";
"type.piste_type.snow_park" = "Snøpark";
"type.piste_type.hike" = "Tursti i snø";
"type.piste_type.connection" = "Pisteforbindelse";

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