MM2-0 / Kvaesitso

A search-focused Android launcher
https://kvaesitso.mm20.de/
GNU General Public License v3.0
2.39k stars 74 forks source link

[Feature proposal] Integrate public transport departure times for respective `Location` search results #760

Open Sir-Photch opened 5 months ago

Sir-Photch commented 5 months ago

Now that the OSM search provider is merged, my next idea is to integrate departure times for public transport search results.

To be specific, I picture the use case to be: I search for a bus stop in my area / have one marked as my favorite and can see live departure times for the next 3 (arbitrary number) connections stopping at that station, in the same LocationItem view.

Especially for local transport (not inter-regional, but subways, streetcars and busses in cities) I picture this to be pretty handy, since looking up when the next bus for your daily commute comes might allow you (or me, because I am the proposer, hehe) to stay in bed just a little longer :)

There just happens to exist a java library that wraps all the different available APIs of public transport providers: schildbach/public-transport-enabler. The issue there is that this would require juggling of more API keys, if the APIs that are to be supported require one. (Some need keys, others don't. I have yet to find out which.)

Regarding how this could be integrated into the codebase, I see two (three) possibilities from the top of my head:

  1. Add another module, just as OSM, that implements SearchableRepository<PublicTransportStop>. This would probably integrate easiest in a sense of minimal code change, but causes search strings to be passed to (possibly) closed APIs (privacy issue), and would need matching of Locations and PublicTransportStops afterwards, if both are to be displayed in the same view.
  2. A different module. But in SearchService, only pass search results as queries to this module that are bus-, subway-, streetcar stops and were returned by a SearchableRepository<Location>. This would allow to reuse a PublicTransport module between different implementations of SearchableRepository<Location>. Downside here is that stops would have to be found by the SearchableRepository<Location> first. Where I am from, OSM is pretty complete in cities, but this might not apply to other parts of the world. Otherwise, we'd need a seperate PublicTransportStopItem view, which seems unnecessary to me.

Variant two would work nicely if there will ever be something like a google-maps search plugin. (Or any other search provider, for that matter.) But AFAIK, google maps have their own public transport information? Not sure though if they expose that via their APIs; After all, I'm more the OSM type of guy anyway. If other location search providers come with their own information, we could also:

  1. Add PublicTransportEnabler as a submodule of the OSM repository, so code further up the chain only sees the Location interface and may check something like if (loc is PublicTransportStop) ... given that PublicTransportStop may be another interface that implements Location.

If this sounds like an appropriate addition, I can give this a shot. I am open for suggestions though, of course :)

MM2-0 commented 5 months ago

Given that there countless different public transport service providers, and all of them have their own API, I think this would be a good candidate for a plugin style implementation:

Then we can implement different providers in different plugins, and we don't need to include additional API keys in the app itself (which is always troublesome because they aren't available in the F-Droid build).

However, the plugin SDK currently doesn't support deferred searchables so we need to add support for that as well (maybe add a StorageStrategy.Deferred storage strategy?) – added in 2efc1597

Sir-Photch commented 5 months ago

Given that there countless different public transport service providers, and all of them have their own API, I think this would be a good candidate for a plugin style implementation

Hrm, for APIs that require a key yes, but why not include those that don't in the launcher directly?

And even then, the only difference between plugins that require an API key is the key itself and the instantiation of the provider, since then it's interface can be used: NetworkProvider.java

MM2-0 commented 5 months ago

Hrm, for APIs that require a key yes, but why not include those that don't in the launcher directly?

Because it's one more thing that needs maintaining and I don't want to turn this into an everything app. Plugins are a bit more independent in that regard.