Browse Source

Add basic bricks for support of multiple transport means

Phyks (Lucas Verney) 2 years ago
parent
commit
821dd4ce7f
7 changed files with 102 additions and 48 deletions
  1. 1
    6
      .eslintrc.js
  2. 4
    3
      src/App.vue
  3. 48
    0
      src/api/index.js
  4. 11
    13
      src/components/Home.vue
  5. 34
    25
      src/components/RouteMap.vue
  6. 3
    0
      src/constants.js
  7. 1
    1
      src/router/index.js

+ 1
- 6
.eslintrc.js View File

@@ -42,11 +42,6 @@ module.exports = {
42 42
             "ignorePropertyModificationsFor": ["state"]
43 43
         }
44 44
     ],
45
-    'no-bitwise': [
46
-        "error",
47
-        {
48
-            "int32Hint": true
49
-        }
50
-    ]
45
+    'no-bitwise': 'off',
51 46
   }
52 47
 }

+ 4
- 3
src/App.vue View File

@@ -25,7 +25,7 @@
25 25
         </v-navigation-drawer>
26 26
         <v-toolbar app>
27 27
             <v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
28
-            <v-toolbar-title><router-link :to="{name: 'Home'}">{{ title }}</router-link></v-toolbar-title>
28
+            <v-toolbar-title class="title"><router-link :to="{name: 'Home'}">{{ title }}</router-link></v-toolbar-title>
29 29
         </v-toolbar>
30 30
         <v-content>
31 31
             <router-view></router-view>
@@ -49,8 +49,9 @@ export default {
49 49
 };
50 50
 </script>
51 51
 
