MODE Integration Guide for Third-Party Services

Since MODE is a distributed system with multiple components, it can (or must) be implemented at various levels, mostly in the frontend (Android, iOS apps) and the backend (server) which processes the trips.

Frontend

The MODE smartphone libraries (libmode for Android and iOS) must be integrated in a host app which takes care about user authentication, and starting/stopping the MODE service. While MODE can run continuously in the background, it can adversely affect battery consumption (especially on iOS devices). It should therefore only be started when the user agrees to track a trip.

When MODE is running, it will detect when activities start or end (e.g. due to GPS signals, or when it detects, that the phone is not moving anymore). Once an activity end, the binary data of the trip is sent to a REST server in the background, which does the processing.

Backend

The backend is provided as a Docker image which opens the rest service on port 8080. Its sole purpose is to listen to the binary data from the frontend, process the data, and return JSON output of trips.

If advanced logic is needed, like storing the returned trips in a database, this must be done by some kind of middleware which details are yet to be determined, depending on the concrete use cases of MODE within the project.

Testing

Testing the setup with real data can be cumbersome, as someone would need to walk/drive around to see the data pushed from the frontend to the backend. Therefore we provide some sample data which can be sent to the backend to be processed using a simple test script. Note that the backend server requires an API key which must be changed in the test script and is provided on demand.

Output

If the front end and backend works correctly, the backend will spit out the resulting trips as a JSON file:

