|
|
@@ -18,6 +18,15 @@
|
|
|
//
|
|
|
|
|
|
|
|
|
+var g_info = {
|
|
|
+ "geojson" : {},
|
|
|
+ "route" : {},
|
|
|
+ "route_path": {},
|
|
|
+
|
|
|
+ "active_route" : [],
|
|
|
+ "ol_route_layer" : {}
|
|
|
+};
|
|
|
+
|
|
|
var Feature = ol.Feature;
|
|
|
var Map = ol.Map;
|
|
|
var Overlay = ol.Overlay;
|
|
|
@@ -88,7 +97,6 @@ function example_change_image() {
|
|
|
|
|
|
//---
|
|
|
|
|
|
-//var vectorSource = new VectorSource({ features: [iconFeature], });
|
|
|
var vectorSource = new VectorSource();
|
|
|
var _icon = [];
|
|
|
for (let ii=0; ii<2; ii++) {
|
|
|
@@ -156,6 +164,43 @@ const g_map = new Map({
|
|
|
}),
|
|
|
});
|
|
|
|
|
|
+var g_side_toggle = true;
|
|
|
+
|
|
|
+function toggle_sidebar(tf) {
|
|
|
+
|
|
|
+ g_side_toggle = (g_side_toggle ? false : true);
|
|
|
+ if (typeof tf !== "undefined") {
|
|
|
+ g_side_toggle = tf;
|
|
|
+ }
|
|
|
+
|
|
|
+ // my perpetual fight with CSS.
|
|
|
+ // I can't seem to get these values in when I put them in the
|
|
|
+ // CSS, so we do it here programatically.
|
|
|
+ //
|
|
|
+ // Create a scrollable bar only for the list and not
|
|
|
+ // for the map.
|
|
|
+ // Hide the scroll bar when collapsing.
|
|
|
+ // Hide the x scrollbar but dumping x values that overflow.
|
|
|
+ //
|
|
|
+ let ele = document.getElementById("sidebar-wrapper");
|
|
|
+ if (g_side_toggle) {
|
|
|
+ ele.style["overflow-y"] = "auto";
|
|
|
+ ele.style["overflow-x"] = "hidden";
|
|
|
+ ele.style["margin-left"] = 0;
|
|
|
+ ele.style["min-width"] = "15rem";
|
|
|
+ ele.style["max-height"] = "100vh";
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ ele.style["overflow-y"] = "hidden";
|
|
|
+ ele.style["overflow-x"] = "hidden";
|
|
|
+ ele.style["margin-left"] = "-15rem";
|
|
|
+ ele.style["min-width"] = "0";
|
|
|
+ ele.style["max-height"] = "100vh";
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
class CustomToggle extends Control {
|
|
|
constructor(opt) {
|
|
|
opt = opt || {};
|
|
|
@@ -175,16 +220,19 @@ class CustomToggle extends Control {
|
|
|
}
|
|
|
|
|
|
fire() {
|
|
|
- document.body.classList.toggle('sb-sidenav-toggled');
|
|
|
- localStorage.setItem('sb|sidebar-toggle', document.body.classList.contains('sb-sidenav-toggled'));
|
|
|
+
|
|
|
+ toggle_sidebar();
|
|
|
|
|
|
// hacky, but functional
|
|
|
//
|
|
|
- setTimeout(_resize, 250);
|
|
|
+ setTimeout(resize_map, 250);
|
|
|
|
|
|
}
|
|
|
}
|
|
|
-g_map.addControl(new CustomToggle({ className: 'custom-zoom' }));
|
|
|
+
|
|
|
+// button to toggle side bar route list
|
|
|
+//
|
|
|
+g_map.addControl(new CustomToggle({ className: 'custom-button' }));
|
|
|
|
|
|
//-------------------
|
|
|
//-------------------
|
|
|
@@ -224,7 +272,9 @@ g_map.on('pointermove', function (e) {
|
|
|
const hit = g_map.hasFeatureAtPixel(pixel);
|
|
|
g_map.getTarget().style.cursor = hit ? 'pointer' : '';
|
|
|
});
|
|
|
+
|
|
|
// Close the popup when the map is moved
|
|
|
+//
|
|
|
g_map.on('movestart', function () {
|
|
|
//$(element).popover('dispose');
|
|
|
});
|
|
|
@@ -234,17 +284,7 @@ g_map.on("postrender", function(event) {
|
|
|
});
|
|
|
|
|
|
|
|
|
-//----
|
|
|
-//
|
|
|
-
|
|
|
-setInterval( function() {
|
|
|
- //console.log("bang");
|
|
|
- //map.render();
|
|
|
-}, 1000);
|
|
|
-
|
|
|
-
|
|
|
//-----
|
|
|
-//
|
|
|
|
|
|
function update_buses(json_gtfs) {
|
|
|
|
|
|
@@ -302,34 +342,58 @@ function fetch_gtfs_vehicle_position() {
|
|
|
|
|
|
//--
|
|
|
|
|
|
-function update_route_layer(geojson) {
|
|
|
- if (!geojson) { return; }
|
|
|
- let route_points = geojson.features[0].geometry.coordinates;
|
|
|
- let merc_points = [];
|
|
|
- for (let ii=0; ii<route_points.length; ii++) {
|
|
|
- merc_points.push(ol.proj.transform(route_points[ii], 'EPSG:4326', 'EPSG:3857'));
|
|
|
+function ui_show_single_route(route_id) {
|
|
|
+ if (!(route_id in g_info.ol_route_layer)) {
|
|
|
+ console.log("route", route_id, "not found in g_info.ol_route_layer");
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- let routeLine = new ol.Feature({
|
|
|
- geometry: new ol.geom.LineString(merc_points)
|
|
|
- });
|
|
|
+ for (let i=0; i<g_info.active_route; i++) {
|
|
|
+ let route_id = g_info.active_route[i];
|
|
|
+ let route_layer = g_info.ol_route_layer[route_id];
|
|
|
+ g_map.removeLayer( route_layer );
|
|
|
+ }
|
|
|
+ g_info.active_route = [ route_id ];
|
|
|
|
|
|
- let routeLineVector = new ol.source.Vector({});
|
|
|
- routeLineVector.addFeature(routeLine);
|
|
|
+ g_map.addLayer( g_info.ol_route_layer[route_id] );
|
|
|
+}
|
|
|
|
|
|
- let routeLayer = new VectorLayer({
|
|
|
- source: routeLineVector,
|
|
|
- style: new ol.style.Style({
|
|
|
- fill: new ol.style.Fill({ color: 'rgb(0,0,255,0.25)', weight: 4, opacity: 0.5 }),
|
|
|
- stroke: new ol.style.Stroke({ color: 'rgb(0,0,255,0.25)', width: 6, opacity: 0.5 })
|
|
|
- }),
|
|
|
- zIndex: 0
|
|
|
- });
|
|
|
+function init_route_layer() {
|
|
|
+
|
|
|
+ for (let route_id in g_info.route_path) {
|
|
|
+
|
|
|
+ let route_points = g_info.route_path[route_id];
|
|
|
+ let merc_points = [];
|
|
|
+ for (let ii=0; ii<route_points.length; ii++) {
|
|
|
+ merc_points.push(ol.proj.transform(route_points[ii], 'EPSG:4326', 'EPSG:3857'));
|
|
|
+ }
|
|
|
+
|
|
|
+ let routeLine = new ol.Feature({
|
|
|
+ geometry: new ol.geom.LineString(merc_points)
|
|
|
+ });
|
|
|
+
|
|
|
+ let routeLineVector = new ol.source.Vector({});
|
|
|
+ routeLineVector.addFeature(routeLine);
|
|
|
+
|
|
|
+ let routeLayer = new VectorLayer({
|
|
|
+ source: routeLineVector,
|
|
|
+ style: new ol.style.Style({
|
|
|
+ fill: new ol.style.Fill({ color: 'rgb(0,0,255,0.25)', weight: 4, opacity: 0.5 }),
|
|
|
+ stroke: new ol.style.Stroke({ color: 'rgb(0,0,255,0.25)', width: 6, opacity: 0.5 })
|
|
|
+ }),
|
|
|
+ zIndex: 0
|
|
|
+ });
|
|
|
+
|
|
|
+ g_info.ol_route_layer[route_id] = routeLayer;
|
|
|
+ }
|
|
|
|
|
|
- g_map.addLayer(routeLayer);
|
|
|
}
|
|
|
|
|
|
-function update_stop_layer(geojson) {
|
|
|
+function init_stop_layer(geojson) {
|
|
|
+
|
|
|
+ //DEBUG
|
|
|
+ return;
|
|
|
+
|
|
|
if (!geojson) { return; }
|
|
|
let stop_points = geojson.features[0].properties.route_stops;
|
|
|
|
|
|
@@ -380,8 +444,14 @@ function fetch_geojson(url) {
|
|
|
let xhr = new XMLHttpRequest();
|
|
|
xhr.onload = function() {
|
|
|
let geojson = xhr.response;
|
|
|
- update_route_layer(geojson);
|
|
|
- update_stop_layer(geojson);
|
|
|
+
|
|
|
+ g_info.geojson = geojson;
|
|
|
+
|
|
|
+ //post_process_geojson();
|
|
|
+ ui_add_route();
|
|
|
+
|
|
|
+ init_route_layer(geojson);
|
|
|
+ init_stop_layer(geojson);
|
|
|
};
|
|
|
|
|
|
xhr.responseType = "json";
|
|
|
@@ -392,8 +462,63 @@ function fetch_geojson(url) {
|
|
|
|
|
|
//---
|
|
|
|
|
|
+function post_process_geojson() {
|
|
|
+ let trip = g_info.geojson.features;
|
|
|
+ for (let i=0; i<trip.length; i++) {
|
|
|
+ if (trip[i].type != "trip") { continue; }
|
|
|
+ let prop = trip[i].properties;
|
|
|
+ let _route = prop.route;
|
|
|
+
|
|
|
+ if (_route.route_id in g_info.route) { continue; }
|
|
|
+ g_info.route[_route.route_id] = prop.route_stops;
|
|
|
+ g_info.route_path[_route.route_id] = trip[i].geometry.coordinates;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+// add routes to side menu
|
|
|
+//
|
|
|
+function ui_add_route() {
|
|
|
+ let ele = document.getElementById("ui_route_list");
|
|
|
+
|
|
|
+ ele.innerHTML = '';
|
|
|
+
|
|
|
+ let trip = g_info.geojson.features;
|
|
|
+ for (let i=0; i<trip.length; i++) {
|
|
|
+ if (trip[i].type != "trip") { continue; }
|
|
|
+ let prop = trip[i].properties;
|
|
|
+ let _route = prop.route;
|
|
|
+
|
|
|
+ if (_route.route_id in g_info.route) { continue; }
|
|
|
+ g_info.route[_route.route_id] = prop.route_stops;
|
|
|
+ g_info.route_path[_route.route_id] = trip[i].geometry.coordinates;
|
|
|
+
|
|
|
+ let _a = document.createElement("a");
|
|
|
+ _a.classList.add("list-group-item");
|
|
|
+ _a.classList.add("list-gorup-item-action");
|
|
|
+ _a.classList.add("list-gorup-item-light");
|
|
|
+ _a.classList.add("p-3");
|
|
|
+ _a.innerText = prop.route.route_long_name;
|
|
|
+ _a.onclick = (function(_r) {
|
|
|
+ return function() {
|
|
|
+ ui_show_single_route(_r);
|
|
|
+ }
|
|
|
+ })(_route.route_id);
|
|
|
+
|
|
|
+ ele.appendChild(_a);
|
|
|
|
|
|
-function _resize() {
|
|
|
+ }
|
|
|
+
|
|
|
+ toggle_sidebar(g_side_toggle);
|
|
|
+}
|
|
|
+
|
|
|
+//---
|
|
|
+
|
|
|
+// resize map
|
|
|
+//
|
|
|
+function resize_map() {
|
|
|
|
|
|
let h = $(window).height();
|
|
|
let m = document.getElementById("map");
|
|
|
@@ -405,38 +530,13 @@ function init() {
|
|
|
setInterval(fetch_gtfs_vehicle_position, 1000);
|
|
|
setTimeout( function() { fetch_geojson("geojson/test_route.geojson"); }, 100);
|
|
|
|
|
|
- $(window).on('resize', _resize);
|
|
|
+ $(window).on('resize', resize_map);
|
|
|
}
|
|
|
|
|
|
-window.addEventListener('DOMContentLoaded', event => {
|
|
|
-
|
|
|
- // Toggle the side navigation
|
|
|
- const sidebarToggle = document.body.querySelector('#sidebarToggle');
|
|
|
- if (sidebarToggle) {
|
|
|
- // Uncomment Below to persist sidebar toggle between refreshes
|
|
|
- // if (localStorage.getItem('sb|sidebar-toggle') === 'true') {
|
|
|
- // document.body.classList.toggle('sb-sidenav-toggled');
|
|
|
- // }
|
|
|
- sidebarToggle.addEventListener('click', event => {
|
|
|
- event.preventDefault();
|
|
|
- document.body.classList.toggle('sb-sidenav-toggled');
|
|
|
- localStorage.setItem('sb|sidebar-toggle', document.body.classList.contains('sb-sidenav-toggled'));
|
|
|
-
|
|
|
-
|
|
|
- // hacky, but functional
|
|
|
- //
|
|
|
- setTimeout(_resize, 250);
|
|
|
- });
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
- //init();
|
|
|
- //_resize();
|
|
|
-
|
|
|
-});
|
|
|
|
|
|
$(document).ready(function() {
|
|
|
init();
|
|
|
- _resize();
|
|
|
+ resize_map();
|
|
|
+ toggle_sidebar(g_side_toggle);
|
|
|
});
|
|
|
|