/* * Copyright (c) 2011 Metropolitan Transportation Authority * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var OBA = window.OBA || {}; // do not add constructor params here! OBA.Popups = (function() { var infoWindow = null; var refreshPopupRequest = null; var stopBubbleListener = null, stopBubbleTrigger = null; function closeInfoWindow() { if(infoWindow !== null) { infoWindow.close(); } infoWindow = null; } // PUBLIC METHODS function showPopupWithContent(map, marker, content) { closeInfoWindow(); infoWindow = new google.maps.InfoWindow({ pixelOffset: new google.maps.Size(0, (marker.getIcon().size.height / 2)), disableAutoPan: false }); google.maps.event.addListener(infoWindow, "closeclick", closeInfoWindow); infoWindow.setContent(content); infoWindow.open(map, marker); } function showPopupWithContentFromRequest(map, marker, url, params, contentFn, routeFilter) { closeInfoWindow(); infoWindow = new google.maps.InfoWindow({ pixelOffset: new google.maps.Size(0, (marker.getIcon().size.height / 2)), disableAutoPan: false, stopId: marker.stopId // to lock an icon on the map when a popup is open for it }); google.maps.event.addListener(infoWindow, "closeclick", closeInfoWindow); var popupContainerId = "container" + Math.floor(Math.random() * 1000000); var refreshFn = function(openBubble) { // pass a new "now" time for debugging if we're given one if(OBA.Config.time !== null) { params.time = OBA.Config.time; } if( typeof refreshPopupRequest !== 'undefined' && refreshPopupRequest !== null) { if ('abort' in refreshPopupRequest) { refreshPopupRequest.abort(); } openBubble = true; } refreshPopupRequest = jQuery.getJSON(url, params, function(json) { if(infoWindow === null) { return; } var preload_content = jQuery("#" + popupContainerId); var scroll = preload_content.scrollTop(); infoWindow.setContent(contentFn(json, popupContainerId, marker, routeFilter)); if(openBubble === true) { infoWindow.open(map, marker); } // hack to prevent scrollbars in the IEs var sizeChanged = false; var content = jQuery("#" + popupContainerId); if(content.height() > 300) { content.css("overflow-y", "scroll") .css("height", "280"); sizeChanged = true; } if(content.width() > 500) { content.css("overflow-x", "hidden") .css("width", "480"); sizeChanged = true; } if(sizeChanged) { infoWindow.setContent(content.get(0)); infoWindow.open(map, marker); } content.scrollTop(scroll); }); }; refreshFn(true); infoWindow.refreshFn = refreshFn; var updateTimestamp = function() { var timestampContainer = jQuery("#" + popupContainerId).find(".updated"); if(timestampContainer.length === 0) { return; } var age = parseInt(timestampContainer.attr("age"), 10); var referenceEpoch = parseInt(timestampContainer.attr("referenceEpoch"), 10); var newAge = age + ((new Date().getTime() - referenceEpoch) / 1000); timestampContainer.text("Data updated " + OBA.Util.displayTime(newAge)); }; updateTimestamp(); infoWindow.updateTimestamp = updateTimestamp; } // CONTENT GENERATION // this method is no longer used.... function getServiceAlerts(r, situationRefs) { var html = ''; var situationIds = {}; var situationRefsCount = 0; if (situationRefs != null) { jQuery.each(situationRefs, function(_, situation) { situationIds[situation.SituationSimpleRef] = true; situationRefsCount += 1; }); } if (situationRefs == null || situationRefsCount > 0) { if (r.Siri.ServiceDelivery.SituationExchangeDelivery != null && r.Siri.ServiceDelivery.SituationExchangeDelivery.length > 0) { jQuery.each(r.Siri.ServiceDelivery.SituationExchangeDelivery[0].Situations.PtSituationElement, function(_, ptSituationElement) { var situationId = ptSituationElement.SituationNumber; if (ptSituationElement.Description && (situationRefs == null || situationIds[situationId] === true)) { html += '
Service Change:
' + activity.MonitoredVehicleJourney.PublishedLineName + " " + activity.MonitoredVehicleJourney.DestinationName + '
'; //don't show block id if there is none or if config says no if (OBA.Config.showBlockIdInVehiclePopup == 'false' || typeof blockIdWithoutAgency === 'undefined' || blockIdWithoutAgency === null) { html += 'Vehicle #' + vehicleIdWithoutAgency + ''; } else { html += 'Vehicle #' + vehicleIdWithoutAgency + ' - ' + blockIdWithoutAgency + ''; } var updateTimestamp = OBA.Util.ISO8601StringToDate(activity.RecordedAtTime).getTime(); var updateTimestampReference = OBA.Util.ISO8601StringToDate(r.Siri.ServiceDelivery.ResponseTimestamp).getTime(); var age = (parseInt(updateTimestampReference, 10) - parseInt(updateTimestamp, 10)) / 1000; var staleClass = ((age > OBA.Config.staleTimeout) ? " stale" : ""); html += 'Data updated ' + OBA.Util.displayTime(age) + ''; // (end header) html += '
'; html += 'Next stops are not known for this vehicle.
'; } else { if(typeof activity.MonitoredVehicleJourney.OnwardCalls !== 'undefined' && typeof activity.MonitoredVehicleJourney.OnwardCalls.OnwardCall !== 'undefined') { var lastExpectedArrivalTime = null; // SIRI occasionally gives us historical info -- if all calls are older than staleTimeout don't display jQuery.each(activity.MonitoredVehicleJourney.OnwardCalls.OnwardCall, function(_, onwardCall) { if(typeof onwardCall.ExpectedArrivalTime !== 'undefined' && onwardCall.ExpectedArrivalTime !== null) { var staleThresholdDate = new Date(updateTimestampReference - (OBA.Config.staleTimeout*1000)).getTime(); if (OBA.Util.ISO8601StringToDate(onwardCall.ExpectedArrivalTime).getTime() > staleThresholdDate) { lastExpectedArrivalTime = OBA.Util.ISO8601StringToDate(onwardCall.ExpectedArrivalTime); } } } ); if (lastExpectedArrivalTime === null) { // we have nothing to show //console.log("no valid arrivals for " + vehicleId); } else { html += 'Next stops:
'; // Alert if Realtime Data is unavailable if(!hasRealtime){ html += 'Realtime data currently unavailable for this vehicle
Occupancy: '+occupancyLoad+'
'; } function getOccupancyForStop(MonitoredVehicleJourney){ var occupancyLoad = getOccupancy(MonitoredVehicleJourney, false); if (occupancyLoad == '') return ''; else return occupancyLoad; } function getStopContentForResponse(r, popupContainerId, marker, routeFilter) { var siri = r.siri; var stopResult = r.stop; var alertData = processAlertData(r.siri.Siri.ServiceDelivery.SituationExchangeDelivery); var html = '' + stopResult.name + '
'; html += '' + OBA.Config.stopTerm + ' ' + stopCode + ''; // update time across all arrivals var updateTimestampReference = OBA.Util.ISO8601StringToDate(siri.Siri.ServiceDelivery.ResponseTimestamp).getTime(); var maxUpdateTimestamp = null; var monitoredStopVisit = []; if(siri.Siri.ServiceDelivery.StopMonitoringDelivery[0].MonitoredStopVisit){ monitoredStopVisit = siri.Siri.ServiceDelivery.StopMonitoringDelivery[0].MonitoredStopVisit; } jQuery.each(monitoredStopVisit, function(_, monitoredJourney) { var updateTimestamp = OBA.Util.ISO8601StringToDate(monitoredJourney.RecordedAtTime).getTime(); if(updateTimestamp > maxUpdateTimestamp) { maxUpdateTimestamp = updateTimestamp; } }); if (maxUpdateTimestamp === null) { maxUpdateTimestamp = updateTimestampReference; } if(maxUpdateTimestamp !== null) { var age = (parseInt(updateTimestampReference, 10) - parseInt(maxUpdateTimestamp, 10)) / 1000; var staleClass = ((age > OBA.Config.staleTimeout) ? " stale" : ""); html += 'Data updated ' + OBA.Util.displayTime(age) + ''; } // (end header) html += '
'; html += '" + OBA.Config.serviceAlertText + " for " + stopCode + ". Click for info
"); var serviceAlertList = jQuery("" + "Buses en-route:
'; jQuery.each(routeAndDirectionWithArrivals, function(_, mvjs) { var mvj = mvjs[0]; html += 'No buses en-route to this stop for:
'; html += 'No scheduled service at this time for:
'; html += '