(function() { "use strict"; LS.imagePath = 'images/'; LS.dataPath = 'data.json'; var $sidebars = [ $('#buildingsSidebar'), $('#sitesSidebar'), $('#busRoutesSidebar') ]; var $sidebarLi = [ $('#navBuildingsLi'), $('#navSitesLi'), $('#navBusRoutesLi') ]; var sidebarHideButtons = [ "buildingsSidebarHideButton", "sitesSidebarHideButton", "busRoutesSidebarHideButton" ]; function hideSidebars() { $sidebars.forEach(function($sidebar) { $sidebar.hide(); }); $sidebarLi.forEach(function($sidebarLi) { $sidebarLi.removeClass('active'); }); } $sidebarLi.forEach(function($li, index) { var liLink = $li.children('a')[0]; liLink.onclick = function() { // hide the other sidebars $sidebars.forEach(function($sidebar, hideIndex) { if (index === hideIndex) return; // don't hide this sidebar $sidebar.hide(); $sidebarLi[hideIndex].removeClass('active'); }); $li.toggleClass("active"); $sidebars[index].toggle(); map.invalidateSize(); return false; }; }); sidebarHideButtons.forEach(function(buttonId, index) { var button = document.getElementById(buttonId); button.onclick = function() { $sidebars[index].hide(); $sidebarLi[index].removeClass('active'); map.invalidateSize(); return false; }; }); var map = LS.map('map', { workstations: true, indoor: true, popupWidth: 400, popupHeight: 550, busRoutes: true, zoomControl: false, levelControlPosition: 'bottomleft' }); /* map.showInfo = function(content, latlng, options) { var $content = $(content); var contentTitle = $content.children('h2'); var titleText = contentTitle.text(); contentTitle.remove(); $("#feature-title").html(titleText); $("#feature-info").html(content); $("#featureModal").modal("show"); }; map.closeInfo = function() { $("#featureModal").modal("hide"); }; */ var zoomControl = L.control.zoom({ position: "bottomright" }).addTo(map); /* GPS enabled geolocation control set to follow the user's location */ var locateControl = L.control.locate({ position: "bottomright", drawCircle: true, follow: true, setView: true, keepCurrentZoomLevel: true, markerStyle: { weight: 1, opacity: 0.8, fillOpacity: 0.8 }, circleStyle: { weight: 1, clickable: false }, icon: "icon-direction", metric: false, strings: { title: "My location", popup: "You are within {distance} {unit} from this point", outsideMapBoundsMsg: "You seem located outside the boundaries of the map" }, locateOptions: { maxZoom: 18, watch: true, enableHighAccuracy: true, maximumAge: 10000, timeout: 10000 } }).addTo(map); /* Larger screens get expanded layer control and visible sidebar */ if (document.body.clientWidth <= 767) { var isCollapsed = true; } else { var isCollapsed = false; } function createStopList(route) { var ul = L.DomUtil.create('ul', 'stop-list'); ul.style.listStyleImage = "url(" + LS.imagePath + "bus_stop.png)"; var busStops = map.routeLayer.getStops(); for (var i in route.properties.stops) { var stop = route.properties.stops[i]; var li = L.DomUtil.create('li', '', ul); var busStop = busStops[stop]; var a = L.DomUtil.create('a', '', li); if (typeof(busStop) !== "undefined") { a.textContent = busStop.properties.name; a.onclick = (function(uri) { return function() { if (document.body.clientWidth <= 767) { hideSidebars(); map.invalidateSize(); } map.routeLayer.panToStop(uri, { animate: true }); }; })(busStop.properties.uri); a.onmouseover = (function(uri) { return function() { map.routeLayer.highlightStop(uri); }; })(busStop.properties.uri); a.onmouseout = (function(uri) { return function() { map.routeLayer.resetStop(uri); }; })(busStop.properties.uri); } else { a.textContent = "Name Unknown"; } } return ul; } function createRouteList(routeMaster, routeSelected) { var ul = L.DomUtil.create('ul', 'route-list'); var stopLists = {}; for (var i in routeMaster.routes) { var route = routeMaster.routes[i]; var li = L.DomUtil.create('li', '', ul); var a = L.DomUtil.create('a', null, li); a.style.background = route.properties.colour; a.textContent = "U"; var strong = document.createElement("strong"); strong.textContent = route.properties.ref.slice(1); a.appendChild(strong); a.onclick = (function(routeName) { return function() { a.style.border = "2px"; routeSelected(routeName); }; })(route.properties.name); } return ul; } function buildBusRoutesControl() { function showStopList(name) { var previousActiveRoute = activeRouteForRouteMaster[activeRouteMaster]; console.log("hiding " + previousActiveRoute); stopLists[previousActiveRoute].style.display = "none"; descriptions[previousActiveRoute].style.display = "none" console.log("showing " + name); stopLists[name].style.display = "block"; descriptions[name].style.display = "block" } var busRouteSidebarContent = document.getElementById("busRoutesContent"); var routeMasters = map.routeLayer.getRouteMasters(); var routeMasterRouteLists = {}; var stopLists = {}; var descriptions = {}; var ul = L.DomUtil.create('ul', '', busRouteSidebarContent); ul.id = "route-master-list"; var routeMasterNames = Object.keys(routeMasters); routeMasterNames.sort(function(a, b) { var refs = { "U1": 1, "U2": 2, "U6": 6, "U9": 9, "U1N": 10 }; return refs[a] - refs[b]; }); var activeRouteMaster = "U1"; var activeRouteForRouteMaster = {}; for (var i in routeMasterNames) { var routeMasterName = routeMasterNames[i]; var routeMaster = routeMasters[routeMasterName]; var li = L.DomUtil.create('li', '', ul); var a = L.DomUtil.create('a', '', li); a.style.background = routeMaster.routes[0].properties.colour; a.textContent = "U"; var strong = document.createElement("strong"); strong.textContent = routeMasterName.slice(1); console.log(routeMaster); a.appendChild(strong); activeRouteForRouteMaster[routeMasterName] = routeMaster.routes[0].properties.name; a.onclick = (function(routeMasterName) { return function() { routeMasterRouteLists[activeRouteMaster].style.display = "none"; routeMasterRouteLists[routeMasterName].style.display = "block"; var activeRoute = activeRouteForRouteMaster[routeMasterName]; showStopList(activeRoute); activeRouteMaster = routeMasterName; map.routeLayer.resetRoutes(); map.routeLayer.highlightRoute(activeRoute); }; })(routeMasterName); // The route lists var routeList = createRouteList(routeMaster, function(routeName) { map.routeLayer.resetRoutes(); showStopList(routeName); activeRouteForRouteMaster[activeRouteMaster] = routeName; map.routeLayer.highlightRoute(routeName); }); routeMasterRouteLists[routeMasterName] = routeList; routeList.style.display = "none"; busRouteSidebarContent.appendChild(routeList); // The stops for (var i in routeMaster.routes) { var route = routeMaster.routes[i]; // Add the description var description = L.DomUtil.create('div', 'ls-route-description'); description.textContent = route.properties.name.split(": ")[1].replace("=>", "\u2192"); descriptions[route.properties.name] = description; // Add the list of stops var stopList = createStopList(route); stopLists[route.properties.name] = stopList; if (activeRouteMaster === routeMasterName && activeRouteForRouteMaster[routeMasterName] === route.properties.name) { stopList.style.display = "block"; description.style.display = "block"; } else { stopList.style.display = "none"; description.style.display = "none"; } busRouteSidebarContent.appendChild(description); busRouteSidebarContent.appendChild(stopList); } } routeMasterRouteLists[activeRouteMaster].style.display = "block"; } /* Typeahead search functionality */ LS.getData(function(data) { buildBusRoutesControl(); function buildRow(first, second) { var tr = document.createElement("tr"); tr.style = "cursor: pointer;" var reftd = document.createElement("td"); reftd.className = "feature-ref"; reftd.style.verticalAlign = "middle"; reftd.appendChild(first); tr.appendChild(reftd); var featuretd = document.createElement("td"); featuretd.className = "feature-name"; featuretd.appendChild(second); tr.appendChild(featuretd); var arrowtd = document.createElement("td"); arrowtd.style.verticalAlign = "middle"; var i = document.createElement("i"); i.className = "glyphicon glyphicon-chevron-right pull-right"; arrowtd.appendChild(i); tr.appendChild(arrowtd); return tr; } function show(uri) { return function() { map.panByURI(uri); /* Hide sidebars and go to the map on small screens */ if (document.body.clientWidth <= 767) { hideSidebars(); map.invalidateSize(); } }; } var buildingstbody = $("#buildingsList tbody"); data.buildings.features.forEach(function(building) { if (!("loc_ref" in building.properties) || building.properties.name.length === 0) { return; } var loc_ref = document.createTextNode(building.properties.loc_ref); var name = document.createTextNode(building.properties.name); var tr = buildRow(loc_ref, name); tr.onclick = show(building.properties.uri); buildingstbody.append(tr); }); var buildingsList = new List("buildings", { valueNames: [ "feature-ref", "feature-name" ] }); buildingsList.sort("feature-name", { order:"asc" }); buildingsList.on("filterStart", function() { console.log("filterComplete"); console.log(buildingsList.matchingItems); }); var sitestbody = $("#sitesList tbody"); data.sites.features.forEach(function(site) { if (!("name" in site.properties)) { return; } var loc_ref = document.createTextNode(site.properties.loc_ref); var name = document.createTextNode(site.properties.name); var tr = buildRow(loc_ref, name); tr.onclick = show(site.properties.uri); sitestbody.append(tr); }); var sitesList = new List("sites", {valueNames: ["feature-ref", "feature-name"]}); sitesList.sort("feature-name", {order:"asc"}); var buildingsBH = new Bloodhound({ name: "Buildings", datumTokenizer: function (d) { return Bloodhound.tokenizers.whitespace(d.properties.loc_ref + " " + d.properties.name); }, queryTokenizer: Bloodhound.tokenizers.whitespace, local: data.buildings.features, limit: 10 }); buildingsBH.initialize(); var sitesBH = new Bloodhound({ name: "Buildings", datumTokenizer: function (d) { return Bloodhound.tokenizers.whitespace(d.properties.loc_ref + " " +d.properties.name); }, queryTokenizer: Bloodhound.tokenizers.whitespace, local: data.sites.features, limit: 10 }); sitesBH.initialize(); var $searchbox = $("#searchbox"); /* Highlight search box text on click */ $searchbox.click(function () { $(this).select(); }); // prevent the page reloading $searchbox.submit(function () { return false; }); /* instantiate the typeahead UI */ $searchbox.typeahead({ minLength: 1, highlight: true, hint: false }, { name: "Buildings", displayKey: "name", source: buildingsBH.ttAdapter(), templates: { header: "