// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.pt_assistant.validation;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.openstreetmap.josm.actions.AutoScaleAction;
import org.openstreetmap.josm.command.ChangeCommand;
import org.openstreetmap.josm.command.Command;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.data.osm.OsmPrimitive;
import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
import org.openstreetmap.josm.data.osm.Way;
import org.openstreetmap.josm.data.validation.Severity;
import org.openstreetmap.josm.data.validation.Test;
import org.openstreetmap.josm.data.validation.TestError;
import org.openstreetmap.josm.data.validation.TestError.Builder;
import org.openstreetmap.josm.plugins.pt_assistant.utils.RouteUtils;
import org.openstreetmap.josm.plugins.pt_assistant.utils.StopUtils;
public class NodeChecker extends Checker {
protected NodeChecker(Node node, Test test) {
super(node, test);
}
/**
* Checks if the given stop_position node belongs to any way
*/
protected void performSolitaryStopPositionTest() {
List<OsmPrimitive> referrers = node.getReferrers();
for (OsmPrimitive referrer : referrers) {
if (referrer.getType().equals(OsmPrimitiveType.WAY)) {
Way referrerWay = (Way) referrer;
if (RouteUtils.isWaySuitableForPublicTransport(referrerWay)) {
return;
}
}
}
List<OsmPrimitive> primitives = new ArrayList<>(1);
primitives.add(node);
Builder builder = TestError.builder(this.test, Severity.WARNING, PTAssistantValidatorTest.ERROR_CODE_SOLITARY_STOP_POSITION);
builder.message(tr("PT: Stop_position is not part of a way"));
builder.primitives(primitives);
TestError e = builder.build();
errors.add(e);
}
/**
* Checks if the given platform node belongs to any way
*/
protected void performPlatformPartOfWayTest() {
List<OsmPrimitive> referrers = node.getReferrers();
for (OsmPrimitive referrer : referrers) {
List<Node> primitives = new ArrayList<>(1);
primitives.add(node);
if (referrer.getType().equals(OsmPrimitiveType.WAY)) {
Way referringWay = (Way) referrer;
if (RouteUtils.isWaySuitableForPublicTransport(referringWay)) {
Builder builder = TestError.builder(this.test, Severity.WARNING, PTAssistantValidatorTest.ERROR_CODE_PLATFORM_PART_OF_HIGHWAY);
builder.message(tr("PT: Platform should not be part of a way"));
builder.primitives(primitives);
TestError e = builder.build();
errors.add(e);
return;
}
}
}
}
/**
* Checks if the given stop_position node belongs to any stop_area relation
*
* @author xamanu
*/
protected void performNodePartOfStopAreaTest() {
if (!StopUtils.verifyIfMemberOfStopArea(node)) {
List<OsmPrimitive> primitives = new ArrayList<>(1);
primitives.add(node);
Builder builder = TestError.builder(this.test, Severity.WARNING, PTAssistantValidatorTest.ERROR_CODE_NOT_PART_OF_STOP_AREA);
builder.message(tr("PT: Stop position or platform is not part of a stop area relation"));
builder.primitives(primitives);
TestError e = builder.build();
errors.add(e);
}
}
/**
* Fixes errors: solitary stop position and platform which is part of a way.
* Asks the user first.
*
* @param testError
* test error
* @return fix command
*/
protected static Command fixError(TestError testError) {
if (testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_SOLITARY_STOP_POSITION
&& testError.getCode() != PTAssistantValidatorTest.ERROR_CODE_PLATFORM_PART_OF_HIGHWAY) {
return null;
}
Node problematicNode = (Node) testError.getPrimitives().iterator().next();
final int[] userSelection = { JOptionPane.YES_OPTION };
final TestError errorParameter = testError;
if (SwingUtilities.isEventDispatchThread()) {
userSelection[0] = showFixNodeTagDialog(errorParameter);
} else {
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
userSelection[0] = showFixNodeTagDialog(errorParameter);
}
});
} catch (InvocationTargetException | InterruptedException e) {
e.printStackTrace();
return null;
}
}
if (userSelection[0] == JOptionPane.YES_OPTION) {
Node modifiedNode = new Node(problematicNode);
if (testError.getCode() == PTAssistantValidatorTest.ERROR_CODE_SOLITARY_STOP_POSITION) {
modifiedNode.put("public_transport", "platform");
ChangeCommand command = new ChangeCommand(problematicNode, modifiedNode);
return command;
} else {
modifiedNode.put("public_transport", "stop_position");
ChangeCommand command = new ChangeCommand(problematicNode, modifiedNode);
return command;
}
}
return null;
}
private static int showFixNodeTagDialog(TestError e) {
Node problematicNode = (Node) e.getPrimitives().iterator().next();
// Main.map.mapView.zoomTo(problematicNode.getCoor());
// zoom to problem:
Collection<OsmPrimitive> primitives = new ArrayList<>(1);
primitives.add(problematicNode);
AutoScaleAction.zoomTo(primitives);
String[] options = { tr("Yes"), tr("No") };
String message;
if (e.getCode() == PTAssistantValidatorTest.ERROR_CODE_SOLITARY_STOP_POSITION) {
message = "Do you want to change the tag public_transport=stop_position to public_transport=platform?";
} else {
message = "Do you want to change the tag public_transport=platform to public_transport=stop_position?";
}
return JOptionPane.showOptionDialog(null, message, tr("PT_Assistant Message"), JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE, null, options, 0);
}
}