/** {@inheritDoc} */ public void putAll(TIntIntMap map) { ensureCapacity(map.size()); TIntIntIterator iter = map.iterator(); while (iter.hasNext()) { iter.advance(); this.put(iter.key(), iter.value()); } }
/** * @param freqmap * @return */ public static TreeMap<Integer, Integer> countFrequency(TIntIntHashMap freqmap) { TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>(); TIntIntIterator it = freqmap.iterator(); while (it.hasNext()) { it.advance(); int freq = it.value(); if (map.containsKey(freq)) { map.put(freq, map.get(freq) + 1); } else map.put(freq, 1); } return map; }
/** * Combine the results of several street searches using different modes into a single map It also * saves with which mode was stop reached into stopModeMap. This map is then used to create * itineraries in response */ private TIntIntMap combineMultimodalRoutingAccessTimes( Map<LegMode, StreetRouter> routers, TIntObjectMap<LegMode> stopModeMap, ProfileRequest request) { // times at transit stops TIntIntMap times = new TIntIntHashMap(); // weights at transit stops TIntIntMap weights = new TIntIntHashMap(); for (Map.Entry<LegMode, StreetRouter> entry : routers.entrySet()) { int maxTime = 30; int minTime = 0; int penalty = 0; LegMode mode = entry.getKey(); switch (mode) { case BICYCLE: maxTime = request.maxBikeTime; minTime = request.minBikeTime; penalty = BIKE_PENALTY; break; case BICYCLE_RENT: // TODO this is not strictly correct, bike rent is partly walking maxTime = request.maxBikeTime; minTime = request.minBikeTime; penalty = BIKESHARE_PENALTY; break; case WALK: maxTime = request.maxWalkTime; break; case CAR: // TODO this is not strictly correct, CAR PARK is partly walking case CAR_PARK: maxTime = request.maxCarTime; minTime = request.minCarTime; penalty = CAR_PENALTY; break; } maxTime *= 60; // convert to seconds minTime *= 60; // convert to seconds final int maxTimeFinal = maxTime; final int minTimeFinal = minTime; final int penaltyFinal = penalty; StreetRouter router = entry.getValue(); router .getReachedStops() .forEachEntry( (stop, time) -> { if (time > maxTimeFinal || time < minTimeFinal) return true; // Skip stops that can't be used with wheelchairs if wheelchair routing is requested if (request.wheelchair && !transportNetwork.transitLayer.stopsWheelchair.get(stop)) { return true; } int weight = time + penaltyFinal; // There are penalties for using certain modes, to avoid bike/car trips that are // only marginally faster // than walking, so we use weights to decide which mode "wins" to access a // particular stop. if (!weights.containsKey(stop) || weight < weights.get(stop)) { times.put(stop, time); weights.put(stop, weight); stopModeMap.put(stop, mode); } return true; // iteration should continue }); } // we don't want to explore a boatload of access/egress stops. Pick only the closest several // hundred. // What this means is that in urban environments you'll get on the bus nearby, in suburban // environments // you may walk/bike/drive a very long way. // NB in testing it's not clear this actually does a lot for performance, maybe 1-1.5s int stopsFound = times.size(); if (stopsFound > MAX_ACCESS_STOPS) { TIntList timeList = new TIntArrayList(); times.forEachValue(timeList::add); timeList.sort(); // This gets last time in timeList int cutoff = timeList.get( MAX_ACCESS_STOPS); // it needs to be same as MAX_ACCESS_STOPS since if there are // minimally MAX_ACCESS_STOPS + 1 stops the indexes are from // 0-MAX_ACCESS_STOPS for (TIntIntIterator it = times.iterator(); it.hasNext(); ) { it.advance(); if (it.value() > cutoff) it.remove(); } LOG.warn("{} stops found, using {} nearest", stopsFound, times.size()); } else { LOG.info("{} stops found", stopsFound); } // return the times, not the weights return times; }