From 4d882e6d16036c99055cfb8df0bf8c25bcbb8d8c Mon Sep 17 00:00:00 2001 From: Jacek Kowalski <Jacek@jacekk.info> Date: Sun, 14 May 2017 22:21:25 +0000 Subject: [PATCH] Change alert view and add top menu --- map.js | 359 +++++++++++++++++++++++++++++++++++++---------------------- 1 files changed, 225 insertions(+), 134 deletions(-) diff --git a/map.js b/map.js index 550d05d..5a8c6bf 100644 --- a/map.js +++ b/map.js @@ -15,7 +15,6 @@ var stop_points_layer = null; var feature_clicked = null; -var feature_selected = []; var feature_xhr = null; var feature_timer = null; @@ -24,19 +23,58 @@ var map = null; var map_sphere = null; -var popup_element = document.getElementById('popup'); -var fail_element = document.getElementById('fail'); var ignore_hashchange = false; -function fail(msg) { - setText(fail_element, msg); - fail_element.style.top = '0.5em'; -} +var Panel = { + element: document.getElementById('panel'), + closeCallback: undefined, + + callCloseCallback: function() { + var callback = this.closeCallback; + this.closeCallback = null; + if(callback) callback(); + }, + + show: function(contents, closeCallback) { + this.callCloseCallback(); + this.closeCallback = closeCallback; + + deleteChildren(this.element); + + var close = addParaWithText(this.element, '×'); + close.className = 'close'; + close.addEventListener('click', this.hide.bind(this)); + + this.element.appendChild(contents); + + $(this.element).addClass('show'); + }, + + hide: function() { + this.callCloseCallback(); + + $(this.element).removeClass('show'); + }, + + fail: function(message) { + addParaWithText(this.element, message).className = 'error'; + }, +}; -function fail_popup(msg) { - addElementWithText(popup_element, 'p', msg).className = 'error'; -} +var Alert = { + element: document.getElementById('alert'), + + show: function(message) { + setText(this.element, message); + this.element.className = ''; + }, + + fail: function(message) { + this.show(message); + this.element.className = 'error'; + }, +}; function fail_ajax_generic(data, fnc) { // abort() is not a failure @@ -52,103 +90,113 @@ } function fail_ajax(data) { - fail_ajax_generic(data, fail); + fail_ajax_generic(data, Alert.fail.bind(Alert)); } function fail_ajax_popup(data) { - fail_ajax_generic(data, fail_popup); + fail_ajax_generic(data, Panel.fail.bind(Panel)); } function getGeometry(object) { return new ol.geom.Point(ol.proj.fromLonLat([object.longitude / 3600000.0, object.latitude / 3600000.0])); } -function styleVehicle(vehicle, selected) { - var color_type = 'black'; - if(vehicle.get('vehicle_type')) { - switch(vehicle.get('vehicle_type').low) { - case 0: - color_type = 'orange'; +var Style = { + specialSelection: 2, + selectedFeatures: [], + + getStyleForVehicle: function(vehicleFeature, isSelected) { + var color_type = 'black'; + if(vehicleFeature.get('vehicle_type')) { + switch(vehicleFeature.get('vehicle_type').low) { + case 0: + color_type = 'orange'; + break; + case 1: + color_type = 'blue'; + break; + case 2: + color_type = 'green'; + break; + } + } + + var fill = (isSelected ? '#a00' : '#3399ff'); + + var image = '<svg xmlns="http://www.w3.org/2000/svg" height="30" width="20"><polygon points="10,0 20,23 0,23" style="fill:'+fill+';stroke:'+color_type+';stroke-width:2" /></svg>'; + + return new ol.style.Style({ + image: new ol.style.Icon({ + src: 'data:image/svg+xml;base64,' + btoa(image), + rotation: Math.PI * parseFloat(vehicleFeature.get('heading')) / 180.0, + }), + text: new ol.style.Text({ + font: 'bold 10px sans-serif', + text: vehicleFeature.get('line'), + fill: new ol.style.Fill({color: 'white'}), + }), + }); + }, + + getStyleForStop: function(stopFeature, isSelected) { + var fill = 'orange'; + var stroke = 'red'; + var stroke_width = 1; + var radius = 3; + + if(isSelected == this.specialSelection) { + radius = 5; + } else if(isSelected) { + fill = 'red'; + stroke = '#900'; + stroke_width = 2; + radius = 5; + } + + return new ol.style.Style({ + image: new ol.style.Circle({ + fill: new ol.style.Fill({color: fill}), + stroke: new ol.style.Stroke({color: stroke, width: stroke_width}), + radius: radius, + }), + }); + }, + + getStyleForStopPoint: function(stopFeature, isSelected) { + return this.getStyleForStop(stopFeature, isSelected); + }, + + feature: function(feature, isSelected) { + if(!feature) return; + if(!feature.getId()) return; + + var style = null; + + switch(feature.getId().substr(0, 1)) { + case 'v': + style = this.getStyleForVehicle(feature, isSelected); break; - case 1: - color_type = 'blue'; + case 's': + style = this.getStyleForStop(feature, isSelected); break; - case 2: - color_type = 'green'; + case 'p': + style = this.getStyleForStopPoint(feature, isSelected); break; } - } - - var fill = (selected ? '#a00' : '#3399ff'); - - var image = '<svg xmlns="http://www.w3.org/2000/svg" height="30" width="20"><polygon points="10,0 20,23 0,23" style="fill:'+fill+';stroke:'+color_type+';stroke-width:2" /></svg>'; - - return new ol.style.Style({ - image: new ol.style.Icon({ - src: 'data:image/svg+xml;base64,' + btoa(image), - rotation: Math.PI * parseFloat(vehicle.get('heading')) / 180.0, - }), - text: new ol.style.Text({ - font: 'bold 10px sans-serif', - text: vehicle.get('line'), - fill: new ol.style.Fill({color: 'white'}), - }), - }); -} - -function styleStop(stop, selected) { - var fill = 'orange'; - var stroke = 'red'; - var stroke_width = 1; - var radius = 3; - - if(selected == 2) { - radius = 5; - } else if(selected) { - fill = 'red'; - stroke = '#900'; - stroke_width = 2; - radius = 5; - } - - return new ol.style.Style({ - image: new ol.style.Circle({ - fill: new ol.style.Fill({color: fill}), - stroke: new ol.style.Stroke({color: stroke, width: stroke_width}), - radius: radius, - }), - }); -} - -function styleFeature(feature, selected) { - if(!feature) return; - if(!feature.getId()) return; - - var style = null; - - switch(feature.getId().substr(0, 1)) { - case 'v': - style = styleVehicle(feature, selected); - break; - case 's': - case 'p': - style = styleStop(feature, selected); - break; - } + feature.setStyle(style); + if(isSelected) { + this.selectedFeatures.push(feature); + } + }, - feature.setStyle(style); - if(selected) { - feature_selected.push(feature); + unstyleSelected: function() { + for(var i = 0; i < this.selectedFeatures.length; i++) { + this.feature(this.selectedFeatures[i]); + } + this.selectedFeatures = []; } -} - -function unstyleSelectedFeatures() { - for(var i = 0; i < feature_selected.length; i++) { - styleFeature(feature_selected[i]); - } - feature_selected = []; -} +}; function updateVehicles() { if(vehicles_timer) clearTimeout(vehicles_timer); @@ -169,7 +217,7 @@ if(vehicle.isDeleted) { if(vehicle_feature) { vehicles_source.removeFeature(vehicle_feature); - if(feature_clicked.getId() == vehicle_feature.getId()) { + if(feature_clicked && feature_clicked.getId() == vehicle_feature.getId()) { featureClicked(); } } @@ -190,7 +238,7 @@ vehicle_feature = new ol.Feature(vehicle); vehicle_feature.setId('v' + vehicle.id); - styleFeature(vehicle_feature); + Style.feature(vehicle_feature); vehicles_source.addFeature(vehicle_feature); } else { vehicle_feature.setProperties(vehicle); @@ -218,7 +266,7 @@ var stop_feature = new ol.Feature(stop); stop_feature.setId(prefix + stop.id); - styleFeature(stop_feature); + Style.feature(stop_feature); source.addFeature(stop_feature); } @@ -257,7 +305,7 @@ + '?tripId=' + encodeURIComponent(tripId) + '&mode=departure' ).done(function(data) { - if(!data.routeName || !data.directionText || data.old.length + data.actual.length == 0) { + if(!data.routeName || !data.directionText) { return; } @@ -272,15 +320,15 @@ table.appendChild(tr); } - unstyleSelectedFeatures(); - styleFeature(feature_clicked, true); + Style.unstyleSelected(); + Style.feature(feature_clicked, true); for(var i = 0, il = data.actual.length; i < il; i++) { var tr = document.createElement('tr'); addCellWithText(tr, data.actual[i].actualTime || data.actual[i].plannedTime); addCellWithText(tr, data.actual[i].stop_seq_num + '. ' + data.actual[i].stop.name); - styleFeature(stops_source.getFeatureById('s' + data.actual[i].stop.id), 2); + Style.feature(stops_source.getFeatureById('s' + data.actual[i].stop.id), 2); if(data.actual[i].status == 'STOPPING') { tr.className = 'success'; @@ -293,7 +341,7 @@ if(!vehicleId) return; feature_xhr = $.get( - ttss_base + '/internetservice/geoserviceDispatcher/services/pathinfo/vehicle' + ttss_base + '/geoserviceDispatcher/services/pathinfo/vehicle' + '?id=' + encodeURIComponent(vehicleId) ).done(function(data) { if(!data || !data.paths || !data.paths[0] || !data.paths[0].wayPoints) return; @@ -371,27 +419,17 @@ function featureClicked(feature) { if(feature && !feature.getId()) return; - unstyleSelectedFeatures(); + Style.unstyleSelected(); route_source.clear(); if(!feature) { - feature_clicked = null; - - $(popup_element).removeClass('show'); - - ignore_hashchange = true; - window.location.hash = ''; - + Panel.hide(); return; } var coordinates = feature.getGeometry().getCoordinates(); - deleteChildren(popup_element); - - var close = addParaWithText(popup_element, '×'); - close.className = 'close'; - close.addEventListener('click', function() { featureClicked(); }); + var div = document.createElement('div'); var type; var name = feature.get('name'); @@ -458,27 +496,39 @@ var loader = addElementWithText(tbody, 'td', lang.loading); loader.className = 'active'; - loader.colspan = thead.childNodes.length; + loader.colSpan = thead.childNodes.length; - addParaWithText(popup_element, type).className = 'type'; - addParaWithText(popup_element, name).className = 'name'; + addParaWithText(div, type).className = 'type'; + addParaWithText(div, name).className = 'name'; if(additional) { - popup_element.appendChild(additional); + div.appendChild(additional); } - popup_element.appendChild(table); + div.appendChild(table); - ignore_hashchange = true; - window.location.hash = '#!' + feature.getId(); - - styleFeature(feature, true); + Style.feature(feature, true); setTimeout(function () {map.getView().animate({ center: feature.getGeometry().getCoordinates(), }) }, 10); - $(popup_element).addClass('show'); + ignore_hashchange = true; + window.location.hash = '#!' + feature.getId(); + + Panel.show(div, function() { + if(!ignore_hashchange) { + ignore_hashchange = true; + window.location.hash = ''; + + feature_clicked = null; + Style.unstyleSelected(); + route_source.clear(); + + if(feature_xhr) feature_xhr.abort(); + if(feature_timer) clearTimeout(feature_timer); + } + }); feature_clicked = feature; } @@ -546,7 +596,7 @@ function init() { if(!window.jQuery) { - fail(lang.jquery_not_loaded); + Alert.show(lang.jquery_not_loaded); return; } @@ -560,6 +610,7 @@ }); stops_layer = new ol.layer.Vector({ source: stops_source, + }); stop_points_source = new ol.source.Vector({ @@ -572,6 +623,7 @@ vehicles_source = new ol.source.Vector({ features: [], + attributions: lang.copy_zikit, }); vehicles_layer = new ol.layer.Vector({ source: vehicles_source, @@ -579,6 +631,7 @@ route_source = new ol.source.Vector({ features: [], + attributions: lang.copy_jacekk, }); route_layer = new ol.layer.Vector({ source: route_source, @@ -591,7 +644,9 @@ target: 'map', layers: [ new ol.layer.Tile({ - source: new ol.source.OSM() + source: new ol.source.OSM({ + attributions: lang.copy_osm, + }) }), route_layer, stops_layer, @@ -606,14 +661,7 @@ attributionOptions: ({ collapsible: false, }) - }).extend([ - new ol.control.Control({ - element: document.getElementById('title'), - }), - new ol.control.Control({ - element: fail_element, - }) - ]), + }), loadTilesWhileAnimating: true, }); map_sphere = new ol.Sphere(6378137); @@ -621,8 +669,50 @@ // Display popup on click map.on('singleclick', function(e) { var point = e.coordinate; - var feature = map.forEachFeatureAtPixel(e.pixel, function(feature) { return feature; }); + var features = []; + map.forEachFeatureAtPixel(e.pixel, function(feature) { if(feature.getId()) features.push(feature); }); + if(features.length > 1) { + var div = document.createElement('div'); + + addParaWithText(div, lang.select_feature); + + for(var i = 0; i < features.length; i++) { + var feature = features[i]; + + var p = document.createElement('p'); + var a = document.createElement('a'); + p.appendChild(a); + a.addEventListener('click', function(feature) { return function() { + featureClicked(feature); + }}(feature)); + + var type = ''; + switch(feature.getId().substr(0, 1)) { + case 'v': + type = lang.type_vehicle + ' ' + feature.get('vehicle_type').num; + break; + case 's': + type = lang.type_stop; + break; + case 'p': + type = lang.type_stoppoint; + break; + } + + addElementWithText(a, 'span', type).className = 'small'; + a.appendChild(document.createTextNode(' ')); + addElementWithText(a, 'span', feature.get('name')); + + div.appendChild(p); + } + + Panel.show(div); + + return; + } + + var feature = features[0]; if(!feature) { if(stops_layer.getVisible()) { feature = returnClosest(point, feature, stops_source.getClosestFeatureToCoordinate(point)); @@ -668,8 +758,9 @@ if(vehicles_xhr) vehicles_xhr.abort(); if(vehicles_timer) clearTimeout(vehicles_timer); - fail(lang.error_refresh); + Alert.show(lang.error_refresh); }, 1800000); } init(); +checkVersion(); -- Gitblit v1.9.1