Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Route longName translations #4356

Merged
merged 16 commits into from
Aug 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.opentripplanner.routing.core.FareRuleSet;
import org.opentripplanner.routing.core.Money;
import org.opentripplanner.routing.fares.FareService;
import org.opentripplanner.transit.model.basic.NonLocalizedString;
import org.opentripplanner.transit.model.basic.TransitMode;
import org.opentripplanner.transit.model.framework.FeedScopedId;
import org.opentripplanner.transit.model.network.Route;
Expand Down Expand Up @@ -225,6 +226,12 @@ private static List<Arguments> createTestCases() {
}

private static Route route(String id, String name) {
return Route.of(id(id)).withLongName(name).withAgency(agency).withMode(TransitMode.BUS).build();
NonLocalizedString lName = new NonLocalizedString(name);
return Route
.of(id(id))
.withLongName(lName)
.withAgency(agency)
.withMode(TransitMode.BUS)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,12 @@ public static PlaceType toModel(LegacyGraphQLFilterPlaceType type) {
public static Instant getTimeOrNow(long epochSeconds) {
return epochSeconds != 0 ? Instant.ofEpochSecond(epochSeconds) : Instant.now();
}

public static boolean startsWith(String str, String name, Locale locale) {
hannesj marked this conversation as resolved.
Show resolved Hide resolved
return str != null && str.toLowerCase(locale).startsWith(name);
}

public static boolean startsWith(I18NString str, String name, Locale locale) {
return str != null && str.toString(locale).toLowerCase(locale).startsWith(name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -910,14 +910,10 @@ public DataFetcher<Iterable<Route>> routes() {
String name = args.getLegacyGraphQLName().toLowerCase(environment.getLocale());
routeStream =
routeStream.filter(route ->
Stream
.of(route.getShortName(), route.getLongName())
.filter(Objects::nonNull)
.map(s -> s.toLowerCase(environment.getLocale()))
.anyMatch(s -> s.startsWith(name))
LegacyGraphQLUtils.startsWith(route.getShortName(), name, environment.getLocale()) ||
LegacyGraphQLUtils.startsWith(route.getLongName(), name, environment.getLocale())
);
}

return routeStream.collect(Collectors.toList());
};
}
Expand Down Expand Up @@ -963,11 +959,7 @@ public DataFetcher<Iterable<Object>> stations() {
String name = args.getLegacyGraphQLName().toLowerCase(environment.getLocale());
stationStream =
stationStream.filter(station ->
station
.getName()
.toString(environment.getLocale())
.toLowerCase(environment.getLocale())
.startsWith(name)
LegacyGraphQLUtils.startsWith(station.getName(), name, environment.getLocale())
);
}

Expand Down Expand Up @@ -1008,11 +1000,7 @@ public DataFetcher<Iterable<Object>> stops() {
String name = args.getLegacyGraphQLName().toLowerCase(environment.getLocale());
stopStream =
stopStream.filter(stop ->
stop
.getName()
.toString(environment.getLocale())
.toLowerCase(environment.getLocale())
.startsWith(name)
LegacyGraphQLUtils.startsWith(stop.getName(), name, environment.getLocale())
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.Collection;
import java.util.stream.Collectors;
import org.opentripplanner.ext.legacygraphqlapi.LegacyGraphQLRequestContext;
import org.opentripplanner.ext.legacygraphqlapi.LegacyGraphQLUtils;
import org.opentripplanner.ext.legacygraphqlapi.generated.LegacyGraphQLDataFetchers;
import org.opentripplanner.ext.legacygraphqlapi.generated.LegacyGraphQLTypes;
import org.opentripplanner.routing.alertpatch.EntitySelector;
Expand Down Expand Up @@ -164,7 +165,8 @@ public DataFetcher<Relay.ResolvedGlobalId> id() {

@Override
public DataFetcher<String> longName() {
return environment -> getSource(environment).getLongName();
return environment ->
LegacyGraphQLUtils.getTranslation(getSource(environment).getLongName(), environment);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2548,6 +2548,25 @@ public void setLegacyGraphQLTypes(Iterable<LegacyGraphQLRouteAlertType> types) {
}
}

public static class LegacyGraphQLRouteLongNameArgs {

private String language;

public LegacyGraphQLRouteLongNameArgs(Map<String, Object> args) {
if (args != null) {
this.language = (String) args.get("language");
}
}

public String getLegacyGraphQLLanguage() {
return this.language;
}

public void setLegacyGraphQLLanguage(String language) {
this.language = language;
}
}

/** Entities that are relevant for routes that can contain alerts */
public enum LegacyGraphQLRouteAlertType {
AGENCY,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,7 @@ private GraphQLSchema create() {
.filter(route ->
route
.getLongName()
.toString()
.toLowerCase()
.startsWith(((String) environment.getArgument("name")).toLowerCase())
);
Expand Down
6 changes: 5 additions & 1 deletion src/ext/resources/legacygraphqlapi/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -2728,7 +2728,11 @@ type Route implements Node {
shortName: String

"""Long name of the route, e.g. Helsinki-Leppävaara"""
longName: String
longName(
"""If translated longName is found from gtfs translation.txt and wanted language is not same as
feed's language then returns wanted translation. Otherwise uses name from routes.txt.
"""
language: String): String

"""Transport mode of this route, e.g. `BUS`"""
mode: Mode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@

public class I18NStringMapper {

private Locale locale;

I18NStringMapper(Locale locale) {
this.locale = locale;
}

public String mapToApi(I18NString string) {
return string == null ? null : string.toString(locale);
}

static String mapToApi(I18NString string, Locale locale) {
hannesj marked this conversation as resolved.
Show resolved Hide resolved
return string == null ? null : string.toString(locale);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@ public class LegMapper {
private final PlaceMapper placeMapper;
private final boolean addIntermediateStops;

private final I18NStringMapper i18NStringMapper;

public LegMapper(Locale locale, boolean addIntermediateStops) {
this.walkStepMapper = new WalkStepMapper(locale);
this.streetNoteMaperMapper = new StreetNoteMaperMapper(locale);
this.alertMapper = new AlertMapper(locale);
this.placeMapper = new PlaceMapper(locale);
this.addIntermediateStops = addIntermediateStops;
this.i18NStringMapper = new I18NStringMapper(locale);
}

public List<ApiLeg> mapLegs(List<Leg> domain) {
Expand Down Expand Up @@ -98,12 +101,12 @@ public ApiLeg mapLeg(
api.agencyBrandingUrl = agency.getBrandingUrl();

var route = domain.getRoute();
api.route = route.getLongName();
api.route = i18NStringMapper.mapToApi(route.getLongName());
api.routeColor = route.getColor();
api.routeType = domain.getRouteType();
api.routeId = FeedScopedIdMapper.mapToApi(route.getId());
api.routeShortName = route.getShortName();
api.routeLongName = route.getLongName();
api.routeLongName = i18NStringMapper.mapToApi(route.getLongName());
api.routeTextColor = route.getTextColor();

var trip = domain.getTrip();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
public class PlaceMapper {

private final Locale locale;
private final I18NStringMapper i18NStringMapper;

public PlaceMapper(Locale locale) {
this.locale = locale;
i18NStringMapper = new I18NStringMapper(this.locale);
}

public List<ApiPlace> mapStopArrivals(Collection<StopArrival> domain) {
Expand Down Expand Up @@ -115,10 +117,10 @@ private ApiVehicleParkingWithEntrance mapVehicleParking(
return ApiVehicleParkingWithEntrance
.builder()
.id(FeedScopedIdMapper.mapToApi(vp.getId()))
.name(I18NStringMapper.mapToApi(vp.getName(), locale))
.name(i18NStringMapper.mapToApi(vp.getName()))
.entranceId(FeedScopedIdMapper.mapToApi(e.getEntranceId()))
.entranceName(I18NStringMapper.mapToApi(e.getName(), locale))
.note(I18NStringMapper.mapToApi(vp.getNote(), locale))
.entranceName(i18NStringMapper.mapToApi(e.getName()))
.note(i18NStringMapper.mapToApi(vp.getNote()))
.detailsUrl(vp.getDetailsUrl())
.imageUrl(vp.getImageUrl())
.tags(new ArrayList<>(vp.getTags()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ public static ApiRoute mapToApi(Route domain) {
if (domain == null) {
return null;
}

I18NStringMapper stringMapper = new I18NStringMapper(null);
ApiRoute api = new ApiRoute();
api.id = FeedScopedIdMapper.mapToApi(domain.getId());
api.agency = AgencyMapper.mapToApi(domain.getAgency());
api.shortName = domain.getShortName();
api.longName = domain.getLongName();
api.longName = stringMapper.mapToApi(domain.getLongName());
api.mode = TraverseModeMapper.mapToApi(domain.getMode());
api.type =
domain.getGtfsType() != null
Expand Down Expand Up @@ -58,11 +58,11 @@ public static ApiRouteShort mapToApiShort(Route domain) {
if (domain == null) {
return null;
}

I18NStringMapper stringMapper = new I18NStringMapper(null);
ApiRouteShort api = new ApiRouteShort();
api.id = FeedScopedIdMapper.mapToApi(domain.getId());
api.shortName = domain.getShortName();
api.longName = domain.getLongName();
api.longName = stringMapper.mapToApi(domain.getLongName());
api.mode = TraverseModeMapper.mapToApi(domain.getMode());
api.color = domain.getColor();
api.agencyName = domain.getAgency().getName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public GTFSToOtpTransitServiceMapper(
locationGroupMapper = new LocationGroupMapper(stopMapper, locationMapper);
pathwayMapper =
new PathwayMapper(stopMapper, entranceMapper, pathwayNodeMapper, boardingAreaMapper);
routeMapper = new RouteMapper(agencyMapper, issueStore);
routeMapper = new RouteMapper(agencyMapper, issueStore, translationHelper);
directionMapper = new DirectionMapper(issueStore);
tripMapper = new TripMapper(routeMapper, directionMapper);
bookingRuleMapper = new BookingRuleMapper();
Expand Down
24 changes: 21 additions & 3 deletions src/main/java/org/opentripplanner/gtfs/mapping/RouteMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import java.util.HashMap;
import java.util.Map;
import org.opentripplanner.graph_builder.DataImportIssueStore;
import org.opentripplanner.transit.model.basic.I18NString;
import org.opentripplanner.transit.model.basic.NonLocalizedString;
import org.opentripplanner.transit.model.basic.TransitMode;
import org.opentripplanner.transit.model.network.Route;
import org.opentripplanner.util.MapUtils;
Expand All @@ -16,12 +18,19 @@ class RouteMapper {

private final DataImportIssueStore issueStore;

private TranslationHelper translationHelper;

private final Map<org.onebusaway.gtfs.model.Route, Route> mappedRoutes = new HashMap<>();

RouteMapper(AgencyMapper agencyMapper, DataImportIssueStore issueStore) {
RouteMapper(
AgencyMapper agencyMapper,
DataImportIssueStore issueStore,
TranslationHelper helper
) {
this.agencyMapper = agencyMapper;
this.issueStore = issueStore;
this.brandingMapper = new BrandingMapper();
this.translationHelper = helper;
}

Collection<Route> map(Collection<org.onebusaway.gtfs.model.Route> agencies) {
Expand All @@ -35,10 +44,19 @@ Route map(org.onebusaway.gtfs.model.Route orginal) {

private Route doMap(org.onebusaway.gtfs.model.Route rhs) {
var lhs = Route.of(AgencyAndIdMapper.mapAgencyAndId(rhs.getId()));

I18NString longName = null;
if (rhs.getLongName() != null) {
longName =
translationHelper.getTranslation(
org.onebusaway.gtfs.model.Route.class,
"longName",
rhs.getId().getId(),
rhs.getLongName()
);
}
lhs.withAgency(agencyMapper.map(rhs.getAgency()));
lhs.withShortName(rhs.getShortName());
lhs.withLongName(rhs.getLongName());
lhs.withLongName(longName);
lhs.withGtfsType(rhs.getType());

if (rhs.isSortOrderSet()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.opentripplanner.netex.index.api.NetexEntityIndexReadOnlyView;
import org.opentripplanner.netex.mapping.support.FeedScopedIdFactory;
import org.opentripplanner.netex.mapping.support.MainAndSubMode;
import org.opentripplanner.transit.model.basic.NonLocalizedString;
import org.opentripplanner.transit.model.framework.EntityById;
import org.opentripplanner.transit.model.framework.FeedScopedId;
import org.opentripplanner.transit.model.network.BikeAccess;
Expand Down Expand Up @@ -77,7 +78,8 @@ Route mapRoute(Line_VersionStructure line) {
builder.withAgency(findOrCreateAuthority(line));
builder.withOperator(findOperator(line));
builder.withBranding(findBranding(line));
builder.withLongName(line.getName().getValue());
NonLocalizedString longName = NonLocalizedString.ofNullable(line.getName().getValue());
builder.withLongName(longName);
builder.withShortName(line.getPublicCode());

MainAndSubMode mode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
import static java.util.Objects.requireNonNullElse;

import java.util.List;
import java.util.Locale;
import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opentripplanner.transit.model.basic.I18NString;
import org.opentripplanner.transit.model.basic.SubMode;
import org.opentripplanner.transit.model.basic.TransitMode;
import org.opentripplanner.transit.model.framework.AbstractTransitEntity;
Expand All @@ -24,7 +26,7 @@ public final class Route extends AbstractTransitEntity<Route, RouteBuilder> impl
private final Branding branding;
private final List<GroupOfRoutes> groupsOfRoutes;
private final String shortName;
private final String longName;
private final I18NString longName;
private final TransitMode mode;
// TODO: consolidate gtfsType and netexSubmode
private final Integer gtfsType;
Expand Down Expand Up @@ -127,7 +129,7 @@ public String getShortName() {
}

@Nullable
public String getLongName() {
public I18NString getLongName() {
return longName;
}

Expand Down Expand Up @@ -184,10 +186,16 @@ public String getFlexibleLineType() {
return flexibleLineType;
}

/** @return the route's short name, or the long name if the short name is null. */
@Nonnull
public String getName(Locale locale) {
return shortName == null ? longName.toString(locale) : shortName;
}

/** @return the route's short name, or the long name if the short name is null. */
@Nonnull
public String getName() {
hannesj marked this conversation as resolved.
Show resolved Hide resolved
return shortName == null ? longName : shortName;
return shortName == null ? longName.toString() : shortName;
}

@Override
Expand Down
Loading