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



commit 6e445d1b71bdf27eb6ffce68d673d2a1d6633ba5
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 only sends out a query to the OTP instance to get a list of
    all routers (public transportation networks) currently available in
    the server when the transit mode button is selected.

 data/ui/sidebar.ui  |   23 ++++++++++++
 src/application.js  |    3 ++
 src/contextMenu.js  |    7 ++--
 src/mainWindow.js   |    5 ++-
 src/mapView.js      |    7 ++--
 src/printLayout.js  |    3 +-
 src/routeQuery.js   |    9 ++++-
 src/routeService.js |   23 +++++++-----
 src/sidebar.js      |  101 +++++++++++++++++++++++++++++++++++++--------------
 9 files changed, 135 insertions(+), 46 deletions(-)
---
diff --git a/data/ui/sidebar.ui b/data/ui/sidebar.ui
index 77347ed..1524e59 100644
--- a/data/ui/sidebar.ui
+++ b/data/ui/sidebar.ui
@@ -94,6 +94,29 @@
                 </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="active">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 2d6b023..efe9aa4 100644
--- a/src/application.js
+++ b/src/application.js
@@ -37,6 +37,7 @@ 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;
@@ -55,6 +56,7 @@ let geocodeService = null;
 let networkMonitor = null;
 let checkInManager = null;
 let contactStore = null;
+let openTripPlanner = null;
 let osmEdit = null;
 let normalStartup = true;
 
@@ -256,6 +258,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 874414b..b7bb791 100644
--- a/src/contextMenu.js
+++ b/src/contextMenu.js
@@ -34,6 +34,7 @@ const OSMAccountDialog = imports.osmAccountDialog;
 const OSMEdit = imports.osmEdit;
 const OSMEditDialog = imports.osmEditDialog;
 const Place = imports.place;
+const RouteQuery = imports.routeQuery;
 const Utils = imports.utils;
 const ZoomInNotification = imports.zoomInNotification;
 
@@ -66,8 +67,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));
+        RouteQuery.query.connect('notify::points',
+                                 this._routingUpdate.bind(this));
         this._routeItem.visible = false;
         this._routingUpdate();
     },
