transitland-datastore icon indicating copy to clipboard operation
transitland-datastore copied to clipboard

Stops search via lat, lng, range returns an unsorted array

Open denysvitali opened this issue 6 years ago • 2 comments

Problem description

Using the /api/v1/stops endpoint with a latitude, longitude and a range results in an unsorted array. This means that the first item of the array isn't guaranteed to be the closest one.

Take for example the following request: http://transit.land/api/v1/stops?lat=45.485188&lon=9.202954&r=100

Which basically asks for stops within 100 meters of 45.485188, 9.202954.
The query returns a (randomly?) sorted result, with the following distances (calculated with this method)

Current result

In our application, running our test function without sortStops (aka client side sorting) results:

s-u0ndc2jphn-stazionecentralepzaducadaostam2m3 is 61.503709069580765 meters away
s-u0ndc2jnh6-centralefs is 83.20704925537221 meters away
s-u0ndc2jqcq-stazionecentralepzaducadaostam2m3 is 66.50666845595956 meters away
s-u0ndc2m6km-milanocentrale is 0.0 meters away

Original JSON response from server:

{"stops":[{"geometry":{"type":"Point","coordinates":[9.20259573380986,45.4846348838559]},"onestop_id":"s-u0ndc2jphn-stazionecentralepzaducadaostam2m3","created_at":"2016-08-16T22:56:53.508Z","updated_at":"2018-02-27T11:03:20.792Z","tags":{"osm_way_id":"267397287","wheelchair_boarding":"1"},"created_or_updated_in_changeset_id":10031,"name":"stazione centrale p.za duca d'aosta m2 m3","timezone":"Europe/Rome","osm_way_id":267397287,"served_by_vehicle_types":["tram"],"parent_stop_onestop_id":null,"wheelchair_boarding":true,"geometry_reversegeo":null,"geometry_centroid":{"type":"Point","coordinates":[9.20259573380986,45.4846348838559]},"operators_serving_stop":[{"operator_name":"Azienda Trasporti Milanesi","operator_onestop_id":"o-u0nd-comunedimilano"}],"routes_serving_stop":[{"operator_name":"Azienda Trasporti Milanesi","operator_onestop_id":"o-u0nd-comunedimilano","route_name":"5","route_onestop_id":"r-u0ndc-5"}]},{"geometry":{"type":"Point","coordinates":[9.20261280787934,45.4844397010284]},"onestop_id":"s-u0ndc2jnh6-centralefs","created_at":"2016-08-16T22:57:06.498Z","updated_at":"2018-02-27T11:33:13.552Z","tags":{"osm_way_id":"206753480","wheelchair_boarding":"1"},"created_or_updated_in_changeset_id":10031,"name":"CENTRALE FS","timezone":"Europe/Rome","osm_way_id":206753480,"served_by_vehicle_types":["metro"],"parent_stop_onestop_id":null,"wheelchair_boarding":true,"geometry_reversegeo":null,"geometry_centroid":{"type":"Point","coordinates":[9.20261280787934,45.4844397010284]},"operators_serving_stop":[{"operator_name":"Azienda Trasporti Milanesi","operator_onestop_id":"o-u0nd-comunedimilano"}],"routes_serving_stop":[{"operator_name":"Azienda Trasporti Milanesi","operator_onestop_id":"o-u0nd-comunedimilano","route_name":"3","route_onestop_id":"r-u0nd-3"},{"operator_name":"Azienda Trasporti Milanesi","operator_onestop_id":"o-u0nd-comunedimilano","route_name":"2","route_onestop_id":"r-u0nd-2"}]},{"geometry":{"type":"Point","coordinates":[9.20282175182639,45.4845898911612]},"onestop_id":"s-u0ndc2jqcq-stazionecentralepzaducadaostam2m3","created_at":"2016-11-28T21:04:48.125Z","updated_at":"2018-02-27T11:16:39.022Z","tags":{"osm_way_id":"206753480","wheelchair_boarding":"2"},"created_or_updated_in_changeset_id":10031,"name":"stazione centrale p.za duca d'aosta m2 m3","timezone":"Europe/Rome","osm_way_id":206753480,"served_by_vehicle_types":["bus"],"parent_stop_onestop_id":null,"wheelchair_boarding":false,"geometry_reversegeo":null,"geometry_centroid":{"type":"Point","coordinates":[9.20282175182639,45.4845898911612]},"operators_serving_stop":[{"operator_name":"Azienda Trasporti Milanesi","operator_onestop_id":"o-u0nd-comunedimilano"}],"routes_serving_stop":[{"operator_name":"Azienda Trasporti Milanesi","operator_onestop_id":"o-u0nd-comunedimilano","route_name":"N6","route_onestop_id":"r-u0nd9-n6"},{"operator_name":"Azienda Trasporti Milanesi","operator_onestop_id":"o-u0nd-comunedimilano","route_name":"NM3","route_onestop_id":"r-u0nd-nm3"},{"operator_name":"Azienda Trasporti Milanesi","operator_onestop_id":"o-u0nd-comunedimilano","route_name":"81","route_onestop_id":"r-u0ndc-81"},{"operator_name":"Azienda Trasporti Milanesi","operator_onestop_id":"o-u0nd-comunedimilano","route_name":"60","route_onestop_id":"r-u0nd9-60"}]},{"geometry":{"type":"Point","coordinates":[9.202954,45.485188]},"onestop_id":"s-u0ndc2m6km-milanocentrale","created_at":"2016-12-12T02:56:31.489Z","updated_at":"2018-02-27T11:38:31.182Z","tags":{"osm_way_id":"314291413"},"created_or_updated_in_changeset_id":10036,"name":"MILANO CENTRALE","timezone":"Europe/Rome","osm_way_id":314291413,"served_by_vehicle_types":["rail"],"parent_stop_onestop_id":null,"wheelchair_boarding":null,"geometry_reversegeo":null,"geometry_centroid":{"type":"Point","coordinates":[9.202954,45.485188]},"operators_serving_stop":[{"operator_name":"Trenord","operator_onestop_id":"o-u0n-trenord"}],"routes_serving_stop":[{"operator_name":"Trenord","operator_onestop_id":"o-u0n-trenord","route_name":"XP2","route_onestop_id":"r-u0n7-xp2"},{"operator_name":"Trenord","operator_onestop_id":"o-u0n-trenord","route_name":"S8","route_onestop_id":"r-u0ne-s8"},{"operator_name":"Trenord","operator_onestop_id":"o-u0n-trenord","route_name":"S11","route_onestop_id":"r-u0ne-s11"},{"operator_name":"Trenord","operator_onestop_id":"o-u0n-trenord","route_name":"RE_8","route_onestop_id":"r-u0n-re8"},{"operator_name":"Trenord","operator_onestop_id":"o-u0n-trenord","route_name":"RE_6","route_onestop_id":"r-u0p-re6"},{"operator_name":"Trenord","operator_onestop_id":"o-u0n-trenord","route_name":"RE_4","route_onestop_id":"r-u0n-re4"},{"operator_name":"Trenord","operator_onestop_id":"o-u0n-trenord","route_name":"RE_2","route_onestop_id":"r-u0ne-re2"},{"operator_name":"Trenord","operator_onestop_id":"o-u0n-trenord","route_name":"RE_13","route_onestop_id":"r-u0n-re13"},{"operator_name":"Trenord","operator_onestop_id":"o-u0n-trenord","route_name":"RE_11","route_onestop_id":"r-u0p-re11"},{"operator_name":"Trenord","operator_onestop_id":"o-u0n-trenord","route_name":"RE_10","route_onestop_id":"r-u0ne-re10"},{"operator_name":"Trenord","operator_onestop_id":"o-u0n-trenord","route_name":"R4","route_onestop_id":"r-u0n-r4"},{"operator_name":"Trenord","operator_onestop_id":"o-u0n-trenord","route_name":"R38","route_onestop_id":"r-u0n-r38"},{"operator_name":"Trenord","operator_onestop_id":"o-u0n-trenord","route_name":"R28","route_onestop_id":"r-u0n7-r28"}]}],"meta":{"sort_key":"id","sort_order":"asc","per_page":50,"offset":0}}

Expected result

A sorted array such as the items are ordered as following:

s-u0ndc2m6km-milanocentrale is 0.0 meters away
s-u0ndc2jphn-stazionecentralepzaducadaostam2m3 is 61.503709069580765 meters away
s-u0ndc2jqcq-stazionecentralepzaducadaostam2m3 is 66.50666845595956 meters away
s-u0ndc2jnh6-centralefs is 83.20704925537221 meters away

which in our case we get it with a sort function after the API call (reference)

Maybe related

#1077

denysvitali avatar Mar 18 '18 23:03 denysvitali

Hi @denysvitali

You are correct; the default ordering is based on the internal stop id. In the geometry query, I am applying an ordering by distance, but I mistakingly allow this to be overridden by the pagination methods. I'll add this as a feature request.

irees avatar May 22 '18 19:05 irees

Perfect! Thank you!

On an unrelated note, can you please check the SBB (Switzerland) feed? Currently the 2017 (outdated) is being used, and I can't submit the new one (https://opentransportdata.swiss/en/dataset/timetable-2018-gtfs/permalink) because I'm not authorized.

Related issue is https://github.com/transitland/transitland/issues/296 , this problem has led us to create a parallel GTFS-server written in Rust just to handle swiss requests.

denysvitali avatar May 22 '18 22:05 denysvitali