aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MapFragment.kt168
-rw-r--r--androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/UnitMapFragment.kt103
-rw-r--r--androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt3
-rw-r--r--androidApp/src/main/res/layout/map_fragment.xml17
-rw-r--r--androidApp/src/main/res/layout/unit_map_fragment.xml46
5 files changed, 241 insertions, 96 deletions
diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MapFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MapFragment.kt
index 8dbd26c..bd17013 100644
--- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MapFragment.kt
+++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MapFragment.kt
@@ -1,22 +1,41 @@
package mx.trackermap.TrackerMap.android.map
+import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import com.mousebird.maply.*
+import com.mousebird.maply.ComponentObject
+import com.mousebird.maply.GlobeMapFragment
+import com.mousebird.maply.MarkerInfo
+import com.mousebird.maply.Point2d
+import com.mousebird.maply.QuadImageLoader
+import com.mousebird.maply.RemoteTileInfoNew
+import com.mousebird.maply.RenderController
+import com.mousebird.maply.RenderControllerInterface
+import com.mousebird.maply.SamplingParams
+import com.mousebird.maply.ScreenMarker
+import com.mousebird.maply.SphericalMercatorCoordSystem
+import java.io.File
import kotlinx.coroutines.DelicateCoroutinesApi
import mx.trackermap.TrackerMap.android.R
-import mx.trackermap.TrackerMap.android.units.UnitsViewModel
-import org.koin.androidx.viewmodel.ext.android.viewModel
-import java.io.File
@DelicateCoroutinesApi
-class MapFragment: GlobeMapFragment() {
+class MapFragment : GlobeMapFragment() {
+
+ enum class MarkerType {
+ ANIMAL, BICYCLE, BOAT, BUS, CAR, CRANE, DEFAULT, HELICOPTER, MOTORCYCLE, OFFROAD, PERSON,
+ PICKUP, PLANE, SCOOTER, SHIP, TRACTOR, TRAIN, TRAM, TROLLEYBUS, TRUCK, VAN
+ }
- private val unitsViewModel: UnitsViewModel by viewModel()
+ data class Marker(
+ val id: Int,
+ val latitude: Double,
+ val longitude: Double,
+ val type: MarkerType = MarkerType.DEFAULT
+ )
private val markers = mutableListOf<Pair<ScreenMarker, ComponentObject>>()
@@ -38,7 +57,11 @@ class MapFragment: GlobeMapFragment() {
val cacheDir = File(activity!!.cacheDir, cacheDirName)
cacheDir.mkdir()
- val tileInfo = RemoteTileInfoNew("https://mt0.google.com/vt/lyrs=m&hl=en&x={x}&y={y}&z={z}&s=Ga", 0, 21)
+ val tileInfo = RemoteTileInfoNew(
+ "https://mt0.google.com/vt/lyrs=m&hl=en&x={x}&y={y}&z={z}&s=Ga",
+ 0,
+ 21
+ )
tileInfo.cacheDir = cacheDir
val params = SamplingParams()
@@ -58,80 +81,69 @@ class MapFragment: GlobeMapFragment() {
mapControl.setPositionGeo(longitude, latitude, zoom)
}
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
-
- setupObservers()
+ fun clear() {
+ mapControl.removeObjects(
+ markers.map { it.second },
+ RenderControllerInterface.ThreadMode.ThreadAny
+ )
}
- @DelicateCoroutinesApi
- private fun setupObservers() {
- Log.d("MapFragment", "setupObservers()")
- unitsViewModel.units.observe(viewLifecycleOwner) { units ->
- /* Remove all markers */
- markers.forEach {
- mapControl.removeObject(it.second, ThreadMode.ThreadAny)
- }
- markers.clear()
-
- /* Reinsert markers from units */
- units.forEach { unit ->
- unit.position?.let { position ->
- if (position.longitude != null && position.longitude != null) {
- val icon =
- BitmapFactory.decodeResource(
- activity!!.resources,
- when (unit.device.category?.lowercase()) {
- "animal" -> R.drawable.map_animal
- "bicycle" -> R.drawable.map_bicycle
- "boat" -> R.drawable.map_boat
- "bus" -> R.drawable.map_bus
- "car" -> R.drawable.map_car
- "crane" -> R.drawable.map_crane
- "default" -> R.drawable.map_default
- "helicopter" -> R.drawable.map_helicopter
- "motorcycle" -> R.drawable.map_motorcycle
- "offroad" -> R.drawable.map_offroad
- "person" -> R.drawable.map_person
- "pickup" -> R.drawable.map_pickup
- "plane" -> R.drawable.map_plane
- "scooter" -> R.drawable.map_scooter
- "ship" -> R.drawable.map_ship
- "tractor" -> R.drawable.map_tractor
- "train" -> R.drawable.map_train
- "tram" -> R.drawable.map_tram
- "trolleybus" -> R.drawable.map_trolleybus
- "truck" -> R.drawable.map_truck
- "van" -> R.drawable.map_van
- else -> R.drawable.map_default
- }
- )
-
- val marker = ScreenMarker()
- val markerSize = Point2d(144.0, 144.0)
-
- marker.loc = Point2d.FromDegrees(position.longitude!!, position.latitude!!)
- marker.image = icon
- marker.size = markerSize
- marker.userObject = unit
-
- /* Add marker to map */
- val markerInfo = MarkerInfo()
- val componentObject = mapControl.addScreenMarker(marker, markerInfo, ThreadMode.ThreadAny)
- markers.add(marker to componentObject)
- }
- }
- }
+ fun display(markers: Array<Marker>) {
+ Log.d("MapFragment", "Displaying markers")
+
+ clear()
+
+ val screenMarkers = markers.map { marker ->
+ val screenMarker = ScreenMarker()
+ val markerSize = Point2d(144.0, 144.0)
+
+ screenMarker.loc = Point2d.FromDegrees(marker.longitude, marker.latitude)
+ screenMarker.image = getIcon(marker.type)
+ screenMarker.size = markerSize
+ screenMarker.userObject = marker.id
+
+ screenMarker
}
- unitsViewModel.selectedUnit.observe(viewLifecycleOwner) {
- it?.let { unit ->
- unit.position?.let { position ->
- val latitude = position.latitude!! * Math.PI / 180
- val longitude = position.longitude!! * Math.PI / 180
- val zoom = 0.000008
- mapControl.setPositionGeo(longitude, latitude, zoom)
- }
+ mapControl.addScreenMarkers(
+ screenMarkers,
+ MarkerInfo(),
+ RenderControllerInterface.ThreadMode.ThreadAny
+ )
+ }
+
+ fun focusOn(latitude: Double, longitude: Double) {
+ val lat = latitude * Math.PI / 180
+ val lon = longitude * Math.PI / 180
+ val zoom = 0.000008
+ mapControl.setPositionGeo(lon, lat, zoom)
+ }
+
+ private fun getIcon(markerType: MarkerType): Bitmap {
+ return BitmapFactory.decodeResource(
+ activity!!.resources,
+ when (markerType) {
+ MarkerType.ANIMAL -> R.drawable.map_animal
+ MarkerType.BICYCLE -> R.drawable.map_bicycle
+ MarkerType.BOAT -> R.drawable.map_boat
+ MarkerType.BUS -> R.drawable.map_bus
+ MarkerType.CAR -> R.drawable.map_car
+ MarkerType.CRANE -> R.drawable.map_crane
+ MarkerType.DEFAULT -> R.drawable.map_default
+ MarkerType.HELICOPTER -> R.drawable.map_helicopter
+ MarkerType.MOTORCYCLE -> R.drawable.map_motorcycle
+ MarkerType.OFFROAD -> R.drawable.map_offroad
+ MarkerType.PERSON -> R.drawable.map_person
+ MarkerType.PICKUP -> R.drawable.map_pickup
+ MarkerType.PLANE -> R.drawable.map_plane
+ MarkerType.SCOOTER -> R.drawable.map_scooter
+ MarkerType.SHIP -> R.drawable.map_ship
+ MarkerType.TRACTOR -> R.drawable.map_tractor
+ MarkerType.TRAIN -> R.drawable.map_train
+ MarkerType.TRAM -> R.drawable.map_tram
+ MarkerType.TROLLEYBUS -> R.drawable.map_trolleybus
+ MarkerType.TRUCK -> R.drawable.map_truck
+ MarkerType.VAN -> R.drawable.map_van
}
- }
+ )
}
} \ No newline at end of file
diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/UnitMapFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/UnitMapFragment.kt
new file mode 100644
index 0000000..7212a23
--- /dev/null
+++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/UnitMapFragment.kt
@@ -0,0 +1,103 @@
+package mx.trackermap.TrackerMap.android.map
+
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import kotlinx.coroutines.DelicateCoroutinesApi
+import mx.trackermap.TrackerMap.android.R
+import mx.trackermap.TrackerMap.android.databinding.UnitMapFragmentBinding
+import mx.trackermap.TrackerMap.android.units.UnitsViewModel
+import mx.trackermap.TrackerMap.client.models.UnitInformation
+import org.koin.androidx.viewmodel.ext.android.viewModel
+
+@DelicateCoroutinesApi
+class UnitMapFragment : Fragment() {
+
+ private val unitsViewModel: UnitsViewModel by viewModel()
+
+ private var _binding: UnitMapFragmentBinding? = null
+ private val binding get() = _binding!!
+ private lateinit var unitsMapFragment: MapFragment
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ _binding = UnitMapFragmentBinding.inflate(inflater)
+ return binding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ initializeMap()
+ setupObservers()
+ }
+
+ private fun initializeMap() {
+ unitsMapFragment = childFragmentManager.findFragmentById(R.id.unitsMap) as MapFragment
+ }
+
+ private fun setupObservers() {
+ Log.d("MapFragment", "setupObservers()")
+
+ unitsViewModel.units.observe(viewLifecycleOwner) { units ->
+ Log.d("UnitMapFragment", "Available units: $units")
+
+ unitsMapFragment.display(units.mapNotNull(this::unitToMarker).toTypedArray())
+ }
+
+ unitsViewModel.selectedUnit.observe(viewLifecycleOwner) { selectedUnit ->
+ Log.d("UnitMapFragment", "Selected Unit: $selectedUnit")
+
+ binding.mapUnitCard.visibility = if (selectedUnit == null) View.GONE else View.VISIBLE
+ selectedUnit?.position?.let { position ->
+ if (position.latitude == null || position.longitude == null) {
+ return@let
+ }
+
+ unitsMapFragment.focusOn(position.latitude!!, position.longitude!!)
+ }
+ }
+ }
+
+ private fun unitToMarker(unit: UnitInformation): MapFragment.Marker? {
+ if (unit.position == null || unit.position!!.latitude == null || unit.position!!.longitude == null) {
+ return null
+ }
+
+ return MapFragment.Marker(
+ unit.position!!.id!!,
+ unit.position!!.latitude!!,
+ unit.position!!.longitude!!,
+ when (unit.device.category?.lowercase()) {
+ "animal" -> MapFragment.MarkerType.ANIMAL
+ "bicycle" -> MapFragment.MarkerType.BICYCLE
+ "boat" -> MapFragment.MarkerType.BOAT
+ "bus" -> MapFragment.MarkerType.BUS
+ "car" -> MapFragment.MarkerType.CAR
+ "crane" -> MapFragment.MarkerType.CRANE
+ "helicopter" -> MapFragment.MarkerType.HELICOPTER
+ "motorcycle" -> MapFragment.MarkerType.MOTORCYCLE
+ "offroad" -> MapFragment.MarkerType.OFFROAD
+ "person" -> MapFragment.MarkerType.PERSON
+ "pickup" -> MapFragment.MarkerType.PICKUP
+ "plane" -> MapFragment.MarkerType.PLANE
+ "scooter" -> MapFragment.MarkerType.SCOOTER
+ "ship" -> MapFragment.MarkerType.SHIP
+ "tractor" -> MapFragment.MarkerType.TRACTOR
+ "train" -> MapFragment.MarkerType.TRAIN
+ "tram" -> MapFragment.MarkerType.TRAM
+ "trolleybus" -> MapFragment.MarkerType.TROLLEYBUS
+ "truck" -> MapFragment.MarkerType.TRUCK
+ "van" -> MapFragment.MarkerType.VAN
+ else -> MapFragment.MarkerType.DEFAULT
+ }
+ )
+ }
+
+} \ No newline at end of file
diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt
index 8a6f699..796c29f 100644
--- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt
+++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt
@@ -10,6 +10,7 @@ import mx.trackermap.TrackerMap.android.R
import mx.trackermap.TrackerMap.android.databinding.UnitsActivityBinding
import mx.trackermap.TrackerMap.android.devices.DevicesFragment
import mx.trackermap.TrackerMap.android.map.MapFragment
+import mx.trackermap.TrackerMap.android.map.UnitMapFragment
import org.koin.androidx.viewmodel.ext.android.viewModel
@DelicateCoroutinesApi
@@ -69,7 +70,7 @@ class UnitsActivity : AppCompatActivity() {
val newFragment =
when (displayMode) {
UnitsViewModel.UnitsDisplayMode.LIST -> DevicesFragment()
- UnitsViewModel.UnitsDisplayMode.MAP -> MapFragment()
+ UnitsViewModel.UnitsDisplayMode.MAP -> UnitMapFragment()
else -> DevicesFragment()
}
supportFragmentManager.commit {
diff --git a/androidApp/src/main/res/layout/map_fragment.xml b/androidApp/src/main/res/layout/map_fragment.xml
deleted file mode 100644
index 8d36fc1..0000000
--- a/androidApp/src/main/res/layout/map_fragment.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- xmlns:app="http://schemas.android.com/apk/res-auto">
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="MAP"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"/>
-
-</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/androidApp/src/main/res/layout/unit_map_fragment.xml b/androidApp/src/main/res/layout/unit_map_fragment.xml
new file mode 100644
index 0000000..914558a
--- /dev/null
+++ b/androidApp/src/main/res/layout/unit_map_fragment.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+
+ <fragment
+ android:id="@+id/unitsMap"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ android:name="mx.trackermap.TrackerMap.android.map.MapFragment"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/mapUnitCard"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:cardUseCompatPadding="true"
+ app:cardElevation="@dimen/card_elevation"
+ app:cardCornerRadius="@dimen/card_border_radius"
+ app:contentPadding="@dimen/card_padding"
+ android:visibility="gone">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="SELECTED UNIT"
+ android:gravity="center"/>
+
+ </LinearLayout>
+
+ </androidx.cardview.widget.CardView>
+
+</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file