// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.pt_assistant.utils; import java.util.Collection; import org.openstreetmap.josm.data.osm.Node; import org.openstreetmap.josm.data.osm.OsmPrimitiveType; import org.openstreetmap.josm.data.osm.OsmUtils; import org.openstreetmap.josm.data.osm.Relation; import org.openstreetmap.josm.data.osm.RelationMember; import org.openstreetmap.josm.data.osm.Way; /** * Utils class for routes * * @author darya * */ public final class RouteUtils { private RouteUtils() { // private constructor for util classes } /** * Checks if the relation is a route of one of the following categories: * bus, trolleybus, share_taxi, tram, light_rail, subway, train. * * @param r * Relation to be checked * @return true if the route belongs to the categories that can be validated * with the pt_assistant plugin, false otherwise. */ public static boolean isTwoDirectionRoute(Relation r) { if (r == null) { return false; } if (!r.hasKey("route") || !r.hasTag("public_transport:version", "2")) { return false; } if (r.hasTag("route", "bus") || r.hasTag("route", "trolleybus") || r.hasTag("route", "share_taxi") || r.hasTag("route", "tram") || r.hasTag("route", "light_rail") || r.hasTag("route", "subway") || r.hasTag("route", "train")) { if (!r.hasTag("bus", "on_demand")) { return true; } } return false; } /** * Checks if the relation member refers to a stop in a public transport * route. Some stops can be modeled with ways. * * @param rm * relation member to be checked * @return true if the relation member refers to a stop, false otherwise */ public static boolean isPTStop(RelationMember rm) { if (rm.getType().equals(OsmPrimitiveType.NODE)) { return true; } if (rm.getType().equals(OsmPrimitiveType.WAY)) { if (rm.getWay().hasTag("public_transport", "platform") || rm.getWay().hasTag("highway", "platform") || rm.getWay().hasTag("railway", "platform")) { return true; } } return false; } /** * Checks if the relation member refers to a way in a public transport * route. Some OsmPrimitiveType.WAY have to be excluded because platforms * can be modeled with ways. * * @param rm * relation member to be checked * @return true if the relation member refers to a way in a public transport * route, false otherwise. */ public static boolean isPTWay(RelationMember rm) { if (rm.getType().equals(OsmPrimitiveType.NODE)) { return false; } if (rm.getType().equals(OsmPrimitiveType.WAY)) { if (rm.getWay().hasTag("public_transport", "platform") || rm.getWay().hasTag("highway", "platform") || rm.getWay().hasTag("railway", "platform")) { return false; } return true; } Relation nestedRelation = rm.getRelation(); for (RelationMember nestedRelationMember : nestedRelation.getMembers()) { if (!nestedRelationMember.getType().equals(OsmPrimitiveType.WAY)) { return false; } } return true; } /** * Checks if the given way has tags that make it oneway for public * transport. The test does not check whether the way violates those * restrictions. * * @return 0 if the way is not oneway for public transport, 1 if the way is * oneway for public transport, -1 if the way is reversely oneway * for public transport */ public static int isOnewayForPublicTransport(Way way) { if (OsmUtils.isTrue(way.get("oneway")) || OsmUtils.isReversed(way.get("oneway")) || way.hasTag("junction", "roundabout") || way.hasTag("highway", "motorway")) { if (!way.hasTag("busway", "lane") && !way.hasTag("busway:left", "lane") && !way.hasTag("busway:right", "lane") && !way.hasTag("oneway:bus", "no") && !way.hasTag("busway", "opposite_lane") && !way.hasTag("oneway:psv", "no") && !way.hasTag("trolley_wire", "backward")) { if (OsmUtils.isReversed(way.get("oneway"))) { return -1; } return 1; } } return 0; } /** * Checks if the ways have a common node * * @param w1 first way * @param w2 second way * @return {@code true} if the ways have a common node */ public static boolean waysTouch(Way w1, Way w2) { if (w1 == null || w2 == null) { return false; } Node w1FirstNode = w1.firstNode(); Node w1LastNode = w1.lastNode(); Node w2FirstNode = w2.firstNode(); Node w2LastNode = w2.lastNode(); if (w1FirstNode == w2FirstNode || w1FirstNode == w2LastNode || w1LastNode == w2FirstNode || w1LastNode == w2LastNode) { return true; } return false; } /** * Checks if any way from the first collection touches any way from the * second collection * * @param c1 first collection * @param c2 second collection * @return true if ways touch, false otherwise */ public static boolean waysTouch(Collection<Way> c1, Collection<Way> c2) { if (c1 == null || c2 == null) { return false; } for (Way w1 : c1) { for (Way w2 : c2) { if (waysTouch(w1, w2)) { return true; } } } return false; } /** * Checks if the type of the way is suitable for buses to go on it. The * direction of the way (i.e. one-way roads) is irrelevant for this test. * * @param way * to be checked * @return true if the way is suitable for buses, false otherwise. */ public static boolean isWaySuitableForBuses(Way way) { if (way.hasTag("highway", "motorway") || way.hasTag("highway", "trunk") || way.hasTag("highway", "primary") || way.hasTag("highway", "secondary") || way.hasTag("highway", "tertiary") || way.hasTag("highway", "unclassified") || way.hasTag("highway", "road") || way.hasTag("highway", "residential") || way.hasTag("highway", "service") || way.hasTag("highway", "motorway_link") || way.hasTag("highway", "trunk_link") || way.hasTag("highway", "primary_link") || way.hasTag("highway", "secondary_link") || way.hasTag("highway", "tertiary_link") || way.hasTag("highway", "living_street") || way.hasTag("highway", "bus_guideway") || way.hasTag("highway", "road") || way.hasTag("cycleway", "share_busway") || way.hasTag("cycleway", "shared_lane")) { return true; } if (way.hasTag("highway", "pedestrian") && (way.hasTag("bus", "yes") || way.hasTag("psv", "yes") || way.hasTag("bus", "designated") || way.hasTag("psv", "designated"))) { return true; } return false; } /** * Checks if this way is suitable for public transport (not only for buses) * @param way way * @return {@code true} if this way is suitable for public transport */ public static boolean isWaySuitableForPublicTransport(Way way) { if (isWaySuitableForBuses(way) || way.hasTag("railway", "tram") || way.hasTag("railway", "subway") || way.hasTag("railway", "subway") || way.hasTag("railway", "light_rail") || way.hasTag("railway", "rail")) { return true; } return false; } }