@Override
  public List<? extends PlanElement> calcRoute(
      final Facility fromFacility,
      final Facility toFacility,
      final double departureTime,
      final Person person) {
    final Coord originCoord = fromFacility.getCoord();
    final Coord destinationCoord = toFacility.getCoord();

    final List<? extends PlanElement> cached =
        cache.uncache(originCoord, destinationCoord, departureTime);
    if (cached != null) return adapt(cached, fromFacility, toFacility);

    final List<? extends PlanElement> trip =
        calcBinnedRoute(fromFacility, toFacility, departureTime);
    cache.cache(originCoord, destinationCoord, departureTime, trim(trip));

    return trip;
  }
  /** Creates a csv file containing the public transport stops or measure points */
  public static void createStopsFile(
      Map<? extends Id, ? extends Facility> locationFacilitiesMap,
      String outputFileStops,
      String separator) {
    final CSVFileWriter stopsWriter = new CSVFileWriter(outputFileStops, separator);

    stopsWriter.writeField("id");
    stopsWriter.writeField("x");
    stopsWriter.writeField("y");
    stopsWriter.writeNewLine();

    for (Facility fac : locationFacilitiesMap.values()) {
      stopsWriter.writeField(fac.getId());
      stopsWriter.writeField(fac.getCoord().getX());
      stopsWriter.writeField(fac.getCoord().getY());
      stopsWriter.writeNewLine();
    }

    stopsWriter.close();
    log.info("Stops file based on schedule written.");
  }
    private Facility binFacility(final Facility fromFacility) {
      final int cellX = (int) (fromFacility.getCoord().getX() / cellSize_m);
      final int cellY = (int) (fromFacility.getCoord().getY() / cellSize_m);

      TIntObjectHashMap<Facility> atX;
      synchronized (binnedFacilities) {
        atX = binnedFacilities.get(cellX);
        if (atX == null) {
          atX = new TIntObjectHashMap<>();
          binnedFacilities.put(cellX, atX);
        }
      }

      Facility f;
      synchronized (atX) {
        f = atX.get(cellY);
        if (f == null) {
          f =
              new Facility() {
                private Coord coord =
                    new Coord(
                        cellX * cellSize_m + cellSize_m / 2, cellY * cellSize_m + cellSize_m / 2);
                private Id<Link> linkId =
                    NetworkUtils.getNearestLinkExactly(network, coord).getId();

                @Override
                public Id<Link> getLinkId() {
                  return linkId;
                }

                @Override
                public Coord getCoord() {
                  return coord;
                }

                @Override
                public Map<String, Object> getCustomAttributes() {
                  throw new UnsupportedOperationException();
                }

                @Override
                public Id getId() {
                  throw new UnsupportedOperationException();
                }
              };
          atX.put(cellY, f);
        }
      }

      return f;
    }