--- a/origin-src/transitfeed-1.2.6/gtfsscheduleviewer/marey_graph.py
+++ b/origin-src/transitfeed-1.2.6/gtfsscheduleviewer/marey_graph.py
@@ -1,1 +1,470 @@
-
+#!/usr/bin/python2.5
+#
+# Copyright (C) 2007 Google Inc.
+#
+# 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.
+
+"""Output svg/xml data for a marey graph
+
+Marey graphs are a visualization form typically used for timetables. Time
+is on the x-axis and position on the y-axis. This module reads data from a
+transitfeed.Schedule and creates a marey graph in svg/xml format. The graph
+shows the speed between stops for each trip of a route.
+
+TODO: This module was taken from an internal Google tool. It works but is not
+well intergrated into transitfeed and schedule_viewer. Also, it has lots of
+ugly hacks to compensate set canvas size and so on which could be cleaned up.
+
+For a little more information see (I didn't make this URL ;-)
+http://transliteracies.english.ucsb.edu/post/research-project/research-clearinghouse-individual/research-reports/the-indexical-imagination-marey%e2%80%99s-graphic-method-and-the-technological-transformation-of-writing-in-the-nineteenth-century
+
+ MareyGraph: Class, keeps cache of graph data and graph properties
+ and draws marey graphs in svg/xml format on request.
+
+"""
+
+import itertools
+import transitfeed
+
+
+class MareyGraph:
+ """Produces and caches marey graph from transit feed data."""
+
+ _MAX_ZOOM = 5.0 # change docstring of ChangeScaleFactor if this changes
+ _DUMMY_SEPARATOR = 10 #pixel
+
+ def __init__(self):
+ # Timetablerelated state
+ self._cache = str()
+ self._stoplist = []
+ self._tlist = []
+ self._stations = []
+ self._decorators = []
+
+ # TODO: Initialize default values via constructor parameters
+ # or via a class constants
+
+ # Graph properties
+ self._tspan = 30 # number of hours to display
+ self._offset = 0 # starting hour
+ self._hour_grid = 60 # number of pixels for an hour
+ self._min_grid = 5 # number of pixels between subhour lines
+
+ # Canvas properties
+ self._zoomfactor = 0.9 # svg Scaling factor
+ self._xoffset = 0 # move graph horizontally
+ self._yoffset = 0 # move graph veritcally
+ self._bgcolor = "lightgrey"
+
+ # height/width of graph canvas before transform
+ self._gwidth = self._tspan * self._hour_grid
+
+ def Draw(self, stoplist=None, triplist=None, height=520):
+ """Main interface for drawing the marey graph.
+
+ If called without arguments, the data generated in the previous call
+ will be used. New decorators can be added between calls.
+
+ Args:
+ # Class Stop is defined in transitfeed.py
+ stoplist: [Stop, Stop, ...]
+ # Class Trip is defined in transitfeed.py
+ triplist: [Trip, Trip, ...]
+
+ Returns:
+ # A string that contain a svg/xml web-page with a marey graph.
+ " "
+
+ def _DrawDecorators(self):
+ """Used to draw fancy overlays on trip graphs."""
+ return " ".join(self._decorators)
+
+ def _DrawBox(self):
+ tmpstr = """
+ """ % (0, 0, self._gwidth + 20, self._gheight, self._bgcolor)
+ return tmpstr
+
+ def _BuildStations(self, stoplist):
+ """Dispatches the best algorithm for calculating station line position.
+
+ Args:
+ # Class Stop is defined in transitfeed.py
+ stoplist: [Stop, Stop, ...]
+ # Class Trip is defined in transitfeed.py
+ triplist: [Trip, Trip, ...]
+
+ Returns:
+ # One integer y-coordinate for each station normalized between
+ # 0 and X, where X is the height of the graph in pixels
+ [0, 33, 140, ... , X]
+ """
+ stations = []
+ dists = self._EuclidianDistances(stoplist)
+ stations = self._CalculateYLines(dists)
+ return stations
+
+ def _EuclidianDistances(self,slist):
+ """Calculate euclidian distances between stops.
+
+ Uses the stoplists long/lats to approximate distances
+ between stations and build a list with y-coordinates for the
+ horizontal lines in the graph.
+
+ Args:
+ # Class Stop is defined in transitfeed.py
+ stoplist: [Stop, Stop, ...]
+
+ Returns:
+ # One integer for each pair of stations
+ # indicating the approximate distance
+ [0,33,140, ... ,X]
+ """
+ e_dists2 = [transitfeed.ApproximateDistanceBetweenStops(stop, tail) for
+ (stop,tail) in itertools.izip(slist, slist[1:])]
+
+ return e_dists2
+
+ def _CalculateYLines(self, dists):
+ """Builds a list with y-coordinates for the horizontal lines in the graph.
+
+ Args:
+ # One integer for each pair of stations
+ # indicating the approximate distance
+ dists: [0,33,140, ... ,X]
+
+ Returns:
+ # One integer y-coordinate for each station normalized between
+ # 0 and X, where X is the height of the graph in pixels
+ [0, 33, 140, ... , X]
+ """
+ tot_dist = sum(dists)
+ if tot_dist > 0:
+ pixel_dist = [float(d * (self._gheight-20))/tot_dist for d in dists]
+ pixel_grid = [0]+[int(pd + sum(pixel_dist[0:i])) for i,pd in
+ enumerate(pixel_dist)]
+ else:
+ pixel_grid = []
+
+ return pixel_grid
+
+ def _TravelTimes(self,triplist,index=0):
+ """ Calculate distances and plot stops.
+
+ Uses a timetable to approximate distances
+ between stations
+
+ Args:
+ # Class Trip is defined in transitfeed.py
+ triplist: [Trip, Trip, ...]
+ # (Optional) Index of Triplist prefered for timetable Calculation
+ index: 3
+
+ Returns:
+ # One integer for each pair of stations
+ # indicating the approximate distance
+ [0,33,140, ... ,X]
+ """
+
+ def DistanceInTravelTime(dep_secs, arr_secs):
+ t_dist = arr_secs-dep_secs
+ if t_dist<0:
+ t_dist = self._DUMMY_SEPARATOR # min separation
+ return t_dist
+
+ if not triplist:
+ return []
+
+ if 0 < index < len(triplist):
+ trip = triplist[index]
+ else:
+ trip = triplist[0]
+
+ t_dists2 = [DistanceInTravelTime(stop[3],tail[2]) for (stop,tail)
+ in itertools.izip(trip.GetTimeStops(),trip.GetTimeStops()[1:])]
+ return t_dists2
+
+ def _AddWarning(self, str):
+ print str
+
+ def _DrawTrips(self,triplist,colpar=""):
+ """Generates svg polylines for each transit trip.
+
+ Args:
+ # Class Trip is defined in transitfeed.py
+ [Trip, Trip, ...]
+
+ Returns:
+ # A string containing a polyline tag for each trip
+ ' 0 and not colpar:
+ color="purple"
+ scriptcall = 'onmouseover="LineClick(\'%s\',\'Trip %s starting %s\')"' % (t.trip_id,
+ t.trip_id, transitfeed.FormatSecondsSinceMidnight(t.GetStartTime()))
+ tmpstrhead = '')
+ return "".join(tmpstrs)
+
+ def _Uniform(self, triplist):
+ """Fallback to assuming uniform distance between stations"""
+ # This should not be neseccary, but we are in fallback mode
+ longest = max([len(t.GetTimeStops()) for t in triplist])
+ return [100] * longest
+
+ def _DrawStations(self, color="#aaa"):
+ """Generates svg with a horizontal line for each station/stop.
+
+ Args:
+ # Class Stop is defined in transitfeed.py
+ stations: [Stop, Stop, ...]
+
+ Returns:
+ # A string containing a polyline tag for each stop
+ " ' %(color,20,20+y+.5,self._gwidth+20,20+y+.5))
+ return "".join(tmpstrs)
+
+ def _DrawHours(self):
+ """Generates svg to show a vertical hour and sub-hour grid
+
+ Returns:
+ # A string containing a polyline tag for each grid line
+ " ' \
+ % (i + .5 + 20, 20, i + .5 + 20, self._gheight))
+ tmpstrs.append('%d'
+ % (i + 20, 20,
+ (i / self._hour_grid + self._offset) % 24))
+ else:
+ tmpstrs.append('' \
+ % (i + .5 + 20, 20, i + .5 + 20, self._gheight))
+ return "".join(tmpstrs)
+
+ def AddStationDecoration(self, index, color="#f00"):
+ """Flushes existing decorations and highlights the given station-line.
+
+ Args:
+ # Integer, index of stop to be highlighted.
+ index: 4
+ # An optional string with a html color code
+ color: "#fff"
+ """
+ tmpstr = str()
+ num_stations = len(self._stations)
+ ind = int(index)
+ if self._stations:
+ if 0 0 and float(newfactor) < self._MAX_ZOOM:
+ self._zoomfactor = newfactor
+
+ def ScaleLarger(self):
+ """Increases the zoom of the graph one step (0.1 units)."""
+ newfactor = self._zoomfactor + 0.1
+ if float(newfactor) > 0 and float(newfactor) < self._MAX_ZOOM:
+ self._zoomfactor = newfactor
+
+ def ScaleSmaller(self):
+ """Decreases the zoom of the graph one step(0.1 units)."""
+ newfactor = self._zoomfactor - 0.1
+ if float(newfactor) > 0 and float(newfactor) < self._MAX_ZOOM:
+ self._zoomfactor = newfactor
+
+ def ClearDecorators(self):
+ """Removes all the current decorators.
+ """
+ self._decorators = []
+
+ def AddTextStripDecoration(self,txtstr):
+ tmpstr = '%s' % (0,
+ 20 + self._gheight, txtstr)
+ self._decorators.append(tmpstr)
+
+ def SetSpan(self, first_arr, last_arr, mint=5 ,maxt=30):
+ s_hour = (first_arr / 3600) - 1
+ e_hour = (last_arr / 3600) + 1
+ self._offset = max(min(s_hour, 23), 0)
+ self._tspan = max(min(e_hour - s_hour, maxt), mint)
+ self._gwidth = self._tspan * self._hour_grid
+