diff --git a/app/src/main/java/it/reyboz/bustorino/ActivityExperiments.java b/app/src/main/java/it/reyboz/bustorino/ActivityExperiments.java --- a/app/src/main/java/it/reyboz/bustorino/ActivityExperiments.java +++ b/app/src/main/java/it/reyboz/bustorino/ActivityExperiments.java @@ -46,8 +46,9 @@ LinesDetailFragment.Companion.makeArgs("gtt:56U")) .commit(); */ - .add(R.id.fragment_container_view, TestRealtimeGtfsFragment.class, null) + .add(R.id.fragment_container_view, LinesDetailFragment.class, + LinesDetailFragment.Companion.makeArgs("gtt:10U")) .commit(); } } } \ No newline at end of file diff --git a/app/src/main/java/it/reyboz/bustorino/backend/mato/MatoQueries.kt b/app/src/main/java/it/reyboz/bustorino/backend/mato/MatoQueries.kt --- a/app/src/main/java/it/reyboz/bustorino/backend/mato/MatoQueries.kt +++ b/app/src/main/java/it/reyboz/bustorino/backend/mato/MatoQueries.kt @@ -148,26 +148,26 @@ } """ const val TRIP_DETAILS=""" - query TripInfo(${'$'}field: String!){ - trip(id: ${'$'}field){ + query TripInfo(${'$'}field: String!){ + trip(id: ${'$'}field){ + gtfsId + serviceId + route{ gtfsId - serviceId - route{ - gtfsId - } - pattern{ - name - code - headsign - } - wheelchairAccessible - activeDates - tripShortName - tripHeadsign - bikesAllowed - semanticHash } + pattern{ + name + code + headsign + } + wheelchairAccessible + activeDates + tripShortName + tripHeadsign + bikesAllowed + semanticHash } + } """ fun getNameAndRequest(type: QueryType): Pair{ diff --git a/app/src/main/java/it/reyboz/bustorino/backend/mato/ResponseParsing.kt b/app/src/main/java/it/reyboz/bustorino/backend/mato/ResponseParsing.kt --- a/app/src/main/java/it/reyboz/bustorino/backend/mato/ResponseParsing.kt +++ b/app/src/main/java/it/reyboz/bustorino/backend/mato/ResponseParsing.kt @@ -21,6 +21,7 @@ import it.reyboz.bustorino.data.gtfs.* import org.json.JSONException import org.json.JSONObject +import kotlin.jvm.Throws /** * Class to hold the code for the parsing of responses from the Mato API, @@ -28,9 +29,9 @@ */ abstract class ResponseParsing{ - companion object{ + companion object { - final val DEBUG_TAG="BusTO:MatoResponseParse" + final val DEBUG_TAG = "BusTO:MatoResponseParse" fun parseAgencyJSON(jsonObject: JSONObject): GtfsAgency { return GtfsAgency( jsonObject.getString("gtfsId"), @@ -51,7 +52,7 @@ val feed = GtfsFeed(jsonObject.getString("feedId")) val oo = jsonObject.getJSONArray("agencies") agencies.ensureCapacity(oo.length()) - for (i in 0 until oo.length()){ + for (i in 0 until oo.length()) { val agObj = oo.getJSONObject(i) agencies.add( @@ -90,19 +91,19 @@ /** * Parse a route pattern from the JSON response of the MaTO server */ - fun parseRoutePatternsStopsJSON(jsonObject: JSONObject) : ArrayList{ + fun parseRoutePatternsStopsJSON(jsonObject: JSONObject): ArrayList { val routeGtfsId = jsonObject.getString("gtfsId") val patternsJSON = jsonObject.getJSONArray("patterns") val patternsOut = ArrayList(patternsJSON.length()) var mPatternJSON: JSONObject - for(i in 0 until patternsJSON.length()){ + for (i in 0 until patternsJSON.length()) { mPatternJSON = patternsJSON.getJSONObject(i) val stopsJSON = mPatternJSON.getJSONArray("stops") val stopsCodes = ArrayList(stopsJSON.length()) - for(k in 0 until stopsJSON.length()){ + for (k in 0 until stopsJSON.length()) { stopsCodes.add( stopsJSON.getJSONObject(k).getString("gtfsId") ) @@ -116,38 +117,30 @@ MatoPattern( mPatternJSON.getString("name"), mPatternJSON.getString("code"), mPatternJSON.getString("semanticHash"), mPatternJSON.getInt("directionId"), - routeGtfsId,mPatternJSON.getString("headsign"), polyline, numGeo, stopsCodes + routeGtfsId, mPatternJSON.getString("headsign"), polyline, numGeo, stopsCodes ) ) } return patternsOut } - fun parseTripInfo(jsonData: JSONObject): GtfsTrip?{ + @Throws(JSONException::class) + fun parseTripInfo(jsonData: JSONObject): GtfsTrip { + val jsonTrip = jsonData.getJSONObject("trip") - return try { - val jsonTrip = jsonData.getJSONObject("trip") + val routeId = jsonTrip.getJSONObject("route").getString("gtfsId") - val routeId = jsonTrip.getJSONObject("route").getString("gtfsId") - - val patternId =jsonTrip.getJSONObject("pattern").getString("code") - // still have "activeDates" which are the days in which the pattern is active - //Log.d("BusTO:RequestParsing", "Making GTFS trip for: $jsonData") - val trip = GtfsTrip( - routeId, jsonTrip.getString("serviceId"), jsonTrip.getString("gtfsId"), - jsonTrip.getString("tripHeadsign"), -1, "", "", - Converters.wheelchairFromString(jsonTrip.getString("wheelchairAccessible")), - false, patternId, jsonTrip.getString("semanticHash") - ) - trip - } catch (e: JSONException){ - Log.e(DEBUG_TAG, "Cannot parse json to make trip") - Log.e(DEBUG_TAG, "Json Data: $jsonData") - e.printStackTrace() - null - } + val patternId = jsonTrip.getJSONObject("pattern").getString("code") + // still have "activeDates" which are the days in which the pattern is active + //Log.d("BusTO:RequestParsing", "Making GTFS trip for: $jsonData") + val trip = GtfsTrip( + routeId, jsonTrip.getString("serviceId"), jsonTrip.getString("gtfsId"), + jsonTrip.getString("tripHeadsign"), -1, "", "", + Converters.wheelchairFromString(jsonTrip.getString("wheelchairAccessible")), + false, patternId, jsonTrip.getString("semanticHash") + ) + return trip } - } } \ No newline at end of file diff --git a/app/src/main/java/it/reyboz/bustorino/data/DBUpdateWorker.java b/app/src/main/java/it/reyboz/bustorino/data/DBUpdateWorker.java --- a/app/src/main/java/it/reyboz/bustorino/data/DBUpdateWorker.java +++ b/app/src/main/java/it/reyboz/bustorino/data/DBUpdateWorker.java @@ -42,6 +42,7 @@ public static final int ERROR_FETCHING_VERSION = 4; public static final int ERROR_DOWNLOADING_STOPS = 5; public static final int ERROR_DOWNLOADING_LINES = 6; + public static final int ERROR_CODE_DB_CLOSED=-2; public static final String SUCCESS_REASON_KEY = "SUCCESS_REASON"; public static final int SUCCESS_NO_ACTION_NEEDED = 9; @@ -132,6 +133,9 @@ case ERROR_LINES_DOWNLOAD: dataBuilder.put(ERROR_REASON_KEY, ERROR_DOWNLOADING_LINES); break; + case DB_CLOSED: + dataBuilder.put(ERROR_REASON_KEY, ERROR_CODE_DB_CLOSED); + break; } cancelNotification(notification_ID); return ListenableWorker.Result.failure(dataBuilder.build()); diff --git a/app/src/main/java/it/reyboz/bustorino/data/DatabaseUpdate.java b/app/src/main/java/it/reyboz/bustorino/data/DatabaseUpdate.java --- a/app/src/main/java/it/reyboz/bustorino/data/DatabaseUpdate.java +++ b/app/src/main/java/it/reyboz/bustorino/data/DatabaseUpdate.java @@ -63,7 +63,7 @@ enum Result { - DONE, ERROR_STOPS_DOWNLOAD, ERROR_LINES_DOWNLOAD + DONE, ERROR_STOPS_DOWNLOAD, ERROR_LINES_DOWNLOAD, DB_CLOSED } /** @@ -163,18 +163,6 @@ */ public static Result performDBUpdate(Context con, AtomicReference gres) { - final FiveTAPIFetcher f = new FiveTAPIFetcher(); - - final NextGenDB dbHelp = NextGenDB.getInstance(con.getApplicationContext()); - final SQLiteDatabase db = dbHelp.getWritableDatabase(); - - final List palinasMatoAPI = MatoAPIFetcher.Companion.getAllStopsGTT(con, gres); - if (gres.get() != Fetcher.Result.OK) { - Log.w(DEBUG_TAG, "Something went wrong downloading"); - return DatabaseUpdate.Result.ERROR_STOPS_DOWNLOAD; - - } - // GTFS data fetching AtomicReference gtfsRes = new AtomicReference<>(Fetcher.Result.OK); updateGTFSAgencies(con, gtfsRes); @@ -190,7 +178,6 @@ } else{ Log.d(DEBUG_TAG, "Done downloading routes from MaTO"); } - /*db.beginTransaction(); startTime = System.currentTimeMillis(); int countStop = NextGenDB.writeLinesStoppingHere(db, routesStoppingByStop); @@ -203,8 +190,24 @@ endTime = System.currentTimeMillis(); Log.d(DEBUG_TAG, "Updating lines took "+(endTime-startTime)+" ms"); */ + // Stops insertion + final List palinasMatoAPI = MatoAPIFetcher.Companion.getAllStopsGTT(con, gres); + if (gres.get() != Fetcher.Result.OK) { + Log.w(DEBUG_TAG, "Something went wrong downloading stops"); + return DatabaseUpdate.Result.ERROR_STOPS_DOWNLOAD; + + } + final NextGenDB dbHelp = NextGenDB.getInstance(con.getApplicationContext()); + final SQLiteDatabase db = dbHelp.getWritableDatabase(); + + if(!db.isOpen()){ + //catch errors like: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase + //we have to abort the work and restart it + return Result.DB_CLOSED; + } //TODO: Get the type of stop from the lines //Empty the needed tables + db.beginTransaction(); //db.execSQL("DELETE FROM "+StopsTable.TABLE_NAME); //db.delete(LinesTable.TABLE_NAME,null,null); @@ -246,6 +249,7 @@ long endTime = System.currentTimeMillis(); Log.d(DEBUG_TAG, "Inserting stops took: " + ((double) (endTime - startTime) / 1000) + " s"); Log.d(DEBUG_TAG, "\t"+patternsStopsHits+" routes string were built from the patterns"); + db.close(); dbHelp.close(); return DatabaseUpdate.Result.DONE; diff --git a/app/src/main/java/it/reyboz/bustorino/data/MatoDownloadTripsWorker.kt b/app/src/main/java/it/reyboz/bustorino/data/MatoDownloadTripsWorker.kt --- a/app/src/main/java/it/reyboz/bustorino/data/MatoDownloadTripsWorker.kt +++ b/app/src/main/java/it/reyboz/bustorino/data/MatoDownloadTripsWorker.kt @@ -63,13 +63,17 @@ for(trip in tripsList){ queriedMatoTrips.add(trip) matoRepository.requestTripUpdate(trip,{error-> - Log.e(DEBUG_TAG, "Cannot download Gtfs Trip") - error.printStackTrace() + Log.e(DEBUG_TAG, "Cannot download Gtfs Trip $trip") + val stacktrace = error.stackTrace.take(5) + Log.w(DEBUG_TAG, "Stacktrace:\n$stacktrace") failedMatoTripsDownload.add(trip) requestCountDown.countDown() }){ if(it.isSuccess){ + if (it.result == null){ + Log.e(DEBUG_TAG, "Got null result"); + } downloadedMatoTrips.add(it.result!!) } else{ failedMatoTripsDownload.add(trip) diff --git a/app/src/main/java/it/reyboz/bustorino/data/MatoRepository.kt b/app/src/main/java/it/reyboz/bustorino/data/MatoRepository.kt --- a/app/src/main/java/it/reyboz/bustorino/data/MatoRepository.kt +++ b/app/src/main/java/it/reyboz/bustorino/data/MatoRepository.kt @@ -38,7 +38,8 @@ netVolleyManager.addToRequestQueue(MatoVolleyJSONRequest( MatoQueries.QueryType.TRIP,params,{ try { - val result = Result.success(ResponseParsing.parseTripInfo(it)) + val trip: GtfsTrip = ResponseParsing.parseTripInfo(it) + val result = Result.success(trip) callback.onResultAvailable(result) } catch (e: JSONException){ // this might happen when the json is "{'data': {'trip': None}}" diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt --- a/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt +++ b/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt @@ -15,8 +15,10 @@ import it.reyboz.bustorino.backend.gtfs.PolylineParser import it.reyboz.bustorino.data.gtfs.MatoPatternWithStops import it.reyboz.bustorino.data.gtfs.PatternStop +import org.osmdroid.tileprovider.tilesource.OnlineTileSourceBase import org.osmdroid.tileprovider.tilesource.TileSourceFactory import org.osmdroid.util.GeoPoint +import org.osmdroid.util.MapTileIndex import org.osmdroid.views.MapView import org.osmdroid.views.overlay.Polyline @@ -39,6 +41,7 @@ private lateinit var viewModel: LinesViewModel private var polyline = Polyline(); + private var stopPosList = ArrayList() companion object { private const val LINEID_KEY="lineID" @@ -67,18 +70,44 @@ patternsSpinner.adapter = patternsAdapter map = rootView.findViewById(R.id.lineMap) + val USGS_SAT: OnlineTileSourceBase = object : OnlineTileSourceBase( + "USGS National Map Sat", + 0, + 15, + 256, + "", + arrayOf("https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryTopo/MapServer/tile/"), + "USGS" + ) { + override fun getTileURLString(pMapTileIndex: Long): String { + return baseUrl + MapTileIndex.getZoom(pMapTileIndex) + "/" + MapTileIndex.getY(pMapTileIndex) + "/" + MapTileIndex.getX( + pMapTileIndex + ) + } + } map.setTileSource(TileSourceFactory.MAPNIK) + /* + object : OnlineTileSourceBase("USGS Topo", 0, 18, 256, "", + arrayOf("https://basemap.nationalmap.gov/ArcGIS/rest/services/USGSTopo/MapServer/tile/" )) { + override fun getTileURLString(pMapTileIndex: Long) : String{ + return baseUrl + + MapTileIndex.getZoom(pMapTileIndex)+"/" + MapTileIndex.getY(pMapTileIndex) + + "/" + MapTileIndex.getX(pMapTileIndex)+ mImageFilenameEnding; + } + } + */ //map.setTilesScaledToDpi(true); //map.setTilesScaledToDpi(true); map.setFlingEnabled(true) + map.setUseDataConnection(true) // add ability to zoom with 2 fingers map.setMultiTouchControls(true) - map.minZoomLevel = 14.0 + map.minZoomLevel = 10.0 //map controller setup val mapController = map.controller - mapController.setZoom(14.0) + mapController.setZoom(12.0) mapController.setCenter(GeoPoint(DEFAULT_CENTER_LAT, DEFAULT_CENTER_LON)) map.invalidate() @@ -98,6 +127,7 @@ val pointsList = PolylineParser.decodePolyline(pattern.patternGeometryPoly, pattern.patternGeometryLength) //val polyLine=Polyline(map) //polyLine.setPoints(pointsList) + //save points if(map.overlayManager.contains(polyline)){ map.overlayManager.remove(polyline) } @@ -105,7 +135,8 @@ polyline.setPoints(pointsList) map.overlayManager.add(polyline) - //map.controller.animateTo(pointsList[0]) + map.controller.animateTo(pointsList[0]) + map.invalidate() } viewModel.setRouteIDQuery(lineID) diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/MapFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/MapFragment.java --- a/app/src/main/java/it/reyboz/bustorino/fragments/MapFragment.java +++ b/app/src/main/java/it/reyboz/bustorino/fragments/MapFragment.java @@ -590,6 +590,7 @@ private void updateBusPositionsInMap(HashMap> tripsPatterns){ Log.d(DEBUG_TAG, "Updating positions of the buses"); //if(busPositionsOverlay == null) busPositionsOverlay = new FolderOverlay(); + final ArrayList noPatternsTrips = new ArrayList<>(); for(String tripID: tripsPatterns.keySet()) { final Pair pair = tripsPatterns.get(tripID); if (pair == null) continue; @@ -634,7 +635,7 @@ //mdraw.setBounds(0,0,28,28); marker.setIcon(mdraw); if(tripWithPatternStops == null){ - Log.d(DEBUG_TAG, "Trip "+tripID+" has no pattern"); + noPatternsTrips.add(tripID); } marker.setInfoWindow(new BusInfoWindow(map, update, tripWithPatternStops != null ? tripWithPatternStops.getPattern() : null, new BusInfoWindow.onTouchUp() { @Override @@ -655,6 +656,9 @@ } } + if(noPatternsTrips.size()>0){ + Log.i(DEBUG_TAG, "These trips have no matching pattern: "+noPatternsTrips); + } } /**