sforkowany z mirror/meshtastic-android
				
			Working on cache downloader
							rodzic
							
								
									4d81689f21
								
							
						
					
					
						commit
						9b1dfb0d02
					
				| 
						 | 
					@ -140,9 +140,11 @@ dependencies {
 | 
				
			||||||
    kapt "androidx.room:room-compiler:$room_version"
 | 
					    kapt "androidx.room:room-compiler:$room_version"
 | 
				
			||||||
    kapt "com.google.dagger:hilt-compiler:$hilt_version"
 | 
					    kapt "com.google.dagger:hilt-compiler:$hilt_version"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //OSMAND
 | 
					    //OSMDROID, mgrs,
 | 
				
			||||||
    implementation 'org.osmdroid:osmdroid-android:6.1.14'
 | 
					    implementation 'org.osmdroid:osmdroid-android:6.1.14'
 | 
				
			||||||
 | 
					    implementation 'com.github.MKergall:osmbonuspack:6.9.0'
 | 
				
			||||||
    implementation 'mil.nga:mgrs:2.0.0'
 | 
					    implementation 'mil.nga:mgrs:2.0.0'
 | 
				
			||||||
 | 
					    implementation 'org.osmdroid:osmdroid-geopackage:6.1.14'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // optional - Kotlin Extensions and Coroutines support for Room
 | 
					    // optional - Kotlin Extensions and Coroutines support for Room
 | 
				
			||||||
    implementation "androidx.room:room-ktx:$room_version"
 | 
					    implementation "androidx.room:room-ktx:$room_version"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,6 +37,9 @@ import kotlinx.coroutines.flow.flatMapLatest
 | 
				
			||||||
import kotlinx.coroutines.flow.mapLatest
 | 
					import kotlinx.coroutines.flow.mapLatest
 | 
				
			||||||
import kotlinx.coroutines.launch
 | 
					import kotlinx.coroutines.launch
 | 
				
			||||||
import kotlinx.coroutines.withContext
 | 
					import kotlinx.coroutines.withContext
 | 
				
			||||||
 | 
					import org.osmdroid.bonuspack.kml.KmlDocument
 | 
				
			||||||
 | 
					import org.osmdroid.views.MapView
 | 
				
			||||||
 | 
					import org.osmdroid.views.overlay.FolderOverlay
 | 
				
			||||||
import java.io.BufferedWriter
 | 
					import java.io.BufferedWriter
 | 
				
			||||||
import java.io.FileNotFoundException
 | 
					import java.io.FileNotFoundException
 | 
				
			||||||
import java.io.FileWriter
 | 
					import java.io.FileWriter
 | 
				
			||||||
| 
						 | 
					@ -480,6 +483,31 @@ class UIViewModel @Inject constructor(
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun parseUrl(url: String, map: MapView) {
 | 
				
			||||||
 | 
					        viewModelScope.launch(Dispatchers.IO) {
 | 
				
			||||||
 | 
					            parseIt(url, map)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // For Future Use
 | 
				
			||||||
 | 
					    //  model.parseUrl(
 | 
				
			||||||
 | 
					    //                "https://www.google.com/maps/d/kml?forcekml=1&mid=1FmqWhZG3PG3dY92x9yf2RlREcK7kMZs&lid=-ivSjBCePsM",
 | 
				
			||||||
 | 
					    //                map
 | 
				
			||||||
 | 
					    //            )
 | 
				
			||||||
 | 
					    private fun parseIt(url: String, map: MapView) {
 | 
				
			||||||
 | 
					        val kmlDoc = KmlDocument()
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            kmlDoc.parseKMLUrl(url)
 | 
				
			||||||
 | 
					            val kmlOverlay = kmlDoc.mKmlRoot.buildOverlay(map, null, null, kmlDoc) as FolderOverlay
 | 
				
			||||||
 | 
					            kmlDoc.mKmlRoot.mItems
 | 
				
			||||||
 | 
					            kmlDoc.mKmlRoot.mName
 | 
				
			||||||
 | 
					            map.overlayManager.overlays().add(kmlOverlay)
 | 
				
			||||||
 | 
					        } catch (ex: Exception) {
 | 
				
			||||||
 | 
					            debug("Failed to download .kml $ex")
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun addQuickChatAction(name: String, value: String, mode: QuickChatAction.Mode) {
 | 
					    fun addQuickChatAction(name: String, value: String, mode: QuickChatAction.Mode) {
 | 
				
			||||||
        viewModelScope.launch(Dispatchers.Main) {
 | 
					        viewModelScope.launch(Dispatchers.Main) {
 | 
				
			||||||
            val action = QuickChatAction(0, name, value, mode, _quickChatActions.value.size)
 | 
					            val action = QuickChatAction(0, name, value, mode, _quickChatActions.value.size)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
package com.geeksville.mesh.ui
 | 
					package com.geeksville.mesh.ui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.app.AlertDialog
 | 
				
			||||||
import android.content.Context
 | 
					import android.content.Context
 | 
				
			||||||
import android.content.SharedPreferences
 | 
					import android.content.SharedPreferences
 | 
				
			||||||
import android.graphics.Canvas
 | 
					import android.graphics.Canvas
 | 
				
			||||||
| 
						 | 
					@ -7,33 +8,41 @@ import android.graphics.Color
 | 
				
			||||||
import android.graphics.Paint
 | 
					import android.graphics.Paint
 | 
				
			||||||
import android.graphics.Rect
 | 
					import android.graphics.Rect
 | 
				
			||||||
import android.os.Bundle
 | 
					import android.os.Bundle
 | 
				
			||||||
 | 
					import android.text.Editable
 | 
				
			||||||
 | 
					import android.text.TextWatcher
 | 
				
			||||||
import android.view.LayoutInflater
 | 
					import android.view.LayoutInflater
 | 
				
			||||||
import android.view.View
 | 
					import android.view.View
 | 
				
			||||||
import android.view.ViewGroup
 | 
					import android.view.ViewGroup
 | 
				
			||||||
 | 
					import android.widget.*
 | 
				
			||||||
 | 
					import android.widget.SeekBar.OnSeekBarChangeListener
 | 
				
			||||||
import androidx.core.content.ContextCompat
 | 
					import androidx.core.content.ContextCompat
 | 
				
			||||||
import androidx.fragment.app.activityViewModels
 | 
					import androidx.fragment.app.activityViewModels
 | 
				
			||||||
import com.geeksville.mesh.android.Logging
 | 
					 | 
				
			||||||
import com.geeksville.mesh.BuildConfig
 | 
					import com.geeksville.mesh.BuildConfig
 | 
				
			||||||
import com.geeksville.mesh.NodeInfo
 | 
					import com.geeksville.mesh.NodeInfo
 | 
				
			||||||
import com.geeksville.mesh.R
 | 
					import com.geeksville.mesh.R
 | 
				
			||||||
 | 
					import com.geeksville.mesh.android.Logging
 | 
				
			||||||
import com.geeksville.mesh.databinding.MapViewBinding
 | 
					import com.geeksville.mesh.databinding.MapViewBinding
 | 
				
			||||||
import com.geeksville.mesh.model.CustomTileSource
 | 
					import com.geeksville.mesh.model.CustomTileSource
 | 
				
			||||||
import com.geeksville.mesh.model.UIViewModel
 | 
					import com.geeksville.mesh.model.UIViewModel
 | 
				
			||||||
import com.geeksville.mesh.util.formatAgo
 | 
					import com.geeksville.mesh.util.formatAgo
 | 
				
			||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
 | 
					import com.google.android.material.dialog.MaterialAlertDialogBuilder
 | 
				
			||||||
 | 
					import com.google.android.material.floatingactionbutton.FloatingActionButton
 | 
				
			||||||
import dagger.hilt.android.AndroidEntryPoint
 | 
					import dagger.hilt.android.AndroidEntryPoint
 | 
				
			||||||
import org.osmdroid.api.IMapController
 | 
					import org.osmdroid.api.IMapController
 | 
				
			||||||
import org.osmdroid.config.Configuration
 | 
					import org.osmdroid.config.Configuration
 | 
				
			||||||
 | 
					import org.osmdroid.tileprovider.cachemanager.CacheManager
 | 
				
			||||||
import org.osmdroid.tileprovider.tilesource.ITileSource
 | 
					import org.osmdroid.tileprovider.tilesource.ITileSource
 | 
				
			||||||
import org.osmdroid.util.BoundingBox
 | 
					import org.osmdroid.util.BoundingBox
 | 
				
			||||||
import org.osmdroid.util.GeoPoint
 | 
					import org.osmdroid.util.GeoPoint
 | 
				
			||||||
import org.osmdroid.views.CustomZoomButtonsController
 | 
					import org.osmdroid.views.CustomZoomButtonsController
 | 
				
			||||||
import org.osmdroid.views.MapView
 | 
					import org.osmdroid.views.MapView
 | 
				
			||||||
import org.osmdroid.views.overlay.CopyrightOverlay
 | 
					import org.osmdroid.views.overlay.*
 | 
				
			||||||
import org.osmdroid.views.overlay.Marker
 | 
					import kotlin.math.pow
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@AndroidEntryPoint
 | 
					@AndroidEntryPoint
 | 
				
			||||||
class MapFragment : ScreenFragment("Map"), Logging {
 | 
					class MapFragment : ScreenFragment("Map"), Logging, View.OnClickListener, OnSeekBarChangeListener,
 | 
				
			||||||
 | 
					    TextWatcher {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private lateinit var binding: MapViewBinding
 | 
					    private lateinit var binding: MapViewBinding
 | 
				
			||||||
    private lateinit var map: MapView
 | 
					    private lateinit var map: MapView
 | 
				
			||||||
| 
						 | 
					@ -41,20 +50,38 @@ class MapFragment : ScreenFragment("Map"), Logging {
 | 
				
			||||||
    private lateinit var mPrefs: SharedPreferences
 | 
					    private lateinit var mPrefs: SharedPreferences
 | 
				
			||||||
    private val model: UIViewModel by activityViewModels()
 | 
					    private val model: UIViewModel by activityViewModels()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private lateinit var cacheManager: CacheManager
 | 
				
			||||||
 | 
					    private lateinit var btnCache: FloatingActionButton
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private lateinit var cacheNorth: EditText
 | 
				
			||||||
 | 
					    private lateinit var cacheSouth: EditText
 | 
				
			||||||
 | 
					    private lateinit var cacheEast: EditText
 | 
				
			||||||
 | 
					    private lateinit var cacheWest: EditText
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private lateinit var cacheEstimate: TextView
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private lateinit var zoomMin: SeekBar
 | 
				
			||||||
 | 
					    private lateinit var zoomMax: SeekBar
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private var downloadPrompt: AlertDialog? = null
 | 
				
			||||||
 | 
					    private var alertDialog: AlertDialog? = null
 | 
				
			||||||
 | 
					    private lateinit var executeJob: Button
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private val defaultMinZoom = 1.5
 | 
					    private val defaultMinZoom = 1.5
 | 
				
			||||||
    private val nodeZoomLevel = 8.5
 | 
					    private val nodeZoomLevel = 8.5
 | 
				
			||||||
    private val defaultZoomSpeed = 3000L
 | 
					    private val defaultZoomSpeed = 3000L
 | 
				
			||||||
    private val prefsName = "org.andnav.osm.prefs"
 | 
					    private val prefsName = "org.geeksville.osm.prefs"
 | 
				
			||||||
    private val mapStyleId = "map_style_id"
 | 
					    private val mapStyleId = "map_style_id"
 | 
				
			||||||
    private var nodePositions = listOf<MarkerWithLabel>()
 | 
					    private var nodePositions = listOf<MarkerWithLabel>()
 | 
				
			||||||
    private val nodeLayer = 1
 | 
					    private val nodeLayer = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun onCreateView(
 | 
					    override fun onCreateView(
 | 
				
			||||||
        inflater: LayoutInflater, container: ViewGroup?,
 | 
					        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
 | 
				
			||||||
        savedInstanceState: Bundle?
 | 
					 | 
				
			||||||
    ): View {
 | 
					    ): View {
 | 
				
			||||||
        binding = MapViewBinding.inflate(inflater)
 | 
					        binding = MapViewBinding.inflate(inflater)
 | 
				
			||||||
 | 
					        btnCache = binding.root.findViewById(R.id.downloadButton)
 | 
				
			||||||
        return binding.root
 | 
					        return binding.root
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -89,6 +116,191 @@ class MapFragment : ScreenFragment("Map"), Logging {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            zoomToNodes(mapController)
 | 
					            zoomToNodes(mapController)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        btnCache.setOnClickListener(this)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun onClick(v: View) {
 | 
				
			||||||
 | 
					        when (v.id) {
 | 
				
			||||||
 | 
					            R.id.executeJob -> updateEstimate(true)
 | 
				
			||||||
 | 
					            R.id.downloadButton -> showCacheManagerDialog()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun showCacheManagerDialog() {
 | 
				
			||||||
 | 
					        val alertDialogBuilder = AlertDialog.Builder(
 | 
				
			||||||
 | 
					            activity
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        // set title
 | 
				
			||||||
 | 
					        alertDialogBuilder.setTitle("Cache Manager")
 | 
				
			||||||
 | 
					        //.setMessage(R.string.cache_manager_description);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // set dialog message
 | 
				
			||||||
 | 
					        alertDialogBuilder.setItems(
 | 
				
			||||||
 | 
					            arrayOf<CharSequence>(
 | 
				
			||||||
 | 
					                "Cache current size",
 | 
				
			||||||
 | 
					                "Cache Download",
 | 
				
			||||||
 | 
					                resources.getString(R.string.cancel)
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        ) { dialog, which ->
 | 
				
			||||||
 | 
					            when (which) {
 | 
				
			||||||
 | 
					                0 -> showCurrentCacheInfo()
 | 
				
			||||||
 | 
					                1 -> {
 | 
				
			||||||
 | 
					                    downloadJobAlert()
 | 
				
			||||||
 | 
					                    dialog.dismiss()
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else -> dialog.dismiss()
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // create alert dialog
 | 
				
			||||||
 | 
					        alertDialog = alertDialogBuilder.create()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // show it
 | 
				
			||||||
 | 
					        alertDialog!!.show()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun showCurrentCacheInfo() {
 | 
				
			||||||
 | 
					        Toast.makeText(activity, "Calculating...", Toast.LENGTH_SHORT).show()
 | 
				
			||||||
 | 
					        Thread {
 | 
				
			||||||
 | 
					            val alertDialogBuilder = AlertDialog.Builder(
 | 
				
			||||||
 | 
					                activity
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // set title
 | 
				
			||||||
 | 
					            alertDialogBuilder.setTitle("Cache Manager")
 | 
				
			||||||
 | 
					                .setMessage(
 | 
				
			||||||
 | 
					                    """
 | 
				
			||||||
 | 
					                    Cache Capacity (mb): ${cacheManager.cacheCapacity() * 2.0.pow(-20.0)}
 | 
				
			||||||
 | 
					                    Cache Usage (mb): ${cacheManager.currentCacheUsage() * 2.0.pow(-20.0)}
 | 
				
			||||||
 | 
					                    """.trimIndent()
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // set dialog message
 | 
				
			||||||
 | 
					            alertDialogBuilder.setItems(
 | 
				
			||||||
 | 
					                arrayOf<CharSequence>(
 | 
				
			||||||
 | 
					                    resources.getString(R.string.cancel)
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            ) { dialog, _ -> dialog.dismiss() }
 | 
				
			||||||
 | 
					            activity!!.runOnUiThread { // show it
 | 
				
			||||||
 | 
					                // create alert dialog
 | 
				
			||||||
 | 
					                val alertDialog = alertDialogBuilder.create()
 | 
				
			||||||
 | 
					                alertDialog.show()
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }.start()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun downloadJobAlert() {
 | 
				
			||||||
 | 
					        //prompt for input params
 | 
				
			||||||
 | 
					        val builder = AlertDialog.Builder(activity)
 | 
				
			||||||
 | 
					        val view = View.inflate(activity, R.layout.cache_mgr_input, null)
 | 
				
			||||||
 | 
					        val boundingBox: BoundingBox = map.boundingBox
 | 
				
			||||||
 | 
					        zoomMax = view.findViewById(R.id.slider_zoom_max)
 | 
				
			||||||
 | 
					        zoomMax.max = map.maxZoomLevel.toInt()
 | 
				
			||||||
 | 
					        zoomMax.setOnSeekBarChangeListener(this)
 | 
				
			||||||
 | 
					        zoomMin = view.findViewById(R.id.slider_zoom_min)
 | 
				
			||||||
 | 
					        zoomMin.max = map.maxZoomLevel.toInt()
 | 
				
			||||||
 | 
					        zoomMin.progress = map.minZoomLevel.toInt()
 | 
				
			||||||
 | 
					        zoomMin.setOnSeekBarChangeListener(this)
 | 
				
			||||||
 | 
					        cacheEast = view.findViewById(R.id.cache_east)
 | 
				
			||||||
 | 
					        cacheEast.setText(boundingBox.lonEast.toString() + "")
 | 
				
			||||||
 | 
					        cacheNorth = view.findViewById(R.id.cache_north)
 | 
				
			||||||
 | 
					        cacheNorth.setText(boundingBox.latNorth.toString() + "")
 | 
				
			||||||
 | 
					        cacheSouth = view.findViewById(R.id.cache_south)
 | 
				
			||||||
 | 
					        cacheSouth.setText(boundingBox.latSouth.toString() + "")
 | 
				
			||||||
 | 
					        cacheWest = view.findViewById(R.id.cache_west)
 | 
				
			||||||
 | 
					        cacheWest.setText(boundingBox.lonWest.toString() + "")
 | 
				
			||||||
 | 
					        cacheEstimate = view.findViewById(R.id.cache_estimate)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //change listeners for both validation and to trigger the download estimation
 | 
				
			||||||
 | 
					        cacheEast.addTextChangedListener(this)
 | 
				
			||||||
 | 
					        cacheNorth.addTextChangedListener(this)
 | 
				
			||||||
 | 
					        cacheSouth.addTextChangedListener(this)
 | 
				
			||||||
 | 
					        cacheWest.addTextChangedListener(this)
 | 
				
			||||||
 | 
					        executeJob = view.findViewById(R.id.executeJob)
 | 
				
			||||||
 | 
					        executeJob.setOnClickListener {
 | 
				
			||||||
 | 
					            builder.setOnCancelListener {
 | 
				
			||||||
 | 
					                cacheEast.text = null
 | 
				
			||||||
 | 
					                cacheSouth.text = null
 | 
				
			||||||
 | 
					                cacheEstimate.text = ""
 | 
				
			||||||
 | 
					                cacheNorth.text = null
 | 
				
			||||||
 | 
					                cacheWest.text = null
 | 
				
			||||||
 | 
					                zoomMin.progress = 0
 | 
				
			||||||
 | 
					                zoomMax.progress = 0
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        builder.setView(view)
 | 
				
			||||||
 | 
					        builder.setCancelable(true)
 | 
				
			||||||
 | 
					        downloadPrompt = builder.create()
 | 
				
			||||||
 | 
					        downloadPrompt!!.show()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * if true, start the job
 | 
				
			||||||
 | 
					     * if false, just update the dialog box
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private fun updateEstimate(startJob: Boolean) {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            if (cacheWest.text != null && cacheNorth.text != null && cacheSouth.text != null && zoomMax.progress != 0 && zoomMin.progress != 0) {
 | 
				
			||||||
 | 
					                val n: Double = cacheNorth.text.toString().toDouble()
 | 
				
			||||||
 | 
					                val s: Double = cacheSouth.text.toString().toDouble()
 | 
				
			||||||
 | 
					                val e: Double = cacheEast.text.toString().toDouble()
 | 
				
			||||||
 | 
					                val w: Double = cacheWest.text.toString().toDouble()
 | 
				
			||||||
 | 
					                val zoommin: Int = zoomMin.progress
 | 
				
			||||||
 | 
					                val zoommax: Int = zoomMax.progress
 | 
				
			||||||
 | 
					                //nesw
 | 
				
			||||||
 | 
					                val bb = BoundingBox(n, e, s, w)
 | 
				
			||||||
 | 
					                val tilecount: Int = cacheManager.possibleTilesInArea(bb, zoommin, zoommax)
 | 
				
			||||||
 | 
					                cacheEstimate.text = ("$tilecount tiles")
 | 
				
			||||||
 | 
					                if (startJob) {
 | 
				
			||||||
 | 
					                    if (downloadPrompt != null) {
 | 
				
			||||||
 | 
					                        downloadPrompt!!.dismiss()
 | 
				
			||||||
 | 
					                        downloadPrompt = null
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    //this triggers the download
 | 
				
			||||||
 | 
					                    cacheManager.downloadAreaAsync(activity,
 | 
				
			||||||
 | 
					                        bb,
 | 
				
			||||||
 | 
					                        zoommin,
 | 
				
			||||||
 | 
					                        zoommax,
 | 
				
			||||||
 | 
					                        object : CacheManager.CacheManagerCallback {
 | 
				
			||||||
 | 
					                            override fun onTaskComplete() {
 | 
				
			||||||
 | 
					                                Toast.makeText(activity, "Download complete!", Toast.LENGTH_LONG)
 | 
				
			||||||
 | 
					                                    .show()
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            override fun onTaskFailed(errors: Int) {
 | 
				
			||||||
 | 
					                                Toast.makeText(
 | 
				
			||||||
 | 
					                                    activity,
 | 
				
			||||||
 | 
					                                    "Download complete with $errors errors",
 | 
				
			||||||
 | 
					                                    Toast.LENGTH_LONG
 | 
				
			||||||
 | 
					                                ).show()
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            override fun updateProgress(
 | 
				
			||||||
 | 
					                                progress: Int, currentZoomLevel: Int, zoomMin: Int, zoomMax: Int
 | 
				
			||||||
 | 
					                            ) {
 | 
				
			||||||
 | 
					                                //NOOP since we are using the build in UI
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            override fun downloadStarted() {
 | 
				
			||||||
 | 
					                                //NOOP since we are using the build in UI
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            override fun setPossibleTilesInArea(total: Int) {
 | 
				
			||||||
 | 
					                                //NOOP since we are using the build in UI
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        })
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (ex: Exception) {
 | 
				
			||||||
 | 
					            ex.printStackTrace()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun chooseMapStyle() {
 | 
					    private fun chooseMapStyle() {
 | 
				
			||||||
| 
						 | 
					@ -138,8 +350,7 @@ class MapFragment : ScreenFragment("Map"), Logging {
 | 
				
			||||||
                    marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
 | 
					                    marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
 | 
				
			||||||
                    marker.position = GeoPoint(p.latitude, p.longitude)
 | 
					                    marker.position = GeoPoint(p.latitude, p.longitude)
 | 
				
			||||||
                    marker.icon = ContextCompat.getDrawable(
 | 
					                    marker.icon = ContextCompat.getDrawable(
 | 
				
			||||||
                        requireActivity(),
 | 
					                        requireActivity(), R.drawable.ic_baseline_location_on_24
 | 
				
			||||||
                        R.drawable.ic_baseline_location_on_24
 | 
					 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                marker
 | 
					                marker
 | 
				
			||||||
| 
						 | 
					@ -159,8 +370,7 @@ class MapFragment : ScreenFragment("Map"), Logging {
 | 
				
			||||||
     * Adds copyright to map depending on what source is showing
 | 
					     * Adds copyright to map depending on what source is showing
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private fun addCopyright() {
 | 
					    private fun addCopyright() {
 | 
				
			||||||
        val copyrightNotice: String =
 | 
					        val copyrightNotice: String = map.tileProvider.tileSource.copyrightNotice
 | 
				
			||||||
            map.tileProvider.tileSource.copyrightNotice
 | 
					 | 
				
			||||||
        val copyrightOverlay = CopyrightOverlay(context)
 | 
					        val copyrightOverlay = CopyrightOverlay(context)
 | 
				
			||||||
        copyrightOverlay.setCopyrightNotice(copyrightNotice)
 | 
					        copyrightOverlay.setCopyrightNotice(copyrightNotice)
 | 
				
			||||||
        map.overlays.add(copyrightOverlay)
 | 
					        map.overlays.add(copyrightOverlay)
 | 
				
			||||||
| 
						 | 
					@ -168,6 +378,7 @@ class MapFragment : ScreenFragment("Map"), Logging {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun setupMapProperties() {
 | 
					    private fun setupMapProperties() {
 | 
				
			||||||
        if (this::map.isInitialized) {
 | 
					        if (this::map.isInitialized) {
 | 
				
			||||||
 | 
					            cacheManager = CacheManager(map)
 | 
				
			||||||
            map.setDestroyMode(false) // keeps map instance alive when in the background.
 | 
					            map.setDestroyMode(false) // keeps map instance alive when in the background.
 | 
				
			||||||
            map.isVerticalMapRepetitionEnabled = false // disables map repetition
 | 
					            map.isVerticalMapRepetitionEnabled = false // disables map repetition
 | 
				
			||||||
            map.setScrollableAreaLimitLatitude(
 | 
					            map.setScrollableAreaLimitLatitude(
 | 
				
			||||||
| 
						 | 
					@ -194,8 +405,7 @@ class MapFragment : ScreenFragment("Map"), Logging {
 | 
				
			||||||
                nodesWithPosition.forEach {
 | 
					                nodesWithPosition.forEach {
 | 
				
			||||||
                    points.add(
 | 
					                    points.add(
 | 
				
			||||||
                        GeoPoint(
 | 
					                        GeoPoint(
 | 
				
			||||||
                            it.position!!.latitude,
 | 
					                            it.position!!.latitude, it.position!!.longitude
 | 
				
			||||||
                            it.position!!.longitude
 | 
					 | 
				
			||||||
                        )
 | 
					                        )
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -219,6 +429,12 @@ class MapFragment : ScreenFragment("Map"), Logging {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun onPause() {
 | 
					    override fun onPause() {
 | 
				
			||||||
        map.onPause()
 | 
					        map.onPause()
 | 
				
			||||||
 | 
					        if (alertDialog != null && alertDialog!!.isShowing) {
 | 
				
			||||||
 | 
					            alertDialog!!.dismiss()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (downloadPrompt != null && downloadPrompt!!.isShowing) {
 | 
				
			||||||
 | 
					            downloadPrompt!!.dismiss()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        super.onPause()
 | 
					        super.onPause()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -270,6 +486,26 @@ class MapFragment : ScreenFragment("Map"), Logging {
 | 
				
			||||||
            c.drawText(mLabel, (p.x - 0f), (p.y - 110f), textPaint)
 | 
					            c.drawText(mLabel, (p.x - 0f), (p.y - 110f), textPaint)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {
 | 
				
			||||||
 | 
					        updateEstimate(false)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun onStartTrackingTouch(p0: SeekBar?) {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun onStopTrackingTouch(p0: SeekBar?) {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
 | 
				
			||||||
 | 
					        updateEstimate(false)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun afterTextChanged(p0: Editable?) {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,142 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
 | 
					    android:layout_width="match_parent"
 | 
				
			||||||
 | 
					    android:layout_height="match_parent"
 | 
				
			||||||
 | 
					    android:orientation="vertical">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <ScrollView
 | 
				
			||||||
 | 
					        android:id="@+id/scrollView"
 | 
				
			||||||
 | 
					        android:layout_width="match_parent"
 | 
				
			||||||
 | 
					        android:layout_height="match_parent"
 | 
				
			||||||
 | 
					        android:layout_gravity="center_horizontal">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <LinearLayout
 | 
				
			||||||
 | 
					            android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					            android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					            android:orientation="vertical">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <TextView
 | 
				
			||||||
 | 
					                android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:text="Northern most Latitude"
 | 
				
			||||||
 | 
					                android:textAppearance="?android:attr/textAppearanceLarge" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <EditText
 | 
				
			||||||
 | 
					                android:id="@+id/cache_north"
 | 
				
			||||||
 | 
					                android:layout_width="match_parent"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:digits="1234567890.-"
 | 
				
			||||||
 | 
					                android:inputType="number|numberDecimal|numberSigned" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <TextView
 | 
				
			||||||
 | 
					                android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:text="Southern most Latitude"
 | 
				
			||||||
 | 
					                android:textAppearance="?android:attr/textAppearanceLarge" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <EditText
 | 
				
			||||||
 | 
					                android:id="@+id/cache_south"
 | 
				
			||||||
 | 
					                android:layout_width="match_parent"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:digits="1234567890.-"
 | 
				
			||||||
 | 
					                android:inputType="number|numberDecimal|numberSigned" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <TextView
 | 
				
			||||||
 | 
					                android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:text="Eastern most Longitude"
 | 
				
			||||||
 | 
					                android:textAppearance="?android:attr/textAppearanceLarge" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <EditText
 | 
				
			||||||
 | 
					                android:id="@+id/cache_east"
 | 
				
			||||||
 | 
					                android:layout_width="match_parent"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:digits="1234567890.-"
 | 
				
			||||||
 | 
					                android:inputType="number|numberDecimal|numberSigned" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <TextView
 | 
				
			||||||
 | 
					                android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:text="Western most Longitude"
 | 
				
			||||||
 | 
					                android:textAppearance="?android:attr/textAppearanceLarge" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <EditText
 | 
				
			||||||
 | 
					                android:id="@+id/cache_west"
 | 
				
			||||||
 | 
					                android:layout_width="match_parent"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:digits="1234567890.-"
 | 
				
			||||||
 | 
					                android:inputType="number|numberDecimal|numberSigned" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <TextView
 | 
				
			||||||
 | 
					                android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:text="Zoom Level Min"
 | 
				
			||||||
 | 
					                android:textAppearance="?android:attr/textAppearanceLarge" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <SeekBar
 | 
				
			||||||
 | 
					                android:id="@+id/slider_zoom_min"
 | 
				
			||||||
 | 
					                android:layout_width="fill_parent"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <TextView
 | 
				
			||||||
 | 
					                android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:text="Zoom Level Max"
 | 
				
			||||||
 | 
					                android:textAppearance="?android:attr/textAppearanceLarge" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <SeekBar
 | 
				
			||||||
 | 
					                android:id="@+id/slider_zoom_max"
 | 
				
			||||||
 | 
					                android:layout_width="fill_parent"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <TextView
 | 
				
			||||||
 | 
					                android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:text="Tile download estimate:"
 | 
				
			||||||
 | 
					                android:textAppearance="?android:attr/textAppearanceLarge" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <TextView
 | 
				
			||||||
 | 
					                android:id="@+id/cache_estimate"
 | 
				
			||||||
 | 
					                android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <LinearLayout
 | 
				
			||||||
 | 
					                android:id="@+id/cache_archival_section"
 | 
				
			||||||
 | 
					                android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:orientation="vertical"
 | 
				
			||||||
 | 
					                android:visibility="gone">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <TextView
 | 
				
			||||||
 | 
					                    android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					                    android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                    android:text="Archive File name:"
 | 
				
			||||||
 | 
					                    android:textAppearance="?android:attr/textAppearanceLarge" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <EditText
 | 
				
			||||||
 | 
					                    android:id="@+id/cache_output"
 | 
				
			||||||
 | 
					                    android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					                    android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                    android:hint="archive.sqlite"
 | 
				
			||||||
 | 
					                    android:lines="1"
 | 
				
			||||||
 | 
					                    android:text="archive.sqlite"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
 | 
					            </LinearLayout>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <Button
 | 
				
			||||||
 | 
					                android:id="@+id/executeJob"
 | 
				
			||||||
 | 
					                android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:text="Start Download" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        </LinearLayout>
 | 
				
			||||||
 | 
					    </ScrollView>
 | 
				
			||||||
 | 
					</LinearLayout>
 | 
				
			||||||
| 
						 | 
					@ -25,15 +25,15 @@
 | 
				
			||||||
        app:layout_constraintTop_toTopOf="parent" />
 | 
					        app:layout_constraintTop_toTopOf="parent" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <com.google.android.material.floatingactionbutton.FloatingActionButton
 | 
					    <com.google.android.material.floatingactionbutton.FloatingActionButton
 | 
				
			||||||
        android:id="@+id/fab_style_toggle"
 | 
					        android:id="@+id/downloadButton"
 | 
				
			||||||
        android:layout_width="wrap_content"
 | 
					        android:layout_width="wrap_content"
 | 
				
			||||||
        android:layout_height="wrap_content"
 | 
					        android:layout_height="wrap_content"
 | 
				
			||||||
        android:layout_margin="8dp"
 | 
					        android:layout_margin="8dp"
 | 
				
			||||||
        android:backgroundTint="@color/design_default_color_secondary"
 | 
					        android:backgroundTint="@color/design_default_color_secondary"
 | 
				
			||||||
        android:contentDescription="@string/style_selection"
 | 
					        android:contentDescription="@string/style_selection"
 | 
				
			||||||
        android:orientation="vertical"
 | 
					        android:orientation="vertical"
 | 
				
			||||||
 | 
					        android:visibility="visible"
 | 
				
			||||||
        app:layout_constraintBottom_toBottomOf="parent"
 | 
					        app:layout_constraintBottom_toBottomOf="parent"
 | 
				
			||||||
        android:visibility="gone"
 | 
					 | 
				
			||||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
					        app:layout_constraintEnd_toEndOf="parent"
 | 
				
			||||||
        tools:background="@color/design_default_color_secondary" />
 | 
					        tools:background="@color/design_default_color_secondary" />
 | 
				
			||||||
</androidx.constraintlayout.widget.ConstraintLayout>
 | 
					</androidx.constraintlayout.widget.ConstraintLayout>
 | 
				
			||||||
		Ładowanie…
	
		Reference in New Issue