From 242b3fbbf694ab550985963ac14859fdaee6abea Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 19 Jan 2024 18:09:21 +0100 Subject: [PATCH 1/8] Return agencies and feed publisher in geocoding --- docs/apis/Apis.md | 2 +- docs/sandbox/GeocoderAPI.md | 8 ++--- .../ext/geocoder/LuceneIndexTest.java | 1 + .../ext/geocoder/GeocoderResource.java | 24 ++++++++------ .../ext/geocoder/LuceneIndex.java | 28 ++++++++++++---- .../ext/geocoder/StopCluster.java | 15 ++++++++- .../ext/geocoder/StopClusterMapper.java | 32 +++++++++++++++++-- .../opentripplanner/apis/APIEndpoints.java | 2 ++ .../service/DefaultTransitService.java | 5 +++ .../transit/service/TransitService.java | 2 ++ 10 files changed, 96 insertions(+), 23 deletions(-) diff --git a/docs/apis/Apis.md b/docs/apis/Apis.md index 48b530a57e1..d9f0467bbca 100644 --- a/docs/apis/Apis.md +++ b/docs/apis/Apis.md @@ -18,7 +18,7 @@ entities on a vector map. The [Actuator API](../sandbox/ActuatorAPI.md) provides endpoints for checking the health status of the OTP instance and reading live application metrics. -The [Geocoder API](../sandbox/GeocoderAPI.md) allows you to geocode street corners and stop names. +The [Geocoder API](../sandbox/GeocoderAPI.md) allows you to geocode stop names and codes. ## Legacy APIs (to be removed) diff --git a/docs/sandbox/GeocoderAPI.md b/docs/sandbox/GeocoderAPI.md index 0405724fff6..f7a1be3f293 100644 --- a/docs/sandbox/GeocoderAPI.md +++ b/docs/sandbox/GeocoderAPI.md @@ -26,7 +26,7 @@ To enable this you need to add the feature to `otp-config.json`. The required geocode API for Stop and From/To searches in the debug client. -Path: `/otp/routers/{routerId}/geocode` +Path: `/otp/geocode` It supports the following URL parameters: @@ -40,12 +40,12 @@ It supports the following URL parameters: #### Stop clusters A stop cluster is a deduplicated groups of stops. This means that for any stop that has a parent -station only the parent is returned and for stops that have identical names and are very close +station only the parent is returned and for stops that have _identical_ names and are very close to each other, only one is returned. -This is useful for a general purpose fuzzy "stop" search. +This is useful for a general purpose fuzzy stop search. -Path: `/otp/routers/{routerId}/geocode/stopClusters` +Path: `/otp/geocode/stopClusters` It supports the following URL parameters: diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 371bcb249b6..178b8b6fd67 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -105,6 +105,7 @@ static void setup() { .of(ALEXANDERPLATZ_STATION, BERLIN_HAUPTBAHNHOF_STATION, FIVE_POINTS_STATION) .forEach(stopModel::withStation); var transitModel = new TransitModel(stopModel.build(), new Deduplicator()); + transitModel.index(); var transitService = new DefaultTransitService(transitModel) { private final Multimap modes = ImmutableMultimap .builder() diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java b/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java index 39ed6da297c..f5d1f950632 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java @@ -21,24 +21,30 @@ /** * OTP simple built-in geocoder used by the debug client. */ -@Path("/routers/{ignoreRouterId}/geocode") +@Path("/geocode") @Produces(MediaType.APPLICATION_JSON) public class GeocoderResource { private final OtpServerRequestContext serverContext; - /** - * @deprecated The support for multiple routers are removed from OTP2. See - * https://github.com/opentripplanner/OpenTripPlanner/issues/2760 - */ - @Deprecated - @PathParam("ignoreRouterId") - private String ignoreRouterId; - public GeocoderResource(@Context OtpServerRequestContext requestContext) { serverContext = requestContext; } + /** + * This class is only here for backwards-compatibility. It will be removed in the future. + */ + @Path("/routers/{ignoreRouterId}/geocode") + public static class GeocoderResourceOldPath extends GeocoderResource { + + public GeocoderResourceOldPath( + @Context OtpServerRequestContext serverContext, + @PathParam("ignoreRouterId") String ignore + ) { + super(serverContext); + } + } + /** * Geocode using data using the OTP graph for stops, clusters and street names * diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index 71b0cf67b34..e390c900377 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -42,7 +42,6 @@ import org.apache.lucene.store.ByteBuffersDirectory; import org.opentripplanner.ext.geocoder.StopCluster.Coordinate; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.StopLocation; @@ -67,6 +66,7 @@ public class LuceneIndex implements Serializable { public LuceneIndex(TransitService transitService) { this.transitService = transitService; + var stopClusterMapper = new StopClusterMapper(transitService); this.analyzer = new PerFieldAnalyzerWrapper( @@ -80,7 +80,6 @@ public LuceneIndex(TransitService transitService) { var directory = new ByteBuffersDirectory(); - var stopClusterMapper = new StopClusterMapper(transitService); try { try ( var directoryWriter = new IndexWriter( @@ -128,7 +127,7 @@ public LuceneIndex(TransitService transitService) { directoryWriter, StopCluster.class, stopCluster.id().toString(), - new NonLocalizedString(stopCluster.name()), + I18NString.of(stopCluster.name()), stopCluster.code(), stopCluster.coordinate().lat(), stopCluster.coordinate().lon(), @@ -176,17 +175,34 @@ public Stream queryStopLocationGroups(String query, boolean * one of those is chosen at random and returned. */ public Stream queryStopClusters(String query) { - return matchingDocuments(StopCluster.class, query, false).map(LuceneIndex::toStopCluster); + return matchingDocuments(StopCluster.class, query, false).map(this::toStopCluster); } - private static StopCluster toStopCluster(Document document) { + private StopCluster toStopCluster(Document document) { var id = FeedScopedId.parse(document.get(ID)); var name = document.get(NAME); var code = document.get(CODE); var lat = document.getField(LAT).numericValue().doubleValue(); var lon = document.getField(LON).numericValue().doubleValue(); var modes = Arrays.asList(document.getValues(MODE)); - return new StopCluster(id, code, name, new Coordinate(lat, lon), modes); + var stopLocation = transitService.getStopLocation(id); + var agencies = transitService + .getAgenciesForStopLocation(stopLocation) + .stream() + .map(StopClusterMapper::toAgency) + .toList(); + var feedPublisher = StopClusterMapper.toFeedPublisher( + transitService.getFeedInfo(id.getFeedId()) + ); + return new StopCluster( + id, + code, + name, + new Coordinate(lat, lon), + modes, + agencies, + feedPublisher + ); } static IndexWriterConfig iwcWithSuggestField(Analyzer analyzer, final Set suggestFields) { diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java index afb60960ed4..8ffd44511fd 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java @@ -1,6 +1,7 @@ package org.opentripplanner.ext.geocoder; import java.util.Collection; +import java.util.List; import javax.annotation.Nullable; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -18,10 +19,22 @@ record StopCluster( @Nullable String code, String name, Coordinate coordinate, - Collection modes + Collection modes, + List agencies, + @Nullable FeedPublisher feedPublisher ) { /** * Easily serializable version of a coordinate */ public record Coordinate(double lat, double lon) {} + + /** + * Easily serializable version of an agency + */ + public record Agency(FeedScopedId id, String name) {} + + /** + * Easily serializable version of a feed publisher + */ + public record FeedPublisher(String name) {} } diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index bc2f4f7022b..186d6d6b57e 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -6,6 +6,8 @@ import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; +import org.opentripplanner.model.FeedInfo; +import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.site.StopLocationsGroup; import org.opentripplanner.transit.service.TransitService; @@ -62,7 +64,15 @@ StopCluster map(StopLocationsGroup g) { null, g.getName().toString(), toCoordinate(g.getCoordinate()), - modes + modes, + g + .getChildStops() + .stream() + .flatMap(sl -> transitService.getAgenciesForStopLocation(sl).stream()) + .distinct() + .map(StopClusterMapper::toAgency) + .toList(), + toFeedPublisher(transitService.getFeedInfo(g.getId().getFeedId())) ); } @@ -76,7 +86,13 @@ Optional map(StopLocation sl) { sl.getCode(), name.toString(), toCoordinate(sl.getCoordinate()), - modes + modes, + transitService + .getAgenciesForStopLocation(sl) + .stream() + .map(StopClusterMapper::toAgency) + .toList(), + toFeedPublisher(transitService.getFeedInfo(sl.getId().getFeedId())) ); }); } @@ -85,5 +101,17 @@ 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()); + } + } + private record DeduplicationKey(I18NString name, WgsCoordinate coordinate) {} } diff --git a/src/main/java/org/opentripplanner/apis/APIEndpoints.java b/src/main/java/org/opentripplanner/apis/APIEndpoints.java index 68f6bda3d3a..555ea1659f1 100644 --- a/src/main/java/org/opentripplanner/apis/APIEndpoints.java +++ b/src/main/java/org/opentripplanner/apis/APIEndpoints.java @@ -61,6 +61,8 @@ private APIEndpoints() { addIfEnabled(SandboxAPIMapboxVectorTilesApi, VectorTilesResource.class); addIfEnabled(SandboxAPIParkAndRideApi, ParkAndRideResource.class); addIfEnabled(SandboxAPIGeocoder, GeocoderResource.class); + // scheduled to be removed and only here for backwards compatibility + addIfEnabled(SandboxAPIGeocoder, GeocoderResource.GeocoderResourceOldPath.class); addIfEnabled(SandboxAPITravelTime, TravelTimeResource.class); // scheduled to be removed diff --git a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java index 0d08bcf34b2..91d129e0a0c 100644 --- a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java @@ -572,6 +572,11 @@ public List getModesOfStopLocation(StopLocation stop) { return sortByOccurrenceAndReduce(getPatternModesOfStop(stop)).toList(); } + @Override + public List getAgenciesForStopLocation(StopLocation stop) { + return getRoutesForStop(stop).stream().map(Route::getAgency).distinct().toList(); + } + /** * For each pattern visiting this {@link StopLocation} return its {@link TransitMode} */ diff --git a/src/main/java/org/opentripplanner/transit/service/TransitService.java b/src/main/java/org/opentripplanner/transit/service/TransitService.java index d0664aa292d..5006ed93f30 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/TransitService.java @@ -215,4 +215,6 @@ List stopTimesForPatternAtStop( * So, if more patterns of mode BUS than RAIL visit the stop, the result will be [BUS,RAIL]. */ List getModesOfStopLocation(StopLocation stop); + + List getAgenciesForStopLocation(StopLocation stop); } From d4d7c5518f04318c0770d0d96924c49478c2e583 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sat, 20 Jan 2024 09:13:51 +0100 Subject: [PATCH 2/8] Serialize agencies in Lucene index --- .../ext/geocoder/LuceneIndexTest.java | 13 ++++---- .../ext/geocoder/LuceneIndex.java | 31 +++++++++++------- .../ext/geocoder/LuceneStopCluster.java | 19 +++++++++++ .../ext/geocoder/StopClusterMapper.java | 32 +++++++------------ 4 files changed, 56 insertions(+), 39 deletions(-) create mode 100644 src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 178b8b6fd67..01b62a63891 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -175,14 +175,15 @@ class StopClusters { } ) void stopClustersWithTypos(String searchTerm) { - var result1 = index.queryStopClusters(searchTerm).toList(); - assertEquals(List.of(mapper.map(ALEXANDERPLATZ_STATION)), result1); + var results = index.queryStopClusters(searchTerm).toList(); + var ids = results.stream().map(StopCluster::id).toList(); + assertEquals(List.of(ALEXANDERPLATZ_STATION.getId()), ids); } @Test void fuzzyStopClusters() { - var result1 = index.queryStopClusters("arts").toList(); - assertEquals(List.of(mapper.map(ARTS_CENTER).get()), result1); + var result1 = index.queryStopClusters("arts").map(StopCluster::id).toList(); + assertEquals(List.of(ARTS_CENTER.getId()), result1); } @Test @@ -221,8 +222,8 @@ void deduplicatedStopClusters() { } ) void stopClustersWithSpace(String query) { - var result = index.queryStopClusters(query).toList(); - assertEquals(List.of(mapper.map(FIVE_POINTS_STATION)), result); + var result = index.queryStopClusters(query).map(StopCluster::id).toList(); + assertEquals(List.of(FIVE_POINTS_STATION.getId()), result); } @ParameterizedTest diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index e390c900377..26c4d34ce25 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -59,14 +59,16 @@ public class LuceneIndex implements Serializable { 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; private final SuggestIndexSearcher searcher; + private final StopClusterMapper stopClusterMapper; public LuceneIndex(TransitService transitService) { this.transitService = transitService; - var stopClusterMapper = new StopClusterMapper(transitService); + this.stopClusterMapper = new StopClusterMapper(transitService); this.analyzer = new PerFieldAnalyzerWrapper( @@ -98,6 +100,7 @@ public LuceneIndex(TransitService transitService) { stopLocation.getCode(), stopLocation.getCoordinate().latitude(), stopLocation.getCoordinate().longitude(), + Set.of(), Set.of() ) ); @@ -113,6 +116,7 @@ public LuceneIndex(TransitService transitService) { null, stopLocationsGroup.getCoordinate().latitude(), stopLocationsGroup.getCoordinate().longitude(), + Set.of(), Set.of() ) ); @@ -131,7 +135,8 @@ public LuceneIndex(TransitService transitService) { stopCluster.code(), stopCluster.coordinate().lat(), stopCluster.coordinate().lon(), - stopCluster.modes() + stopCluster.modes(), + stopCluster.agencies() ) ); } @@ -179,23 +184,21 @@ public Stream queryStopClusters(String query) { } private StopCluster toStopCluster(Document document) { - var id = FeedScopedId.parse(document.get(ID)); + var clusterId = FeedScopedId.parse(document.get(ID)); var name = document.get(NAME); var code = document.get(CODE); var lat = document.getField(LAT).numericValue().doubleValue(); var lon = document.getField(LON).numericValue().doubleValue(); var modes = Arrays.asList(document.getValues(MODE)); - var stopLocation = transitService.getStopLocation(id); - var agencies = transitService - .getAgenciesForStopLocation(stopLocation) - .stream() - .map(StopClusterMapper::toAgency) - .toList(); + var agencies = Arrays.stream(document.getValues(AGENCY_IDS)).map(id -> { + var fsid = FeedScopedId.parse(id); + return transitService.getAgencyForId(fsid); + }).filter(Objects::nonNull).map(StopClusterMapper::toAgency).toList(); var feedPublisher = StopClusterMapper.toFeedPublisher( - transitService.getFeedInfo(id.getFeedId()) + transitService.getFeedInfo(clusterId.getFeedId()) ); return new StopCluster( - id, + clusterId, code, name, new Coordinate(lat, lon), @@ -230,7 +233,8 @@ private static void addToIndex( @Nullable String code, double latitude, double longitude, - Collection modes + Collection modes, + Collection agencyIds ) { String typeName = type.getSimpleName(); @@ -251,6 +255,9 @@ private static void addToIndex( for (var mode : modes) { document.add(new TextField(MODE, mode, Store.YES)); } + for (var ids : agencyIds) { + document.add(new TextField(AGENCY_IDS, ids, Store.YES)); + } try { writer.addDocument(document); diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java new file mode 100644 index 00000000000..3f916186430 --- /dev/null +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java @@ -0,0 +1,19 @@ +package org.opentripplanner.ext.geocoder; + +import java.util.Collection; +import javax.annotation.Nullable; +import org.opentripplanner.transit.model.framework.FeedScopedId; + +/** + * A package-private helper type for transporting + */ +record LuceneStopCluster( + FeedScopedId id, + @Nullable + String code, + String name, + StopCluster.Coordinate coordinate, + Collection modes, + Collection agencies + ){ +} diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index 186d6d6b57e..c1a6d216ff0 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -13,7 +13,7 @@ import org.opentripplanner.transit.service.TransitService; /** - * Mappers for generating {@link StopCluster} from the transit model. + * Mappers for generating {@link LuceneStopCluster} from the transit model. */ class StopClusterMapper { @@ -23,6 +23,7 @@ class StopClusterMapper { this.transitService = transitService; } + /** * De-duplicates collections of {@link StopLocation} and {@link StopLocationsGroup} into a stream * of {@link StopCluster}. @@ -31,7 +32,7 @@ class StopClusterMapper { * - of "identical" stops which are very close to each other and have an identical name, only one * is chosen (at random) */ - Iterable generateStopClusters( + Iterable generateStopClusters( Collection stopLocations, Collection stopLocationsGroups ) { @@ -57,42 +58,31 @@ Iterable generateStopClusters( return Iterables.concat(deduplicatedStops, stations); } - StopCluster map(StopLocationsGroup g) { + LuceneStopCluster map(StopLocationsGroup g) { var modes = transitService.getModesOfStopLocationsGroup(g).stream().map(Enum::name).toList(); - return new StopCluster( + var agencies = g.getChildStops().stream().flatMap(s -> transitService.getAgenciesForStopLocation(s).stream()).distinct().map(s ->s.getId().toString()).toList(); + return new LuceneStopCluster( g.getId(), null, g.getName().toString(), toCoordinate(g.getCoordinate()), modes, - g - .getChildStops() - .stream() - .flatMap(sl -> transitService.getAgenciesForStopLocation(sl).stream()) - .distinct() - .map(StopClusterMapper::toAgency) - .toList(), - toFeedPublisher(transitService.getFeedInfo(g.getId().getFeedId())) + agencies ); } - Optional map(StopLocation sl) { + Optional map(StopLocation sl) { + var agencies = transitService.getAgenciesForStopLocation(sl).stream().map(a -> a.getId().toString()).toList(); return Optional .ofNullable(sl.getName()) .map(name -> { var modes = transitService.getModesOfStopLocation(sl).stream().map(Enum::name).toList(); - return new StopCluster( + return new LuceneStopCluster( sl.getId(), sl.getCode(), name.toString(), toCoordinate(sl.getCoordinate()), - modes, - transitService - .getAgenciesForStopLocation(sl) - .stream() - .map(StopClusterMapper::toAgency) - .toList(), - toFeedPublisher(transitService.getFeedInfo(sl.getId().getFeedId())) + modes, agencies ); }); } From 8726b2fe10a7e48ed5de4e702b8cc3207897f22f Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sat, 20 Jan 2024 10:01:25 +0100 Subject: [PATCH 3/8] Add test for agencies --- .../ext/geocoder/LuceneIndexTest.java | 52 +++++++++++++++---- .../ext/geocoder/LuceneIndex.java | 18 ++++--- .../ext/geocoder/LuceneStopCluster.java | 6 +-- .../ext/geocoder/StopClusterMapper.java | 18 +++++-- 4 files changed, 69 insertions(+), 25 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 01b62a63891..348586377d4 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -18,6 +18,8 @@ import org.opentripplanner.transit.model._data.TransitModelForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.Deduplicator; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; import org.opentripplanner.transit.model.site.StopLocation; @@ -28,57 +30,63 @@ class LuceneIndexTest { private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + static final Agency BVG = Agency + .of(id("bvg")) + .withName("BVG") + .withTimezone("Europe/Berlin") + .build(); + // Berlin - static Station BERLIN_HAUPTBAHNHOF_STATION = TEST_MODEL + static final Station BERLIN_HAUPTBAHNHOF_STATION = TEST_MODEL .station("Hauptbahnhof") .withCoordinate(52.52495, 13.36952) .build(); - static Station ALEXANDERPLATZ_STATION = TEST_MODEL + static final Station ALEXANDERPLATZ_STATION = TEST_MODEL .station("Alexanderplatz") .withCoordinate(52.52277, 13.41046) .build(); - static RegularStop ALEXANDERPLATZ_BUS = TEST_MODEL + static final RegularStop ALEXANDERPLATZ_BUS = TEST_MODEL .stop("Alexanderplatz Bus") .withCoordinate(52.52277, 13.41046) .withVehicleType(BUS) .withParentStation(ALEXANDERPLATZ_STATION) .build(); - static RegularStop ALEXANDERPLATZ_RAIL = TEST_MODEL + static final RegularStop ALEXANDERPLATZ_RAIL = TEST_MODEL .stop("Alexanderplatz S-Bahn") .withCoordinate(52.52157, 13.41123) .withVehicleType(TransitMode.RAIL) .withParentStation(ALEXANDERPLATZ_STATION) .build(); - static RegularStop LICHTERFELDE_OST_1 = TEST_MODEL + static final RegularStop LICHTERFELDE_OST_1 = TEST_MODEL .stop("Lichterfelde Ost") .withId(id("lichterfelde-gleis-1")) .withCoordinate(52.42986, 13.32808) .build(); - static RegularStop LICHTERFELDE_OST_2 = TEST_MODEL + static final RegularStop LICHTERFELDE_OST_2 = TEST_MODEL .stop("Lichterfelde Ost") .withId(id("lichterfelde-gleis-2")) .withCoordinate(52.42985, 13.32807) .build(); - static RegularStop WESTHAFEN = TEST_MODEL + static final RegularStop WESTHAFEN = TEST_MODEL .stop("Westhafen") .withVehicleType(null) .withCoordinate(52.42985, 13.32807) .build(); // Atlanta - static Station FIVE_POINTS_STATION = TEST_MODEL + static final Station FIVE_POINTS_STATION = TEST_MODEL .station("Five Points") .withCoordinate(33.753899, -84.39156) .build(); - static RegularStop ARTS_CENTER = TEST_MODEL + static final RegularStop ARTS_CENTER = TEST_MODEL .stop("Arts Center") .withCode("4456") .withCoordinate(52.52277, 13.41046) .build(); - static RegularStop ARTHUR = TEST_MODEL + static final RegularStop ARTHUR = TEST_MODEL .stop("Arthur Langford Jr Pl SW at 220") .withCoordinate(52.52277, 13.41046) .build(); @@ -120,6 +128,23 @@ public List getModesOfStopLocation(StopLocation stop) { return List.copyOf(modes.get(stop)); } } + + @Override + public List getAgenciesForStopLocation(StopLocation stop) { + if (stop.equals(ALEXANDERPLATZ_BUS)) { + return List.of(BVG); + } else { + return List.of(); + } + } + + @Override + public Agency getAgencyForId(FeedScopedId id) { + if (id.equals(BVG.getId())) { + return BVG; + } + return null; + } }; index = new LuceneIndex(transitService); mapper = new StopClusterMapper(transitService); @@ -242,5 +267,12 @@ void modes() { assertEquals(WESTHAFEN.getName().toString(), stop.name()); assertEquals(List.of(FERRY.name(), BUS.name()), stop.modes()); } + + @Test + void agencies() { + var result = index.queryStopClusters("alexanderplatz").toList().getFirst(); + assertEquals(ALEXANDERPLATZ_STATION.getName().toString(), result.name()); + assertEquals(List.of(StopClusterMapper.toAgency(BVG)), result.agencies()); + } } } diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index 26c4d34ce25..75e0fc3333a 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -59,16 +59,15 @@ public class LuceneIndex implements Serializable { 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 static final String AGENCY_IDS = "agency_ids"; private final TransitService transitService; private final Analyzer analyzer; private final SuggestIndexSearcher searcher; - private final StopClusterMapper stopClusterMapper; public LuceneIndex(TransitService transitService) { this.transitService = transitService; - this.stopClusterMapper = new StopClusterMapper(transitService); + StopClusterMapper stopClusterMapper = new StopClusterMapper(transitService); this.analyzer = new PerFieldAnalyzerWrapper( @@ -190,10 +189,15 @@ private StopCluster toStopCluster(Document document) { var lat = document.getField(LAT).numericValue().doubleValue(); var lon = document.getField(LON).numericValue().doubleValue(); var modes = Arrays.asList(document.getValues(MODE)); - var agencies = Arrays.stream(document.getValues(AGENCY_IDS)).map(id -> { - var fsid = FeedScopedId.parse(id); - return transitService.getAgencyForId(fsid); - }).filter(Objects::nonNull).map(StopClusterMapper::toAgency).toList(); + var agencies = Arrays + .stream(document.getValues(AGENCY_IDS)) + .map(id -> { + var fsid = FeedScopedId.parse(id); + return transitService.getAgencyForId(fsid); + }) + .filter(Objects::nonNull) + .map(StopClusterMapper::toAgency) + .toList(); var feedPublisher = StopClusterMapper.toFeedPublisher( transitService.getFeedInfo(clusterId.getFeedId()) ); diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java index 3f916186430..25776e1d39f 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java @@ -9,11 +9,9 @@ */ record LuceneStopCluster( FeedScopedId id, - @Nullable - String code, + @Nullable String code, String name, StopCluster.Coordinate coordinate, Collection modes, Collection agencies - ){ -} +) {} diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index c1a6d216ff0..d231765b66d 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -23,7 +23,6 @@ class StopClusterMapper { this.transitService = transitService; } - /** * De-duplicates collections of {@link StopLocation} and {@link StopLocationsGroup} into a stream * of {@link StopCluster}. @@ -60,7 +59,13 @@ Iterable generateStopClusters( LuceneStopCluster map(StopLocationsGroup g) { var modes = transitService.getModesOfStopLocationsGroup(g).stream().map(Enum::name).toList(); - var agencies = g.getChildStops().stream().flatMap(s -> transitService.getAgenciesForStopLocation(s).stream()).distinct().map(s ->s.getId().toString()).toList(); + var agencies = g + .getChildStops() + .stream() + .flatMap(s -> transitService.getAgenciesForStopLocation(s).stream()) + .distinct() + .map(s -> s.getId().toString()) + .toList(); return new LuceneStopCluster( g.getId(), null, @@ -72,7 +77,11 @@ LuceneStopCluster map(StopLocationsGroup g) { } Optional map(StopLocation sl) { - var agencies = transitService.getAgenciesForStopLocation(sl).stream().map(a -> a.getId().toString()).toList(); + var agencies = transitService + .getAgenciesForStopLocation(sl) + .stream() + .map(a -> a.getId().toString()) + .toList(); return Optional .ofNullable(sl.getName()) .map(name -> { @@ -82,7 +91,8 @@ Optional map(StopLocation sl) { sl.getCode(), name.toString(), toCoordinate(sl.getCoordinate()), - modes, agencies + modes, + agencies ); }); } From 1db3ac13d8c5a2b3685087494883f2709407a64b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sat, 20 Jan 2024 17:35:11 +0100 Subject: [PATCH 4/8] Add test for feed publisher --- .../ext/geocoder/LuceneIndexTest.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 348586377d4..0b5933c2a52 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -7,6 +7,7 @@ import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Multimap; +import java.time.LocalDate; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -15,6 +16,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import org.opentripplanner.model.FeedInfo; import org.opentripplanner.transit.model._data.TransitModelForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.Deduplicator; @@ -145,6 +147,11 @@ public Agency getAgencyForId(FeedScopedId id) { } return null; } + + @Override + public FeedInfo getFeedInfo(String feedId) { + return new FeedInfo("F", "A Publisher", "http://example.com", "de", LocalDate.MIN, LocalDate.MIN, "1"); + } }; index = new LuceneIndex(transitService); mapper = new StopClusterMapper(transitService); @@ -154,7 +161,7 @@ public Agency getAgencyForId(FeedScopedId id) { void stopLocations() { var result1 = index.queryStopLocations("lich", true).toList(); assertEquals(1, result1.size()); - assertEquals(LICHTERFELDE_OST_1.getName().toString(), result1.get(0).getName().toString()); + assertEquals(LICHTERFELDE_OST_1.getName().toString(), result1.getFirst().getName().toString()); var result2 = index.queryStopLocations("alexan", true).collect(Collectors.toSet()); assertEquals(Set.of(ALEXANDERPLATZ_BUS, ALEXANDERPLATZ_RAIL), result2); @@ -215,7 +222,7 @@ void fuzzyStopClusters() { void deduplicatedStopClusters() { var result = index.queryStopClusters("lich").toList(); assertEquals(1, result.size()); - assertEquals(LICHTERFELDE_OST_1.getName().toString(), result.get(0).name()); + assertEquals(LICHTERFELDE_OST_1.getName().toString(), result.getFirst().name()); } @ParameterizedTest @@ -256,23 +263,24 @@ void stopClustersWithSpace(String query) { void fuzzyStopCode(String query) { var result = index.queryStopClusters(query).toList(); assertEquals(1, result.size()); - assertEquals(ARTS_CENTER.getName().toString(), result.get(0).name()); + assertEquals(ARTS_CENTER.getName().toString(), result.getFirst().name()); } @Test void modes() { var result = index.queryStopClusters("westh").toList(); assertEquals(1, result.size()); - var stop = result.get(0); + var stop = result.getFirst(); assertEquals(WESTHAFEN.getName().toString(), stop.name()); assertEquals(List.of(FERRY.name(), BUS.name()), stop.modes()); } @Test - void agencies() { + void agenciesAndFeedPublisher() { var result = index.queryStopClusters("alexanderplatz").toList().getFirst(); assertEquals(ALEXANDERPLATZ_STATION.getName().toString(), result.name()); assertEquals(List.of(StopClusterMapper.toAgency(BVG)), result.agencies()); + assertEquals("A Publisher", result.feedPublisher().name()); } } } From 1182afd9f95d1c03b38bc89cfc6cb6238f7de15c Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sun, 21 Jan 2024 00:02:20 +0100 Subject: [PATCH 5/8] Add documentation --- .../opentripplanner/ext/geocoder/LuceneIndexTest.java | 10 +++++++++- .../ext/geocoder/LuceneStopCluster.java | 2 +- .../transit/service/TransitService.java | 4 ++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 0b5933c2a52..8dc3ff77a01 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -150,7 +150,15 @@ public Agency getAgencyForId(FeedScopedId id) { @Override public FeedInfo getFeedInfo(String feedId) { - return new FeedInfo("F", "A Publisher", "http://example.com", "de", LocalDate.MIN, LocalDate.MIN, "1"); + return new FeedInfo( + "F", + "A Publisher", + "http://example.com", + "de", + LocalDate.MIN, + LocalDate.MIN, + "1" + ); } }; index = new LuceneIndex(transitService); diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java index 25776e1d39f..49f1a7ee5c3 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java @@ -5,7 +5,7 @@ import org.opentripplanner.transit.model.framework.FeedScopedId; /** - * A package-private helper type for transporting + * A package-private helper type for transporting data before serializing. */ record LuceneStopCluster( FeedScopedId id, diff --git a/src/main/java/org/opentripplanner/transit/service/TransitService.java b/src/main/java/org/opentripplanner/transit/service/TransitService.java index 5006ed93f30..c16b928d2bd 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/TransitService.java @@ -216,5 +216,9 @@ List stopTimesForPatternAtStop( */ List getModesOfStopLocation(StopLocation stop); + /** + * Iterates over all routes that visit this stop location and return a de-duplicated list + * of their agencies. + */ List getAgenciesForStopLocation(StopLocation stop); } From 0e529c74808670b8579ae0f5499ef7d83a5260bf Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sun, 21 Jan 2024 11:35:18 +0100 Subject: [PATCH 6/8] Add tests --- .../org/opentripplanner/ext/geocoder/LuceneIndex.java | 2 +- .../ext/geocoder/LuceneStopCluster.java | 2 +- .../ext/geocoder/StopClusterMapper.java | 6 ++---- .../transit/service/DefaultTransitService.java | 10 ++++++++++ .../transit/service/TransitService.java | 6 ++++++ .../transit/service/DefaultTransitServiceTest.java | 9 +++++++++ 6 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index 75e0fc3333a..b92b36f5a59 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -135,7 +135,7 @@ public LuceneIndex(TransitService transitService) { stopCluster.coordinate().lat(), stopCluster.coordinate().lon(), stopCluster.modes(), - stopCluster.agencies() + stopCluster.agencyIds() ) ); } diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java index 49f1a7ee5c3..f58d7aa9af9 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java @@ -13,5 +13,5 @@ record LuceneStopCluster( String name, StopCluster.Coordinate coordinate, Collection modes, - Collection agencies + Collection agencyIds ) {} diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index d231765b66d..10243665ac8 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -59,11 +59,9 @@ Iterable generateStopClusters( LuceneStopCluster map(StopLocationsGroup g) { var modes = transitService.getModesOfStopLocationsGroup(g).stream().map(Enum::name).toList(); - var agencies = g - .getChildStops() + var agencies = transitService + .getAgenciesForStopLocationsGroup(g) .stream() - .flatMap(s -> transitService.getAgenciesForStopLocation(s).stream()) - .distinct() .map(s -> s.getId().toString()) .toList(); return new LuceneStopCluster( diff --git a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java index 91d129e0a0c..f38499bfd68 100644 --- a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java @@ -577,6 +577,16 @@ public List getAgenciesForStopLocation(StopLocation stop) { return getRoutesForStop(stop).stream().map(Route::getAgency).distinct().toList(); } + @Override + public List getAgenciesForStopLocationsGroup(StopLocationsGroup group) { + return group + .getChildStops() + .stream() + .flatMap(sl -> getAgenciesForStopLocation(sl).stream()) + .distinct() + .toList(); + } + /** * For each pattern visiting this {@link StopLocation} return its {@link TransitMode} */ diff --git a/src/main/java/org/opentripplanner/transit/service/TransitService.java b/src/main/java/org/opentripplanner/transit/service/TransitService.java index c16b928d2bd..156a3c8dd1a 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/TransitService.java @@ -216,6 +216,12 @@ List stopTimesForPatternAtStop( */ List getModesOfStopLocation(StopLocation stop); + /** + * Iterates over all child stops, the routes that visit this stop and return a de-duplicated list + * of their agencies. + */ + List getAgenciesForStopLocationsGroup(StopLocationsGroup group); + /** * Iterates over all routes that visit this stop location and return a de-duplicated list * of their agencies. diff --git a/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java b/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java index 2a26dc681be..ab3d5c8ae0a 100644 --- a/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java +++ b/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java @@ -43,6 +43,8 @@ static void setup() { .build(); var transitModel = new TransitModel(stopModel, new Deduplicator()); + transitModel.addTripPattern(RAIL_PATTERN.getId(), RAIL_PATTERN); + transitModel.index(); service = new DefaultTransitService(transitModel) { @@ -74,4 +76,11 @@ void stationModes() { var modes = service.getModesOfStopLocationsGroup(STATION); assertEquals(List.of(RAIL, FERRY, TRAM), modes); } + + @Test + void stopAgencies() { + var stop = RAIL_PATTERN.getStopPattern().getStop(0); + var agencies = service.getAgenciesForStopLocation(stop); + assertEquals("[Agency{F:A1 Agency Test}]", agencies.toString()); + } } From a0e40e354167d886e963c3b2662e942dc8ced5ae Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sun, 21 Jan 2024 22:04:56 +0100 Subject: [PATCH 7/8] Inline code --- .../java/org/opentripplanner/ext/geocoder/LuceneIndex.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index b92b36f5a59..56769db0028 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -191,10 +191,7 @@ private StopCluster toStopCluster(Document document) { var modes = Arrays.asList(document.getValues(MODE)); var agencies = Arrays .stream(document.getValues(AGENCY_IDS)) - .map(id -> { - var fsid = FeedScopedId.parse(id); - return transitService.getAgencyForId(fsid); - }) + .map(id -> transitService.getAgencyForId(FeedScopedId.parse(id))) .filter(Objects::nonNull) .map(StopClusterMapper::toAgency) .toList(); From 9f66f5db54ed12a6b426d50b2f7f5acb1c7db1d2 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 5 Feb 2024 09:35:30 +0100 Subject: [PATCH 8/8] Move method into sandbox --- .../ext/geocoder/LuceneIndexTest.java | 15 +++++------- .../ext/geocoder/StopClusterMapper.java | 24 +++++++++++++------ .../service/DefaultTransitService.java | 15 ------------ .../transit/service/TransitService.java | 12 ---------- .../service/DefaultTransitServiceTest.java | 7 ------ 5 files changed, 23 insertions(+), 50 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 8dc3ff77a01..b1fb33dfdd3 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -21,6 +21,7 @@ import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; @@ -131,15 +132,6 @@ public List getModesOfStopLocation(StopLocation stop) { } } - @Override - public List getAgenciesForStopLocation(StopLocation stop) { - if (stop.equals(ALEXANDERPLATZ_BUS)) { - return List.of(BVG); - } else { - return List.of(); - } - } - @Override public Agency getAgencyForId(FeedScopedId id) { if (id.equals(BVG.getId())) { @@ -148,6 +140,11 @@ public Agency getAgencyForId(FeedScopedId id) { return null; } + @Override + public Set getRoutesForStop(StopLocation stop) { + return Set.of(TransitModelForTest.route("route1").withAgency(BVG).build()); + } + @Override public FeedInfo getFeedInfo(String feedId) { return new FeedInfo( diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index 10243665ac8..6f16d4a0cce 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -2,11 +2,13 @@ import com.google.common.collect.Iterables; import java.util.Collection; +import java.util.List; import java.util.Optional; import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.model.FeedInfo; +import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.site.StopLocationsGroup; @@ -59,8 +61,7 @@ Iterable generateStopClusters( LuceneStopCluster map(StopLocationsGroup g) { var modes = transitService.getModesOfStopLocationsGroup(g).stream().map(Enum::name).toList(); - var agencies = transitService - .getAgenciesForStopLocationsGroup(g) + var agencies = agenciesForStopLocationsGroup(g) .stream() .map(s -> s.getId().toString()) .toList(); @@ -75,11 +76,7 @@ LuceneStopCluster map(StopLocationsGroup g) { } Optional map(StopLocation sl) { - var agencies = transitService - .getAgenciesForStopLocation(sl) - .stream() - .map(a -> a.getId().toString()) - .toList(); + var agencies = agenciesForStopLocation(sl).stream().map(a -> a.getId().toString()).toList(); return Optional .ofNullable(sl.getName()) .map(name -> { @@ -95,6 +92,19 @@ Optional map(StopLocation sl) { }); } + private List agenciesForStopLocation(StopLocation stop) { + return transitService.getRoutesForStop(stop).stream().map(Route::getAgency).distinct().toList(); + } + + private List agenciesForStopLocationsGroup(StopLocationsGroup group) { + return group + .getChildStops() + .stream() + .flatMap(sl -> agenciesForStopLocation(sl).stream()) + .distinct() + .toList(); + } + private static StopCluster.Coordinate toCoordinate(WgsCoordinate c) { return new StopCluster.Coordinate(c.latitude(), c.longitude()); } diff --git a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java index f38499bfd68..0d08bcf34b2 100644 --- a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java @@ -572,21 +572,6 @@ public List getModesOfStopLocation(StopLocation stop) { return sortByOccurrenceAndReduce(getPatternModesOfStop(stop)).toList(); } - @Override - public List getAgenciesForStopLocation(StopLocation stop) { - return getRoutesForStop(stop).stream().map(Route::getAgency).distinct().toList(); - } - - @Override - public List getAgenciesForStopLocationsGroup(StopLocationsGroup group) { - return group - .getChildStops() - .stream() - .flatMap(sl -> getAgenciesForStopLocation(sl).stream()) - .distinct() - .toList(); - } - /** * For each pattern visiting this {@link StopLocation} return its {@link TransitMode} */ diff --git a/src/main/java/org/opentripplanner/transit/service/TransitService.java b/src/main/java/org/opentripplanner/transit/service/TransitService.java index 156a3c8dd1a..d0664aa292d 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/TransitService.java @@ -215,16 +215,4 @@ List stopTimesForPatternAtStop( * So, if more patterns of mode BUS than RAIL visit the stop, the result will be [BUS,RAIL]. */ List getModesOfStopLocation(StopLocation stop); - - /** - * Iterates over all child stops, the routes that visit this stop and return a de-duplicated list - * of their agencies. - */ - List getAgenciesForStopLocationsGroup(StopLocationsGroup group); - - /** - * Iterates over all routes that visit this stop location and return a de-duplicated list - * of their agencies. - */ - List getAgenciesForStopLocation(StopLocation stop); } diff --git a/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java b/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java index ab3d5c8ae0a..f04fe782a0a 100644 --- a/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java +++ b/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java @@ -76,11 +76,4 @@ void stationModes() { var modes = service.getModesOfStopLocationsGroup(STATION); assertEquals(List.of(RAIL, FERRY, TRAM), modes); } - - @Test - void stopAgencies() { - var stop = RAIL_PATTERN.getStopPattern().getStop(0); - var agencies = service.getAgenciesForStopLocation(stop); - assertEquals("[Agency{F:A1 Agency Test}]", agencies.toString()); - } }