001/* *********************************************************************** *
002 * project: org.matsim.*
003 * Plansgenerator.java
004 *                                                                         *
005 * *********************************************************************** *
006 *                                                                         *
007 * copyright       : (C) 2007 by the members listed in the COPYING,        *
008 *                   LICENSE and WARRANTY file.                            *
009 * email           : info at matsim dot org                                *
010 *                                                                         *
011 * *********************************************************************** *
012 *                                                                         *
013 *   This program is free software; you can redistribute it and/or modify  *
014 *   it under the terms of the GNU General Public License as published by  *
015 *   the Free Software Foundation; either version 2 of the License, or     *
016 *   (at your option) any later version.                                   *
017 *   See also COPYING, LICENSE and WARRANTY file                           *
018 *                                                                         *
019 * *********************************************************************** */
020package playground.vsp.analysis.modules.ptTripAnalysis.traveltime;
021
022import java.util.ArrayList;
023import java.util.Collection;
024
025import org.locationtech.jts.geom.Coordinate;
026import org.matsim.api.core.v01.TransportMode;
027import org.matsim.api.core.v01.events.Event;
028import org.matsim.api.core.v01.population.Activity;
029import org.matsim.api.core.v01.population.Leg;
030import org.matsim.api.core.v01.population.PlanElement;
031
032import playground.vsp.analysis.modules.ptTripAnalysis.AbstractAnalysisTrip;
033
034/**
035 * @author droeder
036 *
037 */
038public class TTAnalysisTrip  extends AbstractAnalysisTrip implements TTAnalysisTripI {
039        
040        //all modes
041        public double tripTTime = 0.0;
042        
043        // pt only
044        public int accesWalkCnt = 0;
045        public int accesWaitCnt = 0;
046        public int egressWalkCnt = 0;
047        public int switchWalkCnt= 0;
048        public int switchWaitCnt = 0;
049        public int lineCnt = 0;
050        
051        public double accesWalkTTime = 0.0;
052        public double accesWaitTime = 0.0;
053        public double egressWalkTTime = 0.0;
054        public double switchWalkTTime = 0.0;
055        public double switchWaitTime = 0.0;
056        public double lineTTime = 0.0;
057        
058        
059        private Integer nrOfExpEvents = null;
060        private Integer nrOfElements = 0;
061        private PtTimeHandler handler;
062        
063        private Collection<String> networkModes;
064        private Collection<String> ptModes;
065        
066        public TTAnalysisTrip(Collection<String> ptModes, Collection<String> networkModes){
067                this.ptModes = ptModes;
068                this.networkModes = networkModes;
069        }
070        
071        public void addElements(ArrayList<PlanElement> elements){
072                this.nrOfElements = elements.size();
073                this.nrOfExpEvents = this.findExpectedNumberOfEvents(elements);
074                this.analyzeElements(elements);
075                
076                //handler is only needed for pt
077                if(this.ptModes.contains(super.getMode())){
078                        this.handler = new PtTimeHandler();
079                }
080        }
081        
082        
083        private void analyzeElements(ArrayList<PlanElement> elements) {
084                this.findMode(elements);
085                //if no zones in TripSet are defined, coords not necessary
086                if(!(((Activity) elements.get(0)).getCoord() == null) && !(((Activity) elements.get(elements.size() - 1)).getCoord() == null)){
087                        super.setStart(new Coordinate(((Activity) elements.get(0)).getCoord().getX(), 
088                                        ((Activity) elements.get(0)).getCoord().getY()));
089                        super.setEnd(new Coordinate(((Activity) elements.get(elements.size() - 1)).getCoord().getX(), 
090                                        ((Activity) elements.get(elements.size() - 1)).getCoord().getY()));
091                }
092        }
093        
094        // not essential but good to prevent mixing up different modes
095        // might run into problems, when using multi-modal-trip-routing /dr dec '12
096        private void findMode(ArrayList<PlanElement> elements) {
097                for(PlanElement p : elements){
098                        if(p instanceof Leg){
099                                if(((Leg) p).getMode().equals(TransportMode.transit_walk)){
100                                        super.setMode(TransportMode.transit_walk);
101                                }else{
102                                        super.setMode(((Leg) p).getMode());
103                                        return;
104                                }
105                        }
106                }
107        }
108        
109        public Integer getNrOfElements(){
110                return this.nrOfElements;
111        }
112        
113        private int findExpectedNumberOfEvents(ArrayList<PlanElement> elements){
114                int temp = 0;
115                for(PlanElement pe: elements){
116                        if( pe instanceof Leg){
117                        
118                                if(this.ptModes.contains(((Leg) pe).getMode())){
119                                        // +4 for every pt-leg (end, enter, leave, start)
120                                        temp +=6;
121                                }
122                                else if(this.networkModes.contains(((Leg) pe).getMode()))
123                                        // +4 for every simulated-network-mode-leg (end, enter, leave, start)
124                                        temp +=6;
125                                else{
126                                        // +2 for teleported modes (end, start)
127                                        temp +=4;
128                                }
129                        }
130                }
131                return temp;
132        }
133
134        private int handledEvents = 0;
135        private Double first = null;
136        private Double last = 0.0;
137        /**
138         * returns true if enough events are handled and the trip is finished
139         * @param e
140         * @return
141         */
142        public boolean handleEvent(Event e){
143                this.handledEvents++;
144                if(this.ptModes.contains(super.getMode())){
145                        handler.handleEvent(e);
146                        if(this.handledEvents == this.nrOfExpEvents){
147                                handler.finish(this);
148                                return true;
149                        }else{
150                                return false;
151                        }
152                }else{
153                        if(first == null){
154                                first = e.getTime();
155                        }else{
156                                last = e.getTime();
157                        }
158                        
159                        if(this.handledEvents == nrOfExpEvents){
160                                this.tripTTime = last - first;
161                                return true;
162                        }else{
163                                return false;
164                        }
165                }
166                
167        }
168        
169        /**
170         * @return the tripTTime
171         */
172        public Double getTripTTime() {
173                return tripTTime;
174        }
175
176        /**
177         * @return the accesWalkCnt
178         */
179        public int getAccesWalkCnt() {
180                return accesWalkCnt;
181        }
182
183        /**
184         * @return the accesWaitCnt
185         */
186        public int getAccesWaitCnt() {
187                return accesWaitCnt;
188        }
189
190        /**
191         * @return the egressWalkCnt
192         */
193        public int getEgressWalkCnt() {
194                return egressWalkCnt;
195        }
196
197        /**
198         * @return the switchWalkCnt
199         */
200        public int getSwitchWalkCnt() {
201                return switchWalkCnt;
202        }
203
204        /**
205         * @return the switchWaitCnt
206         */
207        public int getSwitchWaitCnt() {
208                return switchWaitCnt;
209        }
210
211        /**
212         * @return the lineCnt
213         */
214        public int getLineCnt() {
215                return lineCnt;
216        }
217
218        /**
219         * @return the accesWalkTTime
220         */
221        public double getAccesWalkTTime() {
222                return accesWalkTTime;
223        }
224
225        /**
226         * @return the accesWaitTime
227         */
228        public double getAccesWaitTime() {
229                return accesWaitTime;
230        }
231
232        /**
233         * @return the egressWalkTTime
234         */
235        public double getEgressWalkTTime() {
236                return egressWalkTTime;
237        }
238
239        /**
240         * @return the switchWalkTTime
241         */
242        public double getSwitchWalkTTime() {
243                return switchWalkTTime;
244        }
245
246        /**
247         * @return the switchWaitTime
248         */
249        public double getSwitchWaitTime() {
250                return switchWaitTime;
251        }
252
253        /**
254         * @return the lineTTime
255         */
256        public double getLineTTime() {
257                return lineTTime;
258        }
259}