Merge branch 'master' of ssh://github.com/osmandapp/Osmand into LoginDialogsUiImprovements

This commit is contained in:
Chumva 2018-07-06 14:07:46 +03:00
commit 57ace448a5
12 changed files with 562 additions and 55 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -5,10 +5,17 @@ import android.graphics.drawable.Drawable
import android.widget.ImageView
import net.osmand.telegram.R
import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.helpers.TelegramHelper.MessageOsmAndBotLocation
import org.drinkless.td.libcore.telegram.TdApi
object TelegramUiHelper {
fun setupPhoto(app: TelegramApplication, iv: ImageView?, photoPath: String?) {
fun setupPhoto(
app: TelegramApplication,
iv: ImageView?,
photoPath: String?,
placeholderId: Int = R.drawable.ic_group
) {
if (iv == null) {
return
}
@ -18,7 +25,7 @@ object TelegramUiHelper {
bitmap = app.uiUtils.getCircleBitmap(photoPath)
}
if (bitmap == null) {
drawable = app.uiUtils.getThemedIcon(R.drawable.ic_group)
drawable = app.uiUtils.getThemedIcon(placeholderId)
}
if (bitmap != null) {
iv.setImageBitmap(bitmap)
@ -26,4 +33,60 @@ object TelegramUiHelper {
iv.setImageDrawable(drawable)
}
}
fun messageToLocationItem(helper: TelegramHelper, message: TdApi.Message): LocationItem? {
val content = message.content
return when (content) {
is MessageOsmAndBotLocation -> botMessageToLocationItem(content)
is TdApi.MessageLocation -> locationMessageToLocationItem(helper, message)
else -> null
}
}
private fun botMessageToLocationItem(content: MessageOsmAndBotLocation): LocationItem? {
return if (content.isValid()) {
LocationItem().apply {
name = content.name
lat = content.lat
lon = content.lon
placeholderId = R.drawable.ic_group
}
} else {
null
}
}
private fun locationMessageToLocationItem(
helper: TelegramHelper,
message: TdApi.Message
): LocationItem? {
val user = helper.getUser(message.senderUserId) ?: return null
val content = message.content as TdApi.MessageLocation
return LocationItem().apply {
name = "${user.firstName} ${user.lastName}".trim()
if (name.isEmpty()) {
name = user.username
}
if (name.isEmpty()) {
name = user.phoneNumber
}
lat = content.location.latitude
lon = content.location.longitude
photoPath = helper.getUserPhotoPath(user)
placeholderId = R.drawable.ic_group
}
}
class LocationItem {
var name: String = ""
internal set
var lat: Double = 0.0
internal set
var lon: Double = 0.0
internal set
var photoPath: String? = null
internal set
var placeholderId: Int = 0
internal set
}
}

View file

@ -13,18 +13,24 @@ import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
import net.osmand.Location
import net.osmand.telegram.R
import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.TelegramLocationProvider.TelegramLocationListener
import net.osmand.telegram.helpers.TelegramHelper
import net.osmand.telegram.helpers.TelegramHelper.*
import net.osmand.telegram.helpers.TelegramUiHelper
import net.osmand.telegram.helpers.TelegramUiHelper.LocationItem
import net.osmand.telegram.utils.AndroidUtils
import net.osmand.telegram.utils.OsmandFormatter
import net.osmand.util.MapUtils
import org.drinkless.td.libcore.telegram.TdApi
private const val CHAT_VIEW_TYPE = 0
private const val CONTACT_VIEW_TYPE = 1
private const val LOCATION_ITEM_VIEW_TYPE = 1
class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessagesListener {
class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessagesListener,
TelegramLocationListener {
private val app: TelegramApplication
get() = activity?.application as TelegramApplication
@ -35,6 +41,8 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
private lateinit var adapter: LiveNowListAdapter
private var location: Location? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -53,11 +61,13 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
super.onResume()
updateList()
telegramHelper.addIncomingMessagesListener(this)
startLocationUpdate()
}
override fun onPause() {
super.onPause()
telegramHelper.removeIncomingMessagesListener(this)
stopLocationUpdate()
}
override fun onTelegramStatusChanged(
@ -92,17 +102,39 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
updateList()
}
override fun onTelegramError(code: Int, message: String) {
}
override fun onTelegramError(code: Int, message: String) {}
override fun onSendLiveLocationError(code: Int, message: String) {
}
override fun onSendLiveLocationError(code: Int, message: String) {}
override fun onReceiveChatLocationMessages(chatTitle: String, vararg messages: TdApi.Message) {
app.runInUIThread { updateList() }
}
override fun updateLocationMessages() {
override fun updateLocationMessages() {}
override fun updateLocation(location: Location?) {
val loc = this.location
val newLocation = loc == null && location != null
val locationChanged = loc != null && location != null
&& loc.latitude != location.latitude
&& loc.longitude != location.longitude
if (newLocation || locationChanged) {
this.location = location
updateLocationUi()
}
}
fun startLocationUpdate() {
app.locationProvider.addLocationListener(this)
updateLocationUi()
}
fun stopLocationUpdate() {
app.locationProvider.removeLocationListener(this)
}
private fun updateLocationUi() {
adapter.notifyDataSetChanged()
}
private fun updateList() {
@ -110,23 +142,33 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
for ((id, messages) in telegramHelper.getMessagesByChatIds()) {
telegramHelper.getChat(id)?.also { chat ->
res.add(chat)
val type = chat.type
if (type is TdApi.ChatTypeBasicGroup || type is TdApi.ChatTypeSupergroup) {
messages.forEach { message ->
if (message.content is MessageOsmAndBotLocation) {
res.add(message.content)
} else {
telegramHelper.getUser(message.senderUserId)?.also { res.add(it) }
}
}
} else if (type is TdApi.ChatTypePrivate && telegramHelper.getUser(type.userId)?.username == TelegramHelper.OSMAND_BOT_USERNAME) {
res.addAll(messages.filter { it.content is MessageOsmAndBotLocation })
if (needLocationItems(chat.type)) {
res.addAll(convertToLocationItems(messages))
}
}
}
adapter.items = res
}
private fun needLocationItems(type: TdApi.ChatType): Boolean {
return when (type) {
is TdApi.ChatTypeBasicGroup -> true
is TdApi.ChatTypeSupergroup -> true
is TdApi.ChatTypePrivate -> {
telegramHelper.getUser(type.userId)?.username == TelegramHelper.OSMAND_BOT_USERNAME
}
else -> false
}
}
private fun convertToLocationItems(messages: List<TdApi.Message>): List<LocationItem> {
return mutableListOf<LocationItem>().apply {
messages.forEach { message ->
TelegramUiHelper.messageToLocationItem(telegramHelper, message)?.also { add(it) }
}
}
}
inner class LiveNowListAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val menuList =
@ -141,7 +183,7 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
override fun getItemViewType(position: Int): Int {
return when (items[position]) {
is TdApi.Chat -> CHAT_VIEW_TYPE
else -> CONTACT_VIEW_TYPE
else -> LOCATION_ITEM_VIEW_TYPE
}
}
@ -173,15 +215,18 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
holder.showOnMapState?.text = menuList[stateTextInd]
holder.bottomDivider?.visibility = if (nextItemIsUser) View.VISIBLE else View.GONE
holder.bottomShadow?.visibility = if (lastItem) View.VISIBLE else View.GONE
} else if (item is TdApi.User && holder is ContactViewHolder) {
TelegramUiHelper.setupPhoto(app, holder.icon, telegramHelper.getUserPhotoPath(item))
holder.title?.text = "${item.firstName} ${item.lastName}"
holder.description?.text = "User description" // FIXME
holder.bottomShadow?.visibility = if (lastItem) View.VISIBLE else View.GONE
} else if (item is MessageOsmAndBotLocation && holder is ContactViewHolder) {
holder.icon?.setImageDrawable(app.uiUtils.getThemedIcon(R.drawable.ic_group))
} else if (item is LocationItem && holder is ContactViewHolder) {
TelegramUiHelper.setupPhoto(app, holder.icon, item.photoPath, item.placeholderId)
holder.title?.text = item.name
holder.description?.text = "Location from osmand_bot" // FIXME
if (location != null) {
val dist = MapUtils.getDistance(
location!!.latitude, location!!.longitude,
item.lat, item.lon
).toFloat()
holder.description?.text = OsmandFormatter.getFormattedDistance(dist, app)
} else {
holder.description?.text = "Current location is not available"
}
holder.bottomShadow?.visibility = if (lastItem) View.VISIBLE else View.GONE
}
}

View file

@ -0,0 +1,63 @@
package net.osmand.telegram.ui.views
import android.graphics.Canvas
import android.graphics.ColorFilter
import android.graphics.PixelFormat
import android.graphics.Rect
import android.graphics.drawable.Drawable
import net.osmand.telegram.TelegramApplication
class DirectionDrawable(private val app: TelegramApplication) : Drawable() {
private var angle: Float = 0.toFloat()
private var arrowImage: Drawable? = null
fun setImage(resourceId: Int, clrId: Int) {
arrowImage = app.uiUtils.getIcon(resourceId, clrId)
onBoundsChange(bounds)
}
fun setAngle(angle: Float) {
this.angle = angle
}
override fun getIntrinsicWidth() = arrowImage?.intrinsicWidth ?: super.getIntrinsicWidth()
override fun getIntrinsicHeight() = arrowImage?.intrinsicHeight ?: super.getIntrinsicHeight()
override fun onBoundsChange(bounds: Rect) {
super.onBoundsChange(bounds)
if (arrowImage != null) {
val w = arrowImage!!.intrinsicWidth
val h = arrowImage!!.intrinsicHeight
val dx = Math.max(0, bounds.width() - w)
val dy = Math.max(0, bounds.height() - h)
if (bounds.width() == 0 && bounds.height() == 0) {
arrowImage!!.setBounds(0, 0, w, h)
} else {
arrowImage!!.setBounds(
bounds.left + dx / 2,
bounds.top + dy / 2,
bounds.right - dx / 2,
bounds.bottom - dy / 2
)
}
}
}
override fun draw(canvas: Canvas) {
canvas.save()
if (arrowImage != null) {
val r = bounds
canvas.rotate(angle, r.centerX().toFloat(), r.centerY().toFloat())
arrowImage!!.draw(canvas)
}
canvas.restore()
}
override fun getOpacity() = PixelFormat.UNKNOWN
override fun setAlpha(alpha: Int) {}
override fun setColorFilter(cf: ColorFilter?) {}
}

View file

@ -1,15 +1,25 @@
package net.osmand.telegram.utils
import android.content.Context
import android.graphics.*
import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable
import android.hardware.Sensor
import android.hardware.SensorManager
import android.support.annotation.ColorInt
import android.support.annotation.ColorRes
import android.support.annotation.DrawableRes
import android.support.v4.content.ContextCompat
import android.support.v4.graphics.drawable.DrawableCompat
import android.view.Surface
import android.view.WindowManager
import android.widget.ImageView
import android.widget.TextView
import net.osmand.Location
import net.osmand.data.LatLon
import net.osmand.telegram.R
import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.ui.views.DirectionDrawable
import java.util.*
class UiUtils(private val app: TelegramApplication) {
@ -122,4 +132,84 @@ class UiUtils(private val app: TelegramApplication) {
return bitmap
}
fun updateLocationView(
arrow: ImageView?,
text: TextView?,
lat: Double,
lon: Double,
cache: UpdateLocationViewCache
) {
updateLocationView(arrow, text, LatLon(lat, lon), cache)
}
fun updateLocationView(
arrow: ImageView?,
text: TextView?,
toLoc: LatLon,
cache: UpdateLocationViewCache
) {
val fromLoc = app.locationProvider.lastKnownLocationLatLon
val heading = app.locationProvider.heading
val mes = FloatArray(2)
val locPassive = fromLoc == null || cache.outdatedLocation
val colorId = if (locPassive) R.color.icon_light else R.color.ctrl_active_light
fromLoc?.also { l ->
Location.distanceBetween(toLoc.latitude, toLoc.longitude, l.latitude, l.longitude, mes)
}
if (arrow != null) {
var newImage = false
val drawable = arrow.drawable
val dd = if (drawable is DirectionDrawable) {
drawable
} else {
newImage = true
DirectionDrawable(app)
}
dd.setImage(R.drawable.ic_direction_arrow, colorId)
if (fromLoc == null || heading == null) {
dd.setAngle(0f)
} else {
dd.setAngle(mes[1] - heading + 180 + cache.screenOrientation)
}
if (newImage) {
arrow.setImageDrawable(dd)
}
arrow.invalidate()
}
if (text != null) {
text.setTextColor(ContextCompat.getColor(app, colorId))
val meters = if (fromLoc == null) 0f else mes[1]
text.text = OsmandFormatter.getFormattedDistance(meters, app)
}
}
fun getUpdateLocationViewCache() =
UpdateLocationViewCache().apply { screenOrientation = getScreenOrientation() }
private fun getScreenOrientation(): Int {
// screenOrientation correction must not be applied for devices without compass
val sensorManager = app.getSystemService(Context.SENSOR_SERVICE) as SensorManager?
if (sensorManager?.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) == null) {
return 0
}
val windowManager = app.getSystemService(Context.WINDOW_SERVICE) as WindowManager?
val rotation = windowManager?.defaultDisplay?.rotation ?: return 0
return when (rotation) {
Surface.ROTATION_90 -> 90
Surface.ROTATION_180 -> 180
Surface.ROTATION_270 -> 270
else -> 0
}
}
class UpdateLocationViewCache {
var screenOrientation: Int = 0
var outdatedLocation: Boolean = false
}
}

View file

@ -3246,4 +3246,124 @@
<string name="poi_cuisine_pita">Πίτα</string>
<string name="poi_cuisine_fondue">Φόντυ</string>
<string name="poi_cuisine_baguette">Μπαγκέτα (ψωμί)</string>
<string name="poi_cuisine_pastel">Εμπανάντα (παστέλ)</string>
<string name="poi_cuisine_burrito">Μπουρίτο</string>
<string name="poi_cuisine_teriyaki">Τεριγιάκι</string>
<string name="poi_cuisine_shawarma">Σαουάρμα</string>
<string name="poi_cuisine_regional">Τοπικό</string>
<string name="poi_cuisine_italian">Ιταλικό</string>
<string name="poi_cuisine_chinese">Κινέζικο</string>
<string name="poi_cuisine_mexican">Μεξικάνικο</string>
<string name="poi_cuisine_japanese">Γιαπωνέζικο</string>
<string name="poi_cuisine_german">Γερμανικό</string>
<string name="poi_cuisine_indian">Ινδικό</string>
<string name="poi_cuisine_american">Αμερικάνικο</string>
<string name="poi_cuisine_asian">Ασιατικό</string>
<string name="poi_cuisine_french">Γαλλικό</string>
<string name="poi_cuisine_greek">Ελληνικό</string>
<string name="poi_cuisine_thai">Τάι</string>
<string name="poi_cuisine_international">Διεθνές</string>
<string name="poi_cuisine_turkish">Τούρκικο</string>
<string name="poi_cuisine_spanish">Ισπανικό</string>
<string name="poi_cuisine_vietnamese">Βιετναμέζικο</string>
<string name="poi_cuisine_korean">Κορεάτικο</string>
<string name="poi_cuisine_mediterranean">Μεσογειακό</string>
<string name="poi_cuisine_bavarian">Βαβαρικό</string>
<string name="poi_cuisine_lebanese">Λιβανέζικο</string>
<string name="poi_cuisine_russian">Ρώσικο</string>
<string name="poi_cuisine_filipino">Φιλιπινέζικο</string>
<string name="poi_cuisine_portuguese">Πορτογαλλικό</string>
<string name="poi_cuisine_georgian">Γεωργιανό</string>
<string name="poi_cuisine_polish">Πολωνικό</string>
<string name="poi_cuisine_brazilian">Βραζιλιάνικο</string>
<string name="poi_cuisine_arab">Αραβικό</string>
<string name="poi_cuisine_danish">Δανικό</string>
<string name="poi_cuisine_indonesian">Ινδονησιακό</string>
<string name="poi_cuisine_african">Αφρικανικό</string>
<string name="poi_cuisine_caribbean">Καραϊβικής</string>
<string name="poi_cuisine_argentinian">Αργεντίνικο</string>
<string name="poi_cuisine_balkan">Βαλκανικό</string>
<string name="poi_cuisine_peruvian">Περουβιανό</string>
<string name="poi_cuisine_croatian">Κροατικό</string>
<string name="poi_cuisine_bolivian">Βολιβιανό</string>
<string name="poi_cuisine_malagasy">Μαδαγασκάρης</string>
<string name="poi_cuisine_persian">Περσικό</string>
<string name="poi_cuisine_moroccan">Μαροκινό</string>
<string name="poi_cuisine_austrian">Αυστριακό</string>
<string name="poi_cuisine_malaysian">Μαλαισιανό</string>
<string name="poi_cuisine_irish">Ιρλανδικό</string>
<string name="poi_cuisine_ethiopian">Αιθιοπικό</string>
<string name="poi_cuisine_hungarian">Ουγγρικό</string>
<string name="poi_cuisine_lao">Λάο</string>
<string name="poi_cuisine_european">Ευρωπαϊκό</string>
<string name="poi_cuisine_uzbek">Ουζμπέκικο</string>
<string name="poi_cuisine_czech">Τσέχικο</string>
<string name="poi_cuisine_cuban">Κουβανικό</string>
<string name="poi_cuisine_british">Βρετανικό</string>
<string name="poi_cuisine_latin_american">Λατινοαμερικάνικο</string>
<string name="poi_cuisine_nepalese">Νεπαλέζικο</string>
<string name="poi_cuisine_mongolian">Μογγολικό</string>
<string name="poi_cuisine_middle_eastern">Μέσης Ανατολής</string>
<string name="poi_cuisine_ukrainian">Ουκρανικό</string>
<string name="poi_cuisine_afghan">Αφγανικό</string>
<string name="poi_cuisine_belgian">Βελγικό</string>
<string name="poi_cuisine_basque">Βασκικό</string>
<string name="poi_cuisine_swiss">Ελβετικό</string>
<string name="poi_cuisine_cantonese">Καντονέζικο</string>
<string name="poi_cuisine_swedish">Σουηδικό</string>
<string name="poi_cuisine_jamaican">Τζαμάικας</string>
<string name="poi_cuisine_armenian">Αρμενικό</string>
<string name="poi_cuisine_hawaiian">Χαβανέζικο</string>
<string name="poi_cuisine_english">Αγγλικό</string>
<string name="poi_cuisine_pakistani">Πακιστανικό</string>
<string name="poi_cuisine_taiwanese">Ταϊβανέζικο</string>
<string name="poi_cuisine_tex_mex">Τέξας-Μεξικό</string>
<string name="poi_cuisine_dutch">Ολλανδικό</string>
<string name="poi_cuisine_syrian">Συριακό</string>
<string name="poi_cuisine_australian">Αυστραλέζικο</string>
<string name="poi_cuisine_cajun">Κατζούν</string>
<string name="poi_cuisine_egyptian">Αιγυπτιακό</string>
<string name="poi_cuisine_senegalese">Σενεγαλέζικο</string>
<string name="poi_cuisine_jewish">Εβραϊκό</string>
<string name="poi_cuisine_bulgarian">Βουλγάρικο</string>
<string name="poi_cuisine_tibetan">Θιβετιανό</string>
<string name="poi_feeding_place">Τόπος για τάισμα ζώων</string>
<string name="poi_party">Προμήθειες γιορτής</string>
<string name="poi_electrical">Ηλεκτρικό κατάστημα</string>
<string name="poi_locksmith">Κλειδαράδικο</string>
<string name="poi_lighting">Φωτισμός</string>
<string name="poi_lottery">Λαχείο</string>
<string name="poi_gambling">Αίθουσα τυχερών παιχνιδιών</string>
<string name="poi_gambling_type">Τύπος</string>
<string name="poi_gambling_lottery">Λοταρία</string>
<string name="poi_gambling_pachinko">Πατσίνκο</string>
<string name="poi_gambling_slot_machines">Κουλοχέρης</string>
<string name="poi_gambling_betting">Στοίχημα</string>
<string name="poi_gambling_bingo">Μπίνγκο</string>
<string name="poi_e_cigarette">Ηλεκτρονικά τσιγάρα</string>
<string name="poi_locomotive">Μηχανή τρένου</string>
<string name="poi_nutrition_supplements">Συμπληρώματα διατροφής</string>
<string name="poi_photo_studio">Φωτογραφείο</string>
<string name="poi_cliff">Γκρεμός</string>
<string name="poi_animal_keeping">Φύλαξη ζώων</string>
<string name="poi_animal_keeping_horse">Φύλαξη ζώων: άλογα</string>
<string name="poi_animal_keeping_sheep">Φύλαξη ζώων: πρόβατα</string>
<string name="poi_animal_keeping_type_paddock">Τύπος: μάντρα</string>
<string name="poi_animal_keeping_type_open_stable">Τύπος: ανοιχτός στάβλος</string>
<string name="poi_tower_construction_lattice">Κατασκευή: πλέγμα</string>
<string name="poi_tower_construction_freestanding">Κατασκευή: ελεύθερη</string>
<string name="poi_tower_construction_dish">Κατασκευή: πιάτο</string>
<string name="poi_tower_construction_dome">Κατασκευή: θόλος</string>
<string name="poi_tower_construction_concealed">Κατασκευή: κρυφή</string>
</resources>

View file

@ -412,7 +412,7 @@
<string name="poi_service_tyres">צמיגים</string>
<string name="poi_vehicle_inspection">מבחן רישוי שנתי לרכב</string>
<string name="poi_car_wash">שטיפת רכב</string>
<string name="poi_fuel">תחנת דלק</string>
<string name="poi_fuel">תחנת דלק;תחנת תדלוק;תחנת מילוי דלק;תחנת בנזין</string>
<string name="poi_fuel_diesel">דיזל</string>
<string name="poi_fuel_gtl_diesel">דיזל מגז</string>
<string name="poi_fuel_biodiesel">ביו דיזל</string>
@ -1576,4 +1576,28 @@
<string name="poi_payment_contactless_yes">ללא מגע</string>
<string name="poi_payment_contactless_no">לא מקבלים ללא מגע</string>
</resources>
<string name="poi_aerialway_magic_carpet">מסוע שטיח</string>
<string name="poi_waterway_turning_point">נקודת מפנה במסלול שיט</string>
<string name="poi_power_substation">תחנת משנה</string>
<string name="poi_power_transformer">שנאי</string>
<string name="poi_recycling_cans">פחיות</string>
<string name="poi_recycling_scrap_metal">מתכת</string>
<string name="poi_recycling_low_energy_bulbs">מנורות מתח נמוך</string>
<string name="poi_recycling_fluorescent_tubes">צינורות פלורוסנט</string>
<string name="poi_recycling_tetrapak">טטרה פק</string>
<string name="poi_recycling_foil">נייר אלומיניום</string>
<string name="poi_recycling_chipboard">שבבית</string>
<string name="poi_waste_disposal">השלכת אשפה</string>
<string name="poi_landuse_railway">אזור מסילות</string>
<string name="poi_commercial">שימוש קרקע מסחרי</string>
<string name="poi_retail">שימוש קרקע קמעונאי</string>
<string name="poi_anchorage">מעגן</string>
<string name="poi_entrance">כניסה</string>
<string name="poi_entrance_exit">יציאה</string>
<string name="poi_icn_ref">מפרק ברשת רכיבה בינלאומית</string>
<string name="poi_ncn_ref">מפרק ברשת רכיבה לאומית</string>
<string name="poi_rcn_ref">מפרק ברשת רכיבה אזורית</string>
<string name="poi_lcn_ref">מפרק ברשת רכיבה מקומית</string>
</resources>

View file

@ -988,7 +988,7 @@
<string name="poi_wheelchair_yes">Да</string>
<string name="poi_wheelchair_no">Не</string>
<string name="poi_wheelchair_limited">Ограничен</string>
<string name="poi_wholesale"></string>
<string name="poi_wholesale"/>
<string name="poi_access_private">Приватни посед</string>
<string name="poi_access_no">Без приступа</string>
@ -1018,7 +1018,7 @@
<string name="poi_bicycle_parking_informal">Неформалан</string>
<string name="poi_leaf_type_broadleaved"></string>
<string name="poi_leaf_type_broadleaved"/>
<string name="poi_trees_olive">Маслина</string>
<string name="poi_trees_apple">Јабука</string>
<string name="poi_trees_oil">Палмино уље</string>
@ -1134,4 +1134,108 @@
<string name="poi_grass">Трава</string>
<string name="poi_sand">Песак</string>
<string name="poi_bicycle_parking_stands">Штандови</string>
<string name="poi_bicycle_parking_building">Специјална зграда</string>
<string name="poi_bicycle_parking_shed">Шупа</string>
<string name="poi_leaf_type_mixed">Мешано</string>
<string name="poi_species">Врсте</string>
<string name="poi_genus">Род</string>
<string name="poi_taxon">Таксон</string>
<string name="poi_intermittent">Повремено</string>
<string name="poi_information_board">Табла</string>
<string name="poi_information_trail_blaze">Маркација на дрвету</string>
<string name="poi_information_route_marker">Маркер пута</string>
<string name="poi_board_type_notice">Огласна табла</string>
<string name="poi_fireplace_no">Нема огњишта</string>
<string name="poi_smoking_dedicated">За пушаче</string>
<string name="poi_toll_yes">Путарина</string>
<string name="poi_toll_no">Без путарине</string>
<string name="poi_dead_wood">Мртво дрво</string>
<string name="poi_level">Ниво</string>
<string name="poi_piste_difficulty_easy">Лака</string>
<string name="poi_piste_difficulty_intermediate">Средња</string>
<string name="poi_piste_difficulty_advanced">Напредна</string>
<string name="poi_piste_difficulty_novice">Почетничка</string>
<string name="poi_piste_difficulty_expert">Експертска</string>
<string name="poi_piste_difficulty_freeride">Слободна вожња</string>
<string name="poi_piste_grooming_classic">Класично</string>
<string name="poi_piste_grooming_classic_skating">Класично+клизање</string>
<string name="poi_piste_grooming_scooter">Скутером</string>
<string name="poi_piste_grooming_skating">Клизање</string>
<string name="poi_piste_grooming_no">Не</string>
<string name="poi_piste_grooming_mogul">Могул</string>
<string name="poi_garden_type_residential">Тип баште: стамбена</string>
<string name="poi_garden_type_community">Тип баште: јавна</string>
<string name="poi_garden_type_private">Тип баште: приватна</string>
<string name="poi_garden_type_botanical">Тип баште: ботаничка</string>
<string name="poi_garden_style_kitchen">Тип баште: кухињска</string>
<string name="poi_garden_style_rosarium">Тип баште: розаријум</string>
<string name="poi_garden_style_french">Тип баште: француски</string>
<string name="poi_garden_style_english">Тип баште: енглески</string>
<string name="poi_garden_style_japanese">Тип баште: јапански</string>
<string name="poi_capacity">Капацитет</string>
<string name="poi_capacity_disabled_yes">Да</string>
<string name="poi_capacity_disabled_no">Нема посебних места за особе са инвалидитетом</string>
<string name="poi_capacity_disabled">Посебна места за особе са инвалидитетом</string>
<string name="poi_capacity_women_yes">Посебна места за жене</string>
<string name="poi_capacity_women_no">Нема посебних места за жене</string>
<string name="poi_capacity_women">Посебна места за жене</string>
<string name="poi_capacity_pupils">Посебна места за ученике</string>
<string name="poi_capacity_teachers">Посебна места за наставнике</string>
<string name="poi_capacity_parent_yes">Посебна места за родитеље</string>
<string name="poi_capacity_parent_no">Без посебних места за родитеље</string>
<string name="poi_capacity_parent">Посебна места за родитеље</string>
<string name="poi_aerialway_capacity">Капацитет на сат</string>
<string name="poi_aerialway_duration">Просечно време путовања, у минутима</string>
<string name="poi_aerialway_bubble_yes">Балон</string>
<string name="poi_aerialway_bubble_no">Без балона</string>
<string name="poi_aerialway_heating_yes">Да</string>
<string name="poi_aerialway_heating_no">Без грејања</string>
<string name="poi_aerialway_bicycle_yes">Дозвољене</string>
<string name="poi_aerialway_bicycle_no">Бицикле: недозвољене</string>
<string name="poi_aerialway_bicycle_summer">Дозвољене само лети</string>
<string name="poi_aerialway_access_entry">Само улаз</string>
<string name="poi_aerialway_access_exit">Само излаз</string>
<string name="poi_aerialway_access_both">Улаз и излаз</string>
<string name="poi_aerialway_summer_access_entry">Летњи приступ: само улаз</string>
<string name="poi_aerialway_summer_access_exit">Летњи приступ: само излаз</string>
<string name="poi_aerialway_summer_access_both">Летњи приступ: улаз и излаз</string>
<string name="poi_rooms">Собе</string>
<string name="poi_love_hotel">Љубавни хотел</string>
<string name="poi_payment_coins_yes">Кованице</string>
<string name="poi_payment_coins_no">Кованице се не прихватају</string>
<string name="poi_payment_coins_0.5">$0.5 кованице</string>
<string name="poi_payment_coins_50c12">50c, 1€ и 2€ кованице</string>
<string name="poi_payment_telephone_cards_yes">Телефонске картице</string>
<string name="poi_payment_telephone_cards_no">Телефонске картице се не прихватају</string>
<string name="poi_payment_credit_cards_yes">Кредитне картице</string>
<string name="poi_payment_credit_cards_no">Кредитне картице се не прихватају</string>
<string name="poi_payment_notes_yes">Новчанице</string>
<string name="poi_payment_notes_no">Новчанице се не прихватају</string>
<string name="poi_payment_electronic_purses_yes">Електронске ташне</string>
<string name="poi_payment_electronic_purses_no">Електронске ташне се не прихватају</string>
<string name="poi_payment_cash_yes">Кеш</string>
<string name="poi_payment_cash_no">Кеш се не прихвата</string>
<string name="poi_payment_debit_cards_yes">Дебитне картице</string>
<string name="poi_payment_debit_cards_no">Дебитне картице се не прихватају</string>
<string name="poi_payment_bitcoin_yes">Биткоин</string>
<string name="poi_payment_bitcoin_no">Биткоин се не прихвата</string>
<string name="poi_payment_visa_yes">Visa картице</string>
<string name="poi_payment_visa_no">Visa картице се не прихватају</string>
<string name="poi_payment_mastercard_yes">MasterCard картице</string>
<string name="poi_payment_mastercard_no">MasterCard картице се не прихватају</string>
<string name="poi_payment_maestro_yes">Maestro картице</string>
<string name="poi_payment_maestro_no">Maestro картице се не прихватају</string>
</resources>

View file

@ -2477,13 +2477,13 @@ Vänligen tillhandahåll fullständig kod</string>
<string name="quick_action_showhide_osmbugs_title">Visa/Dölj OSM-anteckningar</string>
<string name="quick_action_osmbugs_show">Visa OSM-anteckningar</string>
<string name="quick_action_osmbugs_hide">Dölj OSM-anteckningar</string>
<string name="quick_action_showhide_osmbugs_descr">Tryck på åtgärdsknappen visar eller döljer OSM-anteckningar på kartan.</string>
<string name="quick_action_showhide_osmbugs_descr">Ett tryck på denna åtgärdsknapp visar eller döljer OSM-anteckningar på kartan.</string>
<string name="restart_search">Starta om sökningen</string>
<string name="increase_search_radius">Utöka sökradien</string>
<string name="nothing_found">Hittade ingenting :(</string>
<string name="nothing_found">Hittade ingenting</string>
<string name="nothing_found_descr">Ändra sökord eller utöka sökradien.</string>
<string name="sorted_by_distance">Sorterat efter avstånd</string>
<string name="search_favorites">Sök favoriter</string>
<string name="search_favorites">Sök Favoriter</string>
<string name="shared_string_plugin">Insticksmodul</string>
<string name="srtm_color_scheme">Färgschema</string>
<string name="favorite_group_name">Gruppnamn</string>
@ -2541,11 +2541,11 @@ Vänligen tillhandahåll fullständig kod</string>
<string name="choose_navigation_type">Välj navigeringsprofil</string>
<string name="enter_gpx_name">Namn på GPX-fil:</string>
<string name="measurement_tool">Mät avstånd</string>
<string name="quick_action_resume_pause_navigation">Återuppta/Pausa navigeringen</string>
<string name="quick_action_resume_pause_navigation">Pausa/Återuppta navigeringen</string>
<string name="quick_action_start_stop_navigation">Starta/Stoppa navigeringen</string>
<string name="shared_string_reset">Återställ</string>
<string name="shared_string_reload">Ladda om</string>
<string name="wrong_user_name">Fel användarnamn!</string>
<string name="wrong_user_name">Fel användarnamn</string>
<string name="shared_string_to">Till</string>
<string name="mapillary_menu_date_from">Från</string>
<string name="mapillary_menu_title_dates">Datum</string>
@ -2572,7 +2572,7 @@ Vänligen tillhandahåll fullständig kod</string>
<string name="order_by">Ordna efter:</string>
<string name="all_markers_moved_to_history">Alla kartmarkörer har flyttats till historiken</string>
<string name="marker_moved_to_history">Kartmarkören har flyttats till historiken</string>
<string name="do_not_use_animations">Använd inte animeringar</string>
<string name="do_not_use_animations">Inga animeringar</string>
<string name="do_not_use_animations_descr">Inaktiverar animeringar i appen.</string>
<string name="line">Linje</string>
<string name="save_as_route_point">Spara som ruttpunkter</string>
@ -2581,7 +2581,7 @@ Vänligen tillhandahåll fullständig kod</string>
<string name="edit_line">Redigera linje</string>
<string name="add_point_before">Lägg till punkt före</string>
<string name="add_point_after">Lägg till punkt efter</string>
<string name="measurement_tool_save_as_new_track_descr">Du kan spara punkterna antingen som ruttpunkter eller som en linje.</string>
<string name="measurement_tool_save_as_new_track_descr">Spara punkterna antingen som ruttpunkter eller som en linje.</string>
<string name="none_point_error">Lägg till minst en punkt.</string>
<string name="show_on_map_after_saving">Visa på kartan när den sparats</string>
<string name="quick_action_resume_pause_navigation_descr">Peta på denna knapp för att pausa eller fortsätta med navigeringen.</string>
@ -2589,16 +2589,16 @@ Vänligen tillhandahåll fullständig kod</string>
<string name="mapillary_image">Mapillary-bild</string>
<string name="open_mapillary">Öppna Mapillary</string>
<string name="improve_coverage_mapillary">Förbättra fototäckning med Mapillary</string>
<string name="mapillary_widget_descr">Gör så att du snabbt kan bidraga till Mapillary.</string>
<string name="mapillary_widget_descr">Möjliggör snabba bidrag till Mapillary.</string>
<string name="descendingly">nedåt</string>
<string name="ascendingly">uppåt</string>
<string name="marker_moved_to_active">Kartmarkören flyttad till aktiva</string>
<string name="move_all_to_history">Flytta alla till historiken</string>
<string name="keep_showing_on_map">Fortsätt att visa på kartan</string>
<string name="measurement_tool_action_bar">Titta på kartan och lägg till punkter</string>
<string name="quick_action_show_navigation_finish_dialog">Visa dialogen Navigation avslutad</string>
<string name="quick_action_show_navigation_finish_dialog">Visa dialogen \'Navigation avslutad\'</string>
<string name="store_tracks_in_monthly_directories">Spara inspelade spår i mappar efter månad</string>
<string name="store_tracks_in_monthly_directories_descrp">Spara inspelade spår i undermappar efter inspelad månad (typ 2017-01).</string>
<string name="store_tracks_in_monthly_directories_descrp">Spara inspelade spår i undermappar efter inspelad månad (typ 2018-01).</string>
<string name="mapillary_menu_descr_dates">Visa endast tillagda bilder</string>
<string name="mapillary_menu_descr_username">Visa endast bilder tillagda av</string>
<string name="import_gpx_file_description">kan importeras som favoriter eller som GPX-fil.</string>
@ -2682,7 +2682,7 @@ Vänligen tillhandahåll fullständig kod</string>
<string name="shared_string_actions">Åtgärder</string>
<string name="shared_string_marker">Markör</string>
<string name="one_tap_active_descr">Tryck på en markör på kartan för att flytta den till toppen av de aktiva markörerna utan att öppna sammanhangsmenyn.</string>
<string name="one_tap_active">Ett tryck för att aktivera</string>
<string name="one_tap_active">\'Ett tryck\' aktiv</string>
<string name="empty_state_av_notes_desc">Lägg till ljud-, video- eller fotonotering för varje punkt på kartan, med hjälp av widgeten eller menyn.</string>
<string name="add_track_to_markers_descr">Välj ett spår för att lägga till dess waypoints till markörer.</string>
<string name="add_favourites_group_to_markers_descr">Välj en favoritkategori för att lägga till markörer.</string>
@ -2721,27 +2721,25 @@ Vänligen tillhandahåll fullständig kod</string>
<string name="measurement_tool_snap_to_road_descr">Charlott ansluter punkter med vägar för den valda profilen.</string>
<string name="mapillary_menu_descr_tile_cache">Ladda tiles för att se aktuell data.</string>
<string name="mapillary_menu_title_tile_cache">Tile-cache</string>
<string name="mapillary_menu_filter_description">Du kan filtrera bilderna enligt inlämnare eller datum. Filter tillämpas endast för närbildszoom.</string>
<string name="mapillary_menu_filter_description">Filtrera bilderna enligt inlämnare eller datum. Filter tillämpas endast för närbildszoom.</string>
<string name="map_widget_ruler_control">Radielinjal</string>
<string name="improve_coverage_install_mapillary_desc">Du kan ta dina egna bilder eller en serie bilder och bifoga dem till denna kartplats.
\n
\nFör att göra detta måste du installera Mapillary app från Google Play Store.</string>
<string name="improve_coverage_install_mapillary_desc">Installera Mapillary för att lägga till en eller flera bilder till denna plats på kartan.</string>
<string name="mapillary_action_descr">Bidra med din egen gatnivåvy på denna plats via Mapillary.</string>
<string name="mapillary_descr">Online gatunivåbilder för alla. Upptäck platser, samarbeta, fånga världen.</string>
<string name="plugin_mapillary_descr">Gatunivå bilder för alla. Upptäck platser, samarbeta, fånga världen.</string>
<string name="private_access_routing_req">Din destination är belägen i ett område med privat tillträde. Vill du att ge tillgång till privata vägar för denna resa?</string>
<string name="hillshade_menu_download_descr">För att se relief-höjdskuggning på kartan, behöver du för att ladda ner den höjdskuggskartan för denna region.</string>
<string name="hillshade_purchase_header">För att se höjdskuggningsrelief på kartan, behöver du köpa och installera insticksmodulen konturlinjer</string>
<string name="private_access_routing_req">Din destination är belägen i ett område med privat tillträde. Tillåt tillgång till privata vägar för denna resa?</string>
<string name="hillshade_menu_download_descr">För att se relief-höjdskuggning på kartan, ladda ner höjdskuggskartan för denna region.</string>
<string name="hillshade_purchase_header">För att se höjdskuggningsrelief på kartan, behöver du köpa och installera insticksmodulen \'Konturlinjer\'</string>
<string name="hide_from_zoom_level">Dölja från zoom-nivå</string>
<string name="srtm_menu_download_descr">Om du vill visa höjdkurvor på kartan, behöver du ladda ner konturlinjekarta över denna region.</string>
<string name="srtm_purchase_header">För att se höjdkurvor på kartan, behöver du köpa och installera insticksmodulen Konturlinjer</string>
<string name="srtm_menu_download_descr">Ladda ner \'konturlinjekarta\' över denna region.</string>
<string name="srtm_purchase_header">För att se höjdkurvor på kartan, behöver du köpa och installera insticksmodulen \'Konturlinjer\'</string>
<string name="show_from_zoom_level">Visa från zoom-nivå</string>
<string name="routing_attr_allow_private_name">Tillåt privat åtkomst</string>
<string name="routing_attr_allow_private_description">Tillåta åtkomst till privata områden.</string>
<string name="display_zoom_level">Visa zoom-nivå: %1$s</string>
<string name="animate_my_location_desc">Aktivera kartpanoreringsanimation av Min Position under navigering.</string>
<string name="animate_my_location_desc">Aktivera kartpanoreringsanimation av \'Min Position\' under navigering.</string>
<string name="shared_string_overview">Översikt</string>
<string name="quick_action_auto_zoom_desc">Knackning på åtgärdsknappen kommer att slå på/av automatisk zoomkarta enligt din hastighet.</string>
<string name="quick_action_auto_zoom_desc">Ett tryck på den här åtgärdsknappen kommer att slå på/av automatisk zoomkarta enligt din hastighet.</string>
<string name="quick_action_auto_zoom_on">Aktivera autozoom karta</string>
<string name="quick_action_auto_zoom_off">Inaktivera autozoom karta</string>
<string name="quick_action_add_first_intermediate">Lägg till första mellanliggande</string>