kopia lustrzana https://github.com/JOSM/MapWithAI
Add data to data layer (left on RapiD layer for now)
Signed-off-by: Taylor Smock <smocktaylor@gmail.com>pull/1/head
rodzic
78b7ad5048
commit
55f34dd95c
|
@ -1,10 +1,13 @@
|
|||
// License: GPL. For details, see LICENSE file.
|
||||
package org.openstreetmap.josm.plugins.rapid;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
|
||||
import org.openstreetmap.josm.gui.MainApplication;
|
||||
import org.openstreetmap.josm.plugins.Plugin;
|
||||
import org.openstreetmap.josm.plugins.PluginInformation;
|
||||
import org.openstreetmap.josm.plugins.rapid.backend.RapiDAction;
|
||||
import org.openstreetmap.josm.plugins.rapid.backend.RapiDMoveAction;
|
||||
|
||||
public final class RapiDPlugin extends Plugin {
|
||||
/** The name of the plugin */
|
||||
|
@ -14,7 +17,11 @@ public final class RapiDPlugin extends Plugin {
|
|||
super(info);
|
||||
|
||||
RapiDAction action = new RapiDAction();
|
||||
AbstractAction add = new RapiDMoveAction();
|
||||
|
||||
MainApplication.getMenu().dataMenu.add(action);
|
||||
MainApplication.getMenu().dataMenu.add(add);
|
||||
MainApplication.getMenu().fileMenu.add(action);
|
||||
MainApplication.getMenu().fileMenu.add(add);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
// 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.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.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.Way;
|
||||
import org.openstreetmap.josm.data.osm.visitor.MergeSourceBuildingVisitor;
|
||||
import org.openstreetmap.josm.plugins.rapid.RapiDPlugin;
|
||||
import org.openstreetmap.josm.tools.Logging;
|
||||
import org.openstreetmap.josm.tools.Utils;
|
||||
|
||||
public class RapiDAddCommand extends Command {
|
||||
DataSet editable;
|
||||
DataSet rapid;
|
||||
Collection<OsmPrimitive> primitives;
|
||||
AddPrimitivesCommand addPrimitivesCommand;
|
||||
Collection<OsmPrimitive> modifiedPrimitives;
|
||||
|
||||
/**
|
||||
* Add primitives from RapiD to the OSM data layer
|
||||
*
|
||||
* @param rapid The rapid dataset
|
||||
* @param editable The OSM dataset
|
||||
* @param selection The primitives to add from RapiD
|
||||
*/
|
||||
public RapiDAddCommand(DataSet rapid, DataSet editable, Collection<OsmPrimitive> selection) {
|
||||
super(rapid);
|
||||
this.rapid = rapid;
|
||||
this.editable = editable;
|
||||
this.primitives = selection;
|
||||
modifiedPrimitives = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeCommand() {
|
||||
if (rapid.equals(editable)) {
|
||||
Logging.error("{0}: DataSet rapid ({1}) should not be the same as DataSet editable ({2})", RapiDPlugin.NAME,
|
||||
rapid, editable);
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
primitives = new HashSet<>(primitives);
|
||||
addPrimitivesToCollection(/* collection= */ primitives, /* primitives= */ primitives);
|
||||
synchronized (this) {
|
||||
rapid.unlock();
|
||||
Collection<OsmPrimitive> newPrimitives = new TreeSet<>(moveCollection(rapid, editable, primitives));
|
||||
createConnections(editable, newPrimitives);
|
||||
rapid.lock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create connections based off of current RapiD syntax
|
||||
*
|
||||
* @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>
|
||||
String[] connections = node.get("conn").split(",");
|
||||
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);
|
||||
}
|
||||
}
|
||||
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.error("RapiD: Removing conn from {0} in {1}", node, dataSet.getName());
|
||||
node.remove("conn");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param recursion The recursion (how many times this has called itself). Use 0
|
||||
* when calling.
|
||||
*/
|
||||
public static void addNodesToWay(Node toAddNode, Way way, Node first, Node second) {
|
||||
int index = Math.min(way.getNodes().indexOf(first), way.getNodes().indexOf(second));
|
||||
way.addNode(index, toAddNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add primitives and their children to a collection
|
||||
*
|
||||
* @param collection A collection to add the primitives to
|
||||
* @param primitives The primitives to add to the collection
|
||||
*/
|
||||
public static void addPrimitivesToCollection(Collection<OsmPrimitive> collection,
|
||||
Collection<OsmPrimitive> primitives) {
|
||||
for (OsmPrimitive primitive : primitives) {
|
||||
if (primitive instanceof Way) {
|
||||
collection.addAll(((Way) primitive).getNodes());
|
||||
} else if (primitive instanceof Relation) {
|
||||
addPrimitivesToCollection(collection, ((Relation) primitive).getMemberPrimitives());
|
||||
}
|
||||
collection.add(primitive);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescriptionText() {
|
||||
return tr("Add object from RapiD");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
|
||||
Collection<OsmPrimitive> added) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -3,9 +3,9 @@ package org.openstreetmap.josm.plugins.rapid.backend;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.openstreetmap.josm.data.osm.BBox;
|
||||
import org.openstreetmap.josm.data.osm.DataSet;
|
||||
|
@ -20,6 +20,14 @@ import org.openstreetmap.josm.tools.Logging;
|
|||
*/
|
||||
public final class RapiDDataUtils {
|
||||
private static final String RAPID_API_TOKEN = "ASZUVdYpCkd3M6ZrzjXdQzHulqRMnxdlkeBJWEKOeTUoY_Gwm9fuEd2YObLrClgDB_xfavizBsh0oDfTWTF7Zb4C";
|
||||
private static Set<String> API_LIST = new HashSet<>();
|
||||
static {
|
||||
addRapidApi(new StringBuilder().append("https://www.facebook.com/maps/ml_roads?").append("conflate_with_osm=")
|
||||
.append(true).append("&").append("theme=")
|
||||
.append("ml_road_vector").append("&").append("collaborator=").append("fbid").append("&")
|
||||
.append("token=").append(RAPID_API_TOKEN).append("&").append("hash=").append("ASYM8LPNy8k1XoJiI7A")
|
||||
.append("&").append("bbox={bbox}").toString());
|
||||
}
|
||||
|
||||
private RapiDDataUtils() {
|
||||
// Hide the constructor
|
||||
|
@ -30,27 +38,29 @@ public final class RapiDDataUtils {
|
|||
Logging.setLogLevel(Logging.LEVEL_DEBUG);
|
||||
InputStream inputStream = null;
|
||||
DataSet dataSet = new DataSet();
|
||||
try {
|
||||
final String query = new StringBuilder().append("conflate_with_osm=").append(true).append("theme=")
|
||||
.append("ml_road_vector").append("&").append("collaborator=").append("fbid").append("&")
|
||||
.append("token=").append(RAPID_API_TOKEN).append("&").append("hash=").append("ASYM8LPNy8k1XoJiI7A")
|
||||
.append("&").append("bbox=").append(bbox.toString()).toString();
|
||||
final URI uri = new URI("https", null, "www.facebook.com", 80, "/maps/ml_roads", query, null);
|
||||
final URL url = uri.toURL();
|
||||
inputStream = url.openStream();
|
||||
Logging.info("{0}: Getting {1}", RapiDPlugin.NAME, uri.toASCIIString());
|
||||
dataSet = OsmReader.parseDataSet(inputStream, null);
|
||||
} catch (URISyntaxException | UnsupportedOperationException | IllegalDataException | IOException e) {
|
||||
Logging.debug(e);
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
Logging.debug(e);
|
||||
for (String urlString : API_LIST) {
|
||||
try {
|
||||
final URL url = new URL(urlString.replace("{bbox}", bbox.toStringCSV(",")));
|
||||
Logging.error("{0}: Getting {1}", RapiDPlugin.NAME, url.toString());
|
||||
|
||||
inputStream = url.openStream();
|
||||
dataSet.mergeFrom(OsmReader.parseDataSet(inputStream, null));
|
||||
} catch (UnsupportedOperationException | IllegalDataException | IOException e) {
|
||||
Logging.debug(e);
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
Logging.debug(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
public static void addRapidApi(String url) {
|
||||
API_LIST.add(url);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package org.openstreetmap.josm.plugins.rapid.backend;
|
||||
|
||||
import static org.openstreetmap.josm.tools.I18n.tr;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
|
||||
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.OsmDataLayer;
|
||||
import org.openstreetmap.josm.plugins.rapid.RapiDPlugin;
|
||||
|
||||
public class RapiDMoveAction extends AbstractAction {
|
||||
/** UID for abstract action */
|
||||
private static final long serialVersionUID = 319374598;
|
||||
|
||||
public RapiDMoveAction() {
|
||||
super(tr("Add from ".concat(RapiDPlugin.NAME)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
for (RapiDLayer layer : MainApplication.getLayerManager().getLayersOfType(RapiDLayer.class)) {
|
||||
List<OsmDataLayer> osmLayers = MainApplication.getLayerManager().getLayersOfType(OsmDataLayer.class);
|
||||
DataSet editData = null;
|
||||
DataSet rapid = layer.getDataSet();
|
||||
Collection<OsmPrimitive> selected = rapid.getSelected();
|
||||
for (OsmDataLayer osmLayer : osmLayers) {
|
||||
if (!osmLayer.isLocked() && osmLayer.isVisible() && osmLayer.isUploadable()
|
||||
&& osmLayer.getClass().equals(OsmDataLayer.class)) {
|
||||
editData = osmLayer.getDataSet();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (editData != null) {
|
||||
RapiDAddCommand command = new RapiDAddCommand(rapid, editData, selected);
|
||||
UndoRedoHandler.getInstance().add(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
// License: GPL. For details, see LICENSE file.
|
||||
package org.openstreetmap.josm.plugins.rapid;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.TreeSet;
|
||||
|
||||
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.plugins.rapid.backend.RapiDAddCommand;
|
||||
import org.openstreetmap.josm.testutils.JOSMTestRules;
|
||||
|
||||
public class RapiDAddComandTest {
|
||||
@Rule
|
||||
public JOSMTestRules test = new JOSMTestRules();
|
||||
|
||||
@Test
|
||||
public void testMoveCollection() {
|
||||
DataSet ds1 = new DataSet();
|
||||
DataSet ds2 = new DataSet();
|
||||
Way way1 = TestUtils.newWay("highway=residential", new Node(new LatLon(0, 0)),
|
||||
new Node(new LatLon(0, 0.1)));
|
||||
for (Node node : way1.getNodes()) {
|
||||
ds1.addPrimitive(node);
|
||||
}
|
||||
ds1.addPrimitive(way1);
|
||||
ds1.lock();
|
||||
RapiDAddCommand command = new RapiDAddCommand(ds1, ds2, Collections.singleton(way1));
|
||||
command.executeCommand();
|
||||
Assert.assertTrue(ds2.containsWay(way1));
|
||||
Assert.assertTrue(ds2.containsNode(way1.firstNode()));
|
||||
Assert.assertTrue(ds2.containsNode(way1.lastNode()));
|
||||
// Assert.assertFalse(ds1.containsWay(way1)); // Only if we delete ways from
|
||||
// rapid dataset
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddPrimitivesToCollection() {
|
||||
Way way1 = TestUtils.newWay("highway=residential", new Node(new LatLon(0, 0)), new Node(new LatLon(0, 0.1)));
|
||||
Collection<OsmPrimitive> collection = new TreeSet<>();
|
||||
Assert.assertEquals(0, collection.size());
|
||||
RapiDAddCommand.addPrimitivesToCollection(collection, Collections.singletonList(way1));
|
||||
Assert.assertEquals(3, collection.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateConnections() {
|
||||
DataSet ds1 = new DataSet();
|
||||
Way way1 = TestUtils.newWay("highway=residential", new Node(new LatLon(0, 0)), new Node(new LatLon(0, 0.1)));
|
||||
Way way2 = TestUtils.newWay("highway=residential", new Node(new LatLon(0, 0.05)),
|
||||
new Node(new LatLon(0.05, 0.2)));
|
||||
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())));
|
||||
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()));
|
||||
Assert.assertEquals(3, way1.getNodesCount());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// License: GPL. For details, see LICENSE file.
|
||||
package org.openstreetmap.josm.plugins.rapid;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.openstreetmap.josm.data.coor.LatLon;
|
||||
import org.openstreetmap.josm.data.osm.BBox;
|
||||
import org.openstreetmap.josm.data.osm.DataSet;
|
||||
import org.openstreetmap.josm.plugins.rapid.backend.RapiDDataUtils;
|
||||
import org.openstreetmap.josm.testutils.JOSMTestRules;
|
||||
|
||||
public class RapiDDataUtilsTest {
|
||||
@Rule
|
||||
public JOSMTestRules test = new JOSMTestRules();
|
||||
|
||||
/**
|
||||
* This gets data from RapiD. This test may fail if someone adds the data to OSM.
|
||||
*/
|
||||
@Test
|
||||
public void testGetData() {
|
||||
BBox testBBox = new BBox();
|
||||
testBBox.add(new LatLon(39.066058, -108.5683808));
|
||||
testBBox.add(new LatLon(39.0667526, -108.5681757));
|
||||
DataSet ds = new DataSet(RapiDDataUtils.getData(testBBox));
|
||||
Assert.assertEquals(1, ds.getWays().size());
|
||||
}
|
||||
}
|
Ładowanie…
Reference in New Issue