Skip to content

Commit

Permalink
Take NeTEx hierarchy into account when mapping lots
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardehrenfried committed Jul 15, 2024
1 parent c6ae01a commit acaa41f
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 25 deletions.
21 changes: 21 additions & 0 deletions src/main/java/org/opentripplanner/inspector/vector/KeyValue.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
package org.opentripplanner.inspector.vector;

import java.util.Collection;
import java.util.stream.Collectors;
import org.opentripplanner.transit.model.framework.FeedScopedId;

public record KeyValue(String key, Object value) {
public static KeyValue kv(String key, Object value) {
return new KeyValue(key, value);
}
public static KeyValue kv(String key, FeedScopedId value) {
if(value !=null){
return new KeyValue(key, value.toString());
}
else {
return new KeyValue(key, null);
}
}

/**
* Takes a key and a collection of values, calls toString on the values and joins them using
* comma as the separator.
*/
public static KeyValue kColl(String key, Collection<?> value) {
var values = value.stream().map(Object::toString).collect(Collectors.joining(","));
return new KeyValue(key, values);
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
package org.opentripplanner.inspector.vector.vertex;

import static org.opentripplanner.inspector.vector.KeyValue.kColl;
import static org.opentripplanner.inspector.vector.KeyValue.kv;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.opentripplanner.apis.support.mapping.PropertyMapper;
import org.opentripplanner.framework.collection.ListUtils;
import org.opentripplanner.inspector.vector.KeyValue;
import org.opentripplanner.routing.vehicle_parking.VehicleParking;
import org.opentripplanner.routing.vehicle_parking.VehicleParkingEntrance;
import org.opentripplanner.service.vehiclerental.street.VehicleRentalPlaceVertex;
import org.opentripplanner.street.model.vertex.BarrierVertex;
import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex;
import org.opentripplanner.street.model.vertex.Vertex;
import org.opentripplanner.street.search.TraverseMode;

public class VertexPropertyMapper extends PropertyMapper<Vertex> {

Expand All @@ -23,14 +29,36 @@ protected Collection<KeyValue> map(Vertex input) {
List<KeyValue> properties =
switch (input) {
case BarrierVertex v -> List.of(kv("permission", v.getBarrierPermissions().toString()));
case VehicleRentalPlaceVertex v -> List.of(kv("rentalId", v.getStation().getId()));
case VehicleRentalPlaceVertex v -> List.of(kv("rentalId", v.getStation()));
case VehicleParkingEntranceVertex v -> List.of(
kv("rentalId", v.getVehicleParking().getId()),
kv("walkAccessible", Boolean.toString(v.isWalkAccessible())),
kv("carAccessible", Boolean.toString(v.isCarAccessible()))
kv("parkingId", v.getVehicleParking().getId()),
kColl("spacesFor", spacesFor(v.getVehicleParking())),
kColl("traversalPermission", traversalPermissions(v.getParkingEntrance()))
);
default -> List.of();
};
return ListUtils.combine(baseProps, properties);
}

private Set<TraverseMode> spacesFor(VehicleParking vehicleParking) {
var ret = new HashSet<TraverseMode>();
if (vehicleParking.hasAnyCarPlaces()) {
ret.add(TraverseMode.CAR);
}
if (vehicleParking.hasBicyclePlaces()) {
ret.add(TraverseMode.BICYCLE);
}
return ret;
}

private Set<TraverseMode> traversalPermissions(VehicleParkingEntrance entrance) {
var ret = new HashSet<TraverseMode>();
if (entrance.isCarAccessible()) {
ret.add(TraverseMode.CAR);
}
if (entrance.isWalkAccessible()) {
ret.add(TraverseMode.WALK);
}
return ret;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.opentripplanner.model.transfer.ConstrainedTransfer;
import org.opentripplanner.model.transfer.TransferPoint;
import org.opentripplanner.routing.api.request.framework.TimePenalty;
import org.opentripplanner.routing.vehicle_parking.VehicleParking;
import org.opentripplanner.transit.model.basic.Notice;
import org.opentripplanner.transit.model.framework.AbstractTransitEntity;
import org.opentripplanner.transit.model.framework.DefaultEntityById;
Expand Down Expand Up @@ -116,6 +117,8 @@ public class OtpTransitServiceBuilder {

private final EntityById<GroupOfRoutes> groupOfRouteById = new DefaultEntityById<>();

private final List<VehicleParking> vehicleParkings = new ArrayList<>();

private final DataImportIssueStore issueStore;

public OtpTransitServiceBuilder(StopModel stopModel, DataImportIssueStore issueStore) {
Expand Down Expand Up @@ -264,6 +267,14 @@ public CalendarServiceData buildCalendarServiceData() {
);
}

/**
* The list of parking lots contained in the transit data (so far only NeTEx).
* Note that parking lots can also be sourced from OSM data as well as realtime updaters.
*/
public List<VehicleParking> vehicleParkings() {
return vehicleParkings;
}

public OtpTransitService build() {
return new OtpTransitServiceImpl(this);
}
Expand Down
9 changes: 0 additions & 9 deletions src/main/java/org/opentripplanner/netex/NetexBundle.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import jakarta.xml.bind.JAXBException;
import java.io.Closeable;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.opentripplanner.datastore.api.CompositeDataSource;
Expand All @@ -18,7 +17,6 @@
import org.opentripplanner.netex.loader.parser.NetexDocumentParser;
import org.opentripplanner.netex.mapping.NetexMapper;
import org.opentripplanner.netex.validation.Validator;
import org.opentripplanner.routing.vehicle_parking.VehicleParking;
import org.opentripplanner.transit.model.framework.Deduplicator;
import org.rutebanken.netex.model.PublicationDeliveryStructure;
import org.slf4j.Logger;
Expand Down Expand Up @@ -117,13 +115,6 @@ public void close() throws IOException {
source.close();
}

/**
* Return the list of parking lots contained in the netex bundle.
*/
public Collection<VehicleParking> vehicleParkings() {
return mapper.mapVehicleParkings();
}

/** Load all files entries in the bundle */
private void loadFileEntries() {
// Load global shared files
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/opentripplanner/netex/NetexModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public void buildGraph() {

transitModel.validateTimeZones();

var lots = netexBundle.vehicleParkings();
var lots = transitBuilder.vehicleParkings();
graph.getVehicleParkingService().updateVehicleParking(lots, List.of());
var linker = new VehicleParkingHelper(graph);
lots.forEach(linker::linkVehicleParkingToGraph);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ public ReadOnlyHierarchicalVersionMapById<StopPlace> getStopPlaceById() {
}

@Override
public ReadOnlyHierarchicalMapById<Parking> getParkings() {
public ReadOnlyHierarchicalMapById<Parking> getParkingsById() {
return parkings;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public interface NetexEntityIndexReadOnlyView {

ReadOnlyHierarchicalVersionMapById<StopPlace> getStopPlaceById();

ReadOnlyHierarchicalMapById<Parking> getParkings();
ReadOnlyHierarchicalMapById<Parking> getParkingsById();

ReadOnlyHierarchicalVersionMapById<TariffZone_VersionStructure> getTariffZonesById();

Expand Down
25 changes: 16 additions & 9 deletions src/main/java/org/opentripplanner/netex/mapping/NetexMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import org.opentripplanner.netex.mapping.calendar.CalendarServiceBuilder;
import org.opentripplanner.netex.mapping.support.FeedScopedIdFactory;
import org.opentripplanner.netex.mapping.support.NetexMapperIndexes;
import org.opentripplanner.routing.vehicle_parking.VehicleParking;
import org.opentripplanner.transit.model.basic.Notice;
import org.opentripplanner.transit.model.framework.AbstractTransitEntity;
import org.opentripplanner.transit.model.framework.Deduplicator;
Expand Down Expand Up @@ -78,9 +77,9 @@ public class NetexMapper {

/**
* Shared/cached entity index, used by more than one mapper. This index provides alternative
* indexes to netex entites, as well as global indexes to OTP domain objects needed in the mapping
* indexes to netex entities, as well as global indexes to OTP domain objects needed in the mapping
* process. Some of these indexes are feed scoped, and some are file group level scoped. As a rule
* of tomb the indexes for OTP Model entities are global(small memory overhead), while the indexes
* of thumb the indexes for OTP Model entities are global(small memory overhead), while the indexes
* for the Netex entities follow the main index {@link #currentNetexIndex}, hence sopped by file
* group.
*/
Expand Down Expand Up @@ -159,7 +158,7 @@ public void finishUp() {

/**
* <p>
* This method mapes the last Netex file imported using the *local* entities in the hierarchical
* This method maps the last Netex file imported using the *local* entities in the hierarchical
* {@link NetexEntityIndexReadOnlyView}.
* </p>
* <p>
Expand Down Expand Up @@ -200,12 +199,9 @@ public void mapNetexToOtp(NetexEntityIndexReadOnlyView netexIndex) {
mapTripPatterns(serviceIds);
mapNoticeAssignments();

addEntriesToGroupMapperForPostProcessingLater();
}
mapVehicleParkings();

public Collection<VehicleParking> mapVehicleParkings() {
var mapper = new VehicleParkingMapper(idFactory);
return mapper.map(currentNetexIndex.getParkings().localValues());
addEntriesToGroupMapperForPostProcessingLater();
}

/* PRIVATE METHODS */
Expand Down Expand Up @@ -525,6 +521,17 @@ private void addEntriesToGroupMapperForPostProcessingLater() {
}
}

private void mapVehicleParkings() {
var mapper = new VehicleParkingMapper(idFactory);
currentNetexIndex
.getParkingsById()
.localKeys()
.forEach(id -> {
var parking = mapper.map(currentNetexIndex.getParkingsById().lookup(id));
transitBuilder.vehicleParkings().add(parking);
});
}

/**
* The start of period is used to find the valid entities based on the current time. This should
* probably be configurable in the future, or even better incorporate the version number into the
Expand Down

0 comments on commit acaa41f

Please sign in to comment.