diff options
Diffstat (limited to 'src/leaflet-soton.js')
-rw-r--r-- | src/leaflet-soton.js | 376 |
1 files changed, 354 insertions, 22 deletions
diff --git a/src/leaflet-soton.js b/src/leaflet-soton.js index 3e030dc..aea9f1c 100644 --- a/src/leaflet-soton.js +++ b/src/leaflet-soton.js @@ -70,21 +70,25 @@ var contents = part.properties.contents; - for (var j=0; j<contents.length; j++) { - var content = contents[j]; + if (contents) { + for (var j=0; j<contents.length; j++) { + var content = contents[j]; - if (content.feature === uri) { - return part; + if (content.feature === uri) { + return part; + } } } var features = part.properties.features; - for (var j=0; j<features.length; j++) { - var feature = features[j]; + if (features) { + for (var j=0; j<features.length; j++) { + var feature = features[j]; - if (feature.feature === uri) { - return part; + if (feature.feature === uri) { + return part; + } } } } @@ -315,7 +319,7 @@ SELECT * WHERE {\ var emptyFeatureCollection = { type: "FeatureCollection", features: [] }; var transparaentStyle = function(feature) {return {weight: 0, opacity: 0, fillOpacity: 0};}; - var layerNames = ['sites', 'parking', 'bicycleParking', 'buildings', 'busStops', 'busRoutes']; + var layerNames = ['sites', 'parking', 'bicycleParking', 'buildings']; var busRouteStyle = function(feature) { return {weight: 5, opacity: 0.5, color: feature.properties.colour}; @@ -325,6 +329,8 @@ SELECT * WHERE {\ options: { center: [50.9354, -1.3964], indoor: false, + busRoutes: false, + busRouteControl: false, workstations: false, zoom: 17, tileUrl: 'http://bus.southampton.ac.uk/graphics/map/tiles/{z}/{x}/{y}.png', @@ -379,8 +385,6 @@ SELECT * WHERE {\ options.highlight[feature.properties.uri]) { return {weight: 5, opacity: 0.5, color: 'blue'}; - } else if (layerName === "busRoutes") { - return busRouteStyle(feature); } else { return blankStyle(); } @@ -421,15 +425,6 @@ SELECT * WHERE {\ }; } - if (layerName === "busStops") { - layerOptions.pointToLayer = function (feature, latlng) { - return L.circleMarker(latlng, { - radius: 8, - opacity: 1, - }); - }; - } - layers[layerName] = L.geoJson(emptyFeatureCollection, layerOptions).addTo(map); }); @@ -458,6 +453,46 @@ SELECT * WHERE {\ layer.addData(data[layerName]); } + var routeLayer = new LS.RouteLayer(data.busRoutes, data.busStops, { + routeOptions: { + onEachFeature: function(feature, layer) { + layer.on('click', function(e) { + var content = busRouteTemplate(feature.properties); + + showPopup(map, content, e.latlng); + }); + }, + style: options.busRoutes ? busRouteStyle : blankStyle + }, + stopOptions: { + onEachFeature: function(feature, layer) { + layer.on('click', function(e) { + var content = busStopTemplate(feature.properties); + + showPopup(map, content, e.latlng); + }); + } + } + }); + routeLayer.addTo(map); + + if (options.busRouteControl) { + var routeControl = new LS.RouteControl(routeLayer, { + routeMasterSort: function(a, b) { + var refs = { + "U1": 1, + "U2": 2, + "U6": 6, + "U9": 9, + "U1N": 10 + }; + + return refs[a] - refs[b]; + } + }); + routeControl.addTo(map); + } + LS.getWorkstationData(function(workstationData) { if (options.indoor) { @@ -893,8 +928,6 @@ SELECT * WHERE {\ buildings: buildingTemplate, bicycleParking: bicycleParkingTemplate, parking: parkingTemplate, - busStops: busStopTemplate, - busRoutes: busRouteTemplate }; function roomPopupTemplate(properties) { @@ -1592,6 +1625,305 @@ SELECT * WHERE {\ return window.innerWidth < 500; } + LS.RouteLayer = L.FeatureGroup.extend({ + initialize: function (routes, stops, options) { + L.setOptions(this, options); + + this._layers = {}; + + this._routeMasters = {}; + + for (var i in routes.features) { + var route = routes.features[i]; + + if ("routeMaster" in route.properties) { + var routeMaster = route.properties.routeMaster; + + if (routeMaster in this._routeMasters) { + this._routeMasters[routeMaster].routes.push(route); + } else { + this._routeMasters[routeMaster] = { + name: routeMaster, + routes: [ route ] + }; + } + } else { + this._routeMasters[route.properties.ref] = { + name: route.properties.ref, + routes: [ route ] + }; + } + } + + this._routes = routes; + this._busStops = {}; + + for (i in stops.features) { + var busStop = stops.features[i]; + + this._busStops[busStop.properties.uri] = busStop; + } + + var routeLayers = this._routeLayers = {} + this._routeLayer = new L.GeoJSON(routes, { + onEachFeature: function(feature, layer) { + routeLayers[feature.properties.name] = layer; + + if (options.routeOptions.onEachFeature) { + options.routeOptions.onEachFeature(feature, layer); + } + }, + style: options.routeOptions.style + }); + this.addLayer(this._routeLayer); + + var stopLayers = this._stopLayers = {}; + this._stopLayer = new L.GeoJSON(stops, { + onEachFeature: function(feature, layer) { + stopLayers[feature.properties.uri] = layer; + + if (options.stopOptions.onEachFeature) { + console.log("stops"); + options.stopOptions.onEachFeature(feature, layer); + } + }, + pointToLayer: function (feature, latlng) { + return L.circleMarker(latlng, { + radius: 8, + opacity: 0, + }); + }, + style: function(feature) { + return { + radius: 8, + opacity: 0, + fillOpacity: 0 + }; + } + }); + this.addLayer(this._stopLayer); + }, + getRouteMasters: function() { + return this._routeMasters; + }, + getRoutesForRouteMaster: function(id) { + return this._routeMasters[id]; + }, + getRoutes: function() { + return this._routes; + }, + getStops: function() { + return this._busStops; + }, + highlightRoute: function(id) { + var layer = this._routeLayers[id]; + + layer.setStyle({ + weight: 10, + opacity: 1, + }); + + layer.setText('\u25BA', { + repeat: true, + offset: 3, + attributes: { + fill: 'black', + fontSize: 24 + } + }); + + layer.bringToFront(); + }, + resetRoute: function(id) { + var layer = this._routeLayers[id]; + + this._routeLayer.resetStyle(layer); + + layer.setText(null); + }, + highlightStop: function(id) { + var layer = this._stopLayers[id]; + + layer.setStyle({ + color: '#ff0000', + opacity: 1, + fillOpacity: 0.3, + radius: 16, + stroke: true, + fill: true + }); + }, + resetStop: function(id) { + var layer = this._stopLayers[id]; + + this._stopLayer.resetStyle(layer); + }, + panToStop: function(id, panOptions) { + var layer = this._stopLayers[id]; + + this._map.panTo(layer._latlng, panOptions); + } + }); + + LS.RouteControl = L.Control.extend({ + initialize: function (routeLayer, options) { + L.setOptions(this, options); + + this._routeLayer = routeLayer; + }, + onAdd: function (map) { + this._div = L.DomUtil.create('div', 'ls-route-control'); + + var title = L.DomUtil.create('div', 'ls-routes-title', this._div); + title.textContent = "University Bus Routes"; + + var routeMasters = this._routeLayer.getRouteMasters(); + + var routeMasterRouteLists = {}; + + var ul = L.DomUtil.create('ul', 'ls-route-master-list', this._div); + + var routeMasterNames = Object.keys(routeMasters); + if (this.options.routeMasterSort) { + routeMasterNames.sort(this.options.routeMasterSort); + } + + 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 = routeMaster.name; + a.onclick = (function(routeMasterName) { + return function() { + routeMasterRouteLists[activeRouteMaster].style.display = "none"; + routeMasterRouteLists[routeMasterName].style.display = "block"; + activeRouteMaster = routeMasterName; + }; + })(routeMasterName); + + // The route lists + + var routeList = this._createRouteList(routeMaster); + routeMasterRouteLists[routeMasterName] = routeList; + + routeList.style.display = "none"; + + this._div.appendChild(routeList); + } + + var activeRouteMaster = "U1"; // TODO: Dont hardcode like this + + routeMasterRouteLists[activeRouteMaster].style.display = "block"; + + return this._div; + }, + _createRouteList: function(routeMaster) { + var div = L.DomUtil.create('div', null); + + var ul = L.DomUtil.create('ul', 'ls-route-list', div); + + var routeLayer = this._routeLayer; + + 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.borderColor = route.properties.colour; + a.style.background = route.properties.colour; + + a.textContent = route.properties.ref; + a.onclick = (function(routeName) { + return function() { + stopLists[activeStopList].style.display = "none"; + stopLists[routeName].style.display = "block"; + activeStopList = routeName; + }; + })(route.properties.name); + + a.onmouseover = (function(name) { + return function() { + routeLayer.highlightRoute(name); + }; + })(route.properties.name); + a.onmouseout = (function(name) { + return function() { + routeLayer.resetRoute(name); + }; + })(route.properties.name); + + // The stops + + var stopList = this._createStopList(route); + stopLists[route.properties.name] = stopList; + + stopList.style.display = "none"; + + div.appendChild(stopList); + } + + var activeStopList = routeMaster.routes[0].properties.name; + stopLists[activeStopList].style.display = "block"; + + return div; + }, + _createStopList: function(route) { + var div = L.DomUtil.create('div', null, this._div); + + var description = L.DomUtil.create('div', 'ls-route-description', div); + description.textContent = route.properties.name.split(": ")[1].replace("=>", "\u2192"); + + var ul = L.DomUtil.create('ul', 'ls-stop-list', div); + + ul.style.listStyleImage = "url(" + LS.imagePath + "bus_stop.png)"; + + var routeLayer = this._routeLayer; + var busStops = 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() { + routeLayer.panToStop(uri, { + animate: true + }); + }; + })(busStop.properties.uri); + a.onmouseover = (function(uri) { + return function() { + routeLayer.highlightStop(uri); + }; + })(busStop.properties.uri); + a.onmouseout = (function(uri) { + return function() { + routeLayer.resetStop(uri); + }; + })(busStop.properties.uri); + } else { + a.textContent = "Name Unknown"; + } + } + + return div; + } + }); + // Custom Hash Support if ("Hash" in L) { |