source: osm/applications/editors/josm/oldplugins/public_transport_layer/src/ptl/DistanceBetweenStops.java

Last change on this file was 36122, checked in by taylor.smock, 18 months ago

Use jakarta.json instead of java.json

This also fixes various lint issues

File size: 6.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package ptl;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.event.ActionEvent;
7import java.text.DecimalFormat;
8import java.util.ArrayList;
9import java.util.Collections;
10import java.util.List;
11
12import javax.swing.JOptionPane;
13
14import org.openstreetmap.josm.actions.JosmAction;
15import org.openstreetmap.josm.data.SystemOfMeasurement;
16import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
17import org.openstreetmap.josm.data.osm.Node;
18import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
19import org.openstreetmap.josm.data.osm.Relation;
20import org.openstreetmap.josm.data.osm.RelationMember;
21import org.openstreetmap.josm.gui.ExtendedDialog;
22import org.openstreetmap.josm.gui.MainApplication;
23import org.openstreetmap.josm.gui.dialogs.relation.sort.WayConnectionType;
24import org.openstreetmap.josm.gui.dialogs.relation.sort.WayConnectionTypeCalculator;
25import org.openstreetmap.josm.gui.util.GuiHelper;
26import org.openstreetmap.josm.gui.widgets.JosmTextArea;
27import org.openstreetmap.josm.spi.preferences.Config;
28import org.openstreetmap.josm.tools.CheckParameterUtil;
29import org.openstreetmap.josm.tools.Utils;
30
31/**
32 * Computes and displays the distance between stops.
33 */
34public class DistanceBetweenStops extends JosmAction {
35
36 public DistanceBetweenStops() {
37 super(tr("Distance between stops"), null, null, null, false);
38 }
39
40 static String calculateDistanceBetweenStops(final Relation route) {
41 CheckParameterUtil.ensureThat(isRouteSupported(route), "A valid public_transport:version=2 route is required");
42
43 final List<Node> stopNodes = new ArrayList<>();
44 final List<RelationMember> routeSegments = new ArrayList<>();
45 final List<Node> routeNodes = new ArrayList<>();
46 for (final RelationMember member : route.getMembers()) {
47 if (member.hasRole("stop", "stop_exit_only", "stop_entry_only") && OsmPrimitiveType.NODE == member.getType()) {
48 stopNodes.add(member.getNode());
49 } else if (member.hasRole("") && OsmPrimitiveType.WAY == member.getType()) {
50 routeSegments.add(member);
51 }
52 }
53
54 final WayConnectionTypeCalculator connectionTypeCalculator = new WayConnectionTypeCalculator();
55 final List<WayConnectionType> links = connectionTypeCalculator.updateLinks(routeSegments);
56 for (int i = 0; i < links.size(); i++) {
57 final WayConnectionType link = links.get(i);
58 final List<Node> nodes = routeSegments.get(i).getWay().getNodes();
59 switch (link.direction) {
60 case BACKWARD:
61 Collections.reverse(nodes);
62 // fall through
63 case FORWARD:
64 routeNodes.addAll(link.linkPrev ? nodes.subList(1, nodes.size()) : nodes);
65 break;
66 default:
67 break;
68 }
69 }
70
71 final StringBuilder sb = new StringBuilder();
72 Node lastN = null;
73 List<Node> remainingRouteNodes = routeNodes;
74 double totalLength = 0.0;
75 int lengthN = 0;
76 final boolean onlyLowerUnit = Config.getPref().getBoolean("system_of_measurement.use_only_lower_unit", false);
77 Config.getPref().putBoolean("system_of_measurement.use_only_lower_unit", true);
78 try {
79 for (Node n : stopNodes) {
80 final double length;
81 if (lastN != null) {
82 if (remainingRouteNodes.indexOf(lastN) > 0) {
83 remainingRouteNodes = remainingRouteNodes.subList(remainingRouteNodes.indexOf(lastN), remainingRouteNodes.size());
84 }
85 if (remainingRouteNodes.indexOf(n) > 0) {
86 final List<Node> segmentBetweenStops = remainingRouteNodes.subList(0, remainingRouteNodes.indexOf(n) + 1);
87 length = getLength(segmentBetweenStops);
88 totalLength += length;
89 lengthN++;
90 } else {
91 length = Double.NaN;
92 }
93 } else {
94 length = 0.0;
95 }
96 sb.append(SystemOfMeasurement.getSystemOfMeasurement().getDistText(length, new DecimalFormat("0"), -1));
97 sb.append("\t");
98 sb.append(n.getDisplayName(DefaultNameFormatter.getInstance()));
99 sb.append("\n");
100 lastN = n;
101 }
102 sb.insert(0, "\n");
103 sb.insert(0, route.getDisplayName(DefaultNameFormatter.getInstance()));
104 sb.insert(0, "\t");
105 sb.insert(0, SystemOfMeasurement.getSystemOfMeasurement().getDistText(totalLength / lengthN, new DecimalFormat("0"), -1));
106 } finally {
107 Config.getPref().putBoolean("system_of_measurement.use_only_lower_unit", onlyLowerUnit);
108 }
109
110 return sb.toString();
111 }
112
113 private static boolean isRouteSupported(Relation route) {
114 return !route.hasIncompleteMembers()
115 && route.hasTag("type", "route")
116 && route.hasKey("route")
117 && route.hasTag("public_transport:version", "2");
118 }
119
120 private static double getLength(Iterable<Node> nodes) {
121 double length = 0;
122 Node lastN = null;
123 for (Node n : nodes) {
124 if (lastN != null && n != null && lastN.isLatLonKnown() && n.isLatLonKnown()) {
125 length += n.greatCircleDistance(lastN);
126 }
127 lastN = n;
128 }
129 return length;
130 }
131
132 @Override
133 public void actionPerformed(ActionEvent e) {
134 if (getLayerManager().getEditDataSet() == null) {
135 return;
136 }
137 final StringBuilder sb = new StringBuilder();
138 for (Relation relation : getLayerManager().getEditDataSet().getSelectedRelations()) {
139 if (!isRouteSupported(relation)) {
140 JOptionPane.showMessageDialog(MainApplication.getMainFrame(),
141 "<html>" + tr("A valid public_transport:version=2 route is required")
142 + Utils.joinAsHtmlUnorderedList(Collections.singleton(relation.getDisplayName(DefaultNameFormatter.getInstance()))),
143 tr("Invalid selection"), JOptionPane.WARNING_MESSAGE);
144 continue;
145 }
146 sb.append("\n");
147 sb.append(calculateDistanceBetweenStops(relation)).append("\n");
148 }
149
150 ExtendedDialog extendedDialog = new ExtendedDialog(MainApplication.getMainFrame(), getValue(NAME).toString(), tr("Close"));
151 extendedDialog.setButtonIcons("ok");
152 final JosmTextArea jte = new JosmTextArea();
153 jte.setFont(GuiHelper.getMonospacedFont(jte));
154 jte.setEditable(false);
155 jte.append(sb.toString());
156 jte.setSelectionStart(0);
157 jte.setSelectionEnd(0);
158 extendedDialog.setContent(jte);
159 extendedDialog.showDialog();
160 }
161}
Note: See TracBrowser for help on using the repository browser.