001
002/* *********************************************************************** *
003 * project: org.matsim.*
004 * PrepareForMobsimImpl.java
005 *                                                                         *
006 * *********************************************************************** *
007 *                                                                         *
008 * copyright       : (C) 2019 by the members listed in the COPYING,        *
009 *                   LICENSE and WARRANTY file.                            *
010 * email           : info at matsim dot org                                *
011 *                                                                         *
012 * *********************************************************************** *
013 *                                                                         *
014 *   This program is free software; you can redistribute it and/or modify  *
015 *   it under the terms of the GNU General Public License as published by  *
016 *   the Free Software Foundation; either version 2 of the License, or     *
017 *   (at your option) any later version.                                   *
018 *   See also COPYING, LICENSE and WARRANTY file                           *
019 *                                                                         *
020 * *********************************************************************** */
021
022 package org.matsim.core.controler;
023
024import org.apache.log4j.Logger;
025import org.matsim.api.core.v01.Scenario;
026import org.matsim.api.core.v01.TransportMode;
027import org.matsim.api.core.v01.network.Network;
028import org.matsim.api.core.v01.population.Population;
029import org.matsim.core.config.groups.GlobalConfigGroup;
030import org.matsim.core.network.NetworkUtils;
031import org.matsim.core.network.algorithms.TransportModeNetworkFilter;
032import org.matsim.core.population.algorithms.AbstractPersonAlgorithm;
033import org.matsim.core.population.algorithms.ParallelPersonAlgorithmUtils;
034import org.matsim.core.population.algorithms.PersonPrepareForSim;
035import org.matsim.core.router.MainModeIdentifier;
036import org.matsim.core.router.PlanRouter;
037import org.matsim.core.router.TripRouter;
038import org.matsim.facilities.ActivityFacilities;
039
040import javax.inject.Inject;
041import javax.inject.Provider;
042import java.util.HashSet;
043
044public final class PrepareForMobsimImpl implements PrepareForMobsim {
045        // I think it is ok to have this public final.  Since one may want to use it as a delegate.  kai, may'18
046        // yyyyyy but how should that work with a non-public constructor? kai, jun'18
047        // Well, I guess it can be injected as well?!
048        // bind( PrepareForSimImpl.class ) ;
049        // bind( PrepareForSim.class ).to( MyPrepareForSimImpl.class ) ;
050
051        private static Logger log = Logger.getLogger(PrepareForMobsimImpl.class);
052        
053        private final GlobalConfigGroup globalConfigGroup;
054        private final Scenario scenario;
055        private final Network network;
056        private final Population population;
057        private final ActivityFacilities activityFacilities;
058        private final Provider<TripRouter> tripRouterProvider;
059        
060        @Inject
061        PrepareForMobsimImpl(GlobalConfigGroup globalConfigGroup, Scenario scenario, Network network,
062                                Population population, ActivityFacilities activityFacilities, Provider<TripRouter> tripRouterProvider) {
063                this.globalConfigGroup = globalConfigGroup;
064                this.scenario = scenario;
065                this.network = network;
066                this.population = population;
067                this.activityFacilities = activityFacilities;
068                this.tripRouterProvider = tripRouterProvider;
069        }
070        
071        
072        @Override
073        public void run() {
074                /*
075                 * Create single-mode network here and hand it over to PersonPrepareForSim. Otherwise, each instance would create its
076                 * own single-mode network. However, this assumes that the main mode is car - which PersonPrepareForSim also does. Should
077                 * be probably adapted in a way that other main modes are possible as well. cdobler, oct'15.
078                 * This is now only used for xy2links, which is the "street address" of the activity location of facility, and here for the time being we indeed
079                 *  assume that it can be reached by car.  kai, jul'18
080                 */
081                final Network carOnlyNetwork;
082                if (NetworkUtils.isMultimodal(network)) {
083                        log.info("Network seems to be multimodal. Create car-only network which is handed over to PersonPrepareForSim.");
084                        TransportModeNetworkFilter filter = new TransportModeNetworkFilter(network);
085                        carOnlyNetwork = NetworkUtils.createNetwork();
086                        HashSet<String> modes = new HashSet<>();
087                        modes.add(TransportMode.car);
088                        filter.filter(carOnlyNetwork, modes);
089                } else {
090                        carOnlyNetwork = network;
091                }
092                
093                // make sure all routes are calculated.
094                ParallelPersonAlgorithmUtils.run(population, globalConfigGroup.getNumberOfThreads(),
095                                new ParallelPersonAlgorithmUtils.PersonAlgorithmProvider() {
096                                        @Override
097                                        public AbstractPersonAlgorithm getPersonAlgorithm() {
098                                                return new PersonPrepareForSim(new PlanRouter(tripRouterProvider.get(), activityFacilities), scenario, 
099                                                                carOnlyNetwork );
100                                        }
101                                        // yyyyyy This prepared network is only used for computing the distance.  So the full network would
102                                        // actually be better than the car-only network, without doing damage elsewhere.  No?  kai, jul'18
103                                }
104                );
105                
106                // yy Could now set the vehicle IDs in the routes.  But can as well also do this later (currently in PopulationAgentSource).  kai, jun'18
107                
108        }
109        
110}