Skip to content

Commit

Permalink
conveyal/modeify#163 limit profile router responses by access mode
Browse files Browse the repository at this point in the history
  • Loading branch information
abyrd committed Jan 21, 2015
1 parent 849cbba commit 607ac4b
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 14 deletions.
Expand Up @@ -65,7 +65,7 @@ public Response profileRoute (
@QueryParam("minCarTime") @DefaultValue("1") int minCarTime, @QueryParam("minCarTime") @DefaultValue("1") int minCarTime,
@QueryParam("minBikeTime") @DefaultValue("1") int minBikeTime, @QueryParam("minBikeTime") @DefaultValue("1") int minBikeTime,
@QueryParam("orderBy") @DefaultValue("AVG") Option.SortOrder orderBy, @QueryParam("orderBy") @DefaultValue("AVG") Option.SortOrder orderBy,
@QueryParam("limit") @DefaultValue("10") int limit, @QueryParam("limit") @DefaultValue("10") int limit, // max options to return PER ACCESS MODE
@QueryParam("suboptimal") @DefaultValue("5") int suboptimalMinutes, @QueryParam("suboptimal") @DefaultValue("5") int suboptimalMinutes,
@QueryParam("accessModes") @DefaultValue("WALK,BICYCLE") TraverseModeSet accessModes, @QueryParam("accessModes") @DefaultValue("WALK,BICYCLE") TraverseModeSet accessModes,
@QueryParam("egressModes") @DefaultValue("WALK") TraverseModeSet egressModes, @QueryParam("egressModes") @DefaultValue("WALK") TraverseModeSet egressModes,
Expand Down
Expand Up @@ -37,7 +37,7 @@ public class ProfileRequest implements Serializable {


public LocalDate date; public LocalDate date;
public Option.SortOrder orderBy; public Option.SortOrder orderBy;
public int limit; public int limit; // the maximum number of options presented PER ACCESS MODE
public TraverseModeSet accessModes, egressModes, directModes, transitModes; public TraverseModeSet accessModes, egressModes, directModes, transitModes;
public boolean analyst = false; // if true, propagate travel times out to street network public boolean analyst = false; // if true, propagate travel times out to street network


Expand Down
38 changes: 26 additions & 12 deletions src/main/java/org/opentripplanner/profile/ProfileResponse.java
@@ -1,11 +1,12 @@
package org.opentripplanner.profile; package org.opentripplanner.profile;


import java.util.Collection; import java.util.*;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;


import com.beust.jcommander.internal.Sets;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.opentripplanner.routing.core.TraverseMode;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;


Expand All @@ -14,23 +15,23 @@ public class ProfileResponse {


private static final Logger LOG = LoggerFactory.getLogger(ProfileResponse.class); private static final Logger LOG = LoggerFactory.getLogger(ProfileResponse.class);


public List<Option> options = Lists.newArrayList(); public Set<Option> options = Sets.newHashSet();


/** /**
* The constructed response will include all the options that do not use transit, * The constructed response will include all the options that do not use transit,
* as well as the top N options that do use transit. * as well as the top N options that do use transit for each access mode.
* *
* @param orderBy specifies how the top N transit options will be chosen * @param orderBy specifies how the top N transit options will be chosen
* @param limit the maximum number of transit options to include in the response. * @param limit the maximum number of transit options to include in the response. zero or negative means no limit.
*/ */
public ProfileResponse (Collection<Option> options, Option.SortOrder orderBy, int limit) { public ProfileResponse (Collection<Option> options, Option.SortOrder orderBy, int limit) {
List<Option> transitOptions = Lists.newArrayList(); List<Option> transitOptions = Lists.newArrayList();
// Always include non-transit options // Always return all non-transit options
for (Option option : options) { for (Option option : options) {
if (option.transit == null || option.transit.isEmpty()) this.options.add(option); if (option.transit == null || option.transit.isEmpty()) this.options.add(option);
else transitOptions.add(option); else transitOptions.add(option);
} }
// Then choose the top N transit options // Order all transit options by the specified method
Comparator<Option> c; Comparator<Option> c;
switch (orderBy) { switch (orderBy) {
case MAX: case MAX:
Expand All @@ -44,10 +45,23 @@ public ProfileResponse (Collection<Option> options, Option.SortOrder orderBy, in
c = new Option.MinComparator(); c = new Option.MinComparator();
} }
Collections.sort(transitOptions, c); Collections.sort(transitOptions, c);
if (limit > 0 && limit <= transitOptions.size()) { // Group options by access mode, retaining ordering.
transitOptions = transitOptions.subList(0, limit); // ListMultimap can hold duplicate key-value pairs and maintains the insertion ordering of values for a given key.
// TODO update this to also use the egress mode in the key
ListMultimap<TraverseMode, Option> transitOptionsByAccessMode = ArrayListMultimap.create();
for (Option option : transitOptions) {
for (StreetSegment segment : option.access) {
transitOptionsByAccessMode.put(segment.mode, option);
}
}
// Retain the top N transit options for each access mode. Duplicates may be present, but options is a Set.
for (Collection<Option> singleModeOptions : transitOptionsByAccessMode.asMap().values()) {
int n = 0;
for (Option option : singleModeOptions) {
options.add(option);
if (limit > 0 && ++n >= limit) break;
}
} }
this.options.addAll(transitOptions);
for (Option option : this.options) { for (Option option : this.options) {
LOG.info("{} {}", option.stats, option.summary); LOG.info("{} {}", option.stats, option.summary);
} }
Expand Down

0 comments on commit 607ac4b

Please sign in to comment.