Package org.onebusaway.transit_data_federation.impl.beans

Source Code of org.onebusaway.transit_data_federation.impl.beans.RouteBeanServiceImpl

/**
* Copyright (C) 2011 Brian Ferris <bdferris@onebusaway.org>
* Copyright (C) 2011 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.
*/
package org.onebusaway.transit_data_federation.impl.beans;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.onebusaway.container.cache.Cacheable;
import org.onebusaway.geospatial.model.EncodedPolylineBean;
import org.onebusaway.gtfs.model.AgencyAndId;
import org.onebusaway.transit_data.model.AgencyBean;
import org.onebusaway.transit_data.model.NameBean;
import org.onebusaway.transit_data.model.NameBeanTypes;
import org.onebusaway.transit_data.model.RouteBean;
import org.onebusaway.transit_data.model.StopBean;
import org.onebusaway.transit_data.model.StopGroupBean;
import org.onebusaway.transit_data.model.StopGroupingBean;
import org.onebusaway.transit_data.model.StopsForRouteBean;
import org.onebusaway.transit_data.model.TransitDataConstants;
import org.onebusaway.transit_data_federation.impl.DirectedGraph;
import org.onebusaway.transit_data_federation.impl.StopGraphComparator;
import org.onebusaway.transit_data_federation.model.StopSequence;
import org.onebusaway.transit_data_federation.model.StopSequenceCollection;
import org.onebusaway.transit_data_federation.model.narrative.RouteCollectionNarrative;
import org.onebusaway.transit_data_federation.services.RouteService;
import org.onebusaway.transit_data_federation.services.StopSequenceCollectionService;
import org.onebusaway.transit_data_federation.services.StopSequencesService;
import org.onebusaway.transit_data_federation.services.beans.AgencyBeanService;
import org.onebusaway.transit_data_federation.services.beans.RouteBeanService;
import org.onebusaway.transit_data_federation.services.beans.ShapeBeanService;
import org.onebusaway.transit_data_federation.services.beans.StopBeanService;
import org.onebusaway.transit_data_federation.services.blocks.AbstractBlockTripIndex;
import org.onebusaway.transit_data_federation.services.blocks.BlockIndexService;
import org.onebusaway.transit_data_federation.services.blocks.BlockTripIndex;
import org.onebusaway.transit_data_federation.services.blocks.FrequencyBlockTripIndex;
import org.onebusaway.transit_data_federation.services.narrative.NarrativeService;
import org.onebusaway.transit_data_federation.services.transit_graph.BlockTripEntry;
import org.onebusaway.transit_data_federation.services.transit_graph.RouteCollectionEntry;
import org.onebusaway.transit_data_federation.services.transit_graph.RouteEntry;
import org.onebusaway.transit_data_federation.services.transit_graph.StopEntry;
import org.onebusaway.transit_data_federation.services.transit_graph.TransitGraphDao;
import org.onebusaway.transit_data_federation.services.transit_graph.TripEntry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
class RouteBeanServiceImpl implements RouteBeanService {

  private TransitGraphDao _transitGraphDao;

  private NarrativeService _narrativeService;

  private AgencyBeanService _agencyBeanService;

  private StopBeanService _stopBeanService;

  private ShapeBeanService _shapeBeanService;

  private RouteService _routeService;

  private StopSequencesService _stopSequencesService;

  private StopSequenceCollectionService _stopSequenceBlocksService;

  private BlockIndexService _blockIndexService;

  @Autowired
  public void setTransitGraphDao(TransitGraphDao transitGraphDao) {
    _transitGraphDao = transitGraphDao;
  }

  @Autowired
  public void setNarrativeService(NarrativeService narrativeService) {
    _narrativeService = narrativeService;
  }

  @Autowired
  public void setAgencyBeanService(AgencyBeanService agencyBeanService) {
    _agencyBeanService = agencyBeanService;
  }

  @Autowired
  public void setStopBeanService(StopBeanService stopBeanService) {
    _stopBeanService = stopBeanService;
  }

  @Autowired
  public void setShapeBeanService(ShapeBeanService shapeBeanService) {
    _shapeBeanService = shapeBeanService;
  }

  @Autowired
  public void setRouteService(RouteService routeService) {
    _routeService = routeService;
  }

