Fix several bugs with distance

This commit is contained in:
Chumva 2019-02-01 19:11:06 +02:00
parent 4ae629580a
commit 52adc6945f
7 changed files with 123 additions and 126 deletions

View file

@ -199,31 +199,12 @@
<net.osmand.telegram.ui.views.TextViewEx
android:layout_width="wrap_content"
android:id="@+id/gps_points_in_buffer_txt"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/hint_text_size"
app:typeface="@string/font_roboto_regular"
android:text="@string/shared_string_collected" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/gps_points_sent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/hint_text_size"
app:typeface="@string/font_roboto_mono_bold" />
<net.osmand.telegram.ui.views.TextViewEx
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/hint_text_size"
android:text="@string/shared_string_sent"
android:text="@string/gps_points_in_buffer"
app:typeface="@string/font_roboto_regular" />
</LinearLayout>

View file

@ -1,4 +1,5 @@
<resources>
<string name="gps_points_in_buffer">sent (%1$d in buffer)</string>
<string name="points_size">%1$d points</string>
<string name="shared_string_date">Date</string>
<string name="shared_string_collected">Collected</string>

View file

@ -580,7 +580,6 @@ class TelegramSettings(private val app: TelegramApplication) {
obj.put(ShareChatInfo.LAST_SEND_TEXT_TIME_KEY, chatInfo.lastSendTextMessageTime)
obj.put(ShareChatInfo.PENDING_TEXT_MESSAGE_KEY, chatInfo.pendingTextMessage)
obj.put(ShareChatInfo.PENDING_MAP_MESSAGE_KEY, chatInfo.pendingMapMessage)
obj.put(ShareChatInfo.COLLECTED_MESSAGES_KEY, chatInfo.collectedMessages)
obj.put(ShareChatInfo.SENT_MESSAGES_KEY, chatInfo.sentMessages)
obj.put(ShareChatInfo.PENDING_TDLIB_KEY, chatInfo.pendingTdLib)
jArray.put(obj)
@ -611,7 +610,6 @@ class TelegramSettings(private val app: TelegramApplication) {
lastSendTextMessageTime = obj.optInt(ShareChatInfo.LAST_SEND_TEXT_TIME_KEY)
pendingTextMessage = obj.optBoolean(ShareChatInfo.PENDING_TEXT_MESSAGE_KEY)
pendingMapMessage = obj.optBoolean(ShareChatInfo.PENDING_MAP_MESSAGE_KEY)
collectedMessages = obj.optInt(ShareChatInfo.COLLECTED_MESSAGES_KEY)
sentMessages = obj.optInt(ShareChatInfo.SENT_MESSAGES_KEY)
pendingTdLib = obj.optInt(ShareChatInfo.PENDING_TDLIB_KEY)
}
@ -901,7 +899,6 @@ class TelegramSettings(private val app: TelegramApplication) {
var lastSuccessfulSendTimeMs = -1L
var lastSendTextMessageTime = -1
var lastSendMapMessageTime = -1
var collectedMessages = 0
var sentMessages = 0
var pendingTdLib = 0
var pendingTextMessage = false
@ -942,7 +939,6 @@ class TelegramSettings(private val app: TelegramApplication) {
internal const val LAST_SEND_TEXT_TIME_KEY = "lastSendTextMessageTime"
internal const val PENDING_TEXT_MESSAGE_KEY = "pendingTextMessage"
internal const val PENDING_MAP_MESSAGE_KEY = "pendingMapMessage"
internal const val COLLECTED_MESSAGES_KEY = "collectedMessages"
internal const val SENT_MESSAGES_KEY = "sentMessages"
internal const val PENDING_TDLIB_KEY = "sentMessages"
}

View file

@ -39,8 +39,8 @@ class LocationMessages(val app: TelegramApplication) {
return dbHelper.getIngoingMessages(currentUserId, start, end)
}
fun getIngoingUserLocations(currentUserId: Int, start: Long, end: Long): List<UserLocations> {
return dbHelper.getIngoingUserLocations(currentUserId, start, end)
fun getIngoingUserLocations(start: Long, end: Long): List<UserLocations> {
return dbHelper.getIngoingUserLocations(start, end)
}
fun getMessagesForUserInChat(userId: Int, chatId: Long, start: Long, end: Long): List<LocationMessage> {
@ -51,10 +51,6 @@ class LocationMessages(val app: TelegramApplication) {
return dbHelper.getMessagesForUser(userId, start, end)
}
fun getUserLocations(userId: Int, start: Long, end: Long): UserLocations? {
return dbHelper.getUserLocations(userId, start, end)
}
fun addBufferedMessage(message: BufferMessage) {
log.debug("addBufferedMessage $message")
val messages = mutableListOf(*this.bufferedMessages.toTypedArray())
@ -103,6 +99,10 @@ class LocationMessages(val app: TelegramApplication) {
dbHelper.removeBufferedMessage(message)
}
fun getBufferedMessagesCount(): Int {
return bufferedMessages.size
}
private fun readBufferedMessages() {
this.bufferedMessages = dbHelper.getBufferedMessages()
}
@ -153,33 +153,6 @@ class LocationMessages(val app: TelegramApplication) {
return res
}
internal fun getUserLocations(userId: Int, start: Long, end: Long): UserLocations? {
var userLocations: UserLocations? = null
readableDatabase?.rawQuery(
"$TIMELINE_TABLE_SELECT WHERE $COL_USER_ID = ? AND $COL_TIME BETWEEN $start AND $end ORDER BY $COL_CHAT_ID ASC, $COL_TYPE DESC, $COL_TIME ASC ",
arrayOf(userId.toString()))?.apply {
if (moveToFirst()) {
var type = -1
val userLocationsMap: MutableMap<Int, List<LocationMessage>> = mutableMapOf()
userLocations = UserLocations(userId, 0, userLocationsMap)
var userLocationsListByType: MutableList<LocationMessage>? = null
do {
val locationMessage = readLocationMessage(this@apply)
if (type != locationMessage.type) {
type = locationMessage.type
userLocationsListByType = mutableListOf()
userLocationsListByType.add(locationMessage)
userLocationsMap.set(type, userLocationsListByType)
} else {
userLocationsListByType?.add(locationMessage)
}
} while (moveToNext())
}
close()
}
return userLocations
}
internal fun getPreviousMessage(userId: Int, chatId: Long): LocationMessage? {
var res:LocationMessage? = null
readableDatabase?.rawQuery(
@ -208,39 +181,47 @@ class LocationMessages(val app: TelegramApplication) {
return res
}
internal fun getIngoingUserLocations(currentUserId: Int, start: Long, end: Long): List<UserLocations> {
internal fun getIngoingUserLocations(start: Long, end: Long): List<UserLocations> {
val res = arrayListOf<UserLocations>()
readableDatabase?.rawQuery(
"$TIMELINE_TABLE_SELECT WHERE $COL_USER_ID != ? AND $COL_TIME BETWEEN $start AND $end ORDER BY $COL_USER_ID, $COL_CHAT_ID, $COL_TYPE DESC, $COL_TIME ",
arrayOf(currentUserId.toString()))?.apply {
"$TIMELINE_TABLE_SELECT WHERE $COL_TIME BETWEEN $start AND $end ORDER BY $COL_USER_ID, $COL_CHAT_ID, $COL_TYPE DESC, $COL_TIME ", null
)?.apply {
if (moveToFirst()) {
var type = -1
var userId = -1
var chatId = -1L
var userLocations: UserLocations?
var userLocationsMap: MutableMap<Int, List<LocationMessage>>? = null
// TODO query bot name
var botName = ""
var userLocations: UserLocations? = null
var userLocationsMap: MutableMap<Int, MutableList<UserTrkSegment>>? = null
var userLocationsListByType: MutableList<LocationMessage>? = null
var segment: UserTrkSegment? = null
do {
val locationMessage = readLocationMessage(this@apply)
if (userId != locationMessage.userId || chatId != locationMessage.chatId) {
userId = locationMessage.userId
chatId = locationMessage.chatId
type = locationMessage.type
// TODO compare bot name as well
if(userLocations == null || userLocations.userId != userId ||
userLocations.chatId != chatId) {
userLocationsMap = mutableMapOf()
userLocationsListByType = mutableListOf()
userLocationsListByType.add(locationMessage)
userLocationsMap[type] = userLocationsListByType
userLocations = UserLocations(userId, chatId, userLocationsMap)
userLocations = UserLocations(userId, chatId, botName, userLocationsMap)
res.add(userLocations)
segment = null
}
if (type != locationMessage.type) {
type = locationMessage.type
userLocationsListByType = mutableListOf()
userLocationsListByType.add(locationMessage)
userLocationsMap?.set(type, userLocationsListByType)
} else {
userLocationsListByType?.add(locationMessage)
if(segment == null ||
segment.type != locationMessage.type || locationMessage.time - segment.maxTime > 30 * 1000 * 60) {
segment = UserTrkSegment(mutableListOf(), 0.0, locationMessage.type,
locationMessage.time, locationMessage.time)
if(userLocationsMap!![segment.type] == null) {
userLocationsMap[segment.type] = mutableListOf()
}
userLocationsMap[segment.type]!!.add(segment)
}
if(segment.points.size > 0) {
segment.distance += MapUtils.getDistance(locationMessage.lat,
locationMessage.lon, segment.points.last().lat, segment.points.last().lon)
}
segment.maxTime = locationMessage.time
segment.points.add(locationMessage)
} while (moveToNext())
}
close()
@ -438,8 +419,58 @@ class LocationMessages(val app: TelegramApplication) {
data class UserLocations(
var userId: Int,
var chatId: Long,
var locationsByType: Map<Int, List<LocationMessage>>
)
var botName: String,
var locationsByType: Map<Int, List<UserTrkSegment>>
){
fun getUniqueSegments(): List<UserTrkSegment> {
// TODO TYPE_BOT_MAP. TYPE_BOT_TEXT, TYPE_USER_BOTH, TYPE_BOT_BOTH - delete
val list = mutableListOf<UserTrkSegment>()
if(locationsByType.containsKey(TYPE_MY_LOCATION)) {
return locationsByType.get(TYPE_MY_LOCATION)?: list
}
list.addAll(locationsByType.get(TYPE_USER_TEXT)?: emptyList())
val mapList = locationsByType.get(TYPE_USER_MAP)?: emptyList();
mapList.forEach {
var ti = 0;
while(ti < list.size && list[ti].maxTime < it.minTime) {
ti++;
}
if(ti < list.size && list[ti].minTime > it.maxTime ) {
list.add(ti, it)
} else if(ti == list.size) {
list.add(it)
}
}
return list
}
}
data class UserTrkSegment(
val points: MutableList<LocationMessage>,
var distance: Double,
var type: Int,
var minTime: Long,
var maxTime: Long
) {
fun newer(other: UserTrkSegment): Boolean {
return other.maxTime < maxTime;
}
fun overlap(other: UserTrkSegment): Boolean {
if(other.maxTime < maxTime) {
return other.maxTime > minTime;
} else {
return other.minTime < maxTime;
}
}
}
data class LocationHistoryPoint(
val userId: Int,

View file

@ -238,7 +238,6 @@ class ShareLocationHelper(private val app: TelegramApplication) {
log.debug("prepareTextMessage $message")
if (shareInfo.currentTextMessageId == -1L) {
if (shareInfo.pendingTextMessage) {
shareInfo.collectedMessages++
app.locationMessages.addBufferedMessage(message)
} else {
if (isBot) {
@ -254,7 +253,6 @@ class ShareLocationHelper(private val app: TelegramApplication) {
if (shareInfo.pendingTdLib < 10) {
app.telegramHelper.editTextLocation(shareInfo, message)
} else {
shareInfo.collectedMessages++
app.locationMessages.addBufferedMessage(message)
}
}
@ -265,7 +263,6 @@ class ShareLocationHelper(private val app: TelegramApplication) {
log.debug("prepareMapMessage $message")
if (shareInfo.currentMapMessageId == -1L) {
if (shareInfo.pendingMapMessage) {
shareInfo.collectedMessages++
app.locationMessages.addBufferedMessage(message)
} else {
if (isBot) {
@ -281,7 +278,6 @@ class ShareLocationHelper(private val app: TelegramApplication) {
if (shareInfo.pendingTdLib < 10) {
app.telegramHelper.editMapLocation(shareInfo, message)
} else {
shareInfo.collectedMessages++
app.locationMessages.addBufferedMessage(message)
}
}
@ -291,7 +287,6 @@ class ShareLocationHelper(private val app: TelegramApplication) {
private fun prepareMapAndTextMessage(shareInfo: TelegramSettings.ShareChatInfo, message: BufferMessage, isBot:Boolean, sharingMode: String) {
log.debug("prepareMapAndTextMessage $message")
if (shareInfo.pendingMapMessage || shareInfo.pendingTextMessage || shareInfo.pendingTdLib >= 10) {
shareInfo.collectedMessages++
app.locationMessages.addBufferedMessage(message)
} else {
if (isBot) {

View file

@ -718,12 +718,12 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
}
holder.gpsPointsCollected?.apply {
if (shareInfo != null) {
text = "${shareInfo.pendingTdLib + shareInfo.collectedMessages}"
text = " ${shareInfo.sentMessages}"
}
}
holder.gpsPointsSent?.apply {
if (shareInfo != null) {
text = "${shareInfo.sentMessages}"
text = getString(R.string.gps_points_in_buffer,shareInfo.pendingTdLib + app.locationMessages.getBufferedMessagesCount())
}
}
}
@ -764,7 +764,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
val stopSharingFirstPart: TextView? = view.findViewById(R.id.ending_in_first_part)
val stopSharingSecondPart: TextView? = view.findViewById(R.id.ending_in_second_part)
val gpsPointsCollected: TextView? = view.findViewById(R.id.gps_points_collected)
val gpsPointsSent: TextView? = view.findViewById(R.id.gps_points_sent)
val gpsPointsSent: TextView? = view.findViewById(R.id.gps_points_in_buffer_txt)
}
}

View file

@ -158,20 +158,13 @@ class TimelineTabFragment : Fragment() {
private fun updateList() {
val res = mutableListOf<ListItem>()
val currentUserId = telegramHelper.getCurrentUser()?.id
if (currentUserId != null) {
val currentUserLocations = app.locationMessages.getUserLocations(currentUserId, start, end)
if (currentUserLocations != null) {
TelegramUiHelper.userLocationsToChatItem(telegramHelper, currentUserLocations)?.also { chatItem ->
res.add(chatItem)
}
}
val ingoingUserLocations = app.locationMessages.getIngoingUserLocations(currentUserId, start, end)
val ingoingUserLocations = app.locationMessages.getIngoingUserLocations(start, end)
ingoingUserLocations.forEach {
TelegramUiHelper.userLocationsToChatItem(telegramHelper, it)?.also { chatItem ->
res.add(chatItem)
}
}
}
adapter.items = sortAdapterItems(res)
}
@ -214,18 +207,19 @@ class TimelineTabFragment : Fragment() {
val userLocations = item.userLocations
if(userLocations!=null){
val pair = getDistanceAndCountedPoints(userLocations)
val distance = OsmandFormatter.getFormattedDistance(pair.first,app)
val trackData = getDistanceAndCountedPoints(userLocations)
val distance = OsmandFormatter.getFormattedDistance(trackData.dist,app)
val name = if ((!item.privateChat || item.chatWithBot) && item.userId != currentUserId) item.getVisibleName() else ""
holder.groupDescrContainer?.visibility = View.VISIBLE
holder.groupTitle?.text = "$distance (${getString(R.string.points_size, pair.second)}) $name"
}
holder.groupTitle?.text = "$distance (${getString(R.string.points_size, trackData.points)}) $name"
TelegramUiHelper.setupPhoto(app, holder.groupImage, item.groupPhotoPath, item.placeholderId, false)
holder.userRow?.setOnClickListener {
childFragmentManager.also {
UserGpxInfoFragment.showInstance(it, item.userId, item.chatId, start, end)
UserGpxInfoFragment.showInstance(it, item.userId, item.chatId, trackData.minTime, trackData.maxTime)
}
}
}
holder.imageButton?.visibility = View.GONE
holder.showOnMapRow?.visibility = View.GONE
holder.bottomDivider?.visibility = if (lastItem) View.GONE else View.VISIBLE
@ -233,27 +227,20 @@ class TimelineTabFragment : Fragment() {
}
}
private fun getDistanceAndCountedPoints(userLocations: LocationMessages.UserLocations): Pair<Float, Int> {
val textUserLoc = userLocations.locationsByType[LocationMessages.TYPE_USER_TEXT]
val textBotLoc = userLocations.locationsByType[LocationMessages.TYPE_BOT_TEXT]
var dist = 0.0
var countedPoints = 0
when {
textUserLoc != null -> textUserLoc.forEach {
dist += it.distanceFromPrev
countedPoints++
}
textBotLoc != null -> textBotLoc.forEach {
dist += it.distanceFromPrev
countedPoints++
}
else -> userLocations.locationsByType.values.firstOrNull()?.forEach {
dist += it.distanceFromPrev
countedPoints++
}
}
return Pair(dist.toFloat(), countedPoints)
private fun getDistanceAndCountedPoints(userLocations: LocationMessages.UserLocations): UITrackData {
var uiTrackData= UITrackData(0.0f, 0, 0, 0)
userLocations.getUniqueSegments().forEach {
if(uiTrackData.minTime == 0L) {
uiTrackData.minTime = it.minTime
}
uiTrackData.dist += it.distance.toFloat();
uiTrackData.points += it.points.size
uiTrackData.maxTime = it.maxTime
}
return uiTrackData
}
override fun getItemCount() = items.size
@ -276,6 +263,12 @@ class TimelineTabFragment : Fragment() {
}
}
data class UITrackData (
var dist: Float,
var points: Int,
var minTime: Long,
var maxTime: Long
)
companion object {
private const val ADAPTER_UPDATE_INTERVAL_MIL = 15 * 1000L // 15 sec
}