{
    "message": "success",
    "activities": [
        {
            "begin": "2020-07-15T13:20:41.059Z",
            "end": "2020-07-15T13:45:37.059Z",
            "mode": "WALK",
            "modeDetails": " | Sensor mode Walk | GPSQuality(AVERAGE : time gap)",
            "distanceMeters": 1253.2470899042082,
            "route": "ue`eHkddcB??????????rCrAj@Vj@Vh@Th@Vp@Xj@Xp@Xh@Tl@Vl@XJDp@Xn@Xp@Vp@XJDl@Tn@Rp@RRB@@D@?@?@???@???@@????????@???A?????????????????????????????????@????????????????????????Nh@??@E??@??@@B@B@B@@ACAAAC?AM]EICGCE?A???@?@BFBH@DP`A@F?D???B????A@A???EA??A??A????A@??????A????AA????CAI@??A@????A????????@?????B@B?D?B?F@D?B?H@H?F?D@B?@?@????C?CAC?CAGAGCG?CAA?AAA@??ABABCBABAB?@?@?BBBBD@D@F?DCDCBCBEBEBC@EBEBC@EBEBC@EBC@CBCBCBCBCBEBC@EBE@C@C@ABCBCBEBCBE@E@G@G@EBEBEBGBEBG@GBG@G?G?E?ECCEAEAEAECEECECEEECEECECCCCECCECCACACAEACAECECEEECEECCEEECECECECECEEECECECEAECEAECGCGCEEECE?C@CBE@C?CCECC?E?CBCFADCFCDABC@A@A?@A????A?A??@A???@A??@A??????@??A?@@?@??????A?A?AA???????????A?@???????@??@???@A??@?A???A@A?A??????@A??A??@A@???@???@?B????@??A?AA????A?????????A???@?????@?@?@?@?@A??@??????A???@@?A?A???????????A???A?A??????????@??@???A??@A???A@?A??@?@A@?@?@????@????A?????A?A?A?????A??????A????DA??????A??@????A???@??@?????@??A?????????@??????A?????CAAA?AAAA@???@A?????????@@@@?@????@@???????????????A?????????A???AA????????A?????A???@@@??@A?????A?@?????@??A?A@A@A@????@I@????B?@?A@??@?@ABCBA@A???"
        },
        {
            "begin": "2020-07-15T13:45:38.059Z",
            "end": "2020-07-15T13:51:20.059Z",
            "mode": "BUS",
            "modeDetails": "Line 69A (Hauptbahnhof - Simmering) (BUS) from Am Kanal to Arsenalsteg | Sensor mode Bus routed to Bus | GPSQuality(GOOD)",
            "distanceMeters": 2143.843162687046,
            "route": "ch_eHk_dcB????yA`ByAxA??gBbB??}AlA??{BrA??cBp@uBn@??cBZ??s@`C????????????????????AnD??ElC??EjCGlC??EtB??EtBGtB??IxD??KpC????????????????????A`D??IdE????c@xC??_AlB??CzC??m@lC??_AbB????????????qA`C????wBxD??_BfC??wAzB????}A~B????????????????iAbB??gAdB??gB`C??q@~@s@~@s@~@KW"
        },
        {
            "begin": "2020-07-15T13:51:29.059Z",
            "end": "2020-07-15T14:32:45.059Z",
            "mode": "WALK",
            "modeDetails": " | Sensor mode Walk | GPSQuality(BAD : large time gap)",
            "distanceMeters": 1435.4269300101091,
            "route": "mhaeHq{_cBE^@?AAACEAEAE?E?C?CACCCAC?E?CACCAG?CBEBABA@CBCBAB?@D?@?BCFA@C@CBAB?B@B@@@A@C@C@A@@@B?DABAB?B?@@@??@?BABA@?@?@B?D?D@D@F@D@D@F@F@D@FBD@F@FBH@FBHBFBFBFBHBF@HBF@DBF@FBDBDBDBFBD@FBD@D?B?@???????A??????????????@@?B@DBDBF@DBFBDBFBD@FBDBFBFBDBDBDBFBDBFBFBDBFBD@F@FBFBDB@DAD?DAB@D@B@@@A@CBC@CB?BDBFBF@FBD@BDBB@F@F@H?H@H@H@HBHBF@DBF@DBFBBDDDBDBDBDDBDBFBDDFBD@FBFBD@FBFBDBFBDDDDFDFBDDDBDBDBBBBBDBBBBD@B@DABABEBCBCBE@G@G@G@GBE@EBG@E?G@G?E@G?E@GBE@IBGBGDGBGBEBG@E@E@G@E@G@G@G@E@G@G?E@G?G@EBEBEBEBAD?D@FBDBBDDD@F@B@D?D@B?B@B@B??DJ?@@@?@B@LLDBFB@@@?@@@???@@@?@@@???@@@???@@@?@?@@??@@@?@?@@??@?@@@@DBB@NZ?@?@@@?@@??@?@?@@??@??@B??????????????AA???????A????EM??AC????AC?A???A????CG?AAC????????CI?AAA?A???????A??A????A??AE?????AA????A?????AAA?AAC?????A??????AAAE???A????M_@AACEAA??A??AAA??AAA?AA??MKAACCCACCECCCCACCEECCEAE?E@EDEDEFCDAHCHAHAHAH?FAF?DADCBADADAF?FAHAFAFAFAF?H?FAF?FAFCFCDCFCDCDCDEDCBEDCBCDAFCF?FAF@F?FAD?DADAFADCBADCDCDCDAFCDAFADAFCDCDCDCBADADADCDADCDADCFAH?HAF?HAF?F?H?F@FAD?FCFADAHAFAFAFAHAFADCFAF?D?F?D?D?FADADAFAFCFCHAFCFCHCDCFCDEBEDEBEDC@E?EACCEECACCCACCCCCCACCCCCCECCACCCACACA@A@A@?@?@?@?@?????????A??A?A?A?A?@@@?????????@?????@A@ABU??EH?@A@?@ABEJ?@ABA@CHW|@K^ADAH?@?????C?????A???@?????A?E?A?C?????J?@????A?@????????@???A????????????"
        }
    ]
}

The format uses the encoded polyline algorithm for encoding the polylines of the trips (sample code). We will, however, for the project also try to output GeoJSON files directly, which might be easier to consume.

Support and Contact

Important Notes

  • You might get an API key for third-party routing services (e.g. Google Router). Make sure to keep that confident and only use it for testing and sparsingly. Overuse of the API key may result in high fees, as only about 20.000 requests/per month are free!

For production, we must use a different key being used for billing!