Skip to content

Commit

Permalink
Merge pull request #6119 from Jnction/indoor-routing
Browse files Browse the repository at this point in the history
Make indoor=area and indoor=corridor routable
  • Loading branch information
optionsome authored Oct 31, 2024
2 parents 53a2132 + 0d826d7 commit 283e3f9
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,7 @@ public void addWay(OsmWay way) {

applyLevelsForWay(way);

/* An area can be specified as such, or be one by default as an amenity */
if (
(way.isArea() || way.isParkAndRide() || way.isBikeParking() || way.isBoardingArea()) &&
way.getNodeRefs().size() > 2
) {
if (way.isRoutableArea()) {
// this is an area that's a simple polygon. So we can just add it straight
// to the areas, if it's not part of a relation.
if (!areaWayIds.contains(wayId)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class OsmWay extends OsmWithTags {
"backward",
"reversible"
);

private final TLongList nodes = new TLongArrayList();

public void addNodeRef(long nodeRef) {
Expand Down Expand Up @@ -137,8 +138,23 @@ public boolean isBackwardEscalator() {
return isEscalator() && "backward".equals(this.getTag("conveying"));
}

public boolean isArea() {
return isTag("area", "yes");
/**
* Returns true if the way is considered an area.
*
* An area can be specified as such, or be one by default as an amenity.
*/
public boolean isRoutableArea() {
return (
!isTag("area", "no") &&
(
isTag("area", "yes") ||
isParking() ||
isBikeParking() ||
isBoardingArea() ||
isIndoorRoutable()
) &&
getNodeRefs().size() > 2
);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public class OsmWithTags {
"escape"
);

private static final Set<String> INDOOR_ROUTABLE_VALUES = Set.of("corridor", "area");

private static final Set<String> LEVEL_TAGS = Set.of("level", "layer");
private static final Set<String> DEFAULT_LEVEL = Set.of("0");

Expand Down Expand Up @@ -413,14 +415,21 @@ public boolean isPedestrianExplicitlyAllowed() {
return doesTagAllowAccess("foot");
}

/**
* @return True if this node / area is a parking.
*/
public boolean isParking() {
return isTag("amenity", "parking");
}

/**
* @return True if this node / area is a park and ride.
*/
public boolean isParkAndRide() {
String parkingType = getTag("parking");
String parkAndRide = getTag("park_ride");
return (
isTag("amenity", "parking") &&
isParking() &&
(
(parkingType != null && parkingType.contains("park_and_ride")) ||
(parkAndRide != null && !parkAndRide.equalsIgnoreCase("no"))
Expand Down Expand Up @@ -532,7 +541,7 @@ public void setOsmProvider(OsmProvider provider) {
public boolean isRoutable() {
if (isOneOfTags("highway", NON_ROUTABLE_HIGHWAYS)) {
return false;
} else if (hasTag("highway") || isPlatform()) {
} else if (hasTag("highway") || isPlatform() || isIndoorRoutable()) {
if (isGeneralAccessDenied()) {
// There are exceptions.
return (
Expand All @@ -549,6 +558,10 @@ public boolean isRoutable() {
return false;
}

public boolean isIndoorRoutable() {
return isOneOfTags("indoor", INDOOR_ROUTABLE_VALUES);
}

/**
* Is this a link to another road, like a highway ramp.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import static org.opentripplanner.osm.wayproperty.WayPropertiesBuilder.withModes;
import static org.opentripplanner.street.model.StreetTraversalPermission.ALL;
import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN;

import org.opentripplanner.osm.wayproperty.WayProperties;
import org.opentripplanner.osm.wayproperty.WayPropertySet;

/**
Expand Down Expand Up @@ -73,6 +75,10 @@ public void populateProperties(WayPropertySet props) {
props.setCarSpeed("highway=secondary_link", 13.4f); // ~= 30mph
props.setCarSpeed("highway=tertiary", 15.7f); // ~= 35mph

WayProperties pedestrianWayProperties = withModes(PEDESTRIAN).build();
props.setProperties("indoor=area", pedestrianWayProperties);
props.setProperties("indoor=corridor", pedestrianWayProperties);

// Read the rest from the default set
new DefaultMapper().populateProperties(props);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,56 @@ void testIsBicycleDismountForced() {
assertTrue(way.isBicycleDismountForced());
}

@Test
void testAreaMustContain3Nodes() {
OsmWay way = new OsmWay();
way.addTag("area", "yes");
assertFalse(way.isRoutableArea());
way.addNodeRef(1);
assertFalse(way.isRoutableArea());
way.addNodeRef(2);
assertFalse(way.isRoutableArea());
way.addNodeRef(3);
assertTrue(way.isRoutableArea());
way.addNodeRef(4);
assertTrue(way.isRoutableArea());
}

@Test
void testAreaTags() {
OsmWay platform = getClosedPolygon();
platform.addTag("public_transport", "platform");
assertTrue(platform.isRoutableArea());
platform.addTag("area", "no");
assertFalse(platform.isRoutableArea());

OsmWay roundabout = getClosedPolygon();
roundabout.addTag("highway", "roundabout");
assertFalse(roundabout.isRoutableArea());

OsmWay pedestrian = getClosedPolygon();
pedestrian.addTag("highway", "pedestrian");
assertFalse(pedestrian.isRoutableArea());
pedestrian.addTag("area", "yes");
assertTrue(pedestrian.isRoutableArea());

OsmWay indoorArea = getClosedPolygon();
indoorArea.addTag("indoor", "area");
assertTrue(indoorArea.isRoutableArea());

OsmWay bikeParking = getClosedPolygon();
bikeParking.addTag("amenity", "bicycle_parking");
assertTrue(bikeParking.isRoutableArea());

OsmWay corridor = getClosedPolygon();
corridor.addTag("indoor", "corridor");
assertTrue(corridor.isRoutableArea());

OsmWay door = getClosedPolygon();
door.addTag("indoor", "door");
assertFalse(door.isRoutableArea());
}

@Test
void testIsSteps() {
OsmWay way = new OsmWay();
Expand Down Expand Up @@ -125,4 +175,13 @@ void escalator() {
escalator.addTag("conveying", "whoknows?");
assertFalse(escalator.isEscalator());
}

private OsmWay getClosedPolygon() {
var way = new OsmWay();
way.addNodeRef(1);
way.addNodeRef(2);
way.addNodeRef(3);
way.addNodeRef(1);
return way;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ void isWheelchairAccessible() {
@Test
void isRoutable() {
assertFalse(WayTestData.zooPlatform().isRoutable());
assertTrue(WayTestData.indoor("area").isRoutable());
assertFalse(WayTestData.indoor("room").isRoutable());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.opentripplanner.osm.tagmapping;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN;

import org.junit.jupiter.api.Test;
import org.opentripplanner.osm.wayproperty.WayPropertySet;
import org.opentripplanner.osm.wayproperty.specifier.WayTestData;

public class UKMapperTest {

static WayPropertySet wps = new WayPropertySet();

static {
var source = new UKMapper();
source.populateProperties(wps);
}

@Test
void indoor() {
var corridor = wps.getDataForWay(WayTestData.indoor("corridor"));
assertEquals(PEDESTRIAN, corridor.getPermission());
var area = wps.getDataForWay(WayTestData.indoor("area"));
assertEquals(PEDESTRIAN, area.getPermission());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -218,4 +218,10 @@ public static OsmWithTags zooPlatform() {
way.addTag("usage", "tourism");
return way;
}

public static OsmWithTags indoor(String value) {
var way = new OsmWithTags();
way.addTag("indoor", value);
return way;
}
}
2 changes: 2 additions & 0 deletions doc/user/osm/UK.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Lower safety values make an OSM way more desirable and higher values less desira
| `highway=trunk_link; cycleway=opposite_track` | `ALL` | forward: 2.06 <br> back: 0.85 | |
| `highway=trunk; bicycle=designated` | `ALL` | 7.25 | |
| `highway=trunk_link; bicycle=designated` | `ALL` | 2.0 | |
| `indoor=area` | `PEDESTRIAN` | | |
| `indoor=corridor` | `PEDESTRIAN` | | |
| `mtb:scale=3` | `NONE` | | |
| `mtb:scale=4` | `NONE` | | |
| `mtb:scale=5` | `NONE` | | |
Expand Down

0 comments on commit 283e3f9

Please sign in to comment.