52
-<style>
53
-.application .leaflet-bar a {
52
+<style scoped>
53
+.title > a {
54 54
     color: black;
55
+    text-decoration: none;
55 56
 }
56 57
 </style>

+ 48
- 0
src/api/index.js View File

@@ -0,0 +1,48 @@
1
+import fetch from 'isomorphic-fetch';
2
+import moment from 'moment';
3
+
4
+
5
+export function getRVRoutes(startLatLng, endLatLng) {
6
+    return fetch(
7
+        `http://127.0.0.1:8081/api/1/route?point=${startLatLng.lat},${startLatLng.lng}&point=${endLatLng.lat},${endLatLng.lng}&instructions=true&type=json`,
8
+    )
9
+        .then(response => response.json())
10
+        .then((json) => {
11
+            const path = json.paths[0];
12
+            return [
13
+                {
14
+                    geojson: path.points,
15
+                    duration: moment.duration(path.time),
16
+                    distances: {
17
+                        bike: path.distance,
18
+                    },
19
+                    bbox: path.bbox,
20
+                    elevations: path.elevations,
21
+                    departure_date_time: moment(),
22
+                    arrival_date_time: moment().add(path.time, 'ms'),
23
+                    co2_emissions: {
24
+                        unit: 'gEC',
25
+                        value: 0,
26
+                    },
27
+                },
28
+            ];
29
+        });
30
+}
31
+
32
+
33
+export function getNavitiaRoutes(startLatLng, endLatLng) {
34
+    console.log(startLatLng, endLatLng);
35
+    return [];
36
+}
37
+
38
+
39
+export function getRoutes(startLatLng, endLatLng, modes) {
40
+    const promises = [];
41
+    if (modes.includes('bike')) {
42
+        promises.push(getRVRoutes(startLatLng, endLatLng));
43
+    }
44
+    if (modes.includes('transit')) {
45
+        promises.push(getNavitiaRoutes(startLatLng, endLatLng));
46
+    }
47
+    return Promise.all(promises).then(values => Array.concat([], ...values));
48
+}

+ 11
- 13
src/components/Home.vue View File

@@ -62,6 +62,7 @@
62 62
 <script>
63 63
 import AddressInput from './AddressInput.vue';
64 64
 import { splitLatLng } from '../tools';
65
+import { BIKE, TRANSIT } from '../constants';
65 66
 
66 67
 
67 68
 export default {
@@ -74,10 +75,7 @@ export default {
74 75
             fromLatLng: null,
75 76
             toLatLng: null,
76 77
             search: null,
77
-            transport_modes: [
78
-                'bike',
79
-                'transit',
80
-            ],
78
+            transport_modes: BIKE + TRANSIT,
81 79
         };
82 80
     },
83 81
     methods: {
@@ -85,30 +83,30 @@ export default {
85 83
             this.$router.push({
86 84
                 name: 'RouteMap',
87 85
                 params: {
86
+                    transport_modes: this.transport_modes,
88 87
                     start_point: this.fromLatLng,
89 88
                     end_point: this.toLatLng,
90 89
                 },
91 90
             });
92 91
         },
93 92
         toggleTransportMode(mode) {
94
-            const index = this.transport_modes.indexOf(mode);
95
-            if (index > -1) {
96
-                this.transport_modes.splice(index, 1);
93
+            if (this.transport_modes & mode) {
94
+                this.transport_modes -= mode;
97 95
             } else {
98
-                this.transport_modes.push(mode);
96
+                this.transport_modes += mode;
99 97
             }
100 98
 
101
-            if (this.transport_modes.length === 0) {
99
+            if (this.transport_modes > 0) {
102 100
                 this.valid = false;
103 101
             } else {
104 102
                 this.valid = true;
105 103
             }
106 104
         },
107 105
         toggleBike() {
108
-            this.toggleTransportMode('bike');
106
+            this.toggleTransportMode(BIKE);
109 107
         },
110 108
         toggleTransit() {
111
-            this.toggleTransportMode('transit');
109
+            this.toggleTransportMode(TRANSIT);
112 110
         },
113 111
     },
114 112
     computed: {
@@ -131,13 +129,13 @@ export default {
131 129
             };
132 130
         },
133 131
         bikeIconColor() {
134
-            if (this.transport_modes.includes('bike')) {
132
+            if (this.transport_modes & BIKE) {
135 133
                 return 'pink';
136 134
             }
137 135
             return null;
138 136
         },
139 137
         transitIconColor() {
140
-            if (this.transport_modes.includes('transit')) {
138
+            if (this.transport_modes & TRANSIT) {
141 139
                 return 'pink';
142 140
             }
143 141
             return null;

+ 34
- 25
src/components/RouteMap.vue View File

@@ -11,8 +11,8 @@
11 11
                 <div class="fill-height fill-width">
12 12
                     <v-map :bounds="bounds">
13 13
                         <v-tilelayer url="http://{s}.tile.osm.org/{z}/{x}/{y}.png"></v-tilelayer>
14
-                        <v-marker :lat-lng="startPoint.latlng" :autopan="true" :draggable="true" v-on:l-drag="(ev) => { startPoint.latlng = ev.latlng; startPoint.isDragged = true; }" v-on:l-dragend="getPaths"></v-marker>
15
-                        <v-marker :lat-lng="endPoint.latlng" :autopan="true" :draggable="true" v-on:l-drag="(ev) => { endPoint.latlng = ev.latlng; endPoint.isDragged = true; }" v-on:l-dragend="getPaths"></v-marker>
14
+                        <v-marker :lat-lng="startPoint.latlng" :autopan="true" :draggable="true" v-on:l-drag="(ev) => { startPoint.latlng = ev.latlng; startPoint.isDragged = true; }" v-on:l-dragend="getRoutes"></v-marker>
15
+                        <v-marker :lat-lng="endPoint.latlng" :autopan="true" :draggable="true" v-on:l-drag="(ev) => { endPoint.latlng = ev.latlng; endPoint.isDragged = true; }" v-on:l-dragend="getRoutes"></v-marker>
16 16
                         <v-polyline v-if="latLngs" :latLngs="latLngs"></v-polyline>
17 17
                         <v-polyline v-if="startLatLngs" :latLngs="startLatLngs" dashArray="5, 5"></v-polyline>
18 18
                         <v-polyline v-if="endLatLngs" :latLngs="endLatLngs" dashArray="5, 5"></v-polyline>
@@ -29,10 +29,10 @@ import L from 'leaflet';
29 29
 import iconRetinaUrl from 'leaflet/dist/images/marker-icon-2x.png';
30 30
 import iconUrl from 'leaflet/dist/images/marker-icon.png';
31 31
 import shadowUrl from 'leaflet/dist/images/marker-shadow.png';
32
-import moment from 'moment';
33 32
 import polyline from '@mapbox/polyline';
34 33
 import prettyMetric from 'pretty-metric';
35 34
 
35
+import { getRoutes } from '../api';
36 36
 import ElevationGraph from './ElevationGraph.vue';
37 37
 
38 38
 // Fix for a bug in Leaflet default icon
@@ -51,7 +51,7 @@ export default {
51 51
     },
52 52
     created() {
53 53
         this.initializePoints();
54
-        this.getPaths();
54
+        this.getRoutes();
55 55
     },
56 56
     watch: {
57 57
         $route: 'initializePoints',
@@ -68,7 +68,7 @@ export default {
68 68
                 isDragged: false,
69 69
                 name: null,
70 70
             },
71
-            paths: null,
71
+            route: null,
72 72
         };
73 73
     },
74 74
     methods: {
@@ -80,35 +80,38 @@ export default {
80 80
                 this.$route.params.end_point.split(',').map(item => parseFloat(item)),
81 81
             );
82 82
         },
83
-        getPaths() {
84
-            fetch(`http://127.0.0.1:8081/api/1/route?point=${this.startPoint.latlng.lat},${this.startPoint.latlng.lng}&point=${this.endPoint.latlng.lat},${this.endPoint.latlng.lng}&instructions=true&type=json`)
85
-                .then(response => response.json())
86
-                .then((json) => {
87
-                    this.paths = json.paths;
88
-                    this.startPoint.name = 'TODO';
89
-                    this.endPoint.name = 'TODO';
83
+        getRoutes() {
84
+            this.startPoint.name = 'TODO';
85
+            this.endPoint.name = 'TODO';
86
+            getRoutes(
87
+                this.startPoint.latlng,
88
+                this.endPoint.latlng,
89
+                this.$route.params.transport_modes,
90
+            )
91
+                .then((routes) => {
90 92
                     this.startPoint.isDragged = false;
91 93
                     this.endPoint.isDragged = false;
94
+                    this.route = routes[0];
92 95
                 });
93 96
         },
94 97
     },
95 98
     computed: {
96 99
         elevations() {
97
-            if (!this.paths) {
100
+            if (!this.route) {
98 101
                 return [];
99 102
             }
100
-            return this.paths[0].elevations;
103
+            return this.route.elevations;
101 104
         },
102 105
         bounds() {
103
-            if (this.paths && this.paths[0].bbox) {
106
+            if (this.route && this.route.bbox) {
104 107
                 return [
105 108
                     [
106
-                        this.paths[0].bbox[1],
107
-                        this.paths[0].bbox[0],
109
+                        this.route.bbox[1],
110
+                        this.route.bbox[0],
108 111
                     ],
109 112
                     [
110
-                        this.paths[0].bbox[3],
111
-                        this.paths[0].bbox[2],
113
+                        this.route.bbox[3],
114
+                        this.route.bbox[2],
112 115
                     ],
113 116
                 ];
114 117
             }
@@ -124,10 +127,10 @@ export default {
124 127
             ];
125 128
         },
126 129
         latLngs() {
127
-            if (!this.paths) {
130
+            if (!this.route) {
128 131
                 return null;
129 132
             }
130
-            return polyline.decode(this.paths[0].points);
133
+            return polyline.decode(this.route.geojson);
131 134
         },
132 135
         startLatLngs() {
133 136
             if (!this.latLngs || this.startPoint.isDragged) {
@@ -142,21 +145,27 @@ export default {
142 145
             return [this.latLngs[this.latLngs.length - 1], this.endPoint.latlng];
143 146
         },
144 147
         time() {
145
-            if (!this.paths) {
148
+            if (!this.route) {
146 149
                 return null;
147 150
             }
148
-            return moment.duration(this.paths[0].time).humanize();
151
+            return this.route.duration.humanize();
149 152
         },
150 153
         distance() {
151
-            if (!this.paths) {
154
+            if (!this.route) {
152 155
                 return null;
153 156
             }
154
-            return prettyMetric(this.paths[0].distance).humanize();
157
+            return prettyMetric(this.route.distances.bike).humanize();
155 158
         },
156 159
     },
157 160
 };
158 161
 </script>
159 162
 
163
+<style>
164
+.application .leaflet-bar a {
165
+    color: black;
166
+}
167
+</style>
168
+
160 169
 <style scoped>
161 170
 .fill-width {
162 171
     width: 100%;

+ 3
- 0
src/constants.js View File

@@ -0,0 +1,3 @@
1
+// Transport modes
2
+export const BIKE = 1;
3
+export const TRANSIT = 2;

+ 1
- 1
src/router/index.js View File

@@ -13,7 +13,7 @@ export default new Router({
13 13
             component: Home,
14 14
         },
15 15
         {
16
-            path: '/route/:start_point/:end_point',
16
+            path: '/route/:transport_modes/:start_point/:end_point',
17 17
             name: 'RouteMap',
18 18
             component: RouteMap,
19 19
         },