diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index 689b7419122..e0ea8ba36b9 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -52,14 +52,13 @@ public class LuceneIndex implements Serializable { private static final String TYPE = "type"; private static final String ID = "id"; + private static final String SECONDARY_IDS = "secondary_ids"; private static final String SUGGEST = "suggest"; private static final String NAME = "name"; private static final String NAME_NGRAM = "name_ngram"; private static final String CODE = "code"; private static final String LAT = "latitude"; private static final String LON = "longitude"; - private static final String MODE = "mode"; - private static final String AGENCY_IDS = "agency_ids"; private final TransitService transitService; private final Analyzer analyzer; @@ -96,12 +95,11 @@ public LuceneIndex(TransitService transitService) { directoryWriter, StopLocation.class, stopLocation.getId().toString(), + List.of(), ListUtils.ofNullable(stopLocation.getName()), ListUtils.ofNullable(stopLocation.getCode()), stopLocation.getCoordinate().latitude(), - stopLocation.getCoordinate().longitude(), - Set.of(), - Set.of() + stopLocation.getCoordinate().longitude() ) ); @@ -112,12 +110,11 @@ public LuceneIndex(TransitService transitService) { directoryWriter, StopLocationsGroup.class, stopLocationsGroup.getId().toString(), + List.of(), ListUtils.ofNullable(stopLocationsGroup.getName()), List.of(), stopLocationsGroup.getCoordinate().latitude(), - stopLocationsGroup.getCoordinate().longitude(), - Set.of(), - Set.of() + stopLocationsGroup.getCoordinate().longitude() ) ); @@ -131,12 +128,11 @@ public LuceneIndex(TransitService transitService) { directoryWriter, StopCluster.class, stopCluster.primaryId(), + stopCluster.secondaryIds(), stopCluster.names(), stopCluster.codes(), stopCluster.coordinate().lat(), - stopCluster.coordinate().lon(), - stopCluster.modes(), - List.of() + stopCluster.coordinate().lon() ) ); } @@ -187,7 +183,13 @@ private StopCluster toStopCluster(Document document) { var primaryId = FeedScopedId.parse(document.get(ID)); var primary = stopClusterMapper.toLocation(primaryId); - return new StopCluster(primary, List.of()); + var secondaryIds = Arrays + .stream(document.getValues(SECONDARY_IDS)) + .map(FeedScopedId::parse) + .map(stopClusterMapper::toLocation) + .toList(); + + return new StopCluster(primary, secondaryIds); } static IndexWriterConfig iwcWithSuggestField(Analyzer analyzer, final Set suggestFields) { @@ -211,17 +213,19 @@ private static void addToIndex( IndexWriter writer, Class type, String id, + Collection secondaryIds, Collection names, Collection codes, double latitude, - double longitude, - Collection modes, - Collection agencyIds + double longitude ) { String typeName = type.getSimpleName(); Document document = new Document(); document.add(new StoredField(ID, id)); + for (var secondaryId : secondaryIds) { + document.add(new StoredField(SECONDARY_IDS, secondaryId)); + } document.add(new TextField(TYPE, typeName, Store.YES)); for (var name : names) { document.add(new TextField(NAME, Objects.toString(name), Store.YES)); @@ -236,13 +240,6 @@ private static void addToIndex( document.add(new ContextSuggestField(SUGGEST, code, 1, typeName)); } - for (var mode : modes) { - document.add(new TextField(MODE, mode, Store.YES)); - } - for (var aId : agencyIds) { - document.add(new TextField(AGENCY_IDS, aId, Store.YES)); - } - try { writer.addDocument(document); } catch (IOException ex) { diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java index 9ed1b71da76..b4ee0f0919b 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java @@ -10,7 +10,6 @@ record LuceneStopCluster( String primaryId, Collection secondaryIds, Collection names, - Collection modes, Collection codes, StopCluster.Coordinate coordinate ) {} diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index 543f06949ff..bb8f0e72bbe 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; @@ -39,7 +40,7 @@ Iterable generateStopClusters( Collection stopLocations, Collection stopLocationsGroups ) { - var stops = stopLocations + List stops = stopLocations .stream() // remove stop locations without a parent station .filter(sl -> sl.getParentStation() == null) @@ -48,13 +49,17 @@ Iterable generateStopClusters( .toList(); // if they are very close to each other and have the same name, only one is chosen (at random) - var deduplicatedStops = ListUtils - .distinctByKey( - stops, - sl -> new DeduplicationKey(sl.getName(), sl.getCoordinate().roundToApproximate100m()) + var deduplicatedStops = stops + .stream() + .collect( + Collectors.groupingBy(sl -> + new DeduplicationKey(sl.getName(), sl.getCoordinate().roundToApproximate100m()) + ) ) + .values() .stream() - .flatMap(s -> this.map(s).stream()) + .map(group -> this.map(group).orElse(null)) + .filter(Objects::nonNull) .toList(); var stations = stopLocationsGroups.stream().map(this::map).toList(); @@ -62,8 +67,6 @@ Iterable generateStopClusters( } LuceneStopCluster map(StopLocationsGroup g) { - var modes = transitService.getModesOfStopLocationsGroup(g).stream().map(Enum::name).toList(); - var childStops = g.getChildStops(); var ids = childStops.stream().map(s -> s.getId().toString()).toList(); var childNames = childStops @@ -78,32 +81,34 @@ LuceneStopCluster map(StopLocationsGroup g) { ids, ListUtils.combine(List.of(g.getName()), childNames), codes, - modes, toCoordinate(g.getCoordinate()) ); } - Optional map(StopLocation sl) { + Optional map(List stopLocations) { + var primary = stopLocations.getFirst(); + var secondaryIds = stopLocations.stream().skip(1).map(sl -> sl.getId().toString()).toList(); + var names = stopLocations.stream().map(StopLocation::getName).toList(); + var codes = stopLocations.stream().map(StopLocation::getCode).filter(Objects::nonNull).toList(); + return Optional - .ofNullable(sl.getName()) - .map(name -> { - var modes = transitService.getModesOfStopLocation(sl).stream().map(Enum::name).toList(); - return new LuceneStopCluster( - sl.getId().toString(), - List.of(), - List.of(name), - modes, - ListUtils.ofNullable(sl.getCode()), - toCoordinate(sl.getCoordinate()) - ); - }); + .ofNullable(primary.getName()) + .map(name -> + new LuceneStopCluster( + primary.getId().toString(), + secondaryIds, + names, + codes, + toCoordinate(primary.getCoordinate()) + ) + ); } - List agenciesForStopLocation(StopLocation stop) { + private List agenciesForStopLocation(StopLocation stop) { return transitService.getRoutesForStop(stop).stream().map(Route::getAgency).distinct().toList(); } - List agenciesForStopLocationsGroup(StopLocationsGroup group) { + private List agenciesForStopLocationsGroup(StopLocationsGroup group) { return group .getChildStops() .stream() @@ -112,28 +117,10 @@ List agenciesForStopLocationsGroup(StopLocationsGroup group) { .toList(); } - private static StopCluster.Coordinate toCoordinate(WgsCoordinate c) { - return new StopCluster.Coordinate(c.latitude(), c.longitude()); - } - - static StopCluster.Agency toAgency(Agency a) { - return new StopCluster.Agency(a.getId(), a.getName()); - } - - static StopCluster.FeedPublisher toFeedPublisher(FeedInfo fi) { - if (fi == null) { - return null; - } else { - return new StopCluster.FeedPublisher(fi.getPublisherName()); - } - } - StopCluster.Location toLocation(FeedScopedId id) { var loc = transitService.getStopLocation(id); if (loc != null) { - var feedPublisher = toFeedPublisher( - transitService.getFeedInfo(id.getFeedId()) - ); + var feedPublisher = toFeedPublisher(transitService.getFeedInfo(id.getFeedId())); var modes = transitService.getModesOfStopLocation(loc).stream().map(Enum::name).toList(); var agencies = agenciesForStopLocation(loc) .stream() @@ -150,10 +137,12 @@ StopCluster.Location toLocation(FeedScopedId id) { ); } else { var group = transitService.getStopLocationsGroup(id); - var feedPublisher = toFeedPublisher( - transitService.getFeedInfo(id.getFeedId()) - ); - var modes = transitService.getModesOfStopLocationsGroup(group).stream().map(Enum::name).toList(); + var feedPublisher = toFeedPublisher(transitService.getFeedInfo(id.getFeedId())); + var modes = transitService + .getModesOfStopLocationsGroup(group) + .stream() + .map(Enum::name) + .toList(); var agencies = agenciesForStopLocationsGroup(group) .stream() .map(StopClusterMapper::toAgency) @@ -170,5 +159,21 @@ StopCluster.Location toLocation(FeedScopedId id) { } } + private static StopCluster.Coordinate toCoordinate(WgsCoordinate c) { + return new StopCluster.Coordinate(c.latitude(), c.longitude()); + } + + static StopCluster.Agency toAgency(Agency a) { + return new StopCluster.Agency(a.getId(), a.getName()); + } + + private static StopCluster.FeedPublisher toFeedPublisher(FeedInfo fi) { + if (fi == null) { + return null; + } else { + return new StopCluster.FeedPublisher(fi.getPublisherName()); + } + } + private record DeduplicationKey(I18NString name, WgsCoordinate coordinate) {} }