  @Autowired
  public void setStopSequencesLibrary(StopSequencesService service) {
    _stopSequencesService = service;
  }

  @Autowired
  public void setStopSequencesBlocksService(
      StopSequenceCollectionService stopSequenceBlocksService) {
    _stopSequenceBlocksService = stopSequenceBlocksService;
  }

  @Autowired
  public void setBlockIndexService(BlockIndexService blockIndexService) {
    _blockIndexService = blockIndexService;
  }

  @Cacheable
  public RouteBean getRouteForId(AgencyAndId id) {
    RouteCollectionNarrative rc = _narrativeService.getRouteCollectionForId(id);
    if (rc == null)
      return null;
    return getRouteBeanForRouteCollection(id, rc);
  }

  @Cacheable
  public StopsForRouteBean getStopsForRoute(AgencyAndId routeId) {
    RouteCollectionEntry routeCollectionEntry = _transitGraphDao.getRouteCollectionForId(routeId);
    RouteCollectionNarrative narrative = _narrativeService.getRouteCollectionForId(routeId);
    if (routeCollectionEntry == null || narrative == null)
      return null;
    return getStopsForRouteCollectionAndNarrative(routeCollectionEntry,
        narrative);
  }

  /****
   * Private Methods
   ****/

  private RouteBean getRouteBeanForRouteCollection(AgencyAndId id,
      RouteCollectionNarrative rc) {

    RouteBean.Builder bean = RouteBean.builder();
    bean.setId(ApplicationBeanLibrary.getId(id));
    bean.setShortName(rc.getShortName());
    bean.setLongName(rc.getLongName());
    bean.setColor(rc.getColor());
    bean.setDescription(rc.getDescription());
    bean.setTextColor(rc.getTextColor());
    bean.setType(rc.getType());
    bean.setUrl(rc.getUrl());

    AgencyBean agency = _agencyBeanService.getAgencyForId(id.getAgencyId());
    bean.setAgency(agency);

    return bean.create();
  }

  private List<StopBean> getStopBeansForRoute(AgencyAndId routeId) {

    Collection<AgencyAndId> stopIds = _routeService.getStopsForRouteCollection(routeId);
    List<StopBean> stops = new ArrayList<StopBean>();

    for (AgencyAndId stopId : stopIds) {
      StopBean stop = _stopBeanService.getStopForId(stopId);
      stops.add(stop);
    }

    return stops;
  }

  private StopsForRouteBean getStopsForRouteCollectionAndNarrative(
      RouteCollectionEntry routeCollection, RouteCollectionNarrative narrative) {

    StopsForRouteBean result = new StopsForRouteBean();

    AgencyAndId routeCollectionId = routeCollection.getId();
    result.setRoute(getRouteBeanForRouteCollection(routeCollectionId, narrative));
    result.setStops(getStopBeansForRoute(routeCollectionId));

    result.setPolylines(getEncodedPolylinesForRoute(routeCollection));

    StopGroupingBean directionGrouping = new StopGroupingBean();
    directionGrouping.setType(TransitDataConstants.STOP_GROUPING_TYPE_DIRECTION);
    List<StopGroupBean> directionGroups = new ArrayList<StopGroupBean>();
    directionGrouping.setStopGroups(directionGroups);
    directionGrouping.setOrdered(true);
    result.addGrouping(directionGrouping);

    List<BlockTripIndex> blockIndices = _blockIndexService.getBlockTripIndicesForRouteCollectionId(routeCollectionId);
    List<FrequencyBlockTripIndex> frequencyBlockIndices = _blockIndexService.getFrequencyBlockTripIndicesForRouteCollectionId(routeCollectionId);

    List<BlockTripEntry> blockTrips = new ArrayList<BlockTripEntry>();

    getBlockTripsForIndicesMatchingRouteCollection(blockIndices,
        routeCollectionId, blockTrips);
    getBlockTripsForIndicesMatchingRouteCollection(frequencyBlockIndices,
        routeCollectionId, blockTrips);

    List<StopSequence> sequences = _stopSequencesService.getStopSequencesForTrips(blockTrips);

    List<StopSequenceCollection> blocks = _stopSequenceBlocksService.getStopSequencesAsCollections(sequences);

    for (StopSequenceCollection block : blocks) {

      NameBean name = new NameBean(NameBeanTypes.DESTINATION,
          block.getDescription());

      List<StopEntry> stops = getStopsInOrder(block);
      List<String> groupStopIds = new ArrayList<String>();
      for (StopEntry stop : stops)
        groupStopIds.add(ApplicationBeanLibrary.getId(stop.getId()));

      Set<AgencyAndId> shapeIds = getShapeIdsForStopSequenceBlock(block);
      List<EncodedPolylineBean> polylines = _shapeBeanService.getMergedPolylinesForShapeIds(shapeIds);

      StopGroupBean group = new StopGroupBean();
      group.setId(block.getPublicId());
      group.setName(name);
      group.setStopIds(groupStopIds);
      group.setPolylines(polylines);
      directionGroups.add(group);
    }

    sortResult(result);

    return result;
  }

  /**
   * A block index potentially includes trips with different routes. We only
   * want the trips matching our route collection.
   *
   * @param <T>
   * @param blockIndices
   * @param routeCollectionId
   * @param resultingTrips
   */
  private <T extends AbstractBlockTripIndex> void getBlockTripsForIndicesMatchingRouteCollection(
      List<T> blockIndices, AgencyAndId routeCollectionId,
      List<BlockTripEntry> resultingTrips) {
    for (AbstractBlockTripIndex blockIndex : blockIndices) {
      for (BlockTripEntry blockTrip : blockIndex.getTrips()) {
        TripEntry trip = blockTrip.getTrip();
        AgencyAndId rcId = trip.getRouteCollection().getId();
        if (!rcId.equals(routeCollectionId))
          continue;
        resultingTrips.add(blockTrip);
      }
    }
  }

  private List<EncodedPolylineBean> getEncodedPolylinesForRoute(
      RouteCollectionEntry routeCollection) {

    Set<AgencyAndId> shapeIds = new HashSet<AgencyAndId>();
    for (RouteEntry route : routeCollection.getChildren()) {
      for (TripEntry trip : route.getTrips()) {
        if (trip.getShapeId() != null)
          shapeIds.add(trip.getShapeId());
      }
    }

    return _shapeBeanService.getMergedPolylinesForShapeIds(shapeIds);
  }

  private List<StopEntry> getStopsInOrder(StopSequenceCollection block) {
    DirectedGraph<StopEntry> graph = new DirectedGraph<StopEntry>();
    for (StopSequence sequence : block.getStopSequences()) {
      StopEntry prev = null;
      for (StopEntry stop : sequence.getStops()) {
        if (prev != null) {
          // We do this to avoid cycles
          if (!graph.isConnected(stop, prev))
            graph.addEdge(prev, stop);
        }
        prev = stop;
      }
    }

    StopGraphComparator c = new StopGraphComparator(graph);
    return graph.getTopologicalSort(c);
  }

  private Set<AgencyAndId> getShapeIdsForStopSequenceBlock(
      StopSequenceCollection block) {
    Set<AgencyAndId> shapeIds = new HashSet<AgencyAndId>();
    for (StopSequence sequence : block.getStopSequences()) {
      for (BlockTripEntry blockTrip : sequence.getTrips()) {
        TripEntry trip = blockTrip.getTrip();
        AgencyAndId shapeId = trip.getShapeId();
        if (shapeId != null && shapeId.hasValues())
          shapeIds.add(shapeId);
      }
    }
    return shapeIds;
  }

  private void sortResult(StopsForRouteBean result) {

    Collections.sort(result.getStops(), new StopBeanIdComparator());

    Collections.sort(result.getStopGroupings(),
        new Comparator<StopGroupingBean>() {
          public int compare(StopGroupingBean o1, StopGroupingBean o2) {
            return o1.getType().compareTo(o2.getType());
          }
        });

    for (StopGroupingBean grouping : result.getStopGroupings()) {
      Collections.sort(grouping.getStopGroups(),
          new Comparator<StopGroupBean>() {

            public int compare(StopGroupBean o1, StopGroupBean o2) {
              return getName(o1).compareTo(getName(o2));
            }

            private String getName(StopGroupBean bean) {
              StringBuilder b = new StringBuilder();
              for (String name : bean.getName().getNames())
                b.append(name);
              return b.toString();
            }
          });
    }
  }

}
TOP

Related Classes of org.onebusaway.transit_data_federation.impl.beans.RouteBeanServiceImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.