Skip to content

Commit 32867bd

Browse files
Merge pull request #6885 from HSLdevcom/debug-elevators
Visualize elevator edges and vertices in Debug UI
2 parents 0e367fb + 89a2b75 commit 32867bd

File tree

9 files changed

+203
-10
lines changed

9 files changed

+203
-10
lines changed

application/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.opentripplanner.street.model.edge.StreetVehicleParkingLink;
3535
import org.opentripplanner.street.model.edge.TemporaryFreeEdge;
3636
import org.opentripplanner.street.model.edge.TemporaryPartialStreetEdge;
37+
import org.opentripplanner.street.model.vertex.ElevatorVertex;
3738
import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex;
3839
import org.opentripplanner.utils.collection.ListUtils;
3940

@@ -118,6 +119,7 @@ public class DebugStyleSpec {
118119
private static final String RENTAL_GROUP = "Rental";
119120
private static final String PERMISSIONS_GROUP = "Permissions";
120121
private static final String NO_THRU_TRAFFIC_GROUP = "No-thru traffic";
122+
private static final String ELEVATORS_GROUP = "Elevators";
121123

122124
private static final StreetTraversalPermission[] streetModes = new StreetTraversalPermission[] {
123125
StreetTraversalPermission.PEDESTRIAN,
@@ -173,6 +175,7 @@ static StyleSpec build(
173175
traversalPermissions(edges),
174176
edges(edges),
175177
elevation(edges, vertices),
178+
elevators(edges, vertices),
176179
vertices(vertices),
177180
stops(regularStops, areaStops, groupStops)
178181
)
@@ -260,6 +263,35 @@ private static List<StyleBuilder> vertices(VectorSourceLayer vertices) {
260263
);
261264
}
262265

266+
private static List<StyleBuilder> elevators(VectorSourceLayer edges, VectorSourceLayer vertices) {
267+
return List.of(
268+
StyleBuilder.ofId("elevator-hop-edge")
269+
.group(ELEVATORS_GROUP)
270+
.typeLine()
271+
.vectorSourceLayer(edges)
272+
.edgeFilter(ElevatorHopEdge.class)
273+
.lineColor(ORANGE)
274+
.lineWidth(LINE_WIDTH)
275+
.lineOffset(LINE_OFFSET)
276+
.minZoom(6)
277+
.maxZoom(MAX_ZOOM)
278+
.intiallyHidden(),
279+
StyleBuilder.ofId("elevator-vertex")
280+
.group(ELEVATORS_GROUP)
281+
.typeCircle()
282+
.vectorSourceLayer(vertices)
283+
.vertexFilter(ElevatorVertex.class)
284+
.circleStroke(BLACK, CIRCLE_STROKE)
285+
.circleRadius(
286+
new ZoomDependentNumber(List.of(new ZoomStop(15, 1), new ZoomStop(MAX_ZOOM, 7)))
287+
)
288+
.circleColor(ORANGE)
289+
.minZoom(15)
290+
.maxZoom(MAX_ZOOM)
291+
.intiallyHidden()
292+
);
293+
}
294+
263295
private static List<StyleBuilder> rental(
264296
VectorSourceLayer rentalLayer,
265297
VectorSourceLayer geofencingZones
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package org.opentripplanner.inspector.vector.edge;
2+
3+
import org.locationtech.jts.geom.Coordinate;
4+
import org.locationtech.jts.geom.Geometry;
5+
import org.opentripplanner.framework.geometry.GeometryUtils;
6+
import org.opentripplanner.street.model.edge.Edge;
7+
import org.opentripplanner.street.model.edge.ElevatorHopEdge;
8+
import org.opentripplanner.street.model.vertex.Vertex;
9+
10+
class EdgeGeometryMapper {
11+
12+
static Geometry map(Edge edge) {
13+
return switch (edge) {
14+
case ElevatorHopEdge e -> {
15+
// If coordinates are equal, move the other one slightly to make the edge visible
16+
final Vertex toVertex = e.getToVertex();
17+
var toCoord = toVertex.getCoordinate();
18+
var fromV = e.getFromVertex();
19+
if (fromV.getCoordinate().equals(toCoord)) {
20+
Coordinate newTo = toCoord.copy();
21+
newTo.setX(toCoord.getX() + 0.000001);
22+
yield GeometryUtils.makeLineString(fromV.getCoordinate(), newTo);
23+
} else {
24+
yield GeometryUtils.makeLineString(fromV.getCoordinate(), toVertex.getCoordinate());
25+
}
26+
}
27+
default -> edge.getGeometry();
28+
};
29+
}
30+
}

application/src/main/java/org/opentripplanner/inspector/vector/edge/EdgeLayerBuilder.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,15 @@ protected List<Geometry> getGeometries(Envelope query) {
2525
return graph
2626
.findEdges(query)
2727
.stream()
28-
.filter(e -> e.getGeometry() != null)
29-
.map(edge -> {
30-
Geometry geometry = edge.getGeometry();
31-
geometry.setUserData(edge);
28+
.map(e -> new DebugEdge(e, EdgeGeometryMapper.map(e)))
29+
.filter(e -> e.geometry != null)
30+
.map(debugEdge -> {
31+
Geometry geometry = debugEdge.geometry.copy();
32+
geometry.setUserData(debugEdge.edge);
3233
return geometry;
3334
})
3435
.toList();
3536
}
37+
38+
private record DebugEdge(Edge edge, Geometry geometry) {}
3639
}

application/src/main/java/org/opentripplanner/inspector/vector/edge/EdgePropertyMapper.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
import static org.opentripplanner.utils.lang.DoubleUtils.roundTo2Decimals;
55

66
import com.google.common.collect.Lists;
7+
import java.time.Duration;
78
import java.util.Collection;
89
import java.util.List;
910
import org.opentripplanner.apis.support.mapping.PropertyMapper;
1011
import org.opentripplanner.inspector.vector.KeyValue;
1112
import org.opentripplanner.street.model.StreetTraversalPermission;
1213
import org.opentripplanner.street.model.edge.Edge;
14+
import org.opentripplanner.street.model.edge.ElevatorHopEdge;
1315
import org.opentripplanner.street.model.edge.EscalatorEdge;
1416
import org.opentripplanner.street.model.edge.StreetEdge;
1517
import org.opentripplanner.utils.collection.ListUtils;
@@ -24,7 +26,13 @@ protected Collection<KeyValue> map(Edge input) {
2426
case StreetEdge e -> mapStreetEdge(e);
2527
case EscalatorEdge e -> List.of(
2628
kv("distance", e.getDistanceMeters()),
27-
kv("duration", e.getDuration().map(d -> d.toString()).orElse(null))
29+
kv("duration", e.getDuration().map(Duration::toString).orElse(null))
30+
);
31+
case ElevatorHopEdge e -> List.of(
32+
kv("permission", e.getPermission()),
33+
kv("levels", e.getLevels()),
34+
kv("wheelchairAccessible", e.isWheelchairAccessible()),
35+
kv("travelTime", e.getTravelTime().map(Duration::toString).orElse(null))
2836
);
2937
default -> List.of();
3038
};

application/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.opentripplanner.service.vehiclerental.street.VehicleRentalPlaceVertex;
1616
import org.opentripplanner.street.model.edge.StreetEdge;
1717
import org.opentripplanner.street.model.vertex.BarrierVertex;
18+
import org.opentripplanner.street.model.vertex.ElevatorVertex;
1819
import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex;
1920
import org.opentripplanner.street.model.vertex.Vertex;
2021
import org.opentripplanner.street.search.TraverseMode;
@@ -38,6 +39,7 @@ protected Collection<KeyValue> map(Vertex input) {
3839
kColl("spacesFor", spacesFor(v.getVehicleParking())),
3940
kColl("traversalPermission", traversalPermissions(v.getParkingEntrance()))
4041
);
42+
case ElevatorVertex v -> List.of(kv("level", v.getLevel()));
4143
default -> List.of();
4244
};
4345

application/src/main/java/org/opentripplanner/street/model/edge/ElevatorHopEdge.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.opentripplanner.street.model.edge;
22

3+
import java.time.Duration;
4+
import java.util.Optional;
35
import org.opentripplanner.framework.i18n.I18NString;
46
import org.opentripplanner.routing.api.request.preference.RoutingPreferences;
57
import org.opentripplanner.street.model.StreetTraversalPermission;
@@ -98,8 +100,19 @@ public StreetTraversalPermission getPermission() {
98100
return permission;
99101
}
100102

101-
public int getTravelTime() {
102-
return travelTime;
103+
/**
104+
* The number of levels that the elevator travels
105+
*/
106+
public double getLevels() {
107+
return levels;
108+
}
109+
110+
/**
111+
* Returns the travel time of the elevator.
112+
* If travelTime is 0, returns an empty Optional.
113+
*/
114+
public Optional<Duration> getTravelTime() {
115+
return travelTime > 0 ? Optional.of(Duration.ofSeconds(travelTime)) : Optional.empty();
103116
}
104117

105118
@Override

application/src/main/java/org/opentripplanner/street/model/vertex/ElevatorVertex.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ public ElevatorVertex(Vertex sourceVertex, String label, @Nullable String level)
1515
this.label = label;
1616
}
1717

18+
/**
19+
* OSM level name or "{elevatorWay osm id} / {node index}"
20+
*/
21+
public String getLevel() {
22+
return level;
23+
}
24+
1825
@Override
1926
public VertexLabel getLabel() {
2027
return VertexLabel.string(LABEL_TEMPLATE.formatted(label, level));

application/src/test/java/org/opentripplanner/graph_builder/module/osm/moduletests/ElevatorTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package org.opentripplanner.graph_builder.module.osm.moduletests;
22

33
import static com.google.common.truth.Truth.assertThat;
4-
import static org.junit.jupiter.api.Assertions.assertEquals;
54
import static org.opentripplanner.graph_builder.module.osm.moduletests._support.NodeBuilder.node;
65

6+
import java.time.Duration;
77
import org.junit.jupiter.api.Test;
88
import org.opentripplanner.framework.geometry.WgsCoordinate;
99
import org.opentripplanner.graph_builder.module.osm.OsmModuleTestFactory;
@@ -28,7 +28,7 @@ void testDuration() {
2828
var edges = graph.getEdgesOfType(ElevatorHopEdge.class);
2929
assertThat(edges).hasSize(2);
3030
for (var edge : edges) {
31-
assertEquals(62, edge.getTravelTime());
31+
assertThat(edge.getTravelTime()).hasValue(Duration.ofSeconds(62));
3232
}
3333
}
3434

@@ -51,7 +51,7 @@ void testMultilevelNodeDuration() {
5151
var edges = graph.getEdgesOfType(ElevatorHopEdge.class);
5252
assertThat(edges).hasSize(2);
5353
for (var edge : edges) {
54-
assertEquals(62, edge.getTravelTime());
54+
assertThat(edge.getTravelTime()).hasValue(Duration.ofSeconds(62));
5555
}
5656
}
5757
}

application/src/test/resources/org/opentripplanner/apis/vectortiles/style.json

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1586,6 +1586,104 @@
15861586
"group" : "Elevation"
15871587
}
15881588
},
1589+
{
1590+
"id" : "elevator-hop-edge",
1591+
"type" : "line",
1592+
"source" : "vectorSource",
1593+
"source-layer" : "edges",
1594+
"minzoom" : 6,
1595+
"maxzoom" : 23,
1596+
"paint" : {
1597+
"line-color" : "#ffa500",
1598+
"line-width" : [
1599+
"interpolate",
1600+
[
1601+
"linear"
1602+
],
1603+
[
1604+
"zoom"
1605+
],
1606+
13,
1607+
0.2,
1608+
23,
1609+
8.0
1610+
],
1611+
"line-offset" : [
1612+
"interpolate",
1613+
[
1614+
"linear"
1615+
],
1616+
[
1617+
"zoom"
1618+
],
1619+
13,
1620+
0.4,
1621+
23,
1622+
7.0
1623+
]
1624+
},
1625+
"filter" : [
1626+
"in",
1627+
"class",
1628+
"ElevatorHopEdge"
1629+
],
1630+
"layout" : {
1631+
"line-cap" : "round",
1632+
"visibility" : "none"
1633+
},
1634+
"metadata" : {
1635+
"group" : "Elevators"
1636+
}
1637+
},
1638+
{
1639+
"id" : "elevator-vertex",
1640+
"type" : "circle",
1641+
"source" : "vectorSource",
1642+
"source-layer" : "vertices",
1643+
"minzoom" : 15,
1644+
"maxzoom" : 23,
1645+
"paint" : {
1646+
"circle-stroke-color" : "#140d0e",
1647+
"circle-stroke-width" : [
1648+
"interpolate",
1649+
[
1650+
"linear"
1651+
],
1652+
[
1653+
"zoom"
1654+
],
1655+
15,
1656+
0.2,
1657+
23,
1658+
3.0
1659+
],
1660+
"circle-radius" : [
1661+
"interpolate",
1662+
[
1663+
"linear"
1664+
],
1665+
[
1666+
"zoom"
1667+
],
1668+
15,
1669+
1.0,
1670+
23,
1671+
7.0
1672+
],
1673+
"circle-color" : "#ffa500"
1674+
},
1675+
"filter" : [
1676+
"in",
1677+
"class",
1678+
"ElevatorVertex"
1679+
],
1680+
"layout" : {
1681+
"visibility" : "none"
1682+
},
1683+
"metadata" : {
1684+
"group" : "Elevators"
1685+
}
1686+
},
15891687
{
15901688
"id" : "vertex",
15911689
"type" : "circle",

0 commit comments

Comments
 (0)