Package org.onebusaway.transit_data_federation.impl.beans

Source Code of org.onebusaway.transit_data_federation.impl.beans.RoutesBeanServiceImpl$HasItemsVisitor

/**
* 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 org.onebusaway.container.cache.Cacheable;
import org.onebusaway.container.refresh.Refreshable;
import org.onebusaway.exceptions.InvalidArgumentServiceException;
import org.onebusaway.exceptions.NoSuchAgencyServiceException;
import org.onebusaway.exceptions.ServiceException;
import org.onebusaway.geospatial.model.CoordinateBounds;
import org.onebusaway.gtfs.model.AgencyAndId;
import org.onebusaway.transit_data.model.ListBean;
import org.onebusaway.transit_data.model.RouteBean;
import org.onebusaway.transit_data.model.RoutesBean;
import org.onebusaway.transit_data.model.SearchQueryBean;
import org.onebusaway.transit_data.model.StopBean;
import org.onebusaway.transit_data_federation.impl.RefreshableResources;
import org.onebusaway.transit_data_federation.model.SearchResult;
import org.onebusaway.transit_data_federation.services.AgencyAndIdLibrary;
import org.onebusaway.transit_data_federation.services.RouteCollectionSearchService;
import org.onebusaway.transit_data_federation.services.RouteService;
import org.onebusaway.transit_data_federation.services.beans.GeospatialBeanService;
import org.onebusaway.transit_data_federation.services.beans.RouteBeanService;
import org.onebusaway.transit_data_federation.services.beans.RoutesBeanService;
import org.onebusaway.transit_data_federation.services.beans.StopBeanService;
import org.onebusaway.transit_data_federation.services.transit_graph.AgencyEntry;
import org.onebusaway.transit_data_federation.services.transit_graph.RouteCollectionEntry;
import org.onebusaway.transit_data_federation.services.transit_graph.StopEntry;
import org.onebusaway.transit_data_federation.services.transit_graph.TransitGraphDao;

import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.index.ItemVisitor;
import com.vividsolutions.jts.index.strtree.STRtree;

import org.apache.lucene.queryParser.ParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.PostConstruct;

@Component
class RoutesBeanServiceImpl implements RoutesBeanService {

  private static Logger _log = LoggerFactory.getLogger(RoutesBeanServiceImpl.class);

  @Autowired
  private RouteService _routeService;

  @Autowired
  private RouteCollectionSearchService _searchService;

  @Autowired
  private GeospatialBeanService _whereGeospatialService;

  @Autowired
  private RouteBeanService _routeBeanService;

  @Autowired
  private StopBeanService _stopService;

  @Autowired
  private TransitGraphDao _graphDao;

  private Map<AgencyAndId, STRtree> _stopTreesByRouteId = new HashMap<AgencyAndId, STRtree>();

  @Refreshable(dependsOn = {
      RefreshableResources.ROUTE_COLLECTIONS_DATA,
      RefreshableResources.TRANSIT_GRAPH,
      RefreshableResources.NARRATIVE_DATA})
  @PostConstruct
  public void setup() {
    _stopTreesByRouteId.clear();
   
    if (_graphDao.getAllStops().isEmpty()) {
      _log.info("setup called with empty graph, exiting");
      return;
    }
   
    for (StopEntry stop : _graphDao.getAllStops()) {
      Set<AgencyAndId> routeIds = _routeService.getRouteCollectionIdsForStop(stop.getId());
      for (AgencyAndId routeId : routeIds) {
        STRtree tree = _stopTreesByRouteId.get(routeId);
        if (tree == null) {
          tree = new STRtree();
          _stopTreesByRouteId.put(routeId, tree);
        }
        double x = stop.getStopLon();
        double y = stop.getStopLat();
        Envelope env = new Envelope(x, x, y, y);
        tree.insert(env, routeId);
      }
    }
   
    for (STRtree tree : _stopTreesByRouteId.values())
      tree.build();
  }

  @Override
  public RoutesBean getRoutesForQuery(SearchQueryBean query)
      throws ServiceException {
    if (query.getQuery() != null)
      return getRoutesWithRouteNameQuery(query);
    else
      return getRoutesWithoutRouteNameQuery(query);
  }

  @Cacheable
  @Override
  public ListBean<String> getRouteIdsForAgencyId(String agencyId) {
    AgencyEntry agency = _graphDao.getAgencyForId(agencyId);
    if (agency == null)
      throw new NoSuchAgencyServiceException(agencyId);
    List<String> ids = new ArrayList<String>();
    for (RouteCollectionEntry routeCollection : agency.getRouteCollections()) {
      AgencyAndId id = routeCollection.getId();
      ids.add(AgencyAndIdLibrary.convertToString(id));
    }
    return new ListBean<String>(ids, false);
  }

  @Cacheable
  @Override
  public ListBean<RouteBean> getRoutesForAgencyId(String agencyId) {
    AgencyEntry agency = _graphDao.getAgencyForId(agencyId);
    if (agency == null)
      throw new NoSuchAgencyServiceException(agencyId);
    List<RouteBean> routes = new ArrayList<RouteBean>();
    for (RouteCollectionEntry routeCollection : agency.getRouteCollections()) {
      AgencyAndId routeId = routeCollection.getId();
      RouteBean route = _routeBeanService.getRouteForId(routeId);
      routes.add(route);
    }
    return new ListBean<RouteBean>(routes, false);
  }

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

  private RoutesBean getRoutesWithoutRouteNameQuery(SearchQueryBean query) {

    CoordinateBounds bounds = query.getBounds();

    List<AgencyAndId> stops = _whereGeospatialService.getStopsByBounds(bounds);

    Set<RouteBean> routes = new HashSet<RouteBean>();
    for (AgencyAndId stopId : stops) {
      StopBean stop = _stopService.getStopForId(stopId);
      routes.addAll(stop.getRoutes());
    }

    List<RouteBean> routeBeans = new ArrayList<RouteBean>(routes);
    boolean limitExceeded = BeanServiceSupport.checkLimitExceeded(routeBeans,
        query.getMaxCount());
    return constructResult(routeBeans, limitExceeded);
  }

  private RoutesBean getRoutesWithRouteNameQuery(SearchQueryBean query)
      throws ServiceException {

    SearchResult<AgencyAndId> result = searchForRoutes(query);

    List<RouteBean> routeBeans = new ArrayList<RouteBean>();
    CoordinateBounds bounds = query.getBounds();

    for (AgencyAndId id : result.getResults()) {
      STRtree tree = _stopTreesByRouteId.get(id);
      if (tree == null) {
        _log.warn("stop tree not found for routeId=" + id);
        continue;
      }
      Envelope env = new Envelope(bounds.getMinLon(), bounds.getMaxLon(),
          bounds.getMinLat(), bounds.getMaxLat());
      HasItemsVisitor v = new HasItemsVisitor();
      tree.query(env, v);

      if (v.hasItems()) {
        RouteBean routeBean = _routeBeanService.getRouteForId(id);
        routeBeans.add(routeBean);
      }
    }

    boolean limitExceeded = BeanServiceSupport.checkLimitExceeded(routeBeans,
        query.getMaxCount());

    return constructResult(routeBeans, limitExceeded);
  }

  private SearchResult<AgencyAndId> searchForRoutes(SearchQueryBean query)
      throws ServiceException, InvalidArgumentServiceException {

    try {
      return _searchService.searchForRoutesByName(query.getQuery(),
          query.getMaxCount() + 1, query.getMinScoreToKeep());
    } catch (IOException e) {
      throw new ServiceException();
    } catch (ParseException e) {
      throw new InvalidArgumentServiceException("query", "queryParseError");
    }
  }

  private RoutesBean constructResult(List<RouteBean> routeBeans,
      boolean limitExceeded) {

    Collections.sort(routeBeans, new RouteBeanIdComparator());

    RoutesBean result = new RoutesBean();
    result.setRoutes(routeBeans);
    result.setLimitExceeded(limitExceeded);
    return result;
  }

  private static class HasItemsVisitor implements ItemVisitor {

    private boolean _hasItems = false;

    public boolean hasItems() {
      return _hasItems;
    }

    @Override
    public void visitItem(Object arg0) {
      _hasItems = true;
    }
  }

}
TOP

Related Classes of org.onebusaway.transit_data_federation.impl.beans.RoutesBeanServiceImpl$HasItemsVisitor

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.