I have some problems developing my app, the problem is the following: I am trying to create a path between two points. When I enter the points directly on the code the path is displayed correctly:
routePath(43.12628, 12.04705, 43.12124, 11.97211) //this part works correctly
if instead I try to create it using the button I made, which calls the routePath () function, I can't see it on the map:
b.setOnClickListener{
Log.d("Percorso", "Premuto")
val lalati: Double = editTextLatitudine.text.toString().toDouble()
val lolong: Double = editTextLongitudine.text.toString().toDouble()
println("latitudine: $lalati, longitudine: $lolong")
routePath(22.22, 44.33, lolong, lalati)
} //this part does not work correctly
how can i fix this?
my code is this below:
package uk.co.lorenzopulcinelli.trackapp
import android.Manifest
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.os.StrictMode
import android.util.DisplayMetrics
import android.util.Log
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.res.ResourcesCompat
import androidx.preference.PreferenceManager
import org.osmdroid.api.IMapController
import org.osmdroid.bonuspack.clustering.RadiusMarkerClusterer
import org.osmdroid.bonuspack.location.NominatimPOIProvider
import org.osmdroid.bonuspack.location.POI
import org.osmdroid.bonuspack.routing.OSRMRoadManager
import org.osmdroid.bonuspack.routing.Road
import org.osmdroid.bonuspack.routing.RoadManager
import org.osmdroid.bonuspack.routing.RoadNode
import org.osmdroid.bonuspack.utils.BonusPackHelper
import org.osmdroid.config.Configuration
import org.osmdroid.config.Configuration.*
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
import org.osmdroid.util.GeoPoint
import org.osmdroid.views.CustomZoomButtonsController
import org.osmdroid.views.MapView
import org.osmdroid.views.overlay.compass.CompassOverlay
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider
import org.osmdroid.views.overlay.*
import org.osmdroid.views.overlay.gestures.RotationGestureOverlay
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay
import org.osmdroid.views.overlay.Marker
class MainActivity : AppCompatActivity() {
private lateinit var mapView : MapView
private lateinit var myLocationNewOverlay: MyLocationNewOverlay
private lateinit var compassOverlay: CompassOverlay
private lateinit var mapController: IMapController
private lateinit var road: Road
private lateinit var editTextLatitudine: EditText
private lateinit var editTextLongitudine: EditText
override fun onCreate(savedInstanceState: Bundle?) {
// disabilita la policy di strictMode nella onCreate per non fare chiamate network in async tasks
val policy: StrictMode.ThreadPolicy = StrictMode.ThreadPolicy.Builder().permitAll().build()
StrictMode.setThreadPolicy(policy)
super.onCreate(savedInstanceState)
//richiesta per gestire i permessi
requestPermission()
// inizializza la configurazione di osmdroid, non funziona se non si importa org.osmdroid.config.Configuration.*
getInstance().load(this, PreferenceManager.getDefaultSharedPreferences(this))
//crea la mappa
setContentView(R.layout.activity_main)
mapView = findViewById<MapView>(R.id.map)
mapView.setTileSource(TileSourceFactory.MAPNIK)
mapView.zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER)
// crea MapController e setta posizione iniziale
mapController = mapView.controller
// crea overlay posizione
myLocationNewOverlay = MyLocationNewOverlay(GpsMyLocationProvider(this), mapView)
myLocationNewOverlay.enableMyLocation()
myLocationNewOverlay.enableMyLocation()
myLocationNewOverlay.isDrawAccuracyEnabled = true
myLocationNewOverlay.runOnFirstFix { runOnUiThread {
mapController.animateTo(myLocationNewOverlay.myLocation)
mapController.setZoom(9.0)
}
}
mapView.overlays.add(myLocationNewOverlay)
//set user agent
Configuration.getInstance().userAgentValue = "lolloMaps"
// controllo
println(myLocationNewOverlay.myLocation)
println("creato")
// attiva bussola, Non Funziona!
compassOverlay = CompassOverlay(this, InternalCompassOrientationProvider(this), mapView)
compassOverlay.enableCompass()
mapView.overlays.add(compassOverlay)
// attivare griglia latitudine e longitudine
// val overlay = LatLonGridlineOverlay2()
// mapView.overlays.add(overlay)
// abilita gesture rotazione e zoom
val rotationGestureOverlay = RotationGestureOverlay(mapView)
rotationGestureOverlay.isEnabled
mapView.setMultiTouchControls(true)
mapView.overlays.add(rotationGestureOverlay)
// abilita mia posizione
myLocationNewOverlay = MyLocationNewOverlay(GpsMyLocationProvider(this), mapView)
myLocationNewOverlay.enableMyLocation()
mapView.overlays.add(myLocationNewOverlay)
// abilita overlay scala
val dm : DisplayMetrics = resources.displayMetrics
val scaleBarOverlay = ScaleBarOverlay(mapView)
scaleBarOverlay.setCentred(true)
scaleBarOverlay.setScaleBarOffset(dm.widthPixels / 2, 10)
mapView.overlays.add(scaleBarOverlay)
val mapEventsReceiver: MapEventsReceiverImpl = MapEventsReceiverImpl()
val mapEventsOverlay: MapEventsOverlay = MapEventsOverlay(mapEventsReceiver)
mapView.overlays.add(mapEventsOverlay)
// traccia percorso tra i punti degli editText
editTextLatitudine = findViewById<EditText>(R.id.editTextLatitudine)
editTextLongitudine = findViewById<EditText>(R.id.editTextLongitudine)
val b = findViewById<Button>(R.id.location)
b.setOnClickListener{
Log.d("Percorso", "Premuto")
val lalati: Double = editTextLatitudine.text.toString().toDouble()
val lolong: Double = editTextLongitudine.text.toString().toDouble()
println("latitudine: $lalati, longitudine: $lolong")
routePath(22.22, 44.33, lolong, lalati)
}
// traccia percorso tra due punti prestabiliti
routePath(43.12628, 12.04705, 43.12124, 11.97211)
// inserisce POIs nella mappa
val startPoint1:GeoPoint = GeoPoint(43.12628, 12.04705)
val poiProvider: NominatimPOIProvider = NominatimPOIProvider("OSMBonusPackTutoUserAgent")
val pois: ArrayList<POI> = poiProvider.getPOICloseTo(startPoint1, "fuel", 50, 0.1)
val poisRoad: ArrayList<POI> = poiProvider.getPOIAlong(road.routeLow, "cinema", 50, 0.1)
val poiMarkers: FolderOverlay = FolderOverlay()
mapView.overlays.add(poiMarkers)
val poiIcon: Drawable? = ResourcesCompat.getDrawable(resources, R.drawable.marker_poi_default, null)
for (poi: POI in pois){
val poiMarker: Marker = Marker(mapView)
poiMarker.title = poi.mType
poiMarker.snippet = poi.mDescription
poiMarker.position = poi.mLocation
poiMarker.icon = poiIcon
/*if (poi.mThumbnail != null){
poiItem.setImage(BitmapDrawable(poi.mThumbnail))
}*/
poiMarkers.add(poiMarker)
mapView.invalidate()
}
for (poi: POI in poisRoad){
val rPoiMarker: Marker = Marker(mapView)
rPoiMarker.title = poi.mType
rPoiMarker.snippet = poi.mDescription
rPoiMarker.position = poi.mLocation
rPoiMarker.icon = poiIcon
/*if (poi.mThumbnail != null){
poiItem.setImage(BitmapDrawable(poi.mThumbnail))
}*/
poiMarkers.add(rPoiMarker)
mapView.invalidate()
}
// clustering markers
val radiusMarkerCluster: RadiusMarkerClusterer = RadiusMarkerClusterer(this)
val clusterIcon: Bitmap = BonusPackHelper.getBitmapFromVectorDrawable(this, R.drawable.marker_cluster)
radiusMarkerCluster.setIcon(clusterIcon)
}
override fun onResume() {
super.onResume()
mapView.onResume()
}
override fun onPause() {
super.onPause()
mapView.onPause()
}
//funzione per controllare se ho i permessi
private fun hasPermission() : Boolean {
// ritorna true quando abbiamo i permessi
return ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
//funzione per richiedere i permessi
private fun requestPermission() {
//aggiungo i permessi ad una lista
val permission = mutableListOf<String>()
// se non ho i permessi
if (!hasPermission()) {
// aggiungo i permesi alla lista
permission.add(Manifest.permission.ACCESS_FINE_LOCATION)
}
// concede i permessi nella lista
if (permission.isNotEmpty()) {
ActivityCompat.requestPermissions(this, permission.toTypedArray(), 0)
}
}
// funzione per aggiungere Marker
private fun mioMarker(lati: Double, longi: Double, i: Int) {
val pinMarker = Marker(mapView)
val geoPoint = GeoPoint(lati, longi)
pinMarker.position = geoPoint
pinMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER)
pinMarker.title = "Title"
pinMarker.subDescription = "io sono il pin #$i con coordinate $lati, $longi."
pinMarker.isDraggable = true
mapView.overlays.add(pinMarker)
mapView.invalidate()
}
// funzione per creare percorso fra due punti
private fun routePath(p1Latit: Double, p1Laong: Double, p2Latit: Double, p2Laong: Double){
println("inizio")
val roadManager:RoadManager = OSRMRoadManager(this, "lolloMaps")
OSRMRoadManager.MEAN_BY_FOOT
println("passo1 - creoArrayList")
val waypoints = arrayListOf<GeoPoint>()
println("passo2 - CreoPuntiEAggiungoInArrayList")
val startPoint: GeoPoint = GeoPoint(p1Latit, p1Laong) //43.12628, 12.04705
waypoints.add(startPoint)
val endPoint: GeoPoint = GeoPoint(p2Latit, p2Laong) //43.12124, 11.97211
waypoints.add(endPoint)
println("passo3 - CreoStrada")
road = roadManager.getRoad(waypoints)
if (road.mStatus != Road.STATUS_OK){
Toast.makeText(this, "Errore nel caricamento di road - status = " + road.mStatus, Toast.LENGTH_SHORT).show()
}
println("passo4 - CreoPolilinea")
val roadOverlay: Polyline = RoadManager.buildRoadOverlay(road)
println("passo5 - AggiungoPolilineaAllaMappa")
mapView.overlays.add(roadOverlay)
mapView.invalidate()
// crea checkpoint lungo il percorso
val nodeIcon: Drawable? = ResourcesCompat.getDrawable(resources, R.drawable.marker_node, null)
for (i: Int in road.mNodes.indices){
val node: RoadNode = road.mNodes[i]
val nodeMarker: Marker = Marker(mapView)
nodeMarker.position = node.mLocation
nodeMarker.icon = nodeIcon
nodeMarker.title = "Passo $i"
mapView.overlays.add(nodeMarker)
// aggiunge informazioni nelle finestre dei checkpoint
nodeMarker.snippet = node.mInstructions
nodeMarker.subDescription = Road.getLengthDurationText(this,node.mLength, node.mDuration)
// var icon: Drawable = resources.getDrawable(R.drawable.ic_continue)
// nodeMarker.image = icon
}
}
}
this is my xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/location"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/map" />
<EditText style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:id="@+id/editTextLatitudine"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:ems="10"
android:inputType="numberDecimal"
android:hint="@string/latitudine"
/>
<EditText style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:id="@+id/editTextLongitudine"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:ems="10"
android:inputType="numberDecimal"
android:hint="@string/longitudine"/>
</LinearLayout>
<org.osmdroid.views.MapView
android:id="@+id/map"
tilesource="Mapnik"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="-181dp"
tools:layout_editor_absoluteY="57dp">
</org.osmdroid.views.MapView>
</LinearLayout>
and this my gradle:
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
compileSdk 32
defaultConfig {
applicationId "uk.co.lorenzopulcinelli.trackapp"
minSdk 21
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation 'androidx.preference:preference:1.2.0' //aggiunta per utilizzare import androidx.preference.PreferenceManager
implementation 'com.google.android.gms:play-services-location:20.0.0' //aggiunta per richiedere permessi localizzazione
implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation files ('/home/acer/AndroidStudioProjects/TrackApp/app/libs/osmbonuspack_6.9.0.aar')
implementation files ('/home/acer/AndroidStudioProjects/TrackApp/app/libs/osmdroid-android-6.1.13.aar')
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.google.code.gson:gson:2.8.9'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0'
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
}
I found the error, I enclosed the button operations in a try-catch and I discovered that I was wrong in entering the starting coordinates, these were not admissible numbers to represent the latitude and longitude, in addition I had swapped the order of insertion of the coordinates in the function that creates the route.