diff options
Diffstat (limited to 'androidApp/src/main/java/mx')
4 files changed, 87 insertions, 33 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 60c8a47..a8478fd 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 @@ -11,12 +11,15 @@ import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat import androidx.core.graphics.drawable.toBitmap import com.mousebird.maply.* +import com.soywiz.krypto.md5 import mil.nga.sf.Polygon import mil.nga.sf.util.SFException import mil.nga.sf.wkt.GeometryReader import java.io.File import mx.trackermap.TrackerMap.android.R import mx.trackermap.TrackerMap.client.models.Geofence +import mx.trackermap.TrackerMap.client.models.MapLayer +import mx.trackermap.TrackerMap.utils.MapCalculus import mx.trackermap.TrackerMap.utils.MarkerType typealias MarkerCallback = (Int?) -> Unit @@ -56,17 +59,14 @@ class MapFragment : GlobeMapFragment() { override fun controlHasStarted() { Log.d("MapFragment", "controlHasStarted") - val cacheDirName = "stamen_watercolor6" - val cacheDir = File(activity!!.cacheDir, cacheDirName) - cacheDir.mkdir() - if (tileInfo == null) { - tileInfo = RemoteTileInfoNew( - getString(R.string.maps_streets_tile_url), - 0, - 21 - ) - (tileInfo as RemoteTileInfoNew).cacheDir = cacheDir + // Load default map layer + val layer = resources.getStringArray(R.array.maps_streets_tile) + val tmpInfo = RemoteTileInfoNew(layer[0], layer[1].toInt(), layer[2].toInt()) + tileInfo = tileInfoSetCacheDir(layer[0], tmpInfo) + tileInfo?.let { + setZoomLimits(it.minZoom, it.maxZoom) + } } val params = SamplingParams() @@ -83,7 +83,16 @@ class MapFragment : GlobeMapFragment() { val latitude = 23.191 val longitude = -100.36 - focusOn(latitude, longitude, zoom = 0.4, animated = false) + focusOn(latitude, longitude, height = 0.4, animated = false) + } + + override fun mapDidStopMoving( + mapControl: MapController?, + corners: Array<out Point3d>?, + userMotion: Boolean + ) { + super.mapDidStopMoving(mapControl, corners, userMotion) + Log.d("MapFragment", "Height: ${mapControl?.height}") } override fun userDidSelect( @@ -93,7 +102,6 @@ class MapFragment : GlobeMapFragment() { screenLoc: Point2d? ) { super.userDidSelect(mapControl, selObjs, loc, screenLoc) - selObjs?.forEach { selectedObject -> if (selectedObject.selObj is ScreenMarker) { val screenMarker = selectedObject.selObj as ScreenMarker @@ -228,7 +236,8 @@ class MapFragment : GlobeMapFragment() { mbr.expandByFraction(0.1) mapControl.addPostSurfaceRunnable { - val zoom = mapControl.findHeightToViewBounds(mbr, mbr.middle()) + val zoom = mapControl.zoomLimitMax.coerceAtLeast( + mapControl.findHeightToViewBounds(mbr, mbr.middle())) mapControl.setPositionGeo(mbr.middle(), zoom) } } @@ -308,19 +317,57 @@ class MapFragment : GlobeMapFragment() { )) } - fun focusOn(latitude: Double, longitude: Double, zoom: Double = 0.0000144, animated: Boolean = true) { + fun focusOn( + latitude: Double, + longitude: Double, + height: Double? = 0.00001, + animated: Boolean = true + ) { val lat = latitude * Math.PI / 180 val lon = longitude * Math.PI / 180 + // Ensure height is equal or higher than bottom limit + val z = mapControl.zoomLimitMin.coerceAtLeast(height ?: 0.0) if (animated) { - mapControl.animatePositionGeo(lon, lat, zoom, 0.2) + mapControl.animatePositionGeo(lon, lat, z, 0.2) } else { - mapControl.setPositionGeo(lon, lat, zoom) + mapControl.setPositionGeo(lon, lat, z) } } - fun updateTileInfo(tileInfo: TileInfoNew) { - this.tileInfo = tileInfo - loader?.changeTileInfo(tileInfo) + private fun tileInfoSetCacheDir(url: String, tileInfo: TileInfoNew): TileInfoNew? { + return context?.let { + val cacheDirName = url.toByteArray(Charsets.UTF_8).md5().hex + val cacheDirMap = File(it.cacheDir, cacheDirName) + cacheDirMap.mkdir() + Log.d("MapFragment", "Cache dir for $url = ${cacheDirMap.absolutePath}") + + (tileInfo as? RemoteTileInfoNew)?.cacheDir = cacheDirMap + tileInfo + } + } + + fun updateTile(layer: MapLayer) { + val tileInfo = RemoteTileInfoNew(layer.url, layer.minZoom, layer.maxZoom) + this.tileInfo = tileInfoSetCacheDir(layer.url, tileInfo) + this.tileInfo?.let { + loader?.changeTileInfo(it) + setZoomLimits(tileInfo.minZoom, tileInfo.maxZoom) + } + } + + private fun setZoomLimits(minZoom: Int, maxZoom: Int) { + mapControl?.let { + it.setZoomLimits( + it.heightForMapScale( + MapCalculus.zoomLevelToScale(maxZoom) + ?: MapCalculus.zoomLevelToScale(21)!! + ), + it.heightForMapScale( + MapCalculus.zoomLevelToScale(minZoom) + ?: MapCalculus.zoomLevelToScale(1)!! + ) + ) + } } private fun getIcon(markerType: MarkerType): Bitmap { 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 index 09f41a8..6f6596f 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/UnitMapFragment.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/UnitMapFragment.kt @@ -6,6 +6,7 @@ import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.text.HtmlCompat import kotlinx.coroutines.DelicateCoroutinesApi import mx.trackermap.TrackerMap.android.R import mx.trackermap.TrackerMap.android.databinding.UnitMapFragmentBinding @@ -53,6 +54,9 @@ class UnitMapFragment(private val unitsViewModel: UnitsViewModel) : UnitFragment private fun initializeMap() { unitsMapFragment = childFragmentManager.findFragmentById(R.id.unitsMap) as MapFragment unitsMapFragment.markerCallback = unitsViewModel::selectUnitWith + + val layer = resources.getStringArray(R.array.maps_streets_tile) + binding.attributionText.text = HtmlCompat.fromHtml(layer[3], 0) } private fun setupObservers() { @@ -94,9 +98,10 @@ class UnitMapFragment(private val unitsViewModel: UnitsViewModel) : UnitFragment } } - unitsViewModel.mapTileInfo.observe(viewLifecycleOwner) { tileInfo -> + unitsViewModel.mapLayer.observe(viewLifecycleOwner) { layer -> Log.d("UnitMapFragment", "Loading layer!") - unitsMapFragment.updateTileInfo(tileInfo) + unitsMapFragment.updateTile(layer) + binding.attributionText.text = HtmlCompat.fromHtml(layer.attribution, 0) } unitsViewModel.geofences.observe(viewLifecycleOwner) { geofences -> @@ -108,7 +113,7 @@ class UnitMapFragment(private val unitsViewModel: UnitsViewModel) : UnitFragment Log.d("UnitMapFragment", "removeObservers()") unitsViewModel.units.removeObservers(viewLifecycleOwner) unitsViewModel.selectedUnit.removeObservers(viewLifecycleOwner) - unitsViewModel.mapTileInfo.removeObservers(viewLifecycleOwner) + unitsViewModel.mapLayer.removeObservers(viewLifecycleOwner) unitsViewModel.geofences.removeObservers(viewLifecycleOwner) } 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 bf5f1d8..1bbcb80 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 @@ -17,6 +17,7 @@ import mx.trackermap.TrackerMap.android.databinding.UnitsActivityBinding import mx.trackermap.TrackerMap.android.devices.DevicesFragment import mx.trackermap.TrackerMap.android.map.UnitMapFragment import mx.trackermap.TrackerMap.android.session.UserInformationActivity +import mx.trackermap.TrackerMap.client.models.MapLayer import org.koin.androidx.viewmodel.ext.android.viewModel @DelicateCoroutinesApi @@ -90,13 +91,16 @@ class UnitsActivity : AppCompatActivity() { val popOver = PopupMenu(this, view) popOver.menuInflater.inflate(R.menu.map_layers, popOver.menu) popOver.setOnMenuItemClickListener { item -> - unitsViewModel.setMapLayer( + val layer = resources.getStringArray( when (item.itemId) { - R.id.layerStreets -> getString(R.string.maps_streets_tile_url) - R.id.layerSatellite -> getString(R.string.maps_satellite_url) - else -> getString(R.string.maps_streets_tile_url) + R.id.layerStreets -> R.array.maps_streets_tile + R.id.layerSatellite -> R.array.maps_satellite_tile + else -> R.array.maps_streets_tile } ) + unitsViewModel.setMapLayer(MapLayer( + layer[0], layer[1].toInt(), layer[2].toInt(), layer[3] + )) true } popOver.show() diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsViewModel.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsViewModel.kt index 08d35a2..d3060f0 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsViewModel.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsViewModel.kt @@ -2,12 +2,11 @@ package mx.trackermap.TrackerMap.android.units import android.util.Log import androidx.lifecycle.* -import com.mousebird.maply.RemoteTileInfoNew -import com.mousebird.maply.TileInfoNew import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import mx.trackermap.TrackerMap.client.models.Geofence +import mx.trackermap.TrackerMap.client.models.MapLayer import mx.trackermap.TrackerMap.client.models.UnitInformation import mx.trackermap.TrackerMap.controllers.GeofencesController import mx.trackermap.TrackerMap.controllers.UnitsController @@ -30,14 +29,14 @@ class UnitsViewModel( private var _unitsDisplayMode = MutableLiveData(UnitsDisplayMode.MAP) private var _units = MutableLiveData<List<UnitInformation>>() private var _selectedUnit = MutableLiveData<UnitInformation?>() - private var _mapTileInfo = MutableLiveData<TileInfoNew>() + private var _mapLayer = MutableLiveData<MapLayer>() private var _geofences = MutableLiveData<Map<Int, Geofence>>() val searchQuery: LiveData<String> get() = _searchQuery val unitsDisplayMode: LiveData<UnitsDisplayMode> get() = _unitsDisplayMode val units: LiveData<List<UnitInformation>> get() = _units val selectedUnit: LiveData<UnitInformation?> get() = _selectedUnit - val mapTileInfo: LiveData<TileInfoNew> get() = _mapTileInfo + val mapLayer: LiveData<MapLayer> get() = _mapLayer val geofences: LiveData<Map<Int, Geofence>> get() = _geofences init { @@ -86,9 +85,8 @@ class UnitsViewModel( _unitsDisplayMode.postValue(displayMode) } - fun setMapLayer(url: String, minZoom: Int = 0, maxZoom: Int = 21) { - val tileInfo = RemoteTileInfoNew(url, minZoom, maxZoom) - _mapTileInfo.postValue(tileInfo) + fun setMapLayer(layer: MapLayer) { + _mapLayer.postValue(layer) } fun toggleDisplayMode() { |