MergeBuildingAddress: Don't delete duplicate addresses when added together

It is possible that the originating source didn't have addr:unit tags,
so other applications such as StreetComplete should detect duplicate
addresses and ask users if there are addr:unit tags, or which one is the
"main" building.

Furthermore, JOSM has a validator for duplicate addresses, so hopefully
the user will see the duplicate addresses and deal with them
appropriately, if it is obvious that one of the buildings is an
outbuilding.

Signed-off-by: Taylor Smock <tsmock@meta.com>
pull/14/head
Taylor Smock 2022-12-20 07:17:10 -07:00
rodzic f251a0428e
commit 070e4fb9fe
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 233BB2E466604E27
2 zmienionych plików z 45 dodań i 4 usunięć

Wyświetl plik

@ -74,18 +74,19 @@ public class MergeBuildingAddress extends AbstractConflationCommand {
return returnCommand;
}
private static Collection<Command> mergeBuildingAddress(DataSet affectedDataSet, Node node) {
private Collection<Command> mergeBuildingAddress(DataSet affectedDataSet, Node node) {
final List<OsmPrimitive> toCheck = new ArrayList<>();
final BBox bbox = new BBox(node.getCoor().getX(), node.getCoor().getY(), 0.001);
final BBox bbox = new BBox(node.lon(), node.lat(), 0.001);
GuiHelper.runInEDTAndWait(() -> {
toCheck.addAll(affectedDataSet.searchWays(bbox));
toCheck.addAll(affectedDataSet.searchRelations(bbox));
toCheck.addAll(affectedDataSet.searchNodes(bbox));
});
List<OsmPrimitive> possibleDuplicates = toCheck.stream().filter(prim -> prim.hasTag(KEY))
.filter(prim -> prim.get(KEY).equals(node.get(KEY))).filter(prim -> !prim.equals(node))
.filter(prim -> prim.get(KEY).equals(node.get(KEY)))
.filter(prim -> !prim.equals(node) && !this.possiblyAffectedPrimitives.contains(prim))
.collect(Collectors.toList());
for (String tag : Arrays.asList("addr:street", "addr:unit")) {
for (String tag : Arrays.asList("addr:street", "addr:unit", "addr:housenumber", "addr:housename")) {
if (node.hasTag(tag)) {
possibleDuplicates = possibleDuplicates.stream().filter(prim -> prim.hasTag(tag))
.filter(prim -> prim.get(tag).equals(node.get(tag))).collect(Collectors.toList());

Wyświetl plik

@ -2,8 +2,10 @@
package org.openstreetmap.josm.plugins.mapwithai.commands;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import java.util.Arrays;
import java.util.Collections;
import org.junit.jupiter.api.Test;
@ -104,4 +106,42 @@ class MergeBuildingAddressTest {
assertNull(conflation.getCommand(Collections.singletonList(addr)));
assertEquals(1, conflation.getParticipatingPrimitives().size());
}
/**
* Adding two address nodes with the same tags shouldn't result in <i>both</i>
* objects being deleted. The example from Slack had the same address for two
* different buildings. There should probably be an `addr:unit` tag, but that
* can be added later, by something like StreetComplete.
*/
@Test
void testMultiSameAddress() {
DataSet ds = new DataSet();
Node addr = new Node(new LatLon(0, 0));
Node addr2 = new Node(new LatLon(0.00005, 0.00005));
ds.addPrimitive(addr);
ds.addPrimitive(addr2);
addr.put("addr:housenumber", "1");
addr2.put("addr:housenumber", "1");
addr.put("addr:street", "Test");
addr2.put("addr:street", "Test");
Way building1 = TestUtils.newWay("building=yes", new Node(new LatLon(0.00001, 0.00001)),
new Node(new LatLon(0.00001, -0.00001)), new Node(new LatLon(-0.00001, -0.00001)),
new Node(new LatLon(-0.00001, 0.00001)));
Way building2 = TestUtils.newWay("building=yes", new Node(new LatLon(0.00006, 0.00006)),
new Node(new LatLon(0.00006, 0.00004)), new Node(new LatLon(0.00004, 0.00004)),
new Node(new LatLon(0.00004, 0.00006)));
ds.addPrimitiveRecursive(building1);
ds.addPrimitiveRecursive(building2);
building1.addNode(building1.firstNode());
building2.addNode(building2.firstNode());
MergeBuildingAddress conflation = new MergeBuildingAddress(ds);
Command command = conflation.getCommand(Arrays.asList(addr, addr2));
assertNotNull(command);
command.executeCommand();
assertEquals(3, building1.getInterestingTags().size());
assertEquals(3, building2.getInterestingTags().size());
assertEquals(building1.getInterestingTags(), building2.getInterestingTags());
assertEquals("Test", building1.get("addr:street"));
assertEquals("1", building1.get("addr:housenumber"));
}
}