Add undo/redo functionality

* Add various commands
pull/1/head
Taylor Smock 2019-09-26 15:09:42 -06:00
rodzic 42109b4533
commit 8da3279198
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 625F6A74A3E4311A
21 zmienionych plików z 998 dodań i 183 usunięć

Wyświetl plik

@ -12,6 +12,11 @@
</attributes>
</classpathentry>
<classpathentry combineaccessrules="false" kind="src" path="/JOSM"/>
<classpathentry kind="lib" path="/JOSM/test/lib/jmockit.jar">
<attributes>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="output" path="build/classes/java/main"/>
</classpath>

Wyświetl plik

@ -121,7 +121,7 @@ junit tests:
- ./gradlew test
artifacts:
reports:
junit: build/test-results/test/**/TEST-*.xml
junit: build/test-results/test/TEST-*.xml
################
# Deploy stage #

Wyświetl plik

@ -42,10 +42,12 @@ def versions = [
pmd: "6.6.0",
spotbugs: "3.1.12",
wiremock: "2.24.1",
jmockit: "1.48",
]
repositories {
jcenter()
mavenCentral()
}
dependencies {
if (!JavaVersion.current().isJava9Compatible()) {
@ -56,10 +58,12 @@ dependencies {
testImplementation("org.junit.jupiter:junit-jupiter-api:${versions.junit}")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${versions.junit}")
testImplementation("org.junit.vintage:junit-vintage-engine:${versions.junit}")
testCompile("org.jmockit:jmockit:${versions.jmockit}")
testImplementation("com.github.spotbugs:spotbugs-annotations:${versions.spotbugs}")
testImplementation("org.openstreetmap.josm:josm-unittest:"){changing=true}
testImplementation("com.github.tomakehurst:wiremock:${versions.wiremock}")
testImplementation("org.awaitility:awaitility:${versions.awaitility}")
testCompile("org.jmockit:jmockit:${versions.jmockit}")
}
// Add dependencies from ivy.xml
@ -75,6 +79,12 @@ test {
testLogging.exceptionFormat = 'full'
}
tasks.getByName("test") {
project.afterEvaluate {
jvmArgs("-javaagent:${classpath.find { it.name.contains("jmockit") }.absolutePath}")
}
}
sourceSets {
test {
java {

Wyświetl plik

@ -0,0 +1,58 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.rapid.backend;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.util.Arrays;
import java.util.Collection;
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.Way;
public class AddNodeToWayCommand extends Command {
private final Node toAddNode;
private final Way way;
private final Node first;
private final Node second;
/**
* Add a node to a way in an undoable manner
*
* @param toAddNode The node to add
* @param way The way to add the node to
* @param first The node that comes before the node to add
* @param second The node that comes after the node to add
*/
public AddNodeToWayCommand(Node toAddNode, Way way, Node first, Node second) {
super(way.getDataSet());
this.toAddNode = toAddNode;
this.way = way;
this.first = first;
this.second = second;
}
@Override
public boolean executeCommand() {
int index = Math.max(way.getNodes().indexOf(first), way.getNodes().indexOf(second));
way.addNode(index, toAddNode);
return true;
}
@Override
public void undoCommand() {
way.removeNode(toAddNode);
}
@Override
public String getDescriptionText() {
return tr("Add node to way");
}
@Override
public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
Collection<OsmPrimitive> added) {
modified.addAll(Arrays.asList(toAddNode, way));
}
}

Wyświetl plik

@ -0,0 +1,111 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.rapid.backend;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.util.ArrayList;
import java.util.Collection;
import java.util.stream.Collectors;
import org.openstreetmap.josm.command.Command;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.data.osm.OsmPrimitive;
import org.openstreetmap.josm.data.osm.Relation;
import org.openstreetmap.josm.data.osm.Way;
import org.openstreetmap.josm.tools.Utils;
public class AddPrimitivesCommand extends Command {
private final Collection<OsmPrimitive> add;
private final Collection<OsmPrimitive> actuallyAdded;
private final Collection<OsmPrimitive> selection;
/**
* Add source primitives (not {@code PrimitiveData}) to a dataset.
*
* @param data The destination dataset
* @param add The primitives to add. It must be complete.
* @param selection The primitives to select in the dataset. May be null.
*/
public AddPrimitivesCommand(DataSet data, Collection<OsmPrimitive> add, Collection<OsmPrimitive> selection) {
super(data);
this.add = add;
this.selection = selection;
actuallyAdded = new ArrayList<>();
}
@Override
public boolean executeCommand() {
actuallyAdded.addAll(addPrimitives(getAffectedDataSet(), add));
if (selection != null) {
getAffectedDataSet().setSelected(selection);
}
return true;
}
@Override
public void undoCommand() {
DataSet ds = getAffectedDataSet();
Utils.filteredCollection(actuallyAdded, Relation.class).stream().filter(ds::containsRelation)
.forEach(ds::removePrimitive);
Utils.filteredCollection(actuallyAdded, Way.class).stream().filter(ds::containsWay)
.forEach(ds::removePrimitive);
Utils.filteredCollection(actuallyAdded, Node.class).stream().filter(ds::containsNode)
.forEach(ds::removePrimitive);
}
/**
* Add primitives to a dataset
*
* @param ds The dataset to add primitives to
* @param primitives A collection of primitives to add
* @return The primitives actually added
*/
public static Collection<OsmPrimitive> addPrimitives(DataSet ds, Collection<OsmPrimitive> primitives) {
Collection<OsmPrimitive> returnCollection = new ArrayList<>();
returnCollection.addAll(addRelations(ds, Utils.filteredCollection(primitives, Relation.class)));
returnCollection.addAll(addWays(ds, Utils.filteredCollection(primitives, Way.class)));
returnCollection.addAll(addNodes(ds, Utils.filteredCollection(primitives, Node.class)));
return returnCollection;
}
private static Collection<OsmPrimitive> addNodes(DataSet ds, Collection<Node> nodes) {
Collection<OsmPrimitive> toAdd = nodes.stream().filter(node -> node.getDataSet() == null)
.collect(Collectors.toList());
toAdd.stream().forEach(ds::addPrimitive);
return toAdd;
}
private static Collection<OsmPrimitive> addWays(DataSet ds, Collection<Way> ways) {
Collection<OsmPrimitive> toAdd = new ArrayList<>();
ways.stream().map(Way::getNodes).forEach(list -> toAdd.addAll(addNodes(ds, list)));
ways.stream()
.filter(way -> way.getDataSet() == null
&& way.getNodes().stream().filter(node -> node.getDataSet() != ds).count() == 0)
.forEach(way -> {
ds.addPrimitive(way);
toAdd.add(way);
});
return toAdd;
}
// This might break with relations. TODO (not needed right now)
private static Collection<OsmPrimitive> addRelations(DataSet ds, Collection<Relation> relations) {
Collection<OsmPrimitive> toAdd = relations.stream().filter(relation -> relation.getDataSet() != null)
.collect(Collectors.toList());
toAdd.forEach(ds::addPrimitive);
return toAdd;
}
@Override
public String getDescriptionText() {
return tr("Add OSM Primitives to a dataset");
}
@Override
public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
Collection<OsmPrimitive> added) {
added.addAll(actuallyAdded);
}
}

Wyświetl plik

@ -0,0 +1,147 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.rapid.backend;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.openstreetmap.josm.actions.MergeNodesAction;
import org.openstreetmap.josm.command.ChangePropertyCommand;
import org.openstreetmap.josm.command.Command;
import org.openstreetmap.josm.command.SequenceCommand;
import org.openstreetmap.josm.data.osm.DataSet;
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.plugins.rapid.RapiDPlugin;
import org.openstreetmap.josm.tools.Logging;
import org.openstreetmap.josm.tools.Utils;
public class CreateConnectionsCommand extends Command {
private final Collection<OsmPrimitive> primitives;
public final static String DUPE_KEY = "dupe";
public final static String CONN_KEY = "conn";
private Command command = null;
public CreateConnectionsCommand(DataSet data, Collection<OsmPrimitive> primitives) {
super(data);
this.primitives = primitives;
}
@Override
public boolean executeCommand() {
command = createConnections(getAffectedDataSet(), primitives);
if (command != null) {
command.executeCommand();
}
return true;
}
@Override
public void undoCommand() {
if (command != null) {
command.undoCommand();
}
}
/**
* Create connections based off of current RapiD syntax
*
* @param dataSet The {@link DataSet} that should have the primitives we are
* connecting to
* @param collection The primitives with connection information (currently only
* checks Nodes)
* @return
*/
public SequenceCommand createConnections(DataSet dataSet, Collection<OsmPrimitive> collection) {
Collection<Node> nodes = Utils.filteredCollection(collection, Node.class);
List<Command> changedKeyList = new ArrayList<>();
for (Node node : nodes) {
if (node.hasKey(CONN_KEY)) {
// Currently w<way id>,n<node1>,n<node2>
OsmPrimitive[] primitiveConnections = getPrimitives(dataSet, node.get(CONN_KEY));
for (int i = 0; i < primitiveConnections.length / 3; i++) {
if (primitiveConnections[i] instanceof Way && primitiveConnections[i + 1] instanceof Node
&& primitiveConnections[i + 2] instanceof Node) {
changedKeyList.add(addNodesToWay(node, (Way) primitiveConnections[i],
(Node) primitiveConnections[i + 1], (Node) primitiveConnections[i + 2]));
} else {
Logging.error("{0}: {1}, {2}: {3}, {4}: {5}", i, primitiveConnections[i].getClass(), i + 1,
primitiveConnections[i + 1].getClass(), i + 2, primitiveConnections[i + 2].getClass());
}
}
Logging.debug("RapiD: Removing conn from {0} in {1}", node, dataSet.getName());
changedKeyList.add(new ChangePropertyCommand(node, CONN_KEY, null));
}
if (node.hasKey(DUPE_KEY)) {
OsmPrimitive[] primitiveConnections = getPrimitives(dataSet, node.get(DUPE_KEY));
if (primitiveConnections.length != 1) {
Logging.error("RapiD: dupe connection connected to more than one node? (dupe={0})",
node.get(DUPE_KEY));
}
changedKeyList.add(replaceNode(node, (Node) primitiveConnections[0]));
}
}
if (!changedKeyList.isEmpty())
return new SequenceCommand(getDescriptionText(), changedKeyList);
return null;
}
/**
* Get the primitives from a dataset with specified ids
*
* @param dataSet The dataset holding the primitives (hopefully)
* @param ids The ids formated like n<NUMBER>,r<NUMBER>,w<NUMBER>
* @return The primitives that the ids point to, if in the dataset.
*/
private static OsmPrimitive[] getPrimitives(DataSet dataSet, String ids) {
String[] connections = ids.split(",", -1);
OsmPrimitive[] primitiveConnections = new OsmPrimitive[connections.length];
for (int i = 0; i < connections.length; i++) {
String member = connections[i];
long id = Long.parseLong(member.substring(1));
char firstChar = member.charAt(0);
if (firstChar == 'w') {
primitiveConnections[i] = dataSet.getPrimitiveById(id, OsmPrimitiveType.WAY);
} else if (firstChar == 'n') {
primitiveConnections[i] = dataSet.getPrimitiveById(id, OsmPrimitiveType.NODE);
} else if (firstChar == 'r') {
primitiveConnections[i] = dataSet.getPrimitiveById(id, OsmPrimitiveType.RELATION);
}
}
return primitiveConnections;
}
/**
* Add a node to a way
*
* @param toAddNode The node to add
* @param way The way to add the node to
* @param first The first node in a waysegment (the node is between this and
* the second node)
* @param second The second node in a waysegemnt
*/
public static Command addNodesToWay(Node toAddNode, Way way, Node first, Node second) {
return new AddNodeToWayCommand(toAddNode, way, first, second);
}
public static Command replaceNode(Node original, Node newNode) {
return MergeNodesAction.mergeNodes(Arrays.asList(original), newNode, newNode);
}
@Override
public String getDescriptionText() {
return tr("Create connections from {0} data", RapiDPlugin.NAME);
}
@Override
public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
Collection<OsmPrimitive> added) {
// Don't touch the collectioins, since we haven't modified anything -- the
// subcommands should do that.
}
}

Wyświetl plik

@ -0,0 +1,102 @@
package org.openstreetmap.josm.plugins.rapid.backend;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.openstreetmap.josm.command.Command;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.data.osm.OsmPrimitive;
import org.openstreetmap.josm.data.osm.Way;
public class DeletePrimitivesCommand extends Command {
private final Collection<OsmPrimitive> selection;
private final DataSet from;
private final Collection<OsmPrimitive> removed;
private final Collection<Command> commands;
private final boolean deleteChildren;
/**
* Delete primitives from a DataSet
*
* @param from The {@link DataSet} to remove primitives from
* @param selection The primitives to remove
*/
public DeletePrimitivesCommand(DataSet from, Collection<OsmPrimitive> selection) {
this(from, selection, false);
}
/**
* Delete primitives from a DataSet
*
* @param from The {@link DataSet} to remove primitives from
* @param selection The primitives to remove
* @param removeAll {@code true} if all children should be removed (for ways).
*/
public DeletePrimitivesCommand(DataSet from, Collection<OsmPrimitive> selection, boolean removeAll) {
super(from);
this.from = from;
this.selection = selection;
commands = new ArrayList<>();
removed = new ArrayList<>();
this.deleteChildren = removeAll;
}
@Override
public boolean executeCommand() {
for (OsmPrimitive primitive : selection) {
DataSet dataSet = primitive.getDataSet();
if (from.equals(dataSet)) {
dataSet.removePrimitive(primitive);
removed.add(primitive);
}
if (primitive instanceof Way) {
List<OsmPrimitive> nodes = ((Way) primitive).getNodes().stream()
.filter(node -> (!node.hasKeys() || deleteChildren) && !selection.contains(node))
.collect(Collectors.toList());
DeletePrimitivesCommand delNodes = new DeletePrimitivesCommand(from, nodes);
delNodes.executeCommand();
commands.add(delNodes);
}
}
return true;
}
@Override
public void undoCommand() {
for (Command command : commands) {
command.undoCommand();
}
for (OsmPrimitive primitive : removed) {
DataSet removedPrimitiveDataSet = primitive.getDataSet();
if (removedPrimitiveDataSet != null) {
removedPrimitiveDataSet.removePrimitive(primitive);
}
if (primitive instanceof Way) {
for (Node node : ((Way) primitive).getNodes()) {
if (node.getDataSet() == null) {
from.addPrimitive(node);
}
}
}
from.addPrimitive(primitive);
}
}
@Override
public String getDescriptionText() {
return tr("Remove primitives from data set");
}
@Override
public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
Collection<OsmPrimitive> added) {
deleted.addAll(removed);
}
}

Wyświetl plik

@ -0,0 +1,86 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.rapid.backend;
import static org.openstreetmap.josm.tools.I18n.tr;
import static org.openstreetmap.josm.tools.I18n.trn;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.openstreetmap.josm.command.Command;
import org.openstreetmap.josm.command.SequenceCommand;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.OsmPrimitive;
import org.openstreetmap.josm.plugins.rapid.RapiDPlugin;
import org.openstreetmap.josm.tools.Logging;
/**
* Move primitives between datasets (*not* a copy)
*
* @author Taylor Smock
*/
public class MovePrimitiveDataSetCommand extends Command {
private final DataSet to;
private final DataSet from;
private final Collection<OsmPrimitive> primitives;
private SequenceCommand command;
List<Command> commands;
public MovePrimitiveDataSetCommand(DataSet to, DataSet from, Collection<OsmPrimitive> primitives) {
super(to);
this.to = to;
this.from = from;
this.primitives = primitives;
command = null;
commands = new ArrayList<>();
}
@Override
public boolean executeCommand() {
if (to.equals(from))
return false;
command = moveCollection(from, to, primitives);
command.executeCommand();
return true;
}
/**
* Move primitives from one dataset to another
*
* @param to The receiving dataset
* @param from The sending dataset
* @param selection The primitives to move
*/
public SequenceCommand moveCollection(DataSet from, DataSet to, Collection<OsmPrimitive> selection) {
if (from == null || to.isLocked() || from.isLocked()) {
Logging.error("{0}: Cannot move primitives from {1} to {2}", RapiDPlugin.NAME, from, to);
return null;
}
Collection<OsmPrimitive> allNeededPrimitives = new ArrayList<>();
RapiDDataUtils.addPrimitivesToCollection(allNeededPrimitives, selection);
commands.add(new DeletePrimitivesCommand(from, selection, true));
AddPrimitivesCommand addPrimitivesCommand = new AddPrimitivesCommand(to, allNeededPrimitives, selection);
commands.add(addPrimitivesCommand);
return new SequenceCommand(trn("Move {0} OSM Primitive between data sets",
"Move {0} OSM Primitives between data sets", selection.size(), selection.size()), commands);
}
@Override
public void undoCommand() {
command.undoCommand();
}
@Override
public String getDescriptionText() {
return tr("Move OsmPrimitives between layers");
}
@Override
public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
Collection<OsmPrimitive> added) {
modified.addAll(primitives);
}
}

