Skip to content

Commit

Permalink
Merge branch 'praszuk/refactor/buildings-actions-cleanup'
Browse files Browse the repository at this point in the history
  • Loading branch information
praszuk committed May 3, 2022
2 parents 69d9354 + 9bd6b9c commit b68e293
Showing 1 changed file with 122 additions and 116 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ public BuildingsAction() {
null,
DESCRIPTION,
Shortcut.registerShortcut(
"download:building",
tr("Download building"),
KeyEvent.VK_1,
Shortcut.CTRL_SHIFT
"download:building",
tr("Download building"),
KeyEvent.VK_1,
Shortcut.CTRL_SHIFT
),
true
);
Expand Down Expand Up @@ -75,129 +75,135 @@ public static boolean isCloseNode(Node node1, Node node2, double maxOffset) {

public static DataSet getBuildingsAtCurrentLocation(){
LatLon latLonPoint = MainApplication.getMap().mapView.getLatLon(
MainApplication.getMap().mapView.getMousePosition().getX(),
MainApplication.getMap().mapView.getMousePosition().getY()
MainApplication.getMap().mapView.getMousePosition().getX(),
MainApplication.getMap().mapView.getMousePosition().getY()
);

return BuildingsDownloader.downloadBuildings(latLonPoint, "bdot");
}

public static void performBuildingImport(DataSet currentDataSet) {
try {
DataSet importedBuildingsDataSet = getBuildingsAtCurrentLocation();
DataSet importedBuildingsDataSet = getBuildingsAtCurrentLocation();
if (importedBuildingsDataSet == null){
Logging.warn("Connection error: Cannot import building!");
return;
}
if (importedBuildingsDataSet.isEmpty()) {
Logging.info("Imported empty dataset.");
return;
}

if (importedBuildingsDataSet == null || importedBuildingsDataSet.isEmpty()) {
return;
}
List<Way> importedBuildingsCollection = importedBuildingsDataSet.getWays()
.stream()
.filter(way -> way.hasKey("building"))
.collect(Collectors.toList());

// just get first building
Way importedBuilding = (Way) importedBuildingsDataSet.getWays().toArray()[0];

List<Node> newNodes = importedBuilding.getNodes().stream()
.map(node -> new Node(node, true))
.collect(Collectors.toList());

// last node is wrongly duplicated after cloning operation, so remove it now
// and add first node to the way below to get it as closed line (area)
newNodes.remove(newNodes.size() - 1);

Way newBuilding = new Way();
newBuilding.cloneFrom(importedBuilding, false);
importedBuildingsDataSet.clear();

// Check if any building's node is very close to existing node – almost/same lat lon and replace it
BBox bbox = getBBox(newNodes, BuildingsSettings.BBOX_OFFSET.get());

List<Node> closeNodes = currentDataSet.searchNodes(bbox).stream()
.filter(n -> !n.isDeleted())
.collect(Collectors.toList());
List<Node> buildingNodes = new ArrayList<>();
List<Node> nodesToAddToDataSet = new ArrayList<>();

AtomicInteger sameNodeCounter = new AtomicInteger();
newNodes.forEach(newNode -> {
Node sameNode = closeNodes.stream()
.filter(closeNode -> isCloseNode(closeNode, newNode, BuildingsSettings.BBOX_OFFSET.get()))
.findFirst().orElse(null);

if (sameNode != null) {
buildingNodes.add(sameNode);
sameNodeCounter.getAndIncrement();
} else {
buildingNodes.add(newNode);
nodesToAddToDataSet.add(newNode);
}
});

// Whole building is a duplicate – contains the same nodes
if (sameNodeCounter.get() == buildingNodes.size()) {
return;
}
newBuilding.setNodes(buildingNodes);
newBuilding.addNode(buildingNodes.get(0));

List<Command> commands = new ArrayList<>();

nodesToAddToDataSet.forEach(node -> commands.add(new AddCommand(currentDataSet, node)));
commands.add(new AddCommand(currentDataSet, newBuilding));

Collection<OsmPrimitive> selected = currentDataSet.getSelected()
.stream()
.filter(osmPrimitive -> osmPrimitive.getType() == OsmPrimitiveType.WAY)
.collect(Collectors.toList());

// TODO maybe semidetached/terrace auto-change building tag
SequenceCommand importBuildingSequenceCommand = new SequenceCommand(tr("Import building"), commands);
UndoRedoHandler.getInstance().add(importBuildingSequenceCommand);
Logging.debug("Imported new building {0}", newBuilding.getId());

if (selected.size() == 1) {
Way selectedBuilding = (Way) selected.toArray()[0];
try {
ReplaceUpdateBuildingCommand replaceUpdateBuildingCommand = new ReplaceUpdateBuildingCommand(
currentDataSet,
selectedBuilding,
newBuilding
);
UndoRedoHandler.getInstance().add(replaceUpdateBuildingCommand);
Logging.debug("Updated building {0} with new data", selectedBuilding.getId());

} catch (IllegalArgumentException ignored) {
// If user cancel conflict window do nothing
Notification note = new Notification(tr("Canceled merging buildings."));
note.setIcon(JOptionPane.WARNING_MESSAGE);
note.setDuration(Notification.TIME_SHORT);
note.show();

UndoRedoUtils.undoUntil(UndoRedoHandler.getInstance(), importBuildingSequenceCommand, true);
Logging.debug(
"No building (id: {0}) update, caused: Cancel conflict dialog by user",
selectedBuilding.getId()
);
} catch (ReplaceGeometryException ignore) {
// If selected building cannot be merged (e.g. connected ways/relation)
Notification note = new Notification(tr(
"Cannot merge buildings!" +
" Old building may be connected with some ways/relations" +
" or not whole area is downloaded."
));
note.setIcon(JOptionPane.ERROR_MESSAGE);
note.setDuration(Notification.TIME_SHORT);
note.show();

UndoRedoUtils.undoUntil(UndoRedoHandler.getInstance(), importBuildingSequenceCommand, true);
Logging.debug(
"No building update (id: {0}), caused: Replacing Geometry from UtilPlugins2 error",
selectedBuilding.getId()
);
}

currentDataSet.clearSelection();
if (importedBuildingsCollection.isEmpty()){
Logging.warn("Imported dataset with some data, but without buildings!");
return;
}
// just get first building
Way importedBuilding = importedBuildingsCollection.get(0);

List<Node> newNodes = importedBuilding.getNodes().stream()
.map(node -> new Node(node, true))
.collect(Collectors.toList());

// last node is wrongly duplicated after cloning operation, so remove it now
// and add first node to the way below to get it as closed line (area)
newNodes.remove(newNodes.size() - 1);

Way newBuilding = new Way();
newBuilding.cloneFrom(importedBuilding, false);
importedBuildingsDataSet.clear();

// Check if any building's node is very close to existing node – almost/same lat lon and replace it
BBox bbox = getBBox(newNodes, BuildingsSettings.BBOX_OFFSET.get());

List<Node> closeNodes = currentDataSet.searchNodes(bbox).stream()
.filter(n -> !n.isDeleted())
.collect(Collectors.toList());
List<Node> buildingNodes = new ArrayList<>();
List<Node> nodesToAddToDataSet = new ArrayList<>();

AtomicInteger sameNodeCounter = new AtomicInteger();
newNodes.forEach(newNode -> {
Node sameNode = closeNodes.stream()
.filter(closeNode -> isCloseNode(closeNode, newNode, BuildingsSettings.BBOX_OFFSET.get()))
.findFirst().orElse(null);

if (sameNode != null) {
buildingNodes.add(sameNode);
sameNodeCounter.getAndIncrement();
} else {
buildingNodes.add(newNode);
nodesToAddToDataSet.add(newNode);
}
});

// Whole building is a duplicate – contains the same nodes
if (sameNodeCounter.get() == buildingNodes.size()) {
return;
}
newBuilding.setNodes(buildingNodes);
newBuilding.addNode(buildingNodes.get(0));

List<Command> commands = new ArrayList<>();

nodesToAddToDataSet.forEach(node -> commands.add(new AddCommand(currentDataSet, node)));
commands.add(new AddCommand(currentDataSet, newBuilding));

Collection<OsmPrimitive> selected = currentDataSet.getSelected()
.stream()
.filter(osmPrimitive -> osmPrimitive.getType() == OsmPrimitiveType.WAY)
.collect(Collectors.toList());

SequenceCommand importBuildingSequenceCommand = new SequenceCommand(tr("Import building"), commands);
UndoRedoHandler.getInstance().add(importBuildingSequenceCommand);
Logging.debug("Imported new building {0}", newBuilding.getId());

if (selected.size() == 1) {
Way selectedBuilding = (Way) selected.toArray()[0];
try {
ReplaceUpdateBuildingCommand replaceUpdateBuildingCommand = new ReplaceUpdateBuildingCommand(
currentDataSet,
selectedBuilding,
newBuilding
);
UndoRedoHandler.getInstance().add(replaceUpdateBuildingCommand);
Logging.debug("Updated building {0} with new data", selectedBuilding.getId());

} catch (IllegalArgumentException ignored) {
// If user cancel conflict window do nothing
Notification note = new Notification(tr("Canceled merging buildings."));
note.setIcon(JOptionPane.WARNING_MESSAGE);
note.setDuration(Notification.TIME_SHORT);
note.show();

UndoRedoUtils.undoUntil(UndoRedoHandler.getInstance(), importBuildingSequenceCommand, true);
Logging.debug(
"No building (id: {0}) update, caused: Cancel conflict dialog by user",
selectedBuilding.getId()
);
} catch (ReplaceGeometryException ignore) {
// If selected building cannot be merged (e.g. connected ways/relation)
Notification note = new Notification(tr(
"Cannot merge buildings!" +
" Old building may be connected with some ways/relations" +
" or not whole area is downloaded."
));
note.setIcon(JOptionPane.ERROR_MESSAGE);
note.setDuration(Notification.TIME_SHORT);
note.show();

UndoRedoUtils.undoUntil(UndoRedoHandler.getInstance(), importBuildingSequenceCommand, true);
Logging.debug(
"No building update (id: {0}), caused: Replacing Geometry from UtilPlugins2 error",
selectedBuilding.getId()
);
}

} catch (NullPointerException ignored) {
// TODO log it
currentDataSet.clearSelection();
}
}

Expand Down

0 comments on commit b68e293

Please sign in to comment.