Author: Adam Evyčędo <git@apiote.xyz>
show shapes of journeys
%!v(PANIC=String method: strings: negative Repeat count)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 41f9609d54c86b09821831f26252f2a83173b254..c6500bcc5531763874ccc2ded4ecb9767055dc33 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -80,7 +80,7 @@ } kotlin.sourceSets["main"].kotlin.srcDir("${layout.buildDirectory.get()}/generated/src/main/kotlin") -// TODO only in debug +// TODO reuse only in debug tasks.withType<KotlinCompile> { dependsOn("openApiGenerate") dependsOn("lintReuse") @@ -108,7 +108,7 @@ implementation("androidx.core:core-splashscreen:1.0.1") implementation("com.google.openlocationcode:openlocationcode:1.0.4") implementation("org.osmdroid:osmdroid-android:6.1.20") implementation("org.yaml:snakeyaml:2.3") - implementation("androidx.activity:activity-ktx:1.9.3") + implementation("androidx.activity:activity-ktx:1.10.0") implementation("com.otaliastudios:zoomlayout:1.9.0") implementation("dev.bandb.graphview:graphview:0.8.1") implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.8.0") @@ -123,9 +123,7 @@ implementation("ch.acra:acra-http:5.12.0") implementation("ch.acra:acra-notification:5.12.0") implementation("com.squareup.okhttp3:okhttp:4.12.0") implementation("com.squareup.moshi:moshi-kotlin:1.15.2") - implementation("androidx.activity:activity:1.9.3") - implementation("com.google.maps.android:maps-ktx:5.1.1") - implementation("com.google.maps.android:maps-utils-ktx:5.1.1") + implementation("androidx.activity:activity:1.10.0") coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4") diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/api/transitousJourney.kt b/app/src/main/java/xyz/apiote/bimba/czwek/api/transitousJourney.kt index 9a2eec19639badea4389b75735e648bbde2c93d1..be51e850fc9262faf148f370e7acb8a8318b27de 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/api/transitousJourney.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/api/transitousJourney.kt @@ -96,7 +96,7 @@ it.agencyName, it.distance?.toDouble()?.let { Metre(it) }, Second(it.duration), (it.intermediateStops ?: emptyList()).map { Place(it) }, - it.legGeometry, + decode(it.legGeometry.points) /*it.rental, it.steps,*/ ) @@ -108,5 +108,43 @@ ), legs ) } } +} + +/* +The following piece of code © Google, Apache License, Version 2.0 +from https://github.com/googlemaps/android-maps-utils/blob/main/library/src/main/java/com/google/maps/android/PolyUtil.java +with changes to decode with precision 7 +*/ +fun decode(encodedPath: String): MutableList<Position> { + val len = encodedPath.length -} \ No newline at end of file + val path: MutableList<Position> = ArrayList<Position>() + var index = 0 + var lat = 0 + var lng = 0 + + while (index < len) { + var result = 1 + var shift = 0 + var b: Int + do { + b = encodedPath[index++].code - 63 - 1 + result += b shl shift + shift += 5 + } while (b >= 0x1f) + lat += if ((result and 1) != 0) (result shr 1).inv() else (result shr 1) + + result = 1 + shift = 0 + do { + b = encodedPath[index++].code - 63 - 1 + result += b shl shift + shift += 5 + } while (b >= 0x1f) + lng += if ((result and 1) != 0) (result shr 1).inv() else (result shr 1) + + path.add(Position(lat * 1e-7, lng * 1e-7)) + } + + return path +} diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/journey/JourneyFragment.kt b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/journey/JourneyFragment.kt index 76ab1d5c786f805d1d617f5e7424c6a27c3f602f..e7050ea7f9e6a8314d43af88ca623477e008a796 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/journey/JourneyFragment.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/journey/JourneyFragment.kt @@ -481,6 +481,7 @@ setLayerInset(0, dpToPixelI(4f), 0, dpToPixelI(4f), 0) setBounds(0, 0, chip.intrinsicWidth, chip.intrinsicHeight) } val span = ImageSpan(ld) + // FIXME size is one char to small textView.text?.setSpan(span, 0, text.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) @SuppressLint("ClickableViewAccessibility") textView.setOnTouchListener { v, e -> diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/journeys/JourneysActivity.kt b/app/src/main/java/xyz/apiote/bimba/czwek/journeys/JourneysActivity.kt index 89291eb7541d2ab0989fc5e0f2b18f0ed861a7a7..cda4b2d339642c1596e99e5ebfeb6b5b11f999d7 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/journeys/JourneysActivity.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/journeys/JourneysActivity.kt @@ -21,7 +21,6 @@ import androidx.core.view.WindowInsetsCompat import androidx.core.view.updatePadding import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager -import com.google.maps.android.PolyUtil import org.osmdroid.tileprovider.tilesource.TileSourceFactory import org.osmdroid.util.BoundingBox import org.osmdroid.util.GeoPoint @@ -117,30 +116,39 @@ binding.journeys.visibility = View.VISIBLE binding.journeys.adapter = JourneysAdapter(layoutInflater, this, it) { binding.map.overlays.removeAll { true } + // TODO show depending on open/close card + // TODO close other cards + + // TODO show without journey val originMarker = Marker(binding.map).apply { position = GeoPoint(it.legs[0].origin.latitude, it.legs[0].origin.longitude) setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM) - val scale = binding.map.zoomLevelDouble / -4 + 5.5 icon = AppCompatResources.getDrawable( this@JourneysActivity, - R.drawable.pin // R.drawable.legOrigin - ) // TODO scale and colour + R.drawable.pin // TODO R.drawable.legOrigin + ) // TODO colour + setOnMarkerClickListener { marker, map -> + true + } } binding.map.overlays.add(originMarker) + // TODO show without journey val destinationMarker = Marker(binding.map).apply { - position = GeoPoint(it.legs[0].origin.latitude, it.legs[0].origin.longitude) + position = GeoPoint(it.legs.last().destination.latitude, it.legs.last().destination.longitude) setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM) - val scale = binding.map.zoomLevelDouble / -4 + 5.5 icon = AppCompatResources.getDrawable( this@JourneysActivity, - R.drawable.pin //R.drawable.legDestination - ) // TODO scale and colour + R.drawable.pin // TODO R.drawable.legDestination + ) // TODO colour + setOnMarkerClickListener { marker, map -> + true + } } binding.map.overlays.add(destinationMarker) it.legs.forEachIndexed { i, leg -> - val shapePoints = PolyUtil.decode(leg.shape.points).map { + val shapePoints = leg.shape.map { GeoPoint(it.latitude, it.longitude) } val shape = Polyline() @@ -150,6 +158,7 @@ if (leg.start.vehicle.Line.kind == LineType.WALK) { // TODO and other active paint.setPathEffect(DashPathEffect(floatArrayOf(10f, 10f), 0f)) } shape.setPoints(shapePoints) + shape.isVisible = true binding.map.overlays.add(shape) } binding.map.invalidate() @@ -168,6 +177,7 @@ fun zoomMap(margin: Int = 0, box: BoundingBox? = null) { val origin = getOrigin() val destination = getDestination() + // TODO offset bottom sheet val bb = box ?: BoundingBox( max(origin.latitude, destination.latitude), max(origin.longitude, destination.longitude), diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/repo/Journey.kt b/app/src/main/java/xyz/apiote/bimba/czwek/repo/Journey.kt index 0446e96f18431cc2725c62469f36fe8ab25fc40f..116985190dd65e64ffc9a0f26c3d3652a5cfbe40 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/repo/Journey.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/repo/Journey.kt @@ -6,7 +6,6 @@ package xyz.apiote.bimba.czwek.repo import android.os.Parcelable import kotlinx.parcelize.Parcelize -import xyz.apiote.bimba.czwek.api.transitous.model.EncodedPolyline import xyz.apiote.bimba.czwek.api.transitous.model.Place import xyz.apiote.bimba.czwek.units.DistanceUnit import xyz.apiote.bimba.czwek.units.TimeUnit @@ -23,7 +22,7 @@ val agencyName: String?, val distance: DistanceUnit?, val duration: TimeUnit, val intermediateStops: List<xyz.apiote.bimba.czwek.repo.Place>, - val shape: EncodedPolyline, // TODO to list of points + val shape: List<Position>, /* TODO val rental: Rental?, val steps: List<StepInstruction>?,*/