Wyświetl plik

@ -39,10 +39,10 @@ public class RapiDAction extends JosmAction {
* @return A RapiDLayer, or a new RapiDLayer if none exist. May return
* {@code null} if {@code create} is {@code false}.
*/
public RapiDLayer getLayer(boolean create) {
public static RapiDLayer getLayer(boolean create) {
final List<RapiDLayer> rapidLayers = MainApplication.getLayerManager().getLayersOfType(RapiDLayer.class);
RapiDLayer layer;
synchronized (this) {
synchronized (layerLock) {
if (rapidLayers.isEmpty() && create) {
layer = new RapiDLayer(new DataSet(), RapiDPlugin.NAME, null);
MainApplication.getLayerManager().addLayer(layer);
@ -60,7 +60,7 @@ public class RapiDAction extends JosmAction {
*
* @param layer The {@link RapiDLayer} to add data to
*/
public void getRapiDData(RapiDLayer layer) {
public static void getRapiDData(RapiDLayer layer) {
final List<OsmDataLayer> osmLayers = MainApplication.getLayerManager().getLayersOfType(OsmDataLayer.class);
for (final OsmDataLayer osmLayer : osmLayers) {
if (!osmLayer.isLocked()) {
@ -75,13 +75,18 @@ public class RapiDAction extends JosmAction {
* @param layer A pre-existing {@link RapiDLayer}
* @param osmLayer The osm datalayer with a set of bounds
*/
public void getRapiDData(RapiDLayer layer, OsmDataLayer osmLayer) {
public static void getRapiDData(RapiDLayer layer, OsmDataLayer osmLayer) {
final DataSet editSet = osmLayer.getDataSet();
final List<Bounds> editSetBounds = editSet.getDataSourceBounds();
final DataSet rapidSet = layer.getDataSet();
final List<Bounds> rapidBounds = rapidSet.getDataSourceBounds();
for (final Bounds bound : editSetBounds) {
if (!rapidBounds.contains(bound)) {
for (final Bounds rapidBound : rapidBounds) {
if (bound.equals(rapidBound)) {
continue;
}
}
if (rapidBounds.parallelStream().filter(bound::equals).count() == 0) {
final DataSet newData = RapiDDataUtils.getData(bound.toBBox());
/* Microsoft buildings don't have a source, so we add one */
RapiDDataUtils.addSourceTags(newData, "building", "Microsoft");
@ -96,10 +101,6 @@ public class RapiDAction extends JosmAction {
@Override
protected void updateEnabledState() {
if (getLayerManager().getEditDataSet() == null) {
setEnabled(false);
} else {
setEnabled(true);
}
setEnabled(getLayerManager().getEditDataSet() != null);
}
}

Wyświetl plik

@ -3,38 +3,23 @@ package org.openstreetmap.josm.plugins.rapid.backend;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;
import org.openstreetmap.josm.command.AddPrimitivesCommand;
import org.openstreetmap.josm.command.Command;
import org.openstreetmap.josm.command.SequenceCommand;
import org.openstreetmap.josm.data.osm.DataSet;
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.PrimitiveData;
import org.openstreetmap.josm.data.osm.Relation;
import org.openstreetmap.josm.data.osm.RelationMember;
import org.openstreetmap.josm.data.osm.Way;
import org.openstreetmap.josm.data.osm.visitor.MergeSourceBuildingVisitor;
import org.openstreetmap.josm.gui.MainApplication;
import org.openstreetmap.josm.gui.layer.OsmDataLayer;
import org.openstreetmap.josm.plugins.rapid.RapiDPlugin;
import org.openstreetmap.josm.tools.Logging;
import org.openstreetmap.josm.tools.Pair;
import org.openstreetmap.josm.tools.Utils;
public class RapiDAddCommand extends Command {
DataSet editable;
DataSet rapid;
Collection<OsmPrimitive> primitives;
AddPrimitivesCommand addPrimitivesCommand;
Collection<OsmPrimitive> modifiedPrimitives;
Command command = null;
OsmDataLayer editLayer = null;
@ -72,16 +57,18 @@ public class RapiDAddCommand extends Command {
primitives = new HashSet<>(primitives);
RapiDDataUtils.addPrimitivesToCollection(/* collection= */ primitives, /* primitives= */ primitives);
synchronized (this) {
rapid.unlock();
Collection<OsmPrimitive> newPrimitives = new TreeSet<>(moveCollection(rapid, editable, primitives));
createConnections(editable, newPrimitives);
RapiDDataUtils.removePrimitivesFromDataSet(primitives);
rapid.lock();
}
if (editLayer != null && RapiDDataUtils.getSwitchLayers()) {
MainApplication.getLayerManager().setActiveLayer(editLayer);
editable.setSelected(
editable.getSelected().stream().filter(OsmPrimitive::isTagged).collect(Collectors.toSet()));
boolean locked = rapid.isLocked();
if (locked) {
rapid.unlock();
}
Command tCommand = new MovePrimitiveDataSetCommand(editable, rapid, primitives);
Command createConnectionsCommand = createConnections(editable, primitives);
command = new SequenceCommand(getDescriptionText(), tCommand, createConnectionsCommand);
command.executeCommand();
if (locked) {
rapid.lock();
}
}
return true;
}
@ -94,134 +81,22 @@ public class RapiDAddCommand extends Command {
* @param collection The primitives with connection information (currently only
* checks Nodes)
*/
public static void createConnections(DataSet dataSet, Collection<OsmPrimitive> collection) {
Collection<Node> nodes = Utils.filteredCollection(collection, Node.class);
for (Node node : nodes) {
if (node.hasKey("conn")) {
// Currently w<way id>,n<node1>,n<node2>
OsmPrimitive[] primitiveConnections = getPrimitives(dataSet, node.get("conn"));
for (int i = 0; i < primitiveConnections.length / 3; i++) {
if (primitiveConnections[i] instanceof Way && primitiveConnections[i + 1] instanceof Node
&& primitiveConnections[i + 2] instanceof Node) {
addNodesToWay(node, (Way) primitiveConnections[i], (Node) primitiveConnections[i + 1],
(Node) primitiveConnections[i + 2]);
} else {
Logging.error("{0}: {1}, {2}: {3}, {4}: {5}", i, primitiveConnections[i].getClass(), i + 1,
primitiveConnections[i + 1].getClass(), i + 2, primitiveConnections[i + 2].getClass());
}
}
Logging.debug("RapiD: Removing conn from {0} in {1}", node, dataSet.getName());
node.remove("conn");
}
if (node.hasKey("dupe")) {
OsmPrimitive[] primitiveConnections = getPrimitives(dataSet, node.get("dupe"));
if (primitiveConnections.length != 1) {
Logging.error("RapiD: dupe connection connected to more than one node? (dupe={0})",
node.get("dupe"));
}
replaceNode(node, (Node) primitiveConnections[0]);
}
}
public static Command createConnections(DataSet dataSet, Collection<OsmPrimitive> collection) {
return new CreateConnectionsCommand(dataSet, collection);
}
/**
* Get the primitives from a dataset with specified ids
*
* @param dataSet The dataset holding the primitives (hopefully)
* @param ids The ids formated like n<NUMBER>,r<NUMBER>,w<NUMBER>
* @return The primitives that the ids point to, if in the dataset.
*/
private static OsmPrimitive[] getPrimitives(DataSet dataSet, String ids) {
String[] connections = ids.split(",", -1);
OsmPrimitive[] primitiveConnections = new OsmPrimitive[connections.length];
for (int i = 0; i < connections.length; i++) {
String member = connections[i];
long id = Long.parseLong(member.substring(1));
char firstChar = member.charAt(0);
if (firstChar == 'w') {
primitiveConnections[i] = dataSet.getPrimitiveById(id, OsmPrimitiveType.WAY);
} else if (firstChar == 'n') {
primitiveConnections[i] = dataSet.getPrimitiveById(id, OsmPrimitiveType.NODE);
} else if (firstChar == 'r') {
primitiveConnections[i] = dataSet.getPrimitiveById(id, OsmPrimitiveType.RELATION);
}
@Override
public void undoCommand() {
boolean locked = rapid.isLocked();
if (locked) {
rapid.unlock();
}
return primitiveConnections;
}
/**
* Add a node to a way
*
* @param toAddNode The node to add
* @param way The way to add the node to
* @param first The first node in a waysegment (the node is between this and
* the second node)
* @param second The second node in a waysegemnt
*/
public static void addNodesToWay(Node toAddNode, Way way, Node first, Node second) {
int index = Math.max(way.getNodes().indexOf(first), way.getNodes().indexOf(second));
way.addNode(index, toAddNode);
}
public static void replaceNode(Node original, Node newNode) {
for (OsmPrimitive primitive : original.getReferrers()) {
if (primitive instanceof Way) {
Way way = (Way) primitive;
List<Integer> indexes = new ArrayList<>();
List<Node> nodes = way.getNodes();
for (int i = 0; i < nodes.size(); i++) {
if (nodes.get(i).equals(original)) {
indexes.add(i);
}
}
while (way.getNodes().contains(original)) {
way.removeNode(original);
}
for (int index : indexes) {
way.addNode(index, newNode);
}
} else if (primitive instanceof Relation) {
List<Pair<Integer, RelationMember>> replaceMembers = new ArrayList<>();
Relation relation = (Relation) primitive;
List<RelationMember> relationMembers = relation.getMembers();
for (int i = 0; i < relationMembers.size(); i++) {
RelationMember member = relationMembers.get(i);
if (member.getMember().equals(original)) {
replaceMembers.add(new Pair<>(i, new RelationMember(member.getRole(), newNode)));
}
}
relation.removeMembersFor(original);
for (Pair<Integer, RelationMember> pair : replaceMembers) {
relation.addMember(pair.a, pair.b);
}
}
if (command != null) {
command.undoCommand();
}
original.getDataSet().removePrimitive(original);
}
/**
* Move primitives from one dataset to another
*
* @param to The receiving dataset
* @param from The sending dataset
* @param selection The primitives to move
* @return true if the primitives have moved datasets
*/
public Collection<? extends OsmPrimitive> moveCollection(DataSet from, DataSet to,
Collection<OsmPrimitive> selection) {
if (from == null || to.isLocked() || from.isLocked()) {
Logging.error("RapiD: Cannot move primitives from {0} to {1}", from, to);
return Collections.emptySet();
if (locked) {
rapid.lock();
}
Collection<OsmPrimitive> originalSelection = from.getSelected();
from.setSelected(selection);
MergeSourceBuildingVisitor mergeBuilder = new MergeSourceBuildingVisitor(from);
List<PrimitiveData> primitiveDataList = mergeBuilder.build().allPrimitives().stream().map(OsmPrimitive::save)
.collect(Collectors.toList());
from.setSelected(originalSelection);
addPrimitivesCommand = new AddPrimitivesCommand(primitiveDataList, primitiveDataList, to);
addPrimitivesCommand.executeCommand();
return addPrimitivesCommand.getParticipatingPrimitives();
}
@Override
@ -232,7 +107,6 @@ public class RapiDAddCommand extends Command {
@Override
public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
Collection<OsmPrimitive> added) {
// TODO Auto-generated method stub
modified.addAll(primitives);
}
}

Wyświetl plik

@ -35,7 +35,7 @@ import org.openstreetmap.josm.tools.Logging;
*
*/
public final class RapiDDataUtils {
public static final String DEFAULT_RAPID_API = "https://www.facebook.com/maps/ml_roads?conflate_with_osm=true&theme=ml_road_vector&collaborator=fbid&token=ASZUVdYpCkd3M6ZrzjXdQzHulqRMnxdlkeBJWEKOeTUoY_Gwm9fuEd2YObLrClgDB_xfavizBsh0oDfTWTF7Zb4C&hash=ASYM8LPNy8k1XoJiI7A&result_type=road_building_vector_xml&bbox={bbox}";
public static final String DEFAULT_RAPID_API = "https://www.facebook.com/maps/ml_roads?conflate_with_osm=true&theme=ml_road_vector&collaborator=fbid&token=ASZUVdYpCkd3M6ZrzjXdQzHulqRMnxdlkeBJWEKOeTUoY_Gwm9fuEd2YObLrClgDB_xfavizBsh0oDfTWTF7Zb4C&hash=ASYM8LPNy8k1XoJiI7A&result_type=road_building_vector_xml&bbox={bbox}&crop_bbox={bbox}";
private RapiDDataUtils() {
// Hide the constructor

Wyświetl plik

@ -21,6 +21,7 @@ public class RapiDLayer extends OsmDataLayer {
public RapiDLayer(DataSet data, String name, File associatedFile) {
super(data, name, associatedFile);
this.lock();
this.setUploadDiscouraged(true);
}
// @Override only JOSM > 15323

Wyświetl plik

@ -6,9 +6,11 @@ import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.openstreetmap.josm.actions.JosmAction;
import org.openstreetmap.josm.data.UndoRedoHandler;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.OsmPrimitive;
import org.openstreetmap.josm.gui.MainApplication;
import org.openstreetmap.josm.gui.layer.Layer;
@ -41,6 +43,12 @@ public class RapiDMoveAction extends JosmAction {
if (editLayer != null) {
RapiDAddCommand command = new RapiDAddCommand(rapid, editLayer, selected);
UndoRedoHandler.getInstance().add(command);
if (RapiDDataUtils.getSwitchLayers()) {
MainApplication.getLayerManager().setActiveLayer(editLayer);
DataSet editable = editLayer.getDataSet();
editable.setSelected(
editable.getSelected().stream().filter(OsmPrimitive::isTagged).collect(Collectors.toSet()));
}
}
}
}

Wyświetl plik

@ -38,24 +38,19 @@ public class RapiDDataUtilsTest {
@Test
public void testAddSourceTags() {
BBox testBBox = getTestBBox();
DataSet ds = new DataSet(RapiDDataUtils.getData(testBBox));
Assert.assertEquals(1, ds.getWays().size());
Way way1 = (Way) ds.getWays().toArray()[0];
String originalSource = way1.get("source");
Assert.assertNotNull(originalSource);
Way way1 = TestUtils.newWay("highway=residential", new Node(new LatLon(0, 0)), new Node(new LatLon(0.1, 0.1)));
DataSet ds = new DataSet(way1.firstNode(), way1.lastNode(), way1);
String source = "random source";
way1.remove("source");
Assert.assertNull(way1.get("source"));
RapiDDataUtils.addSourceTags(ds, "highway", originalSource);
Assert.assertEquals(originalSource, way1.get("source"));
RapiDDataUtils.addSourceTags(ds, "highway", source);
Assert.assertEquals(source, way1.get("source"));
}
private static BBox getTestBBox() {
public static BBox getTestBBox() {
BBox testBBox = new BBox();
testBBox.add(new LatLon(39.0768984, -108.5462553));
testBBox.add(new LatLon(39.0776276, -108.5452918));
testBBox.add(new LatLon(39.076, -108.547));
testBBox.add(new LatLon(39.078, -108.545));
return testBBox;
}

Wyświetl plik

@ -0,0 +1,66 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.rapid.backend;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.openstreetmap.josm.TestUtils;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.data.osm.OsmPrimitive;
import org.openstreetmap.josm.data.osm.Way;
import org.openstreetmap.josm.testutils.JOSMTestRules;;
public class AddNodeToWayCommandTest {
private Node toAdd;
private Way way;
private AddNodeToWayCommand command;
@Rule
public JOSMTestRules test = new JOSMTestRules();
@Before
public void setupArea() {
toAdd = new Node(new LatLon(0.1, 0.1));
way = TestUtils.newWay("", new Node(new LatLon(0, 0)), new Node(new LatLon(-0.1, -0.1)));
new DataSet(toAdd, way.firstNode(), way.lastNode(), way);
command = new AddNodeToWayCommand(toAdd, way, way.firstNode(), way.lastNode());
}
@Test
public void testAddNodeToWay() {
command.executeCommand();
Assert.assertEquals(3, way.getNodesCount());
command.undoCommand();
Assert.assertEquals(2, way.getNodesCount());
command = new AddNodeToWayCommand(toAdd, way, way.lastNode(), way.firstNode());
command.executeCommand();
Assert.assertEquals(3, way.getNodesCount());
command.undoCommand();
Assert.assertEquals(2, way.getNodesCount());
}
@Test
public void testDescription() {
Assert.assertNotNull(command.getDescriptionText());
}
@Test
public void testModifiedAddedDeleted() {
List<OsmPrimitive> added = new ArrayList<>();
List<OsmPrimitive> modified = new ArrayList<>();
List<OsmPrimitive> deleted = new ArrayList<>();
command.fillModifiedData(modified, deleted, added);
Assert.assertTrue(deleted.isEmpty());
Assert.assertTrue(added.isEmpty());
Assert.assertEquals(2, modified.size());
}
}

Wyświetl plik

@ -0,0 +1,66 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.rapid.backend;
import java.util.Collection;
import java.util.Collections;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.openstreetmap.josm.TestUtils;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.data.osm.OsmPrimitive;
import org.openstreetmap.josm.data.osm.Way;
import org.openstreetmap.josm.testutils.JOSMTestRules;
public class AddPrimitivesCommandTest {
@Rule
public JOSMTestRules test = new JOSMTestRules();
@Test
public void testAddPrimitives() {
DataSet dataSet = new DataSet();
Way way1 = TestUtils.newWay("highway=secondary", new Node(new LatLon(0, 0)), new Node(new LatLon(0.1, 0.1)));
Assert.assertNull(way1.getDataSet());
Collection<OsmPrimitive> added = AddPrimitivesCommand.addPrimitives(dataSet, Collections.singleton(way1));
Assert.assertEquals(3, added.size());
Assert.assertSame(dataSet, way1.getDataSet());
}
@SuppressWarnings("UndefinedEquals")
@Test
public void testUndoRedo() {
DataSet dataSet = new DataSet();
Way way1 = TestUtils.newWay("highway=secondary", new Node(new LatLon(0, 0)), new Node(new LatLon(0.1, -0.1)));
AddPrimitivesCommand command = new AddPrimitivesCommand(dataSet, Collections.singleton(way1), null);
Collection<OsmPrimitive> selection = dataSet.getAllSelected();
Assert.assertNull(way1.getDataSet());
command.executeCommand();
Assert.assertSame(dataSet, way1.getDataSet());
Assert.assertEquals(selection, dataSet.getAllSelected());
command.undoCommand();
Assert.assertNull(way1.getDataSet());
Assert.assertEquals(selection, dataSet.getAllSelected());
command.executeCommand();
Assert.assertSame(dataSet, way1.getDataSet());
Assert.assertEquals(selection, dataSet.getAllSelected());
command.undoCommand();
command = new AddPrimitivesCommand(dataSet, Collections.singleton(way1), Collections.singleton(way1));
command.executeCommand();
Assert.assertSame(dataSet, way1.getDataSet());
Assert.assertNotEquals(selection, dataSet.getAllSelected());
command.undoCommand();
Assert.assertNull(way1.getDataSet());
Assert.assertEquals(selection, dataSet.getAllSelected());
}
}

Wyświetl plik

@ -0,0 +1,71 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.rapid.backend;
import java.util.Collections;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.openstreetmap.josm.TestUtils;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.data.osm.Way;
import org.openstreetmap.josm.testutils.JOSMTestRules;
public class DeletePrimitivesCommandTest {
@Rule
public JOSMTestRules test = new JOSMTestRules();
@Test
public void testDeletePrimitives() {
DataSet ds = new DataSet();
Way way1 = TestUtils.newWay("highway=residential", new Node(new LatLon(0, 0)), new Node(new LatLon(-0.1, 0.1)));
way1.getNodes().forEach(node -> ds.addPrimitive(node));
ds.addPrimitive(way1);
Assert.assertTrue(ds.containsWay(way1));
DeletePrimitivesCommand delete = new DeletePrimitivesCommand(ds, Collections.singleton(way1));
delete.executeCommand();
Assert.assertFalse(ds.containsWay(way1));
Assert.assertEquals(0, ds.allPrimitives().size());
delete.undoCommand();
Assert.assertTrue(ds.containsWay(way1));
Assert.assertEquals(3, ds.allPrimitives().size());
Node tNode = new Node(new LatLon(0.1, 0.1));
ds.addPrimitive(tNode);
Assert.assertEquals(4, ds.allPrimitives().size());
delete.executeCommand();
Assert.assertFalse(ds.containsWay(way1));
Assert.assertEquals(1, ds.allPrimitives().size());
delete.undoCommand();
Assert.assertEquals(4, ds.allPrimitives().size());
way1.firstNode().put("highway", "stop");
delete.executeCommand();
Assert.assertFalse(ds.containsWay(way1));
Assert.assertEquals(2, ds.allPrimitives().size());
delete.undoCommand();
Assert.assertTrue(way1.firstNode().hasKey("highway"));
delete = new DeletePrimitivesCommand(ds, Collections.singleton(way1), true);
delete.executeCommand();
Assert.assertFalse(ds.containsWay(way1));
Assert.assertEquals(1, ds.allPrimitives().size());
delete.undoCommand();
Assert.assertEquals(4, ds.allPrimitives().size());
Assert.assertTrue(way1.firstNode().hasKey("highway"));
}
}

Wyświetl plik

@ -0,0 +1,55 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.rapid.backend;
import java.util.Collections;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.openstreetmap.josm.TestUtils;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.data.osm.Way;
import org.openstreetmap.josm.testutils.JOSMTestRules;
public class MovePrimitiveDataSetCommandTest {
@Rule
public JOSMTestRules test = new JOSMTestRules();
@Test
public void testMovePrimitives() {
DataSet to = new DataSet();
DataSet from = new DataSet();
Way way1 = TestUtils.newWay("highway=tertiary", new Node(new LatLon(0, 0)), new Node(new LatLon(0.1, 0.1)));
way1.getNodes().stream().forEach(node -> from.addPrimitive(node));
from.addPrimitive(way1);
from.addPrimitive(new Node(new LatLon(-0.1, 0.1)));
MovePrimitiveDataSetCommand move = new MovePrimitiveDataSetCommand(to, from, Collections.singleton(way1));
Assert.assertEquals(0, to.allPrimitives().size());
Assert.assertEquals(4, from.allPrimitives().size());
move.executeCommand();
Assert.assertEquals(1, from.allPrimitives().size());
Assert.assertEquals(3, to.allPrimitives().size());
Assert.assertEquals(to, way1.getDataSet());
move.undoCommand();
Assert.assertEquals(0, to.allPrimitives().size());
Assert.assertEquals(4, from.allPrimitives().size());
Assert.assertEquals(from, way1.getDataSet());
way1.firstNode().put("highway", "stop");
move.executeCommand();
Assert.assertEquals(1, from.allPrimitives().size());
Assert.assertEquals(3, to.allPrimitives().size());
Assert.assertEquals(to, way1.getDataSet());
move.undoCommand();
Assert.assertEquals(0, to.allPrimitives().size());
Assert.assertEquals(4, from.allPrimitives().size());
Assert.assertEquals(from, way1.getDataSet());
}
}

Wyświetl plik

@ -0,0 +1,61 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.rapid.backend;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.openstreetmap.josm.data.Bounds;
import org.openstreetmap.josm.data.DataSource;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.gui.MainApplication;
import org.openstreetmap.josm.gui.layer.Layer;
import org.openstreetmap.josm.gui.layer.OsmDataLayer;
import org.openstreetmap.josm.testutils.JOSMTestRules;
public class RapiDActionTest {
@Rule
public JOSMTestRules test = new JOSMTestRules().preferences().main().projection();
@Test
public void testGetLayer() {
Layer rapid = RapiDAction.getLayer(false);
Assert.assertNull(rapid);
rapid = RapiDAction.getLayer(true);
Assert.assertEquals(RapiDLayer.class, rapid.getClass());
Layer tRapid = RapiDAction.getLayer(false);
Assert.assertSame(rapid, tRapid);
tRapid = RapiDAction.getLayer(true);
Assert.assertSame(rapid, tRapid);
}
@Test
public void testGetData() {
RapiDLayer rapid = RapiDAction.getLayer(true);
OsmDataLayer osm = new OsmDataLayer(new DataSet(), "test", null);
MainApplication.getLayerManager().addLayer(osm);
RapiDAction.getRapiDData(rapid, osm);
Assert.assertTrue(rapid.getDataSet().getDataSourceBounds().isEmpty());
osm.getDataSet().addDataSource(new DataSource(new Bounds(0, 0, 0.001, 0.001), "random test"));
osm.lock();
RapiDAction.getRapiDData(rapid);
Assert.assertTrue(rapid.getDataSet().getDataSourceBounds().isEmpty());
osm.unlock();
RapiDAction.getRapiDData(rapid);
Assert.assertFalse(rapid.getDataSet().getDataSourceBounds().isEmpty());
Assert.assertEquals(1, rapid.getDataSet().getDataSourceBounds().parallelStream().distinct().count());
osm.getDataSet().addDataSource(new DataSource(new Bounds(-0.001, -0.001, 0, 0), "random test"));
RapiDAction.getRapiDData(rapid);
Assert.assertEquals(2, rapid.getDataSet().getDataSourceBounds().parallelStream().distinct().count());
RapiDAction.getRapiDData(rapid);
Assert.assertEquals(2, rapid.getDataSet().getDataSourceBounds().parallelStream().distinct().count());
}
}

Wyświetl plik

@ -1,5 +1,5 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.rapid;
package org.openstreetmap.josm.plugins.rapid.backend;
import java.util.Arrays;
import java.util.Collections;
@ -11,8 +11,8 @@ import org.openstreetmap.josm.TestUtils;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.data.osm.Tag;
import org.openstreetmap.josm.data.osm.Way;
import org.openstreetmap.josm.plugins.rapid.backend.RapiDAddCommand;
import org.openstreetmap.josm.testutils.JOSMTestRules;
public class RapiDAddComandTest {
@ -55,6 +55,12 @@ public class RapiDAddComandTest {
Assert.assertTrue(ds2.containsNode(way3.firstNode()));
Assert.assertTrue(ds2.containsNode(way3.lastNode()));
Assert.assertFalse(ds1.containsWay(way3));
command.undoCommand();
Assert.assertFalse(ds2.containsWay(way3));
Assert.assertFalse(ds2.containsNode(way3.firstNode()));
Assert.assertFalse(ds2.containsNode(way3.lastNode()));
Assert.assertTrue(ds1.containsWay(way3));
}
@Test
@ -66,12 +72,12 @@ public class RapiDAddComandTest {
way2.firstNode().put("conn",
"w".concat(Long.toString(way1.getUniqueId())).concat(",n")
.concat(Long.toString(way1.firstNode().getUniqueId())).concat(",n")
.concat(Long.toString(way1.lastNode().getUniqueId())));
.concat(Long.toString(way1.lastNode().getUniqueId())));
way1.getNodes().forEach(node -> ds1.addPrimitive(node));
way2.getNodes().forEach(node -> ds1.addPrimitive(node));
ds1.addPrimitive(way2);
ds1.addPrimitive(way1);
RapiDAddCommand.createConnections(ds1, Collections.singletonList(way2.firstNode()));
RapiDAddCommand.createConnections(ds1, Collections.singletonList(way2.firstNode())).executeCommand();
Assert.assertEquals(3, way1.getNodesCount());
Assert.assertFalse(way1.isFirstLastNode(way2.firstNode()));
@ -81,9 +87,45 @@ public class RapiDAddComandTest {
way3.getNodes().forEach(node -> ds1.addPrimitive(node));
ds1.addPrimitive(way3);
Node way3Node1 = way3.firstNode();
RapiDAddCommand.createConnections(ds1, Collections.singletonList(way3.firstNode()));
RapiDAddCommand.createConnections(ds1, Collections.singletonList(way3.firstNode())).executeCommand();
Assert.assertNotEquals(way3Node1, way3.firstNode());
Assert.assertEquals(way1.firstNode(), way3.firstNode());
Assert.assertFalse(ds1.containsNode(way3Node1));
Assert.assertTrue(way3Node1.isDeleted());
}
@Test
public void testCreateConnectionsUndo() {
DataSet osmData = new DataSet();
DataSet rapidData = new DataSet();
Way way1 = TestUtils.newWay("highway=residential", new Node(new LatLon(0, 0)), new Node(new LatLon(0.1, 0.1)));
Way way2 = TestUtils.newWay("highway=residential", new Node(new LatLon(-0.1, -0.1)),
new Node(new LatLon(0.1, 0.1)));
way1.getNodes().forEach(node -> rapidData.addPrimitive(node));
way2.getNodes().forEach(node -> osmData.addPrimitive(node));
osmData.addPrimitive(way2);
rapidData.addPrimitive(way1);
rapidData.setSelected(way1);
Assert.assertEquals(3, osmData.allPrimitives().size());
Assert.assertEquals(3, rapidData.allPrimitives().size());
RapiDAddCommand command = new RapiDAddCommand(rapidData, osmData, rapidData.getSelected());
command.executeCommand();
Assert.assertEquals(6, osmData.allPrimitives().size());
Assert.assertTrue(rapidData.allPrimitives().isEmpty());
command.undoCommand();
Assert.assertEquals(3, osmData.allPrimitives().size());
Assert.assertEquals(3, rapidData.allPrimitives().size());
Tag dupe = new Tag("dupe", "n".concat(Long.toString(way2.lastNode().getUniqueId())));
way1.lastNode().put(dupe);
command.executeCommand();
Assert.assertEquals(6, osmData.allPrimitives().size());
Assert.assertTrue(rapidData.allPrimitives().isEmpty());
command.undoCommand();
Assert.assertEquals(3, osmData.allPrimitives().size());
Assert.assertEquals(3, rapidData.allPrimitives().size());
}
}

Wyświetl plik

@ -0,0 +1,56 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.rapid.backend;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.openstreetmap.josm.TestUtils;
import org.openstreetmap.josm.data.UndoRedoHandler;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.data.osm.Way;
import org.openstreetmap.josm.gui.MainApplication;
import org.openstreetmap.josm.gui.layer.OsmDataLayer;
import org.openstreetmap.josm.plugins.rapid.RapiDDataUtilsTest;
import org.openstreetmap.josm.testutils.JOSMTestRules;
public class RapiDMoveActionTest {
RapiDMoveAction moveAction;
@Rule
public JOSMTestRules test = new JOSMTestRules().preferences().main().projection();
@Before
public void setup() {
moveAction = new RapiDMoveAction();
}
@Test
public void testMoveAction() {
DataSet osmData = new DataSet();
DataSet rapidData = new DataSet();
Way way1 = TestUtils.newWay("highway=residential", new Node(new LatLon(0, 0)), new Node(new LatLon(0.1, 0.1)));
Way way2 = TestUtils.newWay("highway=residential", new Node(new LatLon(-0.1, -0.1)),
new Node(new LatLon(0.1, 0.1)));
way1.getNodes().forEach(node -> rapidData.addPrimitive(node));
way2.getNodes().forEach(node -> osmData.addPrimitive(node));
osmData.addPrimitive(way2);
rapidData.addPrimitive(way1);
OsmDataLayer osmLayer = new OsmDataLayer(osmData, "osm", null);
RapiDLayer rapidLayer = new RapiDLayer(RapiDDataUtils.getData(RapiDDataUtilsTest.getTestBBox()), "rapid", null);
MainApplication.getLayerManager().addLayer(osmLayer);
MainApplication.getLayerManager().addLayer(rapidLayer);
MainApplication.getLayerManager().setActiveLayer(rapidLayer);
rapidData.addSelected(way1);
moveAction.actionPerformed(null);
Assert.assertEquals(osmLayer, MainApplication.getLayerManager().getActiveLayer());
UndoRedoHandler.getInstance().undo();
}
}