GBFS¶
The GBFS modules provides implementations of the General Bikeshare Feed Specification (GBFS) for Kotlin Multiplatform.
GBFS is a standardized data feed for real-time access to information about bikeshare, scooter-share, and other shared mobility services.
Modules¶
gbfs-v1: Implementation of the GBFS v1.1 specification.gbfs-v2: Implementation of the GBFS v2.3 specification.gbfs-v3: Implementation of the GBFS v3.0 specification.
Features¶
- JSON encoding and decoding with kotlinx-serialization
- HTTP client for fetching feeds using Ktor
- Strong type safety, with appropriate standard library or kotlinx-datetime types
- Kotlin Multiplatform support (JVM, Native, JS, WASM)
- GeoJSON support using Spatial-K
Installation¶
Add the dependency to your build.gradle.kts. The client functionality requires
Ktor, so also add a Ktor engine:
dependencies {
implementation("dev.sargunv.mobility-data:gbfs-v3:0.4.0")
implementation("io.ktor:ktor-client-cio:3.3.1") // or another engine
}
dependencies {
implementation("dev.sargunv.mobility-data:gbfs-v2:0.4.0")
implementation("io.ktor:ktor-client-cio:3.3.1") // or another engine
}
dependencies {
implementation("dev.sargunv.mobility-data:gbfs-v1:0.4.0")
implementation("io.ktor:ktor-client-cio:3.3.1") // or another engine
}
Example¶
GbfsV3Client().use { gbfs -> // (1)!
val service =
gbfs
.getServiceManifest( // (2)!
discoveryUrl = "https://locomotion.app/api/gbfs/3.0/montreal/gbfs"
)
.data
context(service) { // (3)!
val systemInfo = gbfs.getSystemInformation().data // (4)!
println("System: ${systemInfo.name["en-CA"]}")
println("Operator: ${systemInfo.operator?.get("en-CA")}")
println("Timezone: ${systemInfo.timezone}")
val vehicleTypes = gbfs.getVehicleTypes().data // (5)!
println("\nVehicle Types:")
vehicleTypes.forEach { type -> println(" - ${type.formFactor}: (${type.propulsionType})") }
val freeBikes = gbfs.getVehicleStatus().data // (6)!
println("\nAvailable bikes: ${freeBikes.size}")
freeBikes.take(3).forEach { bike ->
println(" - ${bike.vehicleId} at (${bike.lat}, ${bike.lon})")
}
}
}
- Create a GBFS client instance. The client implements
AutoCloseableso it can be used with.useto ensure proper cleanup. - Fetch the manifest (auto-discovery file) which contains URLs for all available feeds.
- Use a context parameter to specify the service to use for subsequent feed requests.
- Fetch system information including the system name, operator, and timezone.
- Fetch the list of available vehicle types with their form factors and propulsion types.
- Fetch real-time status of free-floating vehicles including their locations.
GbfsV2Client().use { gbfs -> // (1)!
val manifest =
gbfs
.getSystemManifest( // (2)!
discoveryUrl = "https://mds.bird.co/gbfs/v2/public/seattle-washington/gbfs.json"
)
.data
context(manifest.getService("en")) { // (3)!
val systemInfo = gbfs.getSystemInformation().data // (4)!
println("System: ${systemInfo.name}")
println("Operator: ${systemInfo.operator}")
println("Timezone: ${systemInfo.timezone}")
val vehicleTypes = gbfs.getVehicleTypes().data.vehicleTypes // (5)!
println("\nVehicle Types:")
vehicleTypes.forEach { type -> println(" - ${type.formFactor}: (${type.propulsionType})") }
val freeBikes = gbfs.getFreeBikeStatus().data.bikes // (6)!
println("\nAvailable bikes: ${freeBikes.size}")
freeBikes.take(3).forEach { bike ->
println(" - ${bike.bikeId} at (${bike.lat}, ${bike.lon})")
}
}
}
- Create a GBFS client instance. The client implements
AutoCloseableso it can be used with.useto ensure proper cleanup. - Fetch the manifest (auto-discovery file) which contains URLs for all available feeds in different languages.
- Use a context parameter to specify which language service to use for subsequent feed requests.
- Fetch system information including the system name, operator, and timezone.
- Fetch the list of available vehicle types with their form factors and propulsion types.
- Fetch real-time status of free-floating vehicles including their locations.
GbfsV1Client().use { gbfs -> // (1)!
val manifest =
gbfs
.getSystemManifest( // (2)!
discoveryUrl = "https://data.lime.bike/api/partners/v1/gbfs/seattle/gbfs.json"
)
.data
context(manifest.getService("en")) { // (3)!
val systemInfo = gbfs.getSystemInformation().data // (4)!
println("System: ${systemInfo.name}")
println("Operator: ${systemInfo.operator}")
println("Timezone: ${systemInfo.timezone}")
val stations = gbfs.getStationInformation().data // (5)!
println("\nStations: ${stations.size}")
stations.take(3).forEach { station ->
println(" - ${station.name} (${station.capacity} bikes)")
}
val freeBikes = gbfs.getFreeBikeStatus().data.bikes // (6)!
println("\nAvailable bikes: ${freeBikes.size}")
freeBikes.take(3).forEach { bike ->
println(" - ${bike.bikeId} at (${bike.lat}, ${bike.lon})")
}
}
}
- Create a GBFS client instance. The client implements
AutoCloseableso it can be used with.useto ensure proper cleanup. - Fetch the manifest (auto-discovery file) which contains URLs for all available feeds in different languages.
- Use a context parameter to specify which language service to use for subsequent feed requests.
- Fetch system information including the system name, operator, and timezone.
- Fetch the list of available stations with their names and capacities.
- Fetch real-time status of free-floating vehicles including their locations.
API Reference¶
For detailed API documentation, see the API Reference: