All Downloads are FREE. Search and download functionalities are using the official Maven repository.

client.js.otp.modules.planner.ItinerariesWidget.js Maven / Gradle / Ivy

There is a newer version: 2.6.0
Show newest version
/* This program is free software: you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public License
   as published by the Free Software Foundation, either version 3 of
   the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see .
*/

otp.namespace("otp.widgets");

otp.widgets.ItinerariesWidget =
    otp.Class(otp.widgets.Widget, {

    module : null,

    itinsAccord : null,
    footer : null,

    itineraries : null,
    activeIndex : 0,
    previousPageCursor: null,
    nextPageCursor: null,

    // set to true by next/previous/etc. to indicate to only refresh the currently active itinerary
    refreshActiveOnly : false,
    showButtonRow : true,
    showItineraryLink : true,
    showPrintLink : true,
    showEmailLink : true,
    showSearchLink : false,


    initialize : function(id, module) {
        this.module = module;

        otp.widgets.Widget.prototype.initialize.call(this, id, module, {
            //TRANSLATORS: Widget title
            title : _tr("Itineraries"),
            cssClass : module.itinerariesWidgetCssClass || 'otp-defaultItinsWidget',
            resizable : true,
            closeable : true,
            persistOnClose : true
        });
        //this.$().addClass('otp-itinsWidget');
        //this.$().resizable();
        //this.minimizable = true;
        //this.addHeader("X Itineraries Returned");
    },

    activeItin : function() {
        return this.itineraries[this.activeIndex];
    },

    updatePlan : function(plan) {
        this.updateItineraries(
            plan.itineraries,
            plan.queryParams,
            undefined,
            plan.previousPageCursor,
            plan.nextPageCursor
        );
    },

    updateItineraries : function(
        itineraries,
        queryParams,
        itinIndex,
        previousPageCursor,
        nextPageCursor
    ) {

        var this_ = this;
        var divId = this.id+"-itinsAccord";

        if(this.minimized) this.unminimize();

        if(this.refreshActiveOnly == true) { // if only refreshing one itinerary; e.g. if next/prev was used

            // swap the old itinerary for the new one in both the TripPlan object and the local array
            var newItin = itineraries[0];
            var oldItin = this.itineraries[this.activeIndex];
            oldItin.tripPlan.replaceItinerary(this.activeIndex, newItin);
            this.itineraries[this.activeIndex] = newItin;

            // create an alert if we moved to another day
            var alerts = null;
            if(newItin.differentServiceDayFrom(oldItin)) {
                alerts = [ _tr("This itinerary departs on a different day from the previous one") ];
            }

            // refresh all itinerary headers
            this.renderHeaders();

            // refresh the main itinerary content
            var itinContainer = $('#'+divId+'-'+this.activeIndex);
            itinContainer.empty();
            this.renderItinerary(newItin, this.activeIndex, alerts).appendTo(itinContainer);
            this.refreshActiveOnly = false;
            return;
        }

        this.itineraries = itineraries;
        this.previousPageCursor = previousPageCursor;
        this.nextPageCursor = nextPageCursor;

        this.clear();
        //TRANSLATORS: widget title
        this.setTitle(ngettext("%d Itinerary Returned", "%d Itineraries Returned", this.itineraries.length));

        var html = "
"; this.itinsAccord = $(html).appendTo(this.$()); this.footer = $('").appendTo(this.footer); //TRANSLATORS: button to next page of itineraries $('').button().appendTo(buttonRow).click(function() { var params = this_.module.lastQueryParams; _.extend(params, { pageCursor : this_.previousPageCursor, }); this_.refreshActiveOnly = false; this_.module.updateActiveOnly = false; this_.module.planTripFunction.call(this_.module, params); }); //TRANSLATORS: button to next page of itineraries $('').button().appendTo(buttonRow).click(function() { var params = this_.module.lastQueryParams; _.extend(params, { pageCursor : this_.nextPageCursor, }); this_.refreshActiveOnly = false; this_.module.updateActiveOnly = false; this_.module.planTripFunction.call(this_.module, params); }); }, // returns HTML text headerContent : function(itin, index) { // show number of this itinerary (e.g. "1.") //var html= '
'+(index+1)+'.
'; /* // show iconographic trip leg summary html += '
'+itin.getIconSummaryHTML()+'
'; // show trip duration html += '
('+itin.getDurationStr()+')
'; if(itin.groupSize) { html += '
[Group size: '+itin.groupSize+']
'; } */ var div = $('
'); div.append('
'+(index+1)+'
'); console.log("header div width: "+div.width()); // clear div //html += '
'; return div; }, renderHeaders : function() { for(var i=0; i
').appendTo(parentDiv); div.append('
'+(index+1)+'.
'); var maxSpan = itin.tripPlan.latestEndTime - itin.tripPlan.earliestStartTime; var startPct = (itin.itinData.startTime - itin.tripPlan.earliestStartTime) / maxSpan; var itinSpan = itin.getEndTime() - itin.getStartTime(); var timeWidth = 40; var startPx = 20+timeWidth, endPx = div.width()-timeWidth - (itin.groupSize ? 48 : 0); var pxSpan = endPx-startPx; var leftPx = startPx + startPct * pxSpan; var widthPx = pxSpan * (itinSpan / maxSpan); div.append('
'); var timeStr = otp.util.Time.formatItinTime(itin.getStartTime(), otp.config.locale.time.time_format); /*timeStr = timeStr.substring(0, timeStr.length - 1);*/ div.append('
' + timeStr + '
'); var timeStr = otp.util.Time.formatItinTime(itin.getEndTime(), otp.config.locale.time.time_format); /*timeStr = timeStr.substring(0, timeStr.length - 1);*/ div.append('
' + timeStr + '
'); for(var l=0; l
'); var legTextColor = otp.util.Itin.getLegTextColor(leg); var legBackgroundColor = otp.util.Itin.getLegBackgroundColor(leg); var routeTitle = _.chain([leg.mode, leg.agencyName, leg.routeShortName, leg.routeLongName]) .filter(function (value) { return !!value; }) .reduce(function (l, r) { return l ? l + " " + r : r; }, "") .value(); var showRouteLabel = widthPx > 40 && otp.util.Itin.isTransit(leg.mode) && leg.routeShortName && leg.routeShortName.length <= 6; var segment = $('
') .css({ width: widthPx, left: leftPx, color: legTextColor, background: legBackgroundColor, }) .appendTo(div); segment.append('
'); if(showRouteLabel) segment.append(''+leg.routeShortName+''); } if(itin.groupSize) { var segment = $('
'+itin.groupSize+'
') .appendTo(div); } }, renderElevationGraphContent : function(itin, index) { if (!itin) { return; } var graph = $("#" + this.id + '-itinElevationGraph-' + index); var width = graph.width(); var graphSegments = []; var transitParts = 0; var onStreetLength = 0; var hasElevation = false; var minElevation = Number.MAX_VALUE; var maxElevation = Number.MIN_VALUE; for (var l = 0; l < itin.itinData.legs.length; l++) { var leg = itin.itinData.legs[l]; if (otp.util.Itin.isTransit(leg.mode)) { graphSegments.push({ leg: leg, mode: leg.mode, textColor: otp.util.Itin.getLegTextColor(leg), backgroundColor: otp.util.Itin.getLegBackgroundColor(leg), transit: true, distance: onStreetLength, transitParts: transitParts, }); transitParts++; } else { var graphPoints = []; if (leg.legElevation) { var regex = /([0-9.]+),([0-9.]+|NaN)/g; var m; while (m = regex.exec(leg.legElevation)) { var elevation = Number.parseFloat(m[2]); if (!Number.isNaN(elevation)) { minElevation = Math.min(minElevation, elevation); maxElevation = Math.max(maxElevation, elevation); } graphPoints.push({ elevation: elevation, distance: onStreetLength + Number.parseFloat(m[1]) }); } hasElevation = true; } graphSegments.push({ leg: leg, transit: false, mode: leg.mode, textColor: otp.util.Itin.getLegTextColor(leg), backgroundColor: otp.util.Itin.getLegBackgroundColor(leg), fromDistance: onStreetLength, toDistance: onStreetLength + leg.distance, graphPoints: graphPoints, transitParts: transitParts, }) onStreetLength += leg.distance; } } var elevationBuffer = (maxElevation - minElevation) * 0.1; minElevation = Math.floor((minElevation - elevationBuffer) / 10) * 10; maxElevation = Math.ceil((maxElevation + elevationBuffer) / 10) * 10; graph.empty(); graph.css({display: hasElevation ? 'inline' : 'none'}); if (hasElevation) { // jquery has problems handling alternate namespaces, so elements are created explicitly var svg = function (elementName, attributes, content) { var element = document.createElementNS('http://www.w3.org/2000/svg', elementName) for (var attr in attributes) if (attributes.hasOwnProperty(attr)) { element.setAttribute(attr, attributes[attr]); } element.textContent = content || ""; return element; }; var graphX = function (transitParts, distance) { return labelWidth + Math.round(distance * pm + transitParts * iconWidth); }; var drawMode = function (point, fromX, toX) { graph.append(svg('rect', { class: "mode", x: fromX + 1, y: 119, width: toX - fromX - 2, height: iconWidth - 2, rx: 2, fill: point.backgroundColor, })); if (toX - fromX >= iconWidth) { graph.append(svg('rect', { class: "mode", x: fromX + 1, y: 119, width: toX - fromX - 2, height: iconWidth - 2, rx: 2, fill: point.textColor, style: "mask: url(" + otp.config.resourcePath + 'images/mode/' + point.mode.toLowerCase() + '.png' + ") center no-repeat", })); } }; var labelWidth = 50; var iconWidth = 22; var endPadding = 10; var streetPixels = width - labelWidth - endPadding - (iconWidth * transitParts); var pm = streetPixels / onStreetLength; _(graphSegments).each(function (segment) { if (segment.transit) { var pointX = graphX(segment.transitParts, segment.distance); drawMode(segment, pointX, pointX + iconWidth); } else { var firstPointX = graphX(segment.transitParts, segment.fromDistance); var lastPointX = graphX(segment.transitParts, segment.toDistance); drawMode(segment, firstPointX, lastPointX); function finishGraphSegment() { if (firstPoint && lastPoint) { path += ' L ' + lastPoint.x + ',115'; path += ' L ' + firstPoint.x + ',115 Z'; graph.append(svg('path', { style: 'elevation', d: path, fill: segment.backgroundColor, })); firstPoint = null; lastPoint = null; path = ''; } } var path = '', firstPoint, lastPoint; _(segment.graphPoints).each(function (graphPoint) { graphPoint.x = graphX(segment.transitParts, graphPoint.distance); if (Number.isNaN(graphPoint.elevation)) { finishGraphSegment(); } else { graphPoint.y = Math.round(10 + 105 * (1 - (graphPoint.elevation - minElevation) / (maxElevation - minElevation))); if (firstPoint) { path += ' L'; lastPoint = graphPoint; } else { firstPoint = lastPoint = graphPoint; path = ' M'; } path += ' ' + graphPoint.x + ',' + graphPoint.y; } }); finishGraphSegment(); } }); // Render step backgrounds var stepTransitParts = 0; var stepTotalDistance = 0; var stepCounter = 0; _(itin.itinData.legs).each(function (leg) { if (otp.util.Itin.isTransit(leg.mode)) { stepTransitParts++; } else { var lastX = graphX(stepTransitParts, stepTotalDistance); _(leg.steps).each(function (step) { stepTotalDistance += step.distance; step.graphX1 = lastX; step.graphX2 = graphX(stepTransitParts, stepTotalDistance); step.graphY1 = 10; step.graphY2 = 115; graph.append(step.graphElement = svg('rect', { class: "step", x: step.graphX1, y: step.graphY1, width: Math.max(1, step.graphX2 - step.graphX1), height: step.graphY2 - step.graphY1, })); lastX = step.graphX2; }); } }); graph.append(svg('line', { class: "line", x1: labelWidth - 1, y1: 10, x2: labelWidth - 1, y2: 115 })); graph.append(svg('line', { class: "line", x1: labelWidth - 1, y1: 10, x2: width - endPadding, y2: 10, "stroke-dasharray": "5,5" })); graph.append(svg('line', { class: "line", x1: labelWidth - 1, y1: 65, x2: width - endPadding, y2: 65, "stroke-dasharray": "5,5" })); graph.append(svg('line', { class: "line", x1: labelWidth - 1, y1: 115, x2: width - endPadding, y2: 115, "stroke-dasharray": "5,5" })); graph.append(svg('text', { class: "label", "text-anchor": "end", x: 45, y: 15 }, otp.util.Itin.distanceString(maxElevation))); graph.append(svg('text', { class: "label", "text-anchor": "end", x: 45, y: 65 }, otp.util.Itin.distanceString(Math.round(minElevation + (maxElevation - minElevation) / 2)))); graph.append(svg('text', { class: "label", "text-anchor": "end", x: 45, y: 115 }, otp.util.Itin.distanceString(minElevation))); } }, municoderResultId : 0, // returns jQuery object renderItinerary : function(itin, index, alerts) { var this_ = this; // render legs var divId = this.module.id+"-itinAccord-"+index; var accordHtml = "
"; var itinAccord = $(accordHtml); for(var l=0; l').appendTo(itinAccord); var leg = itin.itinData.legs[l]; //TRANSLATORS: Used when passengers can stay on vehicle. Continues //as [agency] route name var headerModeText = leg.interlineWithPreviousLeg ? _tr("CONTINUES AS") : otp.util.Itin.modeString(leg.mode).toUpperCase() var headerHtml = "" + headerModeText + ""; // Add info about realtimeness of the leg if (leg.realTime && typeof(leg.arrivalDelay) === 'number') { var minDelay = Math.round(leg.arrivalDelay / 60) if (minDelay > 0) { //TRANSLATORS: Something in Public transport is x minutes late headerHtml += ' (' + ngettext("%d min late", "%d mins late", minDelay) + ')'; } else if (minDelay < 0) { //TRANSLATORS: Something in Public transport is x minutes early headerHtml += ' (' + ngettext("%d min early", "%d mins early", (minDelay * -1)) + ')'; } else { //TRANSLATORS: Something in Public transport is on time headerHtml += ' (' + _tr("on time") + ')'; } } if(leg.mode === "WALK" || leg.mode === "BICYCLE" || leg.mode === "SCOOTER" || leg.mode === "CAR") { headerHtml += " "+otp.util.Itin.distanceString(leg.distance) + ", " + otp.util.Itin.durationString(leg.startTime, leg.endTime) + pgettext("direction", " to ")+otp.util.Itin.getName(leg.to); if(otp.config.municoderHostname) { var spanId = this.newMunicoderRequest(leg.to.lat, leg.to.lon); headerHtml += ''; } } else if(leg.agencyId !== null) { headerHtml += ": " + leg.agencyName + ", "; if (leg.routeShortName) { headerHtml += leg.routeShortName + " "; } if (leg.routeLongName) { headerHtml += leg.routeLongName + " "; } if(leg.headsign) { /*TRANSLATORS: used in sentence like: "to" . Used in showing itinerary*/ headerHtml += pgettext("bus_direction", " to ") + leg.headsign; } } if (leg.alerts) { headerHtml += '  '; } $("

"+headerHtml+"

").appendTo(legDiv).data('leg', leg).hover(function(evt) { //var arr = evt.target.id.split('-'); //var index = parseInt(arr[arr.length-1]); var thisLeg = $(this).data('leg'); this_.module.highlightLeg(thisLeg); this_.module.pathMarkerLayer.clearLayers(); this_.module.drawStartBubble(thisLeg, true); this_.module.drawEndBubble(thisLeg, true); }, function(evt) { this_.module.clearHighlights(); this_.module.pathMarkerLayer.clearLayers(); this_.module.drawAllStartBubbles(itin); }); this_.renderLeg(leg, l>0 ? itin.itinData.legs[l-1] : null, // previous l+1 < itin.itinData.legs.length ? itin.itinData.legs[l+1] : null // next ).appendTo(legDiv); $(legDiv).accordion({ header : 'h3', active: otp.util.Itin.isTransit(leg.mode) ? 0 : false, heightStyle: "content", collapsible: true }); } //itinAccord.accordion({ /*console.log('#' + divId + ' > div') $('#' + divId + ' > div').accordion({ header : 'h3', active: false, heightStyle: "content", collapsible: true });*/ var itinDiv = $("
"); // add alerts, if applicable alerts = alerts || []; // create an alert if this is a different day from the searched day var queryTime = otp.util.Time.constructQueryTime(itin.tripPlan.queryParams); if(itin.differentServiceDayFromQuery(itin.tripPlan.queryParams.originalQueryTime || queryTime)) { //TRANSLATORS: Shown as alert text before showing itinerary. alerts = [ _tr("This itinerary departs on a different day than the one searched for") ]; } for(var i = 0; i < alerts.length; i++) { itinDiv.append("
"+alerts[i]+"
"); } // add start and end time rows and the main leg accordion display //TRANSLATORS: Start: Time and date (Shown before path itinerary) itinDiv.append("
" + pgettext('template', "Start") + ": "+itin.getStartTimeStr()+"
"); if(itin.itinData.systemNotices != null) { let systemTags; for(const it of itin.itinData.systemNotices) { systemTags = (!systemTags) ? it.tag : (systemTags + ", " + it.tag); } itinDiv.append("
System tags: " + systemTags + "
"); } itinDiv.append(itinAccord); if (itin.itinData.arrivedAtDestinationWithRentedBicycle) { itinDiv.append("
" + _tr("Arrived at destination with a rented bicycle!") + "
"); } //TRANSLATORS: End: Time and date (Shown after path itinerary) itinDiv.append("
" + _tr("End") + ": "+itin.getEndTimeStr()+"
"); itinDiv.append(""); // add trip summary var tripSummary = $('
') .append('
' + _tr("Trip Summary") + '
') //TRANSLATORS: Travel: hour date on which this trip is made .append('
' + _tr("Travel") + '
'+itin.getStartTimeStr()+'
') //TRANSLATORS: Time: minutes How long is this trip .append('
' + _tr("Time") + '
'+itin.getDurationStr()+'
') .append('
' + _tr("GenCost") + '
'+itin.getGeneralizedCost()+'
'); var walkDistance = itin.getModeDistance("WALK"); if(walkDistance > 0) { //FIXME: If translation is longer transfers jumps to the right and //it is ugly //TRANSLATORS: Total foot distance for trip tripSummary.append('
' + _tr("Total Walk") + '
' + otp.util.Itin.distanceString(walkDistance) + '
') } var bikeDistance = itin.getModeDistance("BICYCLE"); if(bikeDistance > 0) { //TRANSLATORS: Total distance on a bike for this trip tripSummary.append('
' + _tr("Total Bike") + '
' + otp.util.Itin.distanceString(bikeDistance) + '
') } var carDistance = itin.getModeDistance("CAR"); if(carDistance > 0) { //TRANSLATORS: Total distance in a car for this trip tripSummary.append('
' + _tr("Total drive") + '
' + otp.util.Itin.distanceString(carDistance) + '
') } tripSummary.append('
' + _tr("Elevation Gained") + '
' + otp.util.Itin.distanceString(itin.itinData.elevationGained) + '
') tripSummary.append('
' + _tr("Elevation Lost") + '
' + otp.util.Itin.distanceString(itin.itinData.elevationLost) + '
') if(itin.hasTransit) { //TRANSLATORS: how many public transit transfers in a trip tripSummary.append('
' + _tr("Transfers") + '
'+itin.itinData.transfers+'
') /*if(itin.itinData.walkDistance > 0) { tripSummary.append('
' + _tr("Total Walk") + '
' + otp.util.Itin.distanceString(itin.itinData.walkDistance) + '
') }*/ //TRANSLATORS: cost of trip tripSummary.append('
' + _tr("Fare") +'
'+itin.getFareStr()+'
'); } var tripSummaryFooter = $('
'); //TRANSLATORS: Valid date time; When is this trip correct tripSummaryFooter.append(_tr('Valid') + ' ' + moment().format(otp.config.locale.time.format)); var itinLink = this.constructLink(itin.tripPlan.queryParams, { itinIndex : index }); if(this.showItineraryLink) { //TRANSLATORS: Links to this itinerary tripSummaryFooter.append(' | ' + _tr("Link to Itinerary") + ''); } if(this.showPrintLink) { tripSummaryFooter.append(' | '); $('' + _tr('Print') +'').click(function(evt) { evt.preventDefault(); var printWindow = window.open('','OpenTripPlanner Results','toolbar=yes, scrollbars=yes, height=500, width=800'); printWindow.document.write(itin.getHtmlNarrative()); }).appendTo(tripSummaryFooter); } if(this.showEmailLink) { //TRANSLATORS: Default subject when sending trip to email var subject = _tr("Your Trip"); var body = itin.getTextNarrative(itinLink); //TRANSLATORS: Link to send trip by email tripSummaryFooter.append(' | ' + _tr("Email") + ''); } tripSummary.append(tripSummaryFooter) .appendTo(itinDiv); return itinDiv; }, renderLeg : function(leg, previousLeg, nextLeg) { var this_ = this; if(otp.util.Itin.isTransit(leg.mode)) { var legDiv = $('
'); // show the start time and stop // prevaricate if this is a nonstruct frequency trip if( leg.isNonExactFrequency === true ){ //TRANSLATORS: public transport drives every N minutes $('
' + ngettext("every %d min", "every %d mins", (leg.headway/60))+"
").appendTo(legDiv); } else { $('
'+otp.util.Time.formatItinTime(leg.startTime, otp.config.locale.time.time_format)+"
").appendTo(legDiv); } //TRANSLATORS: Depart station / Board at station in itinerary var startHtml = '
' + (leg.interlineWithPreviousLeg ? "" + pgettext("itinerary", "Depart") + " " : _tr("Board at ")) +leg.from.name; if(otp.config.municoderHostname) { var spanId = this.newMunicoderRequest(leg.from.lat, leg.from.lon); startHtml += ''; } startHtml += '
'; $(startHtml).appendTo(legDiv) .click(function(evt) { this_.module.webapp.map.lmap.panTo(new L.LatLng(leg.from.lat, leg.from.lon)); }).hover(function(evt) { this_.module.pathMarkerLayer.clearLayers(); this_.module.drawStartBubble(leg, true); }, function(evt) { this_.module.pathMarkerLayer.clearLayers(); this_.module.drawAllStartBubbles(this_.itineraries[this_.activeIndex]); }); $( '
' + _tr("Stop") + ' #' + (leg.from.stopCode || leg.from.stopId) + ' [' + _tr("Stop Viewer") + ']' + '
' ) .appendTo(legDiv) .children('a') .click(function(evt) { if(!this_.module.stopViewerWidget) { this_.module.stopViewerWidget = new otp.widgets.transit.StopViewerWidget("otp-"+this_.module.id+"-stopViewerWidget", this_.module); this_.module.stopViewerWidget.$().offset({top: evt.clientY, left: evt.clientX}); } this_.module.stopViewerWidget.show(); this_.module.stopViewerWidget.setActiveTime(leg.startTime); this_.module.stopViewerWidget.setStop(leg.from.stopId, leg.from.name); this_.module.stopViewerWidget.bringToFront(); }); $('
').appendTo(legDiv); // show the "time in transit" line var inTransitDiv = $('
').appendTo(legDiv); $('' + _tr("Time in transit") + ": " + otp.util.Time.secsToHrMin(leg.duration)+'').appendTo(inTransitDiv); $('
') .append($('
').append([ '' + _tr("Route ID") + ":" + leg.routeId + '', '' + _tr("Trip ID") + ":" + leg.tripId + '', '' + _tr("Service Date") + ":" + leg.serviceDate + '' ])) .appendTo(legDiv); $(' [' + _tr("Trip Viewer") + ']') .appendTo(inTransitDiv) .click(function(evt) { if(!this_.module.tripViewerWidget) { this_.module.tripViewerWidget = new otp.widgets.transit.TripViewerWidget("otp-"+this_.module.id+"-tripViewerWidget", this_.module); this_.module.tripViewerWidget.$().offset({top: evt.clientY, left: evt.clientX}); } this_.module.tripViewerWidget.show(); if(this_.module.tripViewerWidget.minimized) this_.module.tripViewerWidget.unminimize(); this_.module.tripViewerWidget.update(leg); this_.module.tripViewerWidget.bringToFront(); }); // show the intermediate stops, if applicable -- REPLACED BY TRIP VIEWER if(this.module.showIntermediateStops) { $('
').appendTo(legDiv); var intStopsDiv = $('
').appendTo(legDiv); var intStopsListDiv = $('
') $('
'+leg.intermediateStops.length+' Intermediate Stops
') .appendTo(intStopsDiv) .click(function(event) { intStopsListDiv.toggle(); }); intStopsListDiv.appendTo(intStopsDiv); for(var i=0; i < leg.intermediateStops.length; i++) { var stop = leg.intermediateStops[i]; var time = stop.arrival === stop.departure ? otp.util.Time.formatItinTime(stop.arrival, otp.config.locale.time.time_format) : otp.util.Time.formatItinTime(stop.arrival, otp.config.locale.time.time_format) + " - " + otp.util.Time.formatItinTime(stop.departure, otp.config.locale.time.time_format); $('
'+time+' '+stop.name+' (#'+(stop.stopCode || stop.stopId)+')
') .appendTo(intStopsListDiv) .children('span') .data("stop", stop) .click(function(evt) { var stop = $(this).data("stop"); this_.module.webapp.map.lmap.panTo(new L.LatLng(stop.lat, stop.lon)); }).hover(function(evt) { var stop = $(this).data("stop"); $(this).css('color', 'red'); L.popup() .setLatLng(new L.LatLng(stop.lat, stop.lon)) .setContent(stop.name) .openOn(this_.module.webapp.map.lmap); }, function(evt) { $(this).css('color', 'black'); this_.module.webapp.map.lmap.closePopup(); }); } intStopsListDiv.hide(); } // show the end time and stop $('
').appendTo(legDiv); if( leg.isNonExactFrequency === true ) { $('
' + _tr('late as') + ' ' + otp.util.Time.formatItinTime(leg.endTime, otp.config.locale.time.time_format)+"
").appendTo(legDiv); } else { $('
'+otp.util.Time.formatItinTime(leg.endTime, otp.config.locale.time.time_format)+"
").appendTo(legDiv); } //TRANSLATORS: Stay on board/Alight [at stop name] var endAction = (nextLeg && nextLeg.interlineWithPreviousLeg) ? _tr("Stay on board") : _tr("Alight"); //TRANSLATORS: [Stay on board/Alight] at [stop name] var endHtml = '
' + endAction + ' ' + _tr('at')+ ' ' +leg.to.name; if(otp.config.municoderHostname) { spanId = this.newMunicoderRequest(leg.to.lat, leg.to.lon); endHtml += ''; } endHtml += '
'; $(endHtml).appendTo(legDiv) .click(function(evt) { this_.module.webapp.map.lmap.panTo(new L.LatLng(leg.to.lat, leg.to.lon)); }).hover(function(evt) { this_.module.pathMarkerLayer.clearLayers(); this_.module.drawEndBubble(leg, true); }, function(evt) { this_.module.pathMarkerLayer.clearLayers(); this_.module.drawAllStartBubbles(this_.itineraries[this_.activeIndex]); }); $( '
' + _tr("Stop") + ' #' + (leg.to.stopCode || leg.to.stopId) + ' [' + _tr("Stop Viewer") + ']' + '
' ) .appendTo(legDiv) .children('a') .click(function(evt) { if(!this_.module.stopViewerWidget) { this_.module.stopViewerWidget = new otp.widgets.transit.StopViewerWidget("otp-"+this_.module.id+"-stopViewerWidget", this_.module); this_.module.stopViewerWidget.$().offset({top: evt.clientY, left: evt.clientX}); } this_.module.stopViewerWidget.show(); this_.module.stopViewerWidget.setActiveTime(leg.endTime); this_.module.stopViewerWidget.setStop(leg.to.stopId, leg.to.name); this_.module.stopViewerWidget.bringToFront(); }); return legDiv; } else if (leg.steps) { // walk / bike / car var legDiv = $('
'); if (leg && leg.steps) { for(var i=0; i'; html += '
'; if(step.relativeDirection) html += ''; html += '
'; var distArr= otp.util.Itin.distanceString(step.distance).split(" "); html += '
' + '' + distArr[0]+'
'+distArr[1]+'
'; html += '
'+text+'
'; html += '
'; $(html).appendTo(legDiv) .data("step", step) .data("stepText", text) .click(function(evt) { var step = $(this).data("step"); this_.module.webapp.map.lmap.panTo(new L.LatLng(step.lat, step.lon)); }).hover(function(evt) { var step = $(this).data("step"); $(this).css('background', '#f0f0f0'); $(step.graphElement).css({display: 'inline'}); var popup = L.popup() .setLatLng(new L.LatLng(step.lat, step.lon)) .setContent($(this).data("stepText")) .openOn(this_.module.webapp.map.lmap); }, function(evt) { var step = $(this).data("step"); $(this).css('background', '#e8e8e8'); $(step.graphElement).css({display: 'none'}); this_.module.webapp.map.lmap.closePopup(); }); } } // render any alerts if(leg.alerts) { for(var i = 0; i < leg.alerts.length; i++) { var alert = leg.alerts[i]; var alertDiv = ich['otp-planner-alert']({ alert: alert, leg: leg }).appendTo(legDiv); alertDiv.find('.otp-itin-alert-description').hide(); alertDiv.find('.otp-itin-alert-toggleButton').data('div', alertDiv).click(function() { var div = $(this).data('div'); var desc = div.find('.otp-itin-alert-description'); var toggle = div.find('.otp-itin-alert-toggleButton'); if(desc.is(":visible")) { desc.slideUp(); toggle.html("▼"); } else { desc.slideDown(); toggle.html("▲"); } }); } } return legDiv; } return $("
Leg details go here
"); }, constructLink : function(queryParams, additionalParams) { additionalParams = additionalParams || { }; return otp.config.siteUrl + '?module=' + this.module.id + "&" + otp.util.Text.constructUrlParamString(_.extend(_.clone(queryParams), additionalParams)); }, newMunicoderRequest : function(lat, lon) { this.municoderResultId++; var spanId = 'otp-municoderResult-'+this.municoderResultId; console.log("muniReq"); $.ajax(otp.config.municoderHostname+"/opentripplanner-municoder/municoder", { data : { location : lat+","+lon }, dataType: 'jsonp', success: function(data) { if(data.name) { $('#'+spanId).html(", "+data.name); } } }); return spanId; } });




© 2015 - 2025 Weber Informatics LLC | Privacy Policy