@@ -87,7 +88,7 @@ const ContextMenu = new Lang.Class({
     },
 
     _routingUpdate: function() {
-        let query = Application.routeService.query;
+        let query = RouteQuery.query;
 
         if (query.points.length === 0)
             return;
diff --git a/src/mainWindow.js b/src/mainWindow.js
index afb7297..7165623 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -39,6 +39,7 @@ const MapView = imports.mapView;
 const PlaceEntry = imports.placeEntry;
 const PlaceStore = imports.placeStore;
 const PrintOperation = imports.printOperation;
+const RouteQuery = imports.routeQuery;
 const Sidebar = imports.sidebar;
 const Utils = imports.utils;
 const ZoomControl = imports.zoomControl;
@@ -134,8 +135,8 @@ const MainWindow = new Lang.Class({
 
     _createSidebar: function() {
         let sidebar = new Sidebar.Sidebar(this._mapView);
-        Application.routeService.query.connect('notify',
-                                               this._setRevealSidebar.bind(this, true));
+        RouteQuery.query.connect('notify',
+                                 this._setRevealSidebar.bind(this, true));
         sidebar.bind_property('reveal-child',
                               this._mapView, 'routeVisible',
                               GObject.BindingFlags.BIDIRECTIONAL);
diff --git a/src/mapView.js b/src/mapView.js
index 2bf8f04..a22bfdf 100644
--- a/src/mapView.js
+++ b/src/mapView.js
@@ -39,6 +39,7 @@ const Maps = imports.gi.GnomeMaps;
 const MapWalker = imports.mapWalker;
 const Place = imports.place;
 const PlaceMarker = imports.placeMarker;
+const RouteQuery = imports.routeQuery;
 const ShapeLayer = imports.shapeLayer;
 const StoredRoute = imports.storedRoute;
 const TurnPointMarker = imports.turnPointMarker;
@@ -72,7 +73,7 @@ const MapView = new Lang.Class({
     },
 
     set routeVisible(value) {
-        let isValid = Application.routeService.query.isValid();
+        let isValid = RouteQuery.query.isValid();
 
         this._routeLayer.visible = value && isValid;
         this._instructionMarkerLayer.visible = value && isValid;
@@ -172,7 +173,7 @@ const MapView = new Lang.Class({
 
     _connectRouteSignals: function() {
         let route = Application.routeService.route;
-        let query = Application.routeService.query;
+        let query = RouteQuery.query;
 
         route.connect('update', this.showRoute.bind(this, route));
         route.connect('reset', (function() {
@@ -448,7 +449,7 @@ const MapView = new Lang.Class({
 
     _showDestinationTurnpoints: function() {
         let route = Application.routeService.route;
-        let query = Application.routeService.query;
+        let query = RouteQuery.query;
         let pointIndex = 0;
 
         this._instructionMarkerLayer.remove_all();
diff --git a/src/printLayout.js b/src/printLayout.js
index b4e72fa..986db03 100644
--- a/src/printLayout.js
+++ b/src/printLayout.js
@@ -30,6 +30,7 @@ const Application = imports.application;
 const InstructionRow = imports.instructionRow;
 const MapMarker = imports.mapMarker;
 const MapView = imports.mapView;
+const RouteQuery = imports.routeQuery;
 const TurnPointMarker = imports.turnPointMarker;
 
 /* Following constant has unit as meters */
@@ -257,7 +258,7 @@ const PrintLayout = new Lang.Class({
     },
 
     _formatQueryPlaceName: function(index) {
-        let query = Application.routeService.query;
+        let query = RouteQuery.query;
         if (index === -1)
             index = query.filledPoints.length - 1;
         let name;
diff --git a/src/routeQuery.js b/src/routeQuery.js
index 2108440..6a84312 100644
--- a/src/routeQuery.js
+++ b/src/routeQuery.js
@@ -27,12 +27,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;
         }
     }
@@ -87,7 +89,8 @@ const RouteQuery = new Lang.Class({
                                                 GObject.ParamFlags.WRITABLE,
                                                 Transportation.CAR,
                                                 Transportation.PEDESTRIAN,
-                                                Transportation.CAR)
+                                                Transportation.CAR,
+                                                Transportation.TRANSIT)
     },
 
     get points() {
@@ -109,6 +112,8 @@ const RouteQuery = new Lang.Class({
         this.parent(args);
         this._points = [];
         this.reset();
+
+        routeQuery = this;
     },
 
     addPoint: function(index) {
@@ -168,3 +173,5 @@ const RouteQuery = new Lang.Class({
                "\nTransportation: " + this.transportation;
     }
 });
+
+const query = new RouteQuery();
diff --git a/src/routeService.js b/src/routeService.js
index 8424c5e..5014747 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,25 @@ 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 = RouteQuery.query;
+
+        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() {
diff --git a/src/sidebar.js b/src/sidebar.js
index f20d535..6fc0aba 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 = RouteQuery.query;
         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();
     },
 
-    _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(RouteQuery.query.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,7 +183,7 @@ 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',
@@ -142,7 +192,7 @@ const Sidebar = new Lang.Class({
         } else if (type === RouteEntry.Type.VIA) {
             routeEntry.button.connect('clicked', function() {
                 let row = routeEntry.get_parent();
-                Application.routeService.query.removePoint(row.get_index());
+                this._query.removePoint(row.get_index());
             });
         }
 
@@ -151,7 +201,6 @@ const Sidebar = new Lang.Class({
 
     _initInstructionList: function() {
         let route = Application.routeService.route;
-        let query = Application.routeService.query;
 
         route.connect('reset', (function() {
             this._clearInstructions();
@@ -159,12 +208,12 @@ const Sidebar = new Lang.Class({
 
             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();
@@ -183,11 +232,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
@@ -227,7 +276,6 @@ 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 srcPlace = this._draggedPoint.place;
 
@@ -236,19 +284,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);


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