diff --git a/onebusaway-gtfs-hibernate/src/main/java/org/onebusaway/gtfs/impl/HibernateGtfsRelationalDaoImpl.java b/onebusaway-gtfs-hibernate/src/main/java/org/onebusaway/gtfs/impl/HibernateGtfsRelationalDaoImpl.java index 89f7a588..6ddc0b32 100644 --- a/onebusaway-gtfs-hibernate/src/main/java/org/onebusaway/gtfs/impl/HibernateGtfsRelationalDaoImpl.java +++ b/onebusaway-gtfs-hibernate/src/main/java/org/onebusaway/gtfs/impl/HibernateGtfsRelationalDaoImpl.java @@ -295,7 +295,7 @@ public Collection getAllLocationGroupElements() { LocationGroupElement locationGroupElement = new LocationGroupElement(); locationGroupElement.setLocationGroupId(group.getId()); locationGroupElement.setName(group.getName()); - locationGroupElement.setLocation(stopLocation); + locationGroupElement.setStop(stopLocation); return locationGroupElement; })).collect(Collectors.toList()); } diff --git a/onebusaway-gtfs/src/main/java/org/onebusaway/gtfs/model/LocationGroup.java b/onebusaway-gtfs/src/main/java/org/onebusaway/gtfs/model/LocationGroup.java index 46ef67e9..b7c884dc 100644 --- a/onebusaway-gtfs/src/main/java/org/onebusaway/gtfs/model/LocationGroup.java +++ b/onebusaway-gtfs/src/main/java/org/onebusaway/gtfs/model/LocationGroup.java @@ -15,18 +15,29 @@ */ package org.onebusaway.gtfs.model; -import java.util.HashSet; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import java.util.Set; +import org.onebusaway.csv_entities.schema.annotations.CsvField; +import org.onebusaway.csv_entities.schema.annotations.CsvFields; +import org.onebusaway.gtfs.serialization.mappings.DefaultAgencyIdFieldMappingFactory; +@CsvFields(filename = "location_groups.txt", required = false) public class LocationGroup extends IdentityBean implements StopLocation { private static final long serialVersionUID = 1L; + @CsvField(name = "location_group_id", mapping = DefaultAgencyIdFieldMappingFactory.class) private AgencyAndId id; - private Set locations = new HashSet<>(); - + @CsvField(name = "location_group_name") private String name; + // we use a List, not Set to keep the insertion order. by definition these stops don't have an + // order but it's nice for clients to not randomly change it. + @CsvField(ignore = true) + private List stops = new ArrayList<>(); + @Override public AgencyAndId getId() { return id; @@ -36,23 +47,22 @@ public void setId(AgencyAndId id) { this.id = id; } - public Set getLocations() { - return locations; + public String getName() { + return name; } - private void setLocations(Set locations) { - this.locations = locations; + public void setName(String name) { + this.name = name; } - public void addLocation(StopLocation location) { - this.locations.add(location); + public void addLocation(StopLocation stop) { + stops.add(stop); } - - public String getName() { - return name; + public void setLocations(Collection stop) { + stops.addAll(stop); } - public void setName(String name) { - this.name = name; + public Set getLocations() { + return Set.copyOf(stops); } } diff --git a/onebusaway-gtfs/src/main/java/org/onebusaway/gtfs/model/LocationGroupElement.java b/onebusaway-gtfs/src/main/java/org/onebusaway/gtfs/model/LocationGroupElement.java index f12f17c0..2e508c8c 100644 --- a/onebusaway-gtfs/src/main/java/org/onebusaway/gtfs/model/LocationGroupElement.java +++ b/onebusaway-gtfs/src/main/java/org/onebusaway/gtfs/model/LocationGroupElement.java @@ -20,19 +20,18 @@ import org.onebusaway.gtfs.serialization.mappings.DefaultAgencyIdFieldMappingFactory; import org.onebusaway.gtfs.serialization.mappings.StopLocationFieldMappingFactory; -@CsvFields(filename = "location_groups.txt", required = false, prefix = "location_group_") +@CsvFields(filename = "location_group_stops.txt", required = false, prefix = "location_group_") public class LocationGroupElement extends IdentityBean { private static final long serialVersionUID = 1L; - @CsvField(ignore = true) private int id; @CsvField(name = "location_group_id", mapping = DefaultAgencyIdFieldMappingFactory.class) private AgencyAndId locationGroupId; @CsvField(name = "stop_id", mapping = StopLocationFieldMappingFactory.class) - private StopLocation location; + private StopLocation stop; @CsvField(optional = true) private String name; @@ -54,12 +53,12 @@ public void setLocationGroupId(AgencyAndId locationGroupId) { this.locationGroupId = locationGroupId; } - public StopLocation getLocation() { - return location; + public StopLocation getStop() { + return stop; } - public void setLocation(StopLocation location) { - this.location = location; + public void setStop(StopLocation stop) { + this.stop = stop; } public String getName() { diff --git a/onebusaway-gtfs/src/main/java/org/onebusaway/gtfs/serialization/GtfsEntitySchemaFactory.java b/onebusaway-gtfs/src/main/java/org/onebusaway/gtfs/serialization/GtfsEntitySchemaFactory.java index 8250536f..f246718a 100644 --- a/onebusaway-gtfs/src/main/java/org/onebusaway/gtfs/serialization/GtfsEntitySchemaFactory.java +++ b/onebusaway-gtfs/src/main/java/org/onebusaway/gtfs/serialization/GtfsEntitySchemaFactory.java @@ -47,6 +47,7 @@ public static List> getEntityClasses() { entityClasses.add(Level.class); entityClasses.add(Stop.class); entityClasses.add(StopAreaElement.class); + entityClasses.add(LocationGroup.class); entityClasses.add(LocationGroupElement.class); entityClasses.add(Trip.class); entityClasses.add(Note.class); diff --git a/onebusaway-gtfs/src/main/java/org/onebusaway/gtfs/serialization/GtfsReader.java b/onebusaway-gtfs/src/main/java/org/onebusaway/gtfs/serialization/GtfsReader.java index 1168c09f..2cb17d27 100644 --- a/onebusaway-gtfs/src/main/java/org/onebusaway/gtfs/serialization/GtfsReader.java +++ b/onebusaway-gtfs/src/main/java/org/onebusaway/gtfs/serialization/GtfsReader.java @@ -74,6 +74,7 @@ public GtfsReader() { _entityClasses.add(Level.class); _entityClasses.add(Stop.class); _entityClasses.add(Location.class); + _entityClasses.add(LocationGroup.class); _entityClasses.add(LocationGroupElement.class); _entityClasses.add(Trip.class); _entityClasses.add(StopAreaElement.class); @@ -360,16 +361,13 @@ public void handleEntity(Object entity) { } else if (entity instanceof Location) { Location location = (Location) entity; registerAgencyId(Location.class, location.getId()); + } else if (entity instanceof LocationGroup) { + var group = (LocationGroup) entity; + registerAgencyId(LocationGroup.class, group.getId()); } else if (entity instanceof LocationGroupElement) { LocationGroupElement locationGroupElement = (LocationGroupElement) entity; LocationGroup locationGroup = _entityStore.getEntityForId(LocationGroup.class, locationGroupElement.getLocationGroupId()); - if (locationGroup == null) { - locationGroup = new LocationGroup(); - locationGroup.setId(locationGroupElement.getLocationGroupId()); - locationGroup.setName(locationGroupElement.getName()); - _entityStore.saveEntity(locationGroup); - } - locationGroup.addLocation(locationGroupElement.getLocation()); + locationGroup.addLocation(locationGroupElement.getStop()); } else if (entity instanceof StopAreaElement) { var stopAreaElement = (StopAreaElement) entity; var stopArea = _entityStore.getEntityForId(StopArea.class, stopAreaElement.getArea().getId()); diff --git a/onebusaway-gtfs/src/test/java/org/onebusaway/gtfs/serialization/FlexReaderTest.java b/onebusaway-gtfs/src/test/java/org/onebusaway/gtfs/serialization/FlexReaderTest.java index 79557807..880377d6 100644 --- a/onebusaway-gtfs/src/test/java/org/onebusaway/gtfs/serialization/FlexReaderTest.java +++ b/onebusaway-gtfs/src/test/java/org/onebusaway/gtfs/serialization/FlexReaderTest.java @@ -105,6 +105,12 @@ public void locationIdAsASeparateColumn() throws CsvEntityIOException, IOExcepti @Test public void locationGroupIdAsSeparateColumn() throws CsvEntityIOException, IOException { var dao = processFeed(GtfsTestData.getAuburnTransitFlex(), AGENCY_ID, false); + var locationGroup = List.copyOf(dao.getAllLocationGroups()).get(0); + assertEquals("Aurburn Loop Stops", locationGroup.getName()); + assertEquals("1_4230479", locationGroup.getId().toString()); + var actualStops = locationGroup.getLocations().stream().map(s -> s.getId().toString()).collect(Collectors.toList()); + assertEquals(30, actualStops.size()); + var trip = dao.getAllTrips().stream().filter(t -> t.getId().getId().equals("t_5756013_b_33000_tn_0")).findAny().get(); var stopTimes = dao.getStopTimesForTrip(trip); stopTimes.forEach(st -> assertNotNull(st.getStopLocation())); diff --git a/onebusaway-gtfs/src/test/resources/org/onebusaway/gtfs/auburn-transit-flex/location_group_stops.txt b/onebusaway-gtfs/src/test/resources/org/onebusaway/gtfs/auburn-transit-flex/location_group_stops.txt new file mode 100644 index 00000000..a2c6ecce --- /dev/null +++ b/onebusaway-gtfs/src/test/resources/org/onebusaway/gtfs/auburn-transit-flex/location_group_stops.txt @@ -0,0 +1,31 @@ +location_group_id,stop_id +4230479,2583236 +4230479,2583237 +4230479,2583238 +4230479,2583242 +4230479,2583244 +4230479,2583246 +4230479,2583249 +4230479,2583250 +4230479,2583251 +4230479,2583252 +4230479,2583253 +4230479,2583254 +4230479,2583255 +4230479,2583256 +4230479,2583259 +4230479,2583260 +4230479,2583262 +4230479,2583263 +4230479,2583266 +4230479,2583268 +4230479,2583271 +4230479,2583276 +4230479,2583280 +4230479,2583281 +4230479,2583282 +4230479,2583284 +4230479,2583285 +4230479,2751414 +4230479,3446932 +4230479,3446933 diff --git a/onebusaway-gtfs/src/test/resources/org/onebusaway/gtfs/auburn-transit-flex/location_groups.txt b/onebusaway-gtfs/src/test/resources/org/onebusaway/gtfs/auburn-transit-flex/location_groups.txt index 7fcf9b6d..b9eba1b7 100644 --- a/onebusaway-gtfs/src/test/resources/org/onebusaway/gtfs/auburn-transit-flex/location_groups.txt +++ b/onebusaway-gtfs/src/test/resources/org/onebusaway/gtfs/auburn-transit-flex/location_groups.txt @@ -1,31 +1,2 @@ -location_group_id,stop_id,location_group_name -4230479,2583236,Aurburn Loop Stops -4230479,2583237,Aurburn Loop Stops -4230479,2583238,Aurburn Loop Stops -4230479,2583242,Aurburn Loop Stops -4230479,2583244,Aurburn Loop Stops -4230479,2583246,Aurburn Loop Stops -4230479,2583249,Aurburn Loop Stops -4230479,2583250,Aurburn Loop Stops -4230479,2583251,Aurburn Loop Stops -4230479,2583252,Aurburn Loop Stops -4230479,2583253,Aurburn Loop Stops -4230479,2583254,Aurburn Loop Stops -4230479,2583255,Aurburn Loop Stops -4230479,2583256,Aurburn Loop Stops -4230479,2583259,Aurburn Loop Stops -4230479,2583260,Aurburn Loop Stops -4230479,2583262,Aurburn Loop Stops -4230479,2583263,Aurburn Loop Stops -4230479,2583266,Aurburn Loop Stops -4230479,2583268,Aurburn Loop Stops -4230479,2583271,Aurburn Loop Stops -4230479,2583276,Aurburn Loop Stops -4230479,2583280,Aurburn Loop Stops -4230479,2583281,Aurburn Loop Stops -4230479,2583282,Aurburn Loop Stops -4230479,2583284,Aurburn Loop Stops -4230479,2583285,Aurburn Loop Stops -4230479,2751414,Aurburn Loop Stops -4230479,3446932,Aurburn Loop Stops -4230479,3446933,Aurburn Loop Stops +location_group_id,location_group_name +4230479,Aurburn Loop Stops \ No newline at end of file