001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.dialogs.relation.sort; 003 004import static org.openstreetmap.josm.gui.dialogs.relation.sort.WayConnectionType.Direction.NONE; 005import static org.openstreetmap.josm.gui.dialogs.relation.sort.WayConnectionType.Direction.ROUNDABOUT_LEFT; 006import static org.openstreetmap.josm.gui.dialogs.relation.sort.WayConnectionType.Direction.ROUNDABOUT_RIGHT; 007 008import org.openstreetmap.josm.data.coor.EastNorth; 009import org.openstreetmap.josm.data.osm.RelationMember; 010import org.openstreetmap.josm.data.osm.Way; 011import org.openstreetmap.josm.gui.dialogs.relation.sort.WayConnectionType.Direction; 012 013final class RelationSortUtils { 014 015 private RelationSortUtils() { 016 // Hide default constructor for utils classes 017 } 018 019 /** 020 * determine, if the way i is a roundabout and if yes, what type of roundabout 021 * @param member relation member 022 * @return roundabout type 023 */ 024 static Direction roundaboutType(RelationMember member) { 025 if (member == null || !member.isWay()) return NONE; 026 return roundaboutType(member.getWay()); 027 } 028 029 static Direction roundaboutType(Way w) { 030 if (w != null && 031 "roundabout".equals(w.get("junction")) && 032 w.getNodesCount() < 200 && 033 w.getNodesCount() > 2 && 034 w.getNode(0) != null && 035 w.getNode(1) != null && 036 w.getNode(2) != null && 037 w.isClosed()) { 038 /** do some simple determinant / cross pruduct test on the first 3 nodes 039 to see, if the roundabout goes clock wise or ccw */ 040 EastNorth en1 = w.getNode(0).getEastNorth(); 041 EastNorth en2 = w.getNode(1).getEastNorth(); 042 EastNorth en3 = w.getNode(2).getEastNorth(); 043 if (en1 != null && en2 != null && en3 != null) { 044 en1 = en2.subtract(en1); 045 en2 = en3.subtract(en2); 046 return en1.north() * en2.east() - en2.north() * en1.east() > 0 ? ROUNDABOUT_LEFT : ROUNDABOUT_RIGHT; 047 } 048 } 049 return NONE; 050 } 051 052 static boolean isBackward(final RelationMember member) { 053 return "backward".equals(member.getRole()); 054 } 055 056 static boolean isForward(final RelationMember member) { 057 return "forward".equals(member.getRole()); 058 } 059 060 static boolean isOneway(final RelationMember member) { 061 return isForward(member) || isBackward(member); 062 } 063}