meta { title: "Jungle Bus – validation ruleset"; version: "dev"; description: "An uncompromising validation rules for public transport"; author: "nlehuby"; link: "http://junglebus.io/"; watch-modified: true; } /* Route tag on relations */ relation[type=route][!route] { throwError: "Jungle : The route tag is missing (add the tag route = bus/coach/tram/etc)"; } relation[type=route_master][!route_master][!route] { throwError: "Jungle : The route_master tag is missing (add the tag route_master = bus/coach/tram/etc)"; } /* Mode in the wrong tag */ relation[type=route_master][route] { throwError: "Jungle : The route_master tag is missing (change the route tag to route_master)"; fixChangeKey: "route=>route_master"; } relation[type=route][route=~/^(bus|coach|train|subway|monorail|trolleybus|aerialway|funicular|ferry|tram|share_taxy|light_rail|school_bus)$/] { set pt_route } relation[type=route_master][route_master=~/^(bus|coach|train|subway|monorail|trolleybus|aerialway|funicular|ferry|tram|share_taxy|light_rail|school_bus)$/] { set pt_route_master } relation.pt_route[!network], relation.pt_route_master[!network] { throwError: "Jungle : The network tag is missing"; } relation.pt_route[!operator], relation.pt_route_master[!operator] { throwError: "Jungle : The operator tag is missing"; } relation.pt_route[!ref], relation.pt_route_master[!ref] { throwError: "Jungle : The ref tag is missing"; } relation.pt_route[!from], relation.pt_route[!to] { throwError: "Jungle : The from or to tag is missing"; } relation.pt_route_master[!frequency] { throwError: "Jungle : The frequency tag is missing"; } relation.pt_route[!travel_time] { throwError: "Jungle : The travel_time tag is missing"; } relation.pt_route_master[!charge] { throwError: "Jungle : The charge tag is missing"; } /* The charge tag must end with GHS */ relation.pt_route_master[charge$="GHS"] { set charge_ok } relation.pt_route_master[charge]!.charge_ok { throwError: "Jungle : The charge tag must end with GHS"; } /* Tags on bus stops */ node[highway=bus_stop][!name] { throwWarning: "Jungle : The name tag is missing"; } node[highway=bus_stop][!public_transport] { throwError: "Jungle : Is it a passenger waiting point (platform) or a stop_position ?"; fixAdd: "public_transport=platform"; } node["public_transport"="platform"][!highway][!railway] { throwError: "Jungle : Is it a bus_stop or a tram_stop ?"; fixAdd: "highway=bus_stop"; } node["public_transport"="platform"][shelter][!highway], node["public_transport"="platform"][bus=yes][!highway] { throwError: "Jungle : Is it a bus_stop ?"; fixAdd: "highway=bus_stop"; } /* All the line variations (route relations) should be part of a line (route_master relation) */ relation[type=route_master] > relation[type=route] { set route_ok } relation.pt_route!.route_ok { throwError: "Jungle : Add this route relation to a route_master relation"; } /* All the stops should be in at least a line variation (route relation) */ relation[type=route] > node[public_transport=platform] { set platform_ok } node[public_transport=platform]!.platform_ok { throwError: "Jungle : Add the stop to a route relation"; }