Skip to content

Commit

Permalink
Haichen/route networking2 (#22)
Browse files Browse the repository at this point in the history
* Added RouteOptions.kt

* Implemented [RouteAdapter]

* Implemented [getRouteOptions]

* Changed some naming

* Change query parameters for routeNetworking

* Changed some location to coordinate

* Fixed generic import call

* Create customDateAdapter

* Create customDateAdapter.

* networking fix

* added stop class

* Computed boardinMins

* Compute boardinMins

* Cleaned up networking code

* Moved [boardInMin] to [Route] and moved [serverFormat] out of a companion object

* Fixed a generic import call

* Moved some code into a helper function

* Added testing comments

* Removed an unnecessary comment

* Fixed mostly all comments, but I had questions about
  • Loading branch information
Haichen-Wang authored Dec 4, 2019
1 parent 2372e33 commit 22fbcff
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.example.ithaca_transit_android_v2
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.example.ithaca_transit_android_v2.networking.NetworkUtils
import com.example.ithaca_transit_android_v2.models.Coordinate
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
Expand All @@ -16,14 +16,36 @@ class MainActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

// ======== FOR TESTING ONLY ========
val end = Coordinate(42.444971674516864, -76.48098092526197)
// val uid = "E4A0256E-5865-4E9F-8A5A-33747CAC7EBF"
val time = 1574292741.0
val destinationName = "Bill & Melinda Gates Hall"
val start = Coordinate(42.44717985041025, -76.48551732274225)
val arriveBy = false

// TODO (lesley): just for testing purposes - replace with rxjava
runBlocking {
val deferred = CoroutineScope(Dispatchers.IO).async {
NetworkUtils().getAllBusStops()
NetworkUtils().getRouteOptions(start, end, time, arriveBy, destinationName)
}.await()

Log.d("testing-final", deferred.toString())
// Printing out [deferred] in log for testing
printLongLog(deferred.toString())
}
//
}
}

private fun printLongLog (s: String) {
val maxLogSize = 1000
val stringLength = s.length
if (stringLength != null) {
for (i in 0..stringLength / maxLogSize) {
val start = i * maxLogSize
var end = (i + 1) * maxLogSize
end = if (end > s.length) s.length else end
Log.v("returnBody", s.substring(start, end))
}
}
}
}

Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.example.ithaca_transit_android_v2.networking
package com.example.ithaca_transit_android_v2

import com.example.ithaca_transit_android_v2.LocationAdapter
import com.example.ithaca_transit_android_v2.models.Coordinate
import com.example.ithaca_transit_android_v2.models.Location
import com.example.ithaca_transit_android_v2.models.RouteOptions
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types.newParameterizedType
Expand Down Expand Up @@ -57,4 +58,41 @@ class NetworkUtils {
val adapter: JsonAdapter<List<Location>> = moshi.adapter(type)
return adapter.fromJson(body) ?: emptyList()
}

fun getRouteOptions(
start: Coordinate,
end: Coordinate,
time: Double,
arriveBy: Boolean = true,
destName : String
): RouteOptions {

val json = JSONObject()
json.put("start", start.toString())
json.put("end", end.toString())
json.put("time", time)
json.put("arriveBy", arriveBy)
json.put("destinationName", destName)

val requestBody = json.toString().toRequestBody(mediaType)
val request: Request = Request.Builder()
.url(url + "route")
.post(requestBody)
.build()

val body = client.newCall(request).execute().body?.string()
val response = JSONObject(body)
val arr = response.get("data")

val type = newParameterizedType(RouteOptions::class.java)
val moshi = Moshi.Builder()
.add(CustomDateAdapter())
.add(RouteAdapter())
.add(KotlinJsonAdapterFactory())
.build()

val adapter: JsonAdapter<RouteOptions> = moshi.adapter(type)

return adapter.fromJson(arr.toString()) ?: RouteOptions(emptyList(), emptyList(), emptyList())
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
package com.example.ithaca_transit_android_v2

import com.example.ithaca_transit_android_v2.models.Coordinate
import com.example.ithaca_transit_android_v2.models.Location
import com.example.ithaca_transit_android_v2.models.LocationType
import com.squareup.moshi.FromJson
import com.example.ithaca_transit_android_v2.models.*
import com.squareup.moshi.JsonClass
import com.squareup.moshi.FromJson
import com.squareup.moshi.ToJson
import com.squareup.moshi.Json
import com.squareup.moshi.JsonWriter
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Calendar
import java.util.Locale
import java.util.concurrent.TimeUnit

@JsonClass(generateAdapter = true)
class LocationAdapter {
class DataLocation(
val data: List<JsonLocation>
)

@JsonClass(generateAdapter = true)
class JsonLocation(
val type: LocationType,
Expand All @@ -21,18 +25,15 @@ class LocationAdapter {
val long: Double,
val detail: String?
)

@FromJson
private fun fromJson(json: DataLocation): List<Location> {
val finalLoc = json.data.map { loc ->
Location(loc.type, loc.name, Coordinate(loc.lat, loc.long), loc.detail)
}
return finalLoc
}

@ToJson
private fun toJson(json: List<Location>): DataLocation {

val final = json.map { loc ->
JsonLocation(
loc.type,
Expand All @@ -44,4 +45,34 @@ class LocationAdapter {
}
return DataLocation(final)
}
}
class RouteAdapter{
class JsonRoute(
val directions: List<Direction>,
val startCoords: Coordinate,
val endCoords: Coordinate,
@Json(name ="arrivalTime")
val arrival: Date,
@Json(name ="departureTime")
val depart: Date
)
@FromJson
private fun fromJson(json: JsonRoute): Route {
var firstBus = if (json.directions[0].type == DirectionType.BUS) 1 else 0
var boardInMins: Int = if (json.directions.size != 1) Route.computeBoardInMin(json.directions[firstBus]) else 0
return Route(json.directions, json.startCoords, json.endCoords, json.arrival, json.depart,
boardInMins)
}
}
class CustomDateAdapter{
private val serverFormat = ("yyyy-MM-dd'T'HH:mm:ss'Z'")
private val dateFormat = SimpleDateFormat(serverFormat, Locale.getDefault())
@FromJson
fun fromJson(date: String): Date {
return dateFormat.parse(date)
}
@ToJson
fun toJson(writer: JsonWriter, value: Date?) {
value?.let { writer.value(value.toString()) }
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package com.example.ithaca_transit_android_v2.models

import com.squareup.moshi.Json

//Coordinate.kt - Represents the longitude and latitude of a Location
data class Coordinate(
@Json(name = "lat")
val latitude: Double,
@Json(name = "long")
val longitude: Double
)
){
override fun toString(): String = "$latitude, $longitude"
}

Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package com.example.ithaca_transit_android_v2.models
import java.util.*
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date

@JsonClass(generateAdapter = true)
data class Direction(
val type : DirectionType,
@Json(name = "path")
val listOfCoordinates: List<Coordinate>,
val startTime: Date,
val endTime: Date,
val startLocation: Location,
val endLocation: Location,
val busStops: List<Location>,
val busNumber: Int
@Json(name = "startLocation")
val startCoords: Coordinate,
@Json(name = "endLocation")
val endCoords: Coordinate,
@Json(name = "stops")
val busStops: List<Stop>,
@Json(name = "routeNumber")
val busNumber: Int?
)
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.example.ithaca_transit_android_v2.models

import com.squareup.moshi.Json

/*
Represents the type of route that is displayed on the map
*/
enum class RouteType {
enum class DirectionType {
@Json(name = "depart")
BUS,
@Json(name = "walk")
WALK
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
package com.example.ithaca_transit_android_v2.models

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import java.util.Date
import java.util.Calendar
import java.util.concurrent.TimeUnit

// [Route] is a collection of [Direction] objects and other essential information
// to represent a way of getting to the destination
@JsonClass(generateAdapter = true)
data class Route (
val directions: List<Direction>,
val startLocation: Location,
val endLocation: Location,
val isWalkingOnly: Boolean,
val startCoords: Coordinate,
val endCoords: Coordinate,
@Json(name ="arrivalTime")
val arrival: Date,
@Json(name ="departureTime")
val depart: Date,
val boardInMin: Int
)
) {
companion object {
fun computeBoardInMin(firstBusDirection: Direction): Int {
val diff = firstBusDirection.startTime.time - Calendar.getInstance().time.time
return TimeUnit.MINUTES.convert(diff, TimeUnit.MILLISECONDS).toInt()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.example.ithaca_transit_android_v2.models

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass

/*
* [RouteOptions] is a collection of three groups of route objects
* (fromStop, walking and boardingSoon) for the RouteOptions view
*/
@JsonClass(generateAdapter = true)
data class RouteOptions (
val boardingSoon: List<Route>,
val fromStop: List<Route>,
val walking: List<Route>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.example.ithaca_transit_android_v2.models
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class Stop(
val stopID: String,
val lat: Double,
val long: Double
)

0 comments on commit 22fbcff

Please sign in to comment.