Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#16632: Fixed selecting gpx track item in history #17774

Merged
merged 2 commits into from
Aug 1, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 118 additions & 43 deletions OsmAnd/src/net/osmand/plus/auto/HistoryScreen.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
package net.osmand.plus.auto

import android.os.AsyncTask
import android.text.SpannableString
import android.text.Spanned
import androidx.car.app.CarContext
import androidx.car.app.constraints.ConstraintManager
import androidx.car.app.model.*
import androidx.core.graphics.drawable.IconCompat
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import net.osmand.data.LatLon
import net.osmand.plus.R
import net.osmand.plus.helpers.SearchHistoryHelper
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry
import net.osmand.plus.search.QuickSearchHelper.SearchHistoryAPI
import net.osmand.plus.search.listitems.QuickSearchListItem
import net.osmand.plus.track.data.GPXInfo
import net.osmand.plus.track.helpers.GPXDatabase.GpxDataItem
import net.osmand.plus.track.helpers.GpxDbHelper
import net.osmand.search.core.ObjectType
import net.osmand.search.core.SearchPhrase
import net.osmand.search.core.SearchResult
Expand All @@ -19,47 +26,38 @@ import net.osmand.util.MapUtils
class HistoryScreen(
carContext: CarContext,
private val settingsAction: Action) : BaseOsmAndAndroidAutoScreen(carContext) {
private lateinit var updateItemsTask: HistoryScreen.UpdateHistoryItemsTask
private lateinit var searchItems: ArrayList<QuickSearchListItem>
val gpxDbHelper: GpxDbHelper = app.gpxDbHelper

init {
lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
updateItemsTask = UpdateHistoryItemsTask()
updateItemsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
}
})
}

private inner class UpdateHistoryItemsTask : AsyncTask<Unit, Unit, Unit>() {
override fun doInBackground(vararg params: Unit?) {
prepareHistoryItems()
}

override fun onPostExecute(result: Unit?) {
invalidate()
}
}


override fun onGetTemplate(): Template {
val listBuilder = ItemList.Builder()
val templateBuilder = ListTemplate.Builder()
val app = app
val historyHelper = SearchHistoryHelper.getInstance(app)
val results = historyHelper.getHistoryEntries(true)
val location = app.mapViewTrackingUtilities.defaultLocation
val resultsSize = results.size
val limitedResults = results.subList(0, resultsSize.coerceAtMost(contentLimit - 1))
for (result in limitedResults) {
val searchResult =
SearchHistoryAPI.createSearchResult(app, result, SearchPhrase.emptyPhrase())
val listItem = QuickSearchListItem(app, searchResult)
val pointDescription = result.name

val title = listItem.name
val icon = CarIcon.Builder(
IconCompat.createWithResource(app, pointDescription.itemIcon)).build()
val rowBuilder = Row.Builder()
.setTitle(title)
.setImage(icon)
.setOnClickListener { onClickHistoryItem(listItem) }
val dist = if (searchResult.location == null) {
0.0
} else {
rowBuilder.setMetadata(
Metadata.Builder().setPlace(
Place.Builder(
CarLocation.create(
result.lat,
result.lon)).build()).build())
MapUtils.getDistance(
result.lat, result.lon,
location.latitude, location.longitude)
}
val address = SpannableString(" ")
val distanceSpan = DistanceSpan.create(TripHelper.getDistance(app, dist))
address.setSpan(distanceSpan, 0, 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
rowBuilder.addText(address)
listBuilder.addItem(rowBuilder.build())
}
val isLoading = updateItemsTask.status != AsyncTask.Status.FINISHED
if (!isLoading) {
prepareList(templateBuilder)
}
val actionStripBuilder = ActionStrip.Builder()
actionStripBuilder.addAction(
Action.Builder()
Expand All @@ -69,23 +67,100 @@ class HistoryScreen(
carContext, R.drawable.ic_action_search_dark)).build())
.setOnClickListener { openSearch() }
.build())
return ListTemplate.Builder()
.setSingleList(listBuilder.build())
return templateBuilder
.setLoading(isLoading)
.setTitle(app.getString(R.string.shared_string_history))
.setHeaderAction(Action.BACK)
.setActionStrip(actionStripBuilder.build())
.build()
}

private fun prepareHistoryItems() {
val historyHelper = SearchHistoryHelper.getInstance(app)
val results = historyHelper.getHistoryEntries(true)
val resultsSize = results.size
searchItems = ArrayList()
var limitedResults = results.subList(0, resultsSize.coerceAtMost(contentLimit - 1))
for (result in limitedResults) {
val searchResult =
SearchHistoryAPI.createSearchResult(app, result, SearchPhrase.emptyPhrase())
val listItem = QuickSearchListItem(app, searchResult)
if (listItem.searchResult.objectType == ObjectType.GPX_TRACK && listItem.searchResult.location == null) {
var gpxInfo = listItem.searchResult.relatedObject as GPXInfo
var gpxFile = gpxInfo.gpxFile
if (gpxFile == null) {
gpxInfo.file?.let { file ->
val item = gpxDbHelper.getItem(file) {
updateSearchResult(
listItem.searchResult,
it)
}
if (item != null) {
updateSearchResult(listItem.searchResult, item)
}
}
} else {
val analysis = gpxFile.getAnalysis(0)
listItem.searchResult.location = analysis?.latLonStart
}
}
searchItems.add(listItem)
}
}

private fun updateSearchResult(searchResult: SearchResult, dataItem: GpxDataItem) {
searchResult.location = dataItem.analysis?.latLonStart
}

private fun prepareList(templateBuilder: ListTemplate.Builder) {
val listBuilder = ItemList.Builder()
val location = app.mapViewTrackingUtilities.defaultLocation
for (item in searchItems) {
if (item.searchResult?.`object` is HistoryEntry) {
val result = item.searchResult?.`object` as HistoryEntry
val pointDescription = result.name
val title = item.name
val icon = CarIcon.Builder(
IconCompat.createWithResource(app, pointDescription.itemIcon)).build()
val rowBuilder = Row.Builder()
.setTitle(title)
.setImage(icon)
.setOnClickListener { onClickHistoryItem(item) }
val dist = if (item.searchResult.location == null) {
0.0
} else {
var startLocation = item.searchResult.location
rowBuilder.setMetadata(
Metadata.Builder().setPlace(
Place.Builder(
CarLocation.create(
startLocation.latitude,
startLocation.longitude)).build()).build())
MapUtils.getDistance(
startLocation.latitude, startLocation.longitude,
location.latitude, location.longitude)
}
val address = SpannableString(" ")
val distanceSpan = DistanceSpan.create(TripHelper.getDistance(app, dist))
address.setSpan(distanceSpan, 0, 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
rowBuilder.addText(address)
listBuilder.addItem(rowBuilder.build())
}
}
templateBuilder.setSingleList(listBuilder.build())
}

override fun getConstraintLimitType(): Int {
return ConstraintManager.CONTENT_LIMIT_TYPE_PLACE_LIST
}

private fun onClickHistoryItem(historyItem: QuickSearchListItem) {
val result = SearchResult()
result.location = LatLon(
historyItem.searchResult.location.latitude,
historyItem.searchResult.location.longitude)
if (historyItem.searchResult.location != null) {
result.location = LatLon(
historyItem.searchResult.location.latitude,
historyItem.searchResult.location.longitude)
}
result.objectType = ObjectType.RECENT_OBJ
result.`object` = historyItem.searchResult.`object`
openRoutePreview(settingsAction, result)
Expand Down