Skip to content

Commit dc2ec7f

Browse files
committed
Visualization refactoring, base for detail window
1 parent 87f04db commit dc2ec7f

File tree

11 files changed

+490
-288
lines changed

11 files changed

+490
-288
lines changed

app/src/main/java/com/honz/itsvisualizer/MapFragment.kt

+7-45
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.honz.itsvisualizer
22

33
import android.Manifest
4-
import android.animation.ObjectAnimator
54
import android.app.AlertDialog
65
import android.content.BroadcastReceiver
76
import android.content.Context
@@ -10,14 +9,11 @@ import android.content.IntentFilter
109
import android.content.pm.PackageManager
1110
import android.location.Location
1211
import android.os.Bundle
13-
import android.util.Log
1412
import androidx.fragment.app.Fragment
1513
import android.view.LayoutInflater
1614
import android.view.View
1715
import android.view.ViewGroup
1816
import androidx.appcompat.content.res.AppCompatResources
19-
import androidx.core.animation.doOnEnd
20-
import androidx.core.animation.doOnStart
2117
import androidx.core.app.ActivityCompat
2218
import androidx.lifecycle.DefaultLifecycleObserver
2319
import androidx.lifecycle.LifecycleOwner
@@ -73,10 +69,8 @@ class MapFragment : Fragment() {
7369
private lateinit var connectionToggleFab: FloatingActionButton
7470
private lateinit var cameraCenteringToggleFab: FloatingActionButton
7571

76-
// TEST
7772
private lateinit var notificationFAB: FloatingActionButton
7873
private lateinit var detailsCard: MaterialCardView
79-
private var doOffsetMap = false
8074

8175
private var isTripSessionStarted = false
8276
private var centerCamera = true
@@ -119,9 +113,8 @@ class MapFragment : Fragment() {
119113
}
120114

121115
private val onMapClickListener = OnMapClickListener {
122-
if(doOffsetMap) {
123-
doOffsetMap = false
124-
displayDetailsCard()
116+
if(VisualizerInstance.visualizer?.detailsCardOpened == true) {
117+
VisualizerInstance.visualizer?.removeCurrentFocused(true)
125118
true
126119
} else false
127120
}
@@ -171,22 +164,20 @@ class MapFragment : Fragment() {
171164
lastLocation?.let { updateCameraPosition(it) }
172165

173166
// Visualization
174-
VisualizerInstance.visualizer = Visualizer(mapView, view.context.applicationContext)
167+
detailsCard = view.findViewById(R.id.detailsCard)
168+
169+
VisualizerInstance.visualizer = Visualizer(view.context.applicationContext, mapView, detailsCard)
175170
lifecycleScope.launch {
176171
MessageStorage.drawAll()
177172
}
178173

179-
// TEST
180174
mapView.getMapboxMap().addOnMapClickListener(onMapClickListener)
181175

182176
notificationFAB = view.findViewById(R.id.notificationTestFAB)
183177
notificationFAB.setOnClickListener {
184-
doOffsetMap = !doOffsetMap
185-
displayDetailsCard()
178+
VisualizerInstance.visualizer?.removeCurrentFocused(true)
186179
}
187180

188-
detailsCard = view.findViewById(R.id.detailsCard)
189-
190181
return view
191182
}
192183

@@ -296,7 +287,7 @@ class MapFragment : Fragment() {
296287
var xOffset = 0.0f
297288
val yOffset = mapView.height * 0.5f
298289

299-
if(doOffsetMap) {
290+
if(VisualizerInstance.visualizer?.detailsCardOpened == true) {
300291
xOffset = mapView.width * 0.25f
301292
}
302293

@@ -328,35 +319,6 @@ class MapFragment : Fragment() {
328319
}
329320
}
330321

331-
private fun displayDetailsCard() {
332-
if(doOffsetMap) {
333-
Log.i("[ANIMATOR]", "Show Animation")
334-
val initialX = -detailsCard.width.toFloat()
335-
val finalX = 0f
336-
337-
val animator = ObjectAnimator.ofFloat(detailsCard, "translationX", initialX, finalX)
338-
animator.duration = 500
339-
340-
animator.doOnStart {
341-
detailsCard.visibility = View.VISIBLE
342-
}
343-
animator.start()
344-
}
345-
else {
346-
Log.i("[ANIMATOR]", "Hide Animation")
347-
val initialX = 0f
348-
val finalX = -detailsCard.width.toFloat()
349-
350-
val animator = ObjectAnimator.ofFloat(detailsCard, "translationX", initialX, finalX)
351-
animator.duration = 1000
352-
animator.doOnEnd {
353-
detailsCard.visibility = View.INVISIBLE
354-
355-
}
356-
animator.start()
357-
}
358-
}
359-
360322
/**
361323
* Toggles the current state of socket connection
362324
*/

app/src/main/java/utils/storage/MessageParser.kt

+6-6
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,17 @@ class MessageParser(private val context: Context) {
7272
"[ITS]",
7373
"Received [$protocol] from station ID: $stationID"
7474
)*/
75-
sendNotification(StatusColor.GREEN, "Received [$protocol] from station ID: $stationID")
75+
sendNotification("Received [$protocol] from station ID: $stationID")
7676
}
7777
}
7878
catch (e: Exception) {
7979
e.printStackTrace()
8080
}
8181
}
8282

83-
private fun sendNotification(icon: StatusColor, text: String) {
83+
private fun sendNotification(text: String) {
8484
val statusIntent = Intent("itsVisualizer.SET_STATUS")
85-
statusIntent.putExtra("statusImg", icon.value)
85+
statusIntent.putExtra("statusImg", StatusColor.GREEN)
8686
statusIntent.putExtra("statusStr", text)
8787
LocalBroadcastManager.getInstance(context).sendBroadcast(statusIntent)
8888
}
@@ -252,9 +252,9 @@ class MessageParser(private val context: Context) {
252252
.getJSONObject("its.PathPoint_element")
253253
.getJSONObject("its.pathPosition_element")
254254

255-
val deltaLat = pathData.getString("its.deltaLatitude").toDouble() / 10000000.0
256-
val deltaLon = pathData.getString("its.deltaLongitude").toDouble() / 10000000.0
257-
val deltaAlt = pathData.getString("its.deltaLongitude").toDouble() / 100.0
255+
val deltaLat = pathData.getString("its.deltaLatitude").toDouble()
256+
val deltaLon = pathData.getString("its.deltaLongitude").toDouble()
257+
val deltaAlt = pathData.getString("its.deltaLongitude").toDouble()
258258

259259
pathHistory.add(Position(deltaLat, deltaLon, deltaAlt))
260260
}

app/src/main/java/utils/storage/MessageStorage.kt

+17-15
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
package utils.storage
22

3-
import android.content.Context
4-
import android.os.Handler
5-
import android.os.Looper
63
import android.util.Log
74
import kotlinx.coroutines.sync.Mutex
85
import kotlinx.coroutines.sync.withLock
@@ -13,6 +10,7 @@ import utils.storage.data.Request
1310
import utils.storage.data.Spatem
1411
import utils.storage.data.Srem
1512
import utils.storage.data.Ssem
13+
import utils.visualization.VisualizerInstance
1614

1715
object MessageStorage {
1816
private val mutex = Mutex()
@@ -35,16 +33,15 @@ object MessageStorage {
3533
val index = denmList.indexOf(existingDenm)
3634

3735
if(data.termination) {
38-
// TODO: Possible problem with status notification
39-
denmList[index].remove()
36+
VisualizerInstance.visualizer?.removeDenm(denmList[index])
4037
denmList.removeAt(index)
4138
return
4239
}
4340
denmList[index].update(data)
4441
} else {
4542
denmList.add(data)
4643
data.calculatePathHistory()
47-
data.draw()
44+
VisualizerInstance.visualizer?.drawDenm(data)
4845
}
4946
}
5047
}
@@ -58,9 +55,11 @@ object MessageStorage {
5855

5956
if (existingCam != null) {
6057
existingCam.update(data)
58+
VisualizerInstance.visualizer?.drawCam(existingCam)
6159
} else {
60+
data.calculatePathOffset()
6261
camList.add(data)
63-
data.draw()
62+
VisualizerInstance.visualizer?.drawCam(data)
6463
}
6564
}
6665
}
@@ -86,7 +85,7 @@ object MessageStorage {
8685
if(matchingMapem != null) {
8786
matchingMapem.latestSpatem = intersection
8887
matchingMapem.modified = true
89-
matchingMapem.draw()
88+
VisualizerInstance.visualizer?.drawMapem(matchingMapem)
9089
}
9190
}
9291
}
@@ -100,12 +99,13 @@ object MessageStorage {
10099
val existingMapem = mapemList.find { it.intersectionID == data.intersectionID }
101100

102101
if (existingMapem != null) {
102+
// Not redrawing, because not expecting sudden change in intersection geometry
103103
val index = mapemList.indexOf(existingMapem)
104104
mapemList[index].modified = true
105105
} else {
106106
mapemList.add(data)
107107
data.prepareForDraw()
108-
data.draw()
108+
VisualizerInstance.visualizer?.drawMapem(data)
109109
}
110110
}
111111
}
@@ -228,7 +228,7 @@ object MessageStorage {
228228
if (denm.modified)
229229
denm.modified = false
230230
else {
231-
denm.remove()
231+
VisualizerInstance.visualizer?.removeDenm(denm)
232232
denmIterator.remove()
233233
}
234234
}
@@ -240,7 +240,7 @@ object MessageStorage {
240240
if (cam.modified)
241241
cam.modified = false
242242
else {
243-
cam.remove()
243+
VisualizerInstance.visualizer?.removeCam(cam)
244244
camIterator.remove()
245245
}
246246
}
@@ -262,7 +262,7 @@ object MessageStorage {
262262
if (mapem.modified)
263263
mapem.modified = false
264264
else {
265-
mapem.remove()
265+
VisualizerInstance.visualizer?.removeMapem(mapem)
266266
mapemIterator.remove()
267267
}
268268
}
@@ -291,9 +291,9 @@ object MessageStorage {
291291

292292
suspend fun drawAll() {
293293
mutex.withLock {
294-
denmList.forEach { it.draw() }
295-
camList.forEach { it.draw() }
296-
mapemList.forEach { it.draw() }
294+
denmList.forEach { VisualizerInstance.visualizer?.drawDenm(it) }
295+
camList.forEach { VisualizerInstance.visualizer?.drawCam(it) }
296+
mapemList.forEach { VisualizerInstance.visualizer?.drawMapem(it) }
297297
}
298298
}
299299

@@ -302,6 +302,8 @@ object MessageStorage {
302302
*/
303303
suspend fun clearStorage() {
304304
mutex.withLock {
305+
VisualizerInstance.visualizer?.removeAllMarkers()
306+
305307
denmList.clear()
306308
camList.clear()
307309
spatemList.clear()

app/src/main/java/utils/storage/data/Cam.kt

+11-29
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,7 @@ class Cam(
2929
var vehicleLights: VehicleLights?,
3030
var timeEpoch: Double, //last update
3131

32-
// POSSIBLE UNUSED
33-
var lastSremUpdate: Int = 0,
34-
var isSrcAttention: Boolean = false
32+
internal var calculatedPathHistory: MutableList<Position> = mutableListOf()
3533

3634
) : Message(
3735
messageID,
@@ -49,41 +47,25 @@ class Cam(
4947

5048
other.speed?.let { speed = it }
5149
other.heading?.let { heading = it }
52-
other.path.let { path = it }
50+
51+
if(other.path != path) {
52+
other.path.let { path = it }
53+
calculatePathOffset()
54+
}
55+
5356
other.vehicleLength?.let { vehicleLength = it }
5457
other.vehicleWidth?.let { vehicleWidth = it }
5558
other.vehicleRole?.let { vehicleRole = it }
5659
other.vehicleLights?.let { vehicleLights = it }
5760

5861
timeEpoch = other.timeEpoch
5962
modified = true
60-
61-
draw()
62-
}
63-
64-
override fun draw() {
65-
val visualizer = VisualizerInstance.visualizer ?: return
66-
val position = originPosition ?: return
67-
val drawable = when(stationType) {
68-
1 -> R.drawable.pedestrian_icon
69-
2 -> R.drawable.cyclist_icon
70-
3 -> R.drawable.moped_icon
71-
4 -> R.drawable.motorbike_icon
72-
5 -> R.drawable.car_icon
73-
6 -> R.drawable.bus_icon
74-
7 -> R.drawable.light_truck_icon
75-
8 -> R.drawable.heavy_truck_icon
76-
10 -> R.drawable.ambulance_icon // Special Vehicle?
77-
11 -> R.drawable.tram_icon
78-
15 -> R.drawable.roadside_unit_icon
79-
else -> R.drawable.unknown_icon
80-
}
81-
visualizer.drawPoint(stationID, position.lat, position.lon, drawable)
8263
}
8364

84-
override fun remove() {
85-
val visualizer = VisualizerInstance.visualizer ?: return
86-
visualizer.removePoint(stationID)
65+
fun calculatePathOffset() {
66+
val refPos = originPosition ?: return
67+
val pathOffset = path ?: return
68+
calculatedPathHistory = calculatePathHistory(refPos, pathOffset).toMutableList()
8769
}
8870

8971
fun getRoleString(): String {

0 commit comments

Comments
 (0)