feat: di, db, and preliminary server-side gtfs parsing
This commit is contained in:
parent
ccc748dc1f
commit
6770c01613
22 changed files with 555 additions and 24 deletions
|
|
@ -2,18 +2,7 @@ package moe.lava.banksia.data.ptv.structures
|
|||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
// Ordinals used for sorting in searcher
|
||||
enum class GtfsSubType(val value: Int) {
|
||||
MetroTrain(2),
|
||||
MetroTram(3),
|
||||
MetroBus(4),
|
||||
RegionalTrain(1),
|
||||
RegionalCoach(5),
|
||||
RegionalBus(6),
|
||||
SkyBus(11),
|
||||
Interstate(10),
|
||||
}
|
||||
import moe.lava.banksia.model.RouteType
|
||||
|
||||
@Serializable
|
||||
data class PtvRoute(
|
||||
|
|
@ -24,13 +13,8 @@ data class PtvRoute(
|
|||
@SerialName("route_gtfs_id") val routeGtfsId: String,
|
||||
@SerialName("geopath") val geopath: List<PtvGeopath>,
|
||||
) {
|
||||
fun gtfsSubType(): GtfsSubType? {
|
||||
GtfsSubType.entries.forEach {
|
||||
if (routeGtfsId.startsWith(it.value.toString()))
|
||||
return it
|
||||
}
|
||||
return null
|
||||
}
|
||||
fun gtfsSubType(): RouteType =
|
||||
RouteType.entries.first { routeGtfsId.startsWith(it.value.toString() + "-") }
|
||||
|
||||
fun getShortFullName(): String {
|
||||
var res = ""
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
package moe.lava.banksia.di
|
||||
|
||||
import moe.lava.banksia.room.Database
|
||||
import org.koin.dsl.module
|
||||
|
||||
val CommonModules = module {
|
||||
includes(PlatformModule)
|
||||
|
||||
single { Database.build(get<PlatformDatabaseBuilder>().getBuilder()) }
|
||||
single { get<Database>().getRouteDao() }
|
||||
single { get<Database>().getShapeDao() }
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package moe.lava.banksia.di
|
||||
|
||||
import androidx.room.RoomDatabase
|
||||
import moe.lava.banksia.room.Database
|
||||
import org.koin.core.parameter.ParametersHolder
|
||||
import org.koin.core.scope.Scope
|
||||
import org.koin.dsl.module
|
||||
|
||||
interface PlatformDatabaseBuilder {
|
||||
fun getBuilder(): RoomDatabase.Builder<Database>
|
||||
}
|
||||
|
||||
expect fun Scope.provideDatabaseBuilder(p: ParametersHolder): PlatformDatabaseBuilder
|
||||
|
||||
internal val PlatformModule = module {
|
||||
single { provideDatabaseBuilder(it) }
|
||||
}
|
||||
12
shared/src/commonMain/kotlin/moe/lava/banksia/model/Route.kt
Normal file
12
shared/src/commonMain/kotlin/moe/lava/banksia/model/Route.kt
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package moe.lava.banksia.model
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity
|
||||
data class Route(
|
||||
@PrimaryKey val id: String,
|
||||
val type: RouteType,
|
||||
val number: String?,
|
||||
val name: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package moe.lava.banksia.model
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
|
||||
enum class RouteType(val value: Int) {
|
||||
MetroTrain(2),
|
||||
MetroTram(3),
|
||||
MetroBus(4),
|
||||
RegionalTrain(1),
|
||||
RegionalCoach(5),
|
||||
RegionalBus(6),
|
||||
SkyBus(11),
|
||||
Interstate(10),
|
||||
;
|
||||
|
||||
companion object {
|
||||
@TypeConverter
|
||||
fun from(value: Int) = RouteType.entries.first { it.value == value }
|
||||
|
||||
@TypeConverter
|
||||
fun to(routeType: RouteType) = routeType.value
|
||||
}
|
||||
}
|
||||
16
shared/src/commonMain/kotlin/moe/lava/banksia/model/Shape.kt
Normal file
16
shared/src/commonMain/kotlin/moe/lava/banksia/model/Shape.kt
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
package moe.lava.banksia.model
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import androidx.room.TypeConverters
|
||||
import moe.lava.banksia.room.converter.ShapeConverter
|
||||
import moe.lava.banksia.util.Point
|
||||
|
||||
typealias ShapePath = List<Point>
|
||||
|
||||
@Entity
|
||||
@TypeConverters(ShapeConverter::class)
|
||||
data class Shape(
|
||||
@PrimaryKey val id: String,
|
||||
val path: ShapePath,
|
||||
)
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package moe.lava.banksia.room
|
||||
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.room.TypeConverters
|
||||
import androidx.sqlite.driver.bundled.BundledSQLiteDriver
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
import moe.lava.banksia.model.Route
|
||||
import moe.lava.banksia.model.RouteType
|
||||
import moe.lava.banksia.model.Shape
|
||||
import moe.lava.banksia.room.dao.RouteDao
|
||||
import moe.lava.banksia.room.dao.ShapeDao
|
||||
import androidx.room.Database as DatabaseAnnotation
|
||||
|
||||
@DatabaseAnnotation(entities = [Route::class, Shape::class], version = 1)
|
||||
@TypeConverters(RouteType.Companion::class)
|
||||
abstract class Database : RoomDatabase() {
|
||||
abstract fun getRouteDao(): RouteDao
|
||||
abstract fun getShapeDao(): ShapeDao
|
||||
|
||||
companion object {
|
||||
fun build(base: Builder<Database>) =
|
||||
base.fallbackToDestructiveMigrationOnDowngrade(true)
|
||||
.setDriver(BundledSQLiteDriver())
|
||||
.setQueryCoroutineContext(Dispatchers.IO)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package moe.lava.banksia.room.converter
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import moe.lava.banksia.model.ShapePath
|
||||
import moe.lava.banksia.util.Point
|
||||
|
||||
object ShapeConverter {
|
||||
@TypeConverter
|
||||
fun from(value: ByteArray): ShapePath {
|
||||
return value
|
||||
.asIterable()
|
||||
.chunked(8) {
|
||||
(it[0].toLong() and 0xFF) or
|
||||
(it[1].toLong() and 0xFF shl 8) or
|
||||
(it[2].toLong() and 0xFF shl 16) or
|
||||
(it[3].toLong() and 0xFF shl 24) or
|
||||
(it[4].toLong() and 0xFF shl 32) or
|
||||
(it[5].toLong() and 0xFF shl 40) or
|
||||
(it[6].toLong() and 0xFF shl 48) or
|
||||
(it[7].toLong() and 0xFF shl 56)
|
||||
}
|
||||
.map { Double.fromBits(it) }
|
||||
.chunked(2)
|
||||
.map { (lat, lng) -> Point(lat, lng) }
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun to(path: ShapePath): ByteArray {
|
||||
return path
|
||||
.flatMap { (lat, lng) -> listOf(lat.toBits(), lng.toBits()) }
|
||||
.flatMap { i -> listOf(
|
||||
i.toByte(),
|
||||
(i shr 8).toByte(),
|
||||
(i shr 16).toByte(),
|
||||
(i shr 24).toByte(),
|
||||
(i shr 32).toByte(),
|
||||
(i shr 40).toByte(),
|
||||
(i shr 48).toByte(),
|
||||
(i shr 56).toByte(),
|
||||
) }
|
||||
.toByteArray()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package moe.lava.banksia.room.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import moe.lava.banksia.model.Route
|
||||
|
||||
@Dao
|
||||
interface RouteDao {
|
||||
@Query("SELECT * FROM Route")
|
||||
suspend fun getAll(): List<Route>
|
||||
|
||||
@Query("SELECT * FROM Route WHERE id == :id")
|
||||
suspend fun get(id: String): Route?
|
||||
|
||||
@Insert
|
||||
suspend fun insertAll(vararg routes: Route)
|
||||
|
||||
@Delete
|
||||
suspend fun delete(route: Route)
|
||||
|
||||
@Query("DELETE FROM Route")
|
||||
suspend fun deleteAll()
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package moe.lava.banksia.room.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import moe.lava.banksia.model.Shape
|
||||
|
||||
@Dao
|
||||
interface ShapeDao {
|
||||
@Query("SELECT * FROM Shape WHERE id == :id")
|
||||
suspend fun get(id: String): Shape?
|
||||
|
||||
@Insert
|
||||
suspend fun insertAll(vararg shapes: Shape)
|
||||
|
||||
@Delete
|
||||
suspend fun delete(shape: Shape)
|
||||
|
||||
@Query("DELETE FROM Shape")
|
||||
suspend fun deleteAll()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue