[gnome-maps/wip/mlundblad/transit-routing: 5/5] WIP: Hook up a new toggle button for transit mode routing



commit 7dc0c6157b1fbf84d71fd8b6209b2712411209d2
Author: Marcus Lundblad <ml update uu se>
Date:   Mon Feb 15 23:19:09 2016 +0100

    WIP: Hook up a new toggle button for transit mode routing
    
    Currently queries the OTP instance (running locally) and dumps the transit
    plans received.

 data/ui/sidebar.ui     |   22 ++++++++++
 src/application.js     |    6 +++
 src/contextMenu.js     |    8 ++--
 src/mainWindow.js      |    4 +-
 src/mapBubble.js       |    2 +-
 src/mapView.js         |    8 ++--
 src/printLayout.js     |    2 +-
 src/routeQuery.js      |    5 ++-
 src/routeService.js    |   32 ++++++++------
 src/sidebar.js         |  107 ++++++++++++++++++++++++++++++++++-------------
 src/turnPointMarker.js |    2 +-
 11 files changed, 140 insertions(+), 58 deletions(-)
---
diff --git a/data/ui/sidebar.ui b/data/ui/sidebar.ui
index 77347ed..9021d5c 100644
--- a/data/ui/sidebar.ui
+++ b/data/ui/sidebar.ui
@@ -94,6 +94,28 @@
                 </style>
               </object>
             </child>
+            <child>
+              <object class="GtkRadioButton" id="modeTransitToggle">
+                <property name="name">mode-transit-toggle</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="draw_indicator">False</property>
+                <property name="group">modeBikeToggle</property>
+                <property name="height-request">32</property>
+                <property name="width-request">42</property>
+                <child>
+                  <object class="GtkImage" id="mode-transit-image">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon-name">route-transit-symbolic</property>
+                  </object>
+                </child>
+                <style>
+                  <class name="transportation-mode-button"/>
+                </style>
+              </object>
+            </child>
             <style>
               <class name="linked"/>
             </style>
diff --git a/src/application.js b/src/application.js
index 5a452ee..e23ac9a 100644
--- a/src/application.js
+++ b/src/application.js
@@ -36,10 +36,12 @@ const GeocodeService = imports.geocodeService;
 const MainWindow = imports.mainWindow;
 const Maps = imports.gi.GnomeMaps;
 const NotificationManager = imports.notificationManager;
+const OpenTripPlanner = imports.openTripPlanner;
 const OSMEdit = imports.osmEdit;
 const OSMTypeSearchEntry = imports.osmTypeSearchEntry;
 const PlaceStore = imports.placeStore;
 const RouteService = imports.routeService;
+const RouteQuery = imports.routeQuery;
 const Settings = imports.settings;
 const Utils = imports.utils;
 
@@ -54,8 +56,10 @@ let geocodeService = null;
 let networkMonitor = null;
 let checkInManager = null;
 let contactStore = null;
+let openTripPlanner = null;
 let osmEdit = null;
 let normalStartup = true;
+let routeQuery = null;
 
 const _ensuredTypes = [WebKit2.WebView,
                        OSMTypeSearchEntry.OSMTypeSearchEntry];
@@ -244,6 +248,7 @@ const Application = new Lang.Class({
 
     _initServices: function() {
         settings       = Settings.getSettings('org.gnome.Maps');
+        routeQuery     = new RouteQuery.RouteQuery();
         routeService   = new RouteService.GraphHopper();
         geoclue        = new Geoclue.Geoclue();
         geocodeService = new GeocodeService.GeocodeService();
@@ -254,6 +259,7 @@ const Application = new Lang.Class({
         contactStore = new Maps.ContactStore();
         contactStore.load();
         osmEdit = new OSMEdit.OSMEdit();
+        openTripPlanner = new OpenTripPlanner.OpenTripPlanner();
     },
 
     _createWindow: function() {
diff --git a/src/contextMenu.js b/src/contextMenu.js
index c399dd2..76f799c 100644
--- a/src/contextMenu.js
+++ b/src/contextMenu.js
@@ -66,8 +66,8 @@ const ContextMenu = new Lang.Class({
                                          this._onAddOSMLocationActivated.bind(this));
         this._routeItem.connect('activate',
                                 this._onRouteActivated.bind(this));
-        Application.routeService.query.connect('notify::points',
-                                               this._routingUpdate.bind(this));
+        Application.routeQuery.connect('notify::points',
+                                 this._routingUpdate.bind(this));
         this._routeItem.visible = false;
         this._routingUpdate();
     },
@@ -87,7 +87,7 @@ const ContextMenu = new Lang.Class({
     },
 
     _routingUpdate: function() {
-        let query = Application.routeService.query;
+        let query = Application.routeQuery;
 
         if (query.points.length === 0)
             return;
@@ -103,7 +103,7 @@ const ContextMenu = new Lang.Class({
     },
 
     _onRouteActivated: function() {
-        let query = Application.routeService.query;
+        let query = Application.routeQuery;
         let location = new Location.Location({ latitude: this._latitude,
                                                longitude: this._longitude,
                                                accuracy: 0 });
diff --git a/src/mainWindow.js b/src/mainWindow.js
index dd28a8e..02386d0 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -134,9 +134,9 @@ const MainWindow = new Lang.Class({
 
     _createSidebar: function() {
         let sidebar = new Sidebar.Sidebar(this._mapView);
-        Application.routeService.query.connect('notify',
-                                               this._setRevealSidebar.bind(this, true));
 
+        Application.routeQuery.connect('notify',
+                                               this._setRevealSidebar.bind(this, true));
         this._toggleSidebarButton.bind_property('active',
                                                 this._mapView, 'routeVisible',
                                                 GObject.BindingFlags.BIDIRECTIONAL);
diff --git a/src/mapBubble.js b/src/mapBubble.js
index 74f8b59..0851655 100644
--- a/src/mapBubble.js
+++ b/src/mapBubble.js
@@ -150,7 +150,7 @@ const MapBubble = new Lang.Class({
     },
 
     _initRouteButton: function(button, routeFrom) {
-        let query = Application.routeService.query;
+        let query = Application.routeQuery;
         let route = Application.routeService.route;
         let from = query.points[0];
         let to = query.points[query.points.length - 1];
diff --git a/src/mapView.js b/src/mapView.js
index aa587da..e8db3bb 100644
--- a/src/mapView.js
+++ b/src/mapView.js
@@ -89,7 +89,7 @@ const MapView = new Lang.Class({
     },
 
     set routeVisible(value) {
-        let isValid = Application.routeService.query.isValid();
+        let isValid = Application.routeQuery.isValid();
 
         this._routeLayer.visible = value && isValid;
         this._instructionMarkerLayer.visible = value && isValid;
@@ -189,7 +189,7 @@ const MapView = new Lang.Class({
 
     _connectRouteSignals: function() {
         let route = Application.routeService.route;
-        let query = Application.routeService.query;
+        let query = Application.routeQuery;
 
         route.connect('update', this.showRoute.bind(this, route));
         route.connect('reset', (function() {
@@ -411,7 +411,7 @@ const MapView = new Lang.Class({
     },
 
     _showStoredRoute: function(stored) {
-        let query = Application.routeService.query;
+        let query = Application.routeQuery;
         let route = Application.routeService.route;
 
         Application.routeService.storedRoute = stored.route;
@@ -465,7 +465,7 @@ const MapView = new Lang.Class({
 
     _showDestinationTurnpoints: function() {
         let route = Application.routeService.route;
-        let query = Application.routeService.query;
+        let query = Application.routeQuery;
         let pointIndex = 0;
 
         this._instructionMarkerLayer.remove_all();
diff --git a/src/printLayout.js b/src/printLayout.js
index b89d9aa..6b541eb 100644
--- a/src/printLayout.js
+++ b/src/printLayout.js
@@ -275,7 +275,7 @@ const PrintLayout = new Lang.Class({
     },
 
     _formatQueryPlaceName: function(index) {
-        let query = Application.routeService.query;
+        let query = Application.routeQuery;
         if (index === -1)
             index = query.filledPoints.length - 1;
         let name;
diff --git a/src/routeQuery.js b/src/routeQuery.js
index 48f0d58..dd81cc9 100644
--- a/src/routeQuery.js
+++ b/src/routeQuery.js
@@ -30,12 +30,14 @@ const Transportation = {
     CAR:        0,
     BIKE:       1,
     PEDESTRIAN: 2,
+    TRANSIT:    3,
 
     toString: function (transportation) {
         switch(transportation) {
         case Transportation.CAR:        return 'car';
         case Transportation.BIKE:       return 'bike';
         case Transportation.PEDESTRIAN: return 'foot';
+        case Transportation.TRANSIT:    return 'transit';
         default:                        return null;
         }
     }
@@ -92,7 +94,8 @@ const RouteQuery = new Lang.Class({
                                                 GObject.ParamFlags.WRITABLE,
                                                 Transportation.CAR,
                                                 Transportation.PEDESTRIAN,
-                                                Transportation.CAR)
+                                                Transportation.CAR,
+                                                Transportation.TRANSIT)
     },
 
     get points() {
diff --git a/src/routeService.js b/src/routeService.js
index 31ad061..d887c31 100644
--- a/src/routeService.js
+++ b/src/routeService.js
@@ -35,10 +35,6 @@ const Utils = imports.utils;
 const GraphHopper = new Lang.Class({
     Name: 'GraphHopper',
 
-    get query() {
-        return this._query;
-    },
-
     get route() {
         return this._route;
     },
@@ -49,16 +45,24 @@ const GraphHopper = new Lang.Class({
         this._baseURL = "https://graphhopper.com/api/1/route?";;
         this._locale  = GLib.get_language_names()[0];
         this._route   = new Route.Route();
-        this._query   = new RouteQuery.RouteQuery();
         this.storedRoute = null;
+        this._query = Application.routeQuery;
+        this.parent();
+    },
 
-        this.query.connect('notify::points', (function() {
-            if (this.query.isValid())
-                this.fetchRoute(this.query.filledPoints,
+    connect: function() {
+        this._signalHandler = this._query.connect('notify::points', (function() {
+            if (this._query.isValid())
+                this.fetchRoute(this._query.filledPoints,
                                 this._query.transportation);
         }).bind(this));
+    },
 
-        this.parent();
+    disconnect: function() {
+        if (this._signalHandler !== 0) {
+            this._query.disconnect(this._signalHandler);
+            this._signalHandler = 0;
+        }
     },
 
     _updateFromStored: function() {
@@ -88,8 +92,8 @@ const GraphHopper = new Lang.Class({
                 let result = this._parseMessage(message);
                 if (!result) {
                     Application.notificationManager.showMessage(_("No route found."));
-                    if (this.query.latest)
-                        this.query.latest.place = null;
+                    if (this._query.latest)
+                        this._query.latest.place = null;
                     else
                         this.route.reset();
 
@@ -100,8 +104,8 @@ const GraphHopper = new Lang.Class({
             } catch(e) {
                 Application.notificationManager.showMessage(_("Route request failed."));
                 Utils.debug(e);
-                if (this.query.latest)
-                    this.query.latest.place = null;
+                if (this._query.latest)
+                    this._query.latest.place = null;
                 else
                     this.route.reset();
             }
@@ -184,7 +188,7 @@ const GraphHopper = new Lang.Class({
             let text = instr.text;
             if (type === Route.TurnPointType.VIA) {
                 via++;
-                let viaPlace = this.query.filledPoints[via].place;
+                let viaPlace = this._query.filledPoints[via].place;
                 text = viaPlace.name || instr.text;
             }
             return new Route.TurnPoint({
diff --git a/src/sidebar.js b/src/sidebar.js
index 64ec5e6..123a5a0 100644
--- a/src/sidebar.js
+++ b/src/sidebar.js
@@ -48,6 +48,7 @@ const Sidebar = new Lang.Class({
                         'modeBikeToggle',
                         'modeCarToggle',
                         'modePedestrianToggle',
+                        'modeTransitToggle',
                         'timeInfo' ],
 
     _init: function(mapView) {
@@ -55,33 +56,66 @@ const Sidebar = new Lang.Class({
 
         this._mapView = mapView;
 
+        Utils.debug('before _initInstructionList');
+
+        this._query = Application.routeQuery;
         this._initInstructionList();
 
+        Utils.debug('after _initInstructionList');
+
         this._initTransportationToggles(this._modePedestrianToggle,
                                         this._modeBikeToggle,
-                                        this._modeCarToggle);
+                                        this._modeCarToggle,
+                                        this._modeTransitToggle);
+
         this._initQuerySignals();
 
-        let query = Application.routeService.query;
+        Utils.debug('after creating query');
 
-        query.addPoint(0);
-        query.addPoint(1);
+        this._query.addPoint(0);
+        this._query.addPoint(1);
+        this._switchRoutingMode(RouteQuery.Transportation.CAR);
     },
 
-    _initTransportationToggles: function(pedestrian, bike, car) {
-        let query = Application.routeService.query;
+    _initTransportationToggles: function(pedestrian, bike, car, transit) {
         let transport = RouteQuery.Transportation;
 
         let onToggle = function(mode, button) {
-            if (button.active && query.transportation !== mode)
-                query.transportation = mode;
+            Utils.debug('onToggle: ' + mode + ', query.mode: ' + this._query.transportation);
+
+            let previousMode = this._query.transportation;
+
+            /* if the transportation mode changes to/from transit
+               change the routing engine */
+            if (button.active &&
+                ((mode !== transport.TRANSIT
+                  && previousMode === transport.TRANSIT)
+                 || (mode === transport.TRANSIT
+                     && previousMode !== transport.TRANSIT))) {
+                Utils.debug('switching routing mode');
+                this._switchRoutingMode(mode);
+            }
+
+            if (button.active && previousMode !== mode)
+                this._query.transportation = mode;
+
+            /*
+            if (button.active && mode === transport.TRANSIT) {
+                let openTripPlanner = Application.openTripPlanner;
+
+                openTripPlanner.fetchRouters(function(status, body) {
+                    Utils.debug('fetched routers: ' + status);
+                });
+            }
+            */
         };
         pedestrian.connect('toggled', onToggle.bind(this, transport.PEDESTRIAN));
         car.connect('toggled', onToggle.bind(this, transport.CAR));
         bike.connect('toggled', onToggle.bind(this, transport.BIKE));
+        transit.connect('toggled', onToggle.bind(this, transport.TRANSIT))
 
         let setToggles = function() {
-            switch(query.transportation) {
+            switch(Application.routeQuery.transportation) {
             case transport.PEDESTRIAN:
                 pedestrian.active = true;
                 break;
@@ -91,21 +125,37 @@ const Sidebar = new Lang.Class({
             case transport.BIKE:
                 bike.active = true;
                 break;
+            case transport.TRANSIT:
+                transit.active = true;
+                break;
             }
         };
 
         setToggles();
-        query.connect('notify::transportation', setToggles);
+        this._query.connect('notify::transportation', setToggles);
     },
 
-    _initQuerySignals: function() {
-        let query = Application.routeService.query;
+    _switchRoutingMode: function(mode) {
+        let graphHopper = Application.routeService;
+        let openTripPlanner = Application.openTripPlanner;
+
+        if (mode === RouteQuery.Transportation.TRANSIT) {
+            Utils.debug('switching to transit');
+            graphHopper.disconnect();
+            openTripPlanner.connect();
+        } else {
+            Utils.debug('switch from transit');
+            openTripPlanner.disconnect();
+            graphHopper.connect();
+        }
+    },
 
-        query.connect('point-added', (function(obj, point, index) {
+    _initQuerySignals: function() {
+        this._query.connect('point-added', (function(obj, point, index) {
             this._createRouteEntry(index, point);
         }).bind(this));
 
-        query.connect('point-removed', (function(obj, point, index) {
+        this._query.connect('point-removed', (function(obj, point, index) {
             let row = this._entryList.get_row_at_index(index);
             row.destroy();
         }).bind(this));
@@ -133,17 +183,17 @@ const Sidebar = new Lang.Class({
         if (type === RouteEntry.Type.FROM) {
             routeEntry.button.connect('clicked', (function() {
                 let lastIndex = this._entryList.get_children().length;
-                Application.routeService.query.addPoint(lastIndex - 1);
+                this._query.addPoint(lastIndex - 1);
             }).bind(this));
 
             this.bind_property('child-revealed',
                                routeEntry.entry, 'has_focus',
                                GObject.BindingFlags.DEFAULT);
         } else if (type === RouteEntry.Type.VIA) {
-            routeEntry.button.connect('clicked', function() {
+            routeEntry.button.connect('clicked', (function() {
                 let row = routeEntry.get_parent();
-                Application.routeService.query.removePoint(row.get_index());
-            });
+                this._query.removePoint(row.get_index());
+            }).bind(this));
         }
 
         this._initRouteDragAndDrop(routeEntry);
@@ -151,19 +201,18 @@ const Sidebar = new Lang.Class({
 
     _initInstructionList: function() {
         let route = Application.routeService.route;
-        let query = Application.routeService.query;
 
         route.connect('reset', (function() {
             this._clearInstructions();
 
             let length = this._entryList.get_children().length;
             for (let index = 1; index < (length - 1); index++) {
-                query.removePoint(index);
+                this._query.removePoint(index);
             }
         }).bind(this));
 
-        query.connect('notify', (function() {
-            if (query.isValid())
+        this._query.connect('notify', (function() {
+            if (this._query.isValid())
                 this._instructionStack.visible_child = this._instructionSpinner;
             else
                 this._clearInstructions();
@@ -181,11 +230,11 @@ const Sidebar = new Lang.Class({
 
             this._storeRouteTimeoutId = Mainloop.timeout_add(5000, (function() {
                 let placeStore = Application.placeStore;
-                let places = query.filledPoints.map(function(point) {
+                let places = this._query.filledPoints.map(function(point) {
                     return point.place;
                 });
                 let storedRoute = new StoredRoute.StoredRoute({
-                    transportation: query.transportation,
+                    transportation: this._query.transportation,
                     route: route,
                     places: places,
                     geoclue: Application.geoclue
@@ -226,8 +275,7 @@ const Sidebar = new Lang.Class({
 
     // Iterate over points and establish the new order of places
     _reorderRoutePoints: function(srcIndex, destIndex) {
-        let query = Application.routeService.query;
-        let points = query.points;
+        let points = this._query.points;
         let srcPlace = this._draggedPoint.place;
 
         // Determine if we are swapping from "above" or "below"
@@ -235,19 +283,18 @@ const Sidebar = new Lang.Class({
 
         // Hold off on notifying the changes to query.points until
         // we have re-arranged the places.
-        query.freeze_notify();
+        this._query.freeze_notify();
 
         for (let i = destIndex; i !== (srcIndex + step); i += step) {
             // swap
             [points[i].place, srcPlace] = [srcPlace, points[i].place];
         }
 
-        query.thaw_notify();
+        this._query.thaw_notify();
     },
 
     _onDragDrop: function(row, context, x, y, time) {
-        let query = Application.routeService.query;
-        let srcIndex = query.points.indexOf(this._draggedPoint);
+        let srcIndex = this._query.points.indexOf(this._draggedPoint);
         let destIndex = row.get_index();
 
         this._reorderRoutePoints(srcIndex, destIndex);
diff --git a/src/turnPointMarker.js b/src/turnPointMarker.js
index 3774083..9bc9036 100644
--- a/src/turnPointMarker.js
+++ b/src/turnPointMarker.js
@@ -91,7 +91,7 @@ const TurnPointMarker = new Lang.Class({
     },
 
     _onMarkerDrag: function() {
-        let query = Application.routeService.query;
+        let query = Application.routeQuery;
         let place = new Place.Place({
             location: new Location.Location({ latitude: this.latitude.toFixed(5),
                                               longitude: this.longitude.toFixed(5) }) });


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]