-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Start creating the routing helper rewrite, at the moment just a bit o…
…f UI that doesn't do much yet
- Loading branch information
Showing
7 changed files
with
321 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
...a/org/openstreetmap/josm/plugins/pt_assistant/actions/routinghelper/BusTransportMode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package org.openstreetmap.josm.plugins.pt_assistant.actions.routinghelper; | ||
|
||
import java.util.Objects; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
|
||
import com.drew.lang.annotations.NotNull; | ||
import org.openstreetmap.josm.data.osm.IRelation; | ||
import org.openstreetmap.josm.data.osm.IWay; | ||
import org.openstreetmap.josm.data.osm.Node; | ||
import org.openstreetmap.josm.data.osm.OsmPrimitiveType; | ||
import org.openstreetmap.josm.data.osm.Relation; | ||
import org.openstreetmap.josm.data.osm.Way; | ||
|
||
public class BusTransportMode implements ITransportMode { | ||
@Override | ||
public boolean canTraverseWay(@NotNull final IWay<?> way, @NotNull final WayTraversalDirection direction) { | ||
final String onewayValue = way.get("oneway"); | ||
return way.hasTag("highway", "primary", "secondary", "tertiary", "residential") && ( | ||
onewayValue == null || "no".equals(way.get("oneway:bus")) || | ||
("yes".equals(onewayValue) && direction == WayTraversalDirection.FORWARD) || | ||
("-1".equals(onewayValue) && direction == WayTraversalDirection.BACKWARD) | ||
); | ||
} | ||
|
||
@Override | ||
public boolean canBeUsedForRelation(@NotNull final IRelation<?> relation) { | ||
return relation.hasTag("route", "bus"); | ||
} | ||
|
||
@Override | ||
public boolean canTurn(@NotNull final Way from, @NotNull final Node via, @NotNull final Way to) { | ||
final Set<Relation> restrictionRelations = from.getReferrers().stream() | ||
.map(it -> it.getType() == OsmPrimitiveType.RELATION ? (Relation) it : null) | ||
.filter(Objects::nonNull) | ||
.filter(it -> "restriction".equals(it.get("type"))) | ||
.filter(it -> it.findRelationMembers("from").contains(from)) | ||
.filter(it -> it.findRelationMembers("via").contains(via)) | ||
.filter(it -> it.findRelationMembers("to").contains(to)) | ||
.collect(Collectors.toSet()); | ||
// TODO: Use the `restrictionRelations` to figure out the turning restrictions that apply | ||
return from.containsNode(via) && to.containsNode(via); | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
...ava/org/openstreetmap/josm/plugins/pt_assistant/actions/routinghelper/ITransportMode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package org.openstreetmap.josm.plugins.pt_assistant.actions.routinghelper; | ||
|
||
import com.drew.lang.annotations.NotNull; | ||
import org.openstreetmap.josm.data.osm.IRelation; | ||
import org.openstreetmap.josm.data.osm.IWay; | ||
import org.openstreetmap.josm.data.osm.Node; | ||
import org.openstreetmap.josm.data.osm.Way; | ||
|
||
public interface ITransportMode { | ||
/** | ||
* Just a convenience method for {@link #canTraverseWay(IWay, WayTraversalDirection)} that assumes {@link WayTraversalDirection#FORWARD} | ||
* @param way the way for which we check, if it can be traversed by the transport mode | ||
* @return {@code true} if the transport mode can travel along the way in the forward direction. Otherwise {@code false}. | ||
*/ | ||
default boolean canTraverseWay(final Way way) { | ||
return canTraverseWay(way, WayTraversalDirection.FORWARD); | ||
} | ||
|
||
/** | ||
* @param way the way that is checked, if the transport mode can traverse | ||
* @param direction the travel direction for which we check | ||
* @return {@code true} iff the transport mode can travel along the given way in the given direction. Otherwise {@code false}. | ||
*/ | ||
boolean canTraverseWay(@NotNull IWay<?> way, @NotNull WayTraversalDirection direction); | ||
|
||
/** | ||
* Checks if this transport mode should be used for the given relation | ||
* @param relation the relation that is checked, if it is suitable for the transport mode | ||
* @return {@code true} if the transport mode is suitable for the relation. Otherwise {@code false}. | ||
*/ | ||
boolean canBeUsedForRelation(@NotNull final IRelation<?> relation); | ||
|
||
/** | ||
* @param from the way from which the vehicle is coming | ||
* @param via the node that the vehicle travels through, must be part of {@code from} and {@code to} ways, | ||
* or this method will return false | ||
* @param to the way onto which the vehicle makes the turn | ||
* @return {@code true} iff the transport mode can make a turn from the given {@code from} way, | ||
* via the given {@code via} node to the given {@code to} way. Otherwise {@code false}. | ||
* This method assumes that both ways can be traversed by the transport mode, it does not check that. | ||
*/ | ||
boolean canTurn(@NotNull final Way from, @NotNull final Node via, @NotNull final Way to); | ||
} |
78 changes: 78 additions & 0 deletions
78
...rg/openstreetmap/josm/plugins/pt_assistant/actions/routinghelper/RoutingHelperAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package org.openstreetmap.josm.plugins.pt_assistant.actions.routinghelper; | ||
|
||
import java.awt.event.ActionEvent; | ||
import java.util.Collections; | ||
import java.util.Objects; | ||
import java.util.Optional; | ||
import java.util.Set; | ||
|
||
import javax.swing.JOptionPane; | ||
|
||
import com.drew.lang.annotations.NotNull; | ||
import com.drew.lang.annotations.Nullable; | ||
import org.openstreetmap.josm.data.osm.Relation; | ||
import org.openstreetmap.josm.data.osm.Way; | ||
import org.openstreetmap.josm.gui.MainApplication; | ||
import org.openstreetmap.josm.gui.MapFrame; | ||
import org.openstreetmap.josm.gui.dialogs.relation.actions.AbstractRelationEditorAction; | ||
import org.openstreetmap.josm.gui.dialogs.relation.actions.IRelationEditorActionAccess; | ||
import org.openstreetmap.josm.gui.dialogs.relation.actions.IRelationEditorUpdateOn; | ||
import org.openstreetmap.josm.plugins.pt_assistant.utils.BoundsUtils; | ||
import org.openstreetmap.josm.tools.I18n; | ||
import org.openstreetmap.josm.tools.ImageProvider; | ||
|
||
public class RoutingHelperAction extends AbstractRelationEditorAction { | ||
private static final Set<ITransportMode> TRANSPORT_MODES = Collections.singleton(new BusTransportMode()); | ||
|
||
private Optional<ITransportMode> activeTransportMode; | ||
|
||
private final RoutingHelperPanel routingHelperPanel = new RoutingHelperPanel(this); | ||
|
||
public RoutingHelperAction(IRelationEditorActionAccess editorAccess) { | ||
super(editorAccess, IRelationEditorUpdateOn.TAG_CHANGE); | ||
new ImageProvider("dialogs/relation", "routing_assistance.svg").getResource().attachImageIcon(this, true); | ||
putValue(SHORT_DESCRIPTION, I18n.tr("Routing helper")); | ||
} | ||
|
||
@Override | ||
protected void updateEnabledState() { | ||
final Relation currentRelation = getEditor().getRelation(); | ||
final Optional<ITransportMode> newActiveTransportMode = TRANSPORT_MODES.stream() | ||
.filter(mode -> mode.canBeUsedForRelation(currentRelation)) | ||
.findFirst(); | ||
this.activeTransportMode = newActiveTransportMode; | ||
setEnabled(newActiveTransportMode.isPresent() && MainApplication.getMap().getTopPanel(RoutingHelperPanel.class) == null); | ||
} | ||
|
||
@Override | ||
public void actionPerformed(@NotNull final ActionEvent actionEvent) { | ||
final MapFrame mapFrame = MainApplication.getMap(); | ||
|
||
if (mapFrame.getTopPanel(RoutingHelperPanel.class) == null) { | ||
mapFrame.addTopPanel(routingHelperPanel); | ||
updateEnabledState(); | ||
} | ||
|
||
final Way currentWay = editorAccess.getEditor().getRelation().getMembers().stream().map(it -> it.isWay() ? it.getWay() : null).filter(Objects::nonNull).findFirst().orElse(null); | ||
if (currentWay != null) { | ||
MainApplication.getMap().mapView.zoomTo(BoundsUtils.fromBBox(currentWay.getBBox())); | ||
} | ||
routingHelperPanel.onCurrentWayChange(currentWay); | ||
} | ||
|
||
public void goToPreviousGap() { | ||
JOptionPane.showMessageDialog(routingHelperPanel, "Not implemented yet", "Not implemented", JOptionPane.ERROR_MESSAGE); | ||
} | ||
|
||
public void goToPreviousWay() { | ||
JOptionPane.showMessageDialog(routingHelperPanel, "Not implemented yet", "Not implemented", JOptionPane.ERROR_MESSAGE); | ||
} | ||
|
||
public void goToNextWay() { | ||
JOptionPane.showMessageDialog(routingHelperPanel, "Not implemented yet", "Not implemented", JOptionPane.ERROR_MESSAGE); | ||
} | ||
|
||
public void goToNextGap() { | ||
JOptionPane.showMessageDialog(routingHelperPanel, "Not implemented yet", "Not implemented", JOptionPane.ERROR_MESSAGE); | ||
} | ||
} |
97 changes: 97 additions & 0 deletions
97
...org/openstreetmap/josm/plugins/pt_assistant/actions/routinghelper/RoutingHelperPanel.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package org.openstreetmap.josm.plugins.pt_assistant.actions.routinghelper; | ||
|
||
import java.awt.BorderLayout; | ||
import java.awt.Color; | ||
import java.awt.Component; | ||
import java.awt.Cursor; | ||
import java.awt.FlowLayout; | ||
import java.util.Optional; | ||
|
||
import javax.swing.JButton; | ||
import javax.swing.JLabel; | ||
import javax.swing.JPanel; | ||
import javax.swing.border.EmptyBorder; | ||
|
||
import com.drew.lang.annotations.Nullable; | ||
import org.openstreetmap.josm.data.osm.Way; | ||
import org.openstreetmap.josm.gui.MainApplication; | ||
import org.openstreetmap.josm.gui.MapFrame; | ||
import org.openstreetmap.josm.tools.I18n; | ||
import org.openstreetmap.josm.tools.ImageProvider; | ||
|
||
/** | ||
* The top panel that is added via {@link MapFrame#addTopPanel(Component)}. | ||
* This class should just handle the display and input. The state of the routing helper should be handled in {@link RoutingHelperAction}. | ||
*/ | ||
public class RoutingHelperPanel extends JPanel { | ||
|
||
private final JLabel wayLabel = new JLabel("Way"); | ||
|
||
private final RoutingHelperAction routingHelperAction; | ||
|
||
public RoutingHelperPanel(final RoutingHelperAction routingHelperAction) { | ||
this.routingHelperAction = routingHelperAction; | ||
|
||
|
||
// Style main label | ||
wayLabel.setBorder(new EmptyBorder(10, 10, 10, 10)); | ||
|
||
JButton closeButton = new JButton(ImageProvider.get("misc", "black_x")); | ||
closeButton.setContentAreaFilled(false); | ||
closeButton.setRolloverEnabled(true); | ||
closeButton.setBorderPainted(false); | ||
closeButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); | ||
closeButton.setToolTipText(I18n.tr("Close the routing helper")); | ||
closeButton.addActionListener(e -> | ||
Optional.ofNullable(MainApplication.getMap()) | ||
.ifPresent(map -> { | ||
map.removeTopPanel(RoutingHelperPanel.class); | ||
routingHelperAction.updateEnabledState(); | ||
}) | ||
); | ||
|
||
final JPanel mainPanel = new JPanel(new BorderLayout()); | ||
mainPanel.setOpaque(false); | ||
mainPanel.add(wayLabel, BorderLayout.CENTER); | ||
mainPanel.add(closeButton, BorderLayout.EAST); | ||
|
||
// build the left and right button panels | ||
final JPanel buttonLeftPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); | ||
buttonLeftPanel.setOpaque(false); | ||
final JButton prevGapButton = new JButton("« to previous gap"); | ||
prevGapButton.addActionListener(e -> routingHelperAction.goToPreviousGap()); | ||
buttonLeftPanel.add(prevGapButton); | ||
final JButton prevButton = new JButton("‹ to previous way"); | ||
prevButton.addActionListener(e -> routingHelperAction.goToPreviousWay()); | ||
buttonLeftPanel.add(prevButton); | ||
|
||
final JPanel buttonRightPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); | ||
buttonRightPanel.setOpaque(false); | ||
final JButton nextButton = new JButton("to next way ›"); | ||
nextButton.addActionListener(e -> routingHelperAction.goToNextWay()); | ||
buttonRightPanel.add(nextButton); | ||
final JButton nextgapButton = new JButton("to next gap »"); | ||
nextgapButton.addActionListener(e -> routingHelperAction.goToNextGap()); | ||
buttonRightPanel.add(nextgapButton); | ||
|
||
// Combine both button panels into one | ||
final JPanel buttonPanel = new JPanel(new BorderLayout()); | ||
buttonPanel.setOpaque(false); | ||
buttonPanel.add(buttonLeftPanel, BorderLayout.WEST); | ||
buttonPanel.add(buttonRightPanel, BorderLayout.EAST); | ||
|
||
// put everything together | ||
setBackground(new Color(0xFF9966)); | ||
setLayout(new BorderLayout()); | ||
add(mainPanel, BorderLayout.CENTER); | ||
add(buttonPanel, BorderLayout.SOUTH); | ||
} | ||
|
||
public void onCurrentWayChange(@Nullable final Way way) { | ||
if (way == null) { | ||
wayLabel.setText(I18n.tr("No way found in relation")); | ||
} else { | ||
wayLabel.setText(I18n.tr("Active way: {0} ({1} nodes)", way.getId(), way.getNodesCount())); | ||
} | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
.../openstreetmap/josm/plugins/pt_assistant/actions/routinghelper/WayTraversalDirection.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package org.openstreetmap.josm.plugins.pt_assistant.actions.routinghelper; | ||
|
||
import java.util.function.Function; | ||
|
||
import com.drew.lang.annotations.NotNull; | ||
import com.drew.lang.annotations.Nullable; | ||
import org.openstreetmap.josm.data.osm.INode; | ||
import org.openstreetmap.josm.data.osm.IWay; | ||
import org.openstreetmap.josm.data.osm.Way; | ||
|
||
public enum WayTraversalDirection { | ||
FORWARD(IWay::firstNode, IWay::lastNode), | ||
BACKWARD(IWay::lastNode, IWay::firstNode); | ||
|
||
private final Function<IWay<? extends INode>, INode> startNodeGetter; | ||
private final Function<IWay<? extends INode>, INode> endNodeGetter; | ||
|
||
WayTraversalDirection( | ||
@NotNull final Function<IWay<? extends INode>, INode> startNodeGetter, | ||
@NotNull final Function<IWay<? extends INode>, INode> endNodeGetter | ||
) { | ||
this.startNodeGetter = startNodeGetter; | ||
this.endNodeGetter = endNodeGetter; | ||
} | ||
|
||
/** | ||
* Finds the first node that you come across when traversin the given way. | ||
* | ||
* @param way the way for which the first or last node is returned, depending on the direction | ||
* @return {@link #FORWARD} returns the {@link Way#firstNode()}, {@link #BACKWARD} returns the {@link Way#lastNode()} | ||
*/ | ||
@Nullable | ||
public INode getStartNodeFor(@NotNull final IWay<? extends INode> way) { | ||
return startNodeGetter.apply(way); | ||
} | ||
|
||
|
||
/** | ||
* Finds the node where traversal of the given way ends. | ||
* | ||
* @param way the way for which the first or last node is returned, depending on the direction | ||
* @return {@link #FORWARD} returns the {@link Way#lastNode()}, {@link #BACKWARD} returns the {@link Way#firstNode()} | ||
*/ | ||
@Nullable | ||
public INode getEndNodeFor(@NotNull final IWay<? extends INode> way) { | ||
return endNodeGetter.apply(way); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters