diff --git a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/backend/GetDataRunnable.java b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/backend/GetDataRunnable.java index 1d8b666..d02ad86 100644 --- a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/backend/GetDataRunnable.java +++ b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/backend/GetDataRunnable.java @@ -125,33 +125,41 @@ public class GetDataRunnable extends RecursiveTask implements CancelLis // This can technically be included in the above block, but it is here so that // cancellation is a little faster if (!monitor.isCanceled()) { - synchronized (LOCK) { - /* Microsoft buildings don't have a source, so we add one */ - MapWithAIDataUtils.addSourceTags(dataSet, "building", "microsoft"); - replaceTags(dataSet); - removeCommonTags(dataSet); - mergeNodes(dataSet); - cleanupDataSet(dataSet); - mergeWays(dataSet); - removeAlreadyAddedData(dataSet); - dataSet.getWays().parallelStream().filter(way -> !way.isDeleted()) - .forEach(GetDataRunnable::cleanupArtifacts); - for (int i = 0; i < 5; i++) { - new MergeDuplicateWays(dataSet).executeCommand(); - } - } + cleanup(dataSet); } monitor.finishTask(); return dataSet; } + /** + * Perform cleanups on a dataset (one dataset at a time) + * + * @param dataSet The dataset to cleanup + */ + public static void cleanup(DataSet dataSet) { + synchronized (LOCK) { + /* Microsoft buildings don't have a source, so we add one */ + MapWithAIDataUtils.addSourceTags(dataSet, "building", "microsoft"); + replaceTags(dataSet); + removeCommonTags(dataSet); + mergeNodes(dataSet); + cleanupDataSet(dataSet); + mergeWays(dataSet); + removeAlreadyAddedData(dataSet); + new MergeDuplicateWays(dataSet).executeCommand(); + dataSet.getWays().parallelStream().filter(way -> !way.isDeleted()) + .forEach(GetDataRunnable::cleanupArtifacts); + } + } + public static void removeAlreadyAddedData(DataSet dataSet) { - List osmData = MainApplication.getLayerManager().getLayersOfType(OsmDataLayer.class).parallelStream() - .map(OsmDataLayer::getDataSet).filter(ds -> !ds.equals(dataSet)).collect(Collectors.toList()); + final List osmData = MainApplication.getLayerManager().getLayersOfType(OsmDataLayer.class) + .parallelStream().map(OsmDataLayer::getDataSet).filter(ds -> !ds.equals(dataSet)) + .collect(Collectors.toList()); dataSet.getWays().parallelStream().filter(way -> !way.isDeleted()) .filter(way -> osmData.stream().anyMatch(ds -> checkIfPrimitiveDuplicatesPrimitiveInDataSet(way, ds))) .forEach(way -> { - List nodes = way.getNodes(); + final List nodes = way.getNodes(); DeleteCommand.delete(Collections.singleton(way), true, true).executeCommand(); nodes.parallelStream() .filter(node -> !node.isDeleted() @@ -161,15 +169,15 @@ public class GetDataRunnable extends RecursiveTask implements CancelLis } private static boolean checkIfPrimitiveDuplicatesPrimitiveInDataSet(OsmPrimitive primitive, DataSet ds) { - List possibleDuplicates = searchDataSet(ds, primitive); + final List possibleDuplicates = searchDataSet(ds, primitive); return possibleDuplicates.parallelStream().filter(prim -> !prim.isDeleted()) .anyMatch(prim -> checkIfProbableDuplicate(prim, primitive)); } private static boolean checkIfProbableDuplicate(OsmPrimitive one, OsmPrimitive two) { boolean equivalent = false; - TagMap oneMap = one.getKeys(); - TagMap twoMap = two.getKeys(); + final TagMap oneMap = one.getKeys(); + final TagMap twoMap = two.getKeys(); oneMap.remove(MAPWITHAI_SOURCE_TAG_KEY); twoMap.remove(MAPWITHAI_SOURCE_TAG_KEY); if (one.getClass().equals(two.getClass()) && oneMap.equals(twoMap)) { @@ -190,7 +198,7 @@ public class GetDataRunnable extends RecursiveTask implements CancelLis private static List searchDataSet(DataSet ds, T primitive) { List returnList = Collections.emptyList(); if (primitive instanceof OsmPrimitive) { - BBox tBBox = new BBox(); + final BBox tBBox = new BBox(); tBBox.addPrimitive((OsmPrimitive) primitive, 0.001); if (primitive instanceof Node) { returnList = new ArrayList<>(ds.searchNodes(tBBox)); @@ -261,12 +269,12 @@ public class GetDataRunnable extends RecursiveTask implements CancelLis bbox.addPrimitive(n1, 0.001); final List nearbyNodes = dataSet.searchNodes(bbox).parallelStream().filter(node -> !node.isDeleted() && !node.equals(n1) - && ((n1.getKeys().equals(node.getKeys()) || n1.getKeys().isEmpty() || node.getKeys().isEmpty()) - && n1.getCoor().greatCircleDistance(node.getCoor()) < MapWithAIPreferenceHelper - .getMaxNodeDistance() - || !n1.getKeys().isEmpty() && n1.getKeys().equals(node.getKeys()) - && n1.getCoor().greatCircleDistance( - node.getCoor()) < MapWithAIPreferenceHelper.getMaxNodeDistance() * 10)) + && (((n1.getKeys().equals(node.getKeys()) || n1.getKeys().isEmpty() || node.getKeys().isEmpty()) + && (n1.getCoor().greatCircleDistance(node.getCoor()) < MapWithAIPreferenceHelper + .getMaxNodeDistance())) + || (!n1.getKeys().isEmpty() && n1.getKeys().equals(node.getKeys()) + && (n1.getCoor().greatCircleDistance( + node.getCoor()) < (MapWithAIPreferenceHelper.getMaxNodeDistance() * 10))))) .collect(Collectors.toList()); final Command mergeCommand = MergeNodesAction.mergeNodes(nearbyNodes, n1); if (mergeCommand != null) { @@ -293,20 +301,20 @@ public class GetDataRunnable extends RecursiveTask implements CancelLis } protected static void addMissingElement(Map.Entry> entry) { - Way way = entry.getKey().way; - Way waySegmentWay = entry.getKey().toWay(); - Node toAdd = entry.getValue().parallelStream() + final Way way = entry.getKey().way; + final Way waySegmentWay = entry.getKey().toWay(); + final Node toAdd = entry.getValue().parallelStream() .flatMap(seg -> Arrays.asList(seg.getFirstNode(), seg.getSecondNode()).parallelStream()) .filter(node -> !waySegmentWay.containsNode(node)).findAny().orElse(null); - if (toAdd != null && convertToMeters( - Geometry.getDistance(waySegmentWay, toAdd)) < MapWithAIPreferenceHelper.getMaxNodeDistance() * 10) { + if ((toAdd != null) && (convertToMeters( + Geometry.getDistance(waySegmentWay, toAdd)) < (MapWithAIPreferenceHelper.getMaxNodeDistance() * 10))) { way.addNode(entry.getKey().lowerIndex + 1, toAdd); } - for (int i = 0; i < way.getNodesCount() - 2; i++) { - Node node0 = way.getNode(i); - Node node3 = way.getNode(i + 2); + for (int i = 0; i < (way.getNodesCount() - 2); i++) { + final Node node0 = way.getNode(i); + final Node node3 = way.getNode(i + 2); if (node0.equals(node3)) { - List nodes = way.getNodes(); + final List nodes = way.getNodes(); nodes.remove(i + 2); // SonarLint doesn't like this (if it was i instead of i + 2, it would be an // issue) way.setNodes(nodes); @@ -319,19 +327,20 @@ public class GetDataRunnable extends RecursiveTask implements CancelLis } protected static void cleanupArtifacts(Way way) { - for (int i = 0; i < way.getNodesCount() - 2; i++) { - Node node0 = way.getNode(i); - Node node1 = way.getNode(i + 1); - Node node2 = way.getNode(i + 2); - double angle = Geometry.getCornerAngle(node0.getEastNorth(), node1.getEastNorth(), node2.getEastNorth()); + for (int i = 0; i < (way.getNodesCount() - 2); i++) { + final Node node0 = way.getNode(i); + final Node node1 = way.getNode(i + 1); + final Node node2 = way.getNode(i + 2); + final double angle = Geometry.getCornerAngle(node0.getEastNorth(), node1.getEastNorth(), + node2.getEastNorth()); if (angle < ARTIFACT_ANGLE) { - List nodes = way.getNodes(); + final List nodes = way.getNodes(); nodes.remove(i + 1); // not an issue since I'm adding it back nodes.add(i + 2, node1); } } - if (way.getNodesCount() == 2 && way.getDataSet() != null) { - BBox tBBox = new BBox(); + if ((way.getNodesCount() == 2) && (way.getDataSet() != null)) { + final BBox tBBox = new BBox(); tBBox.addPrimitive(way, 0.001); if (way.getDataSet().searchWays(tBBox).parallelStream() .filter(tWay -> !way.equals(tWay) && !tWay.isDeleted()) @@ -358,20 +367,20 @@ public class GetDataRunnable extends RecursiveTask implements CancelLis .map(pair -> WaySegment.forNodePair(way2, pair.a, pair.b)).collect(Collectors.toList()); final Map> partials = new TreeMap<>(); for (final WaySegment segment1 : waySegments1) { - Way waySegment1 = segment1.toWay(); + final Way waySegment1 = segment1.toWay(); final List replacements = waySegments2.parallelStream() .filter(seg2 -> waySegment1.isFirstLastNode(seg2.getFirstNode()) || waySegment1.isFirstLastNode(seg2.getSecondNode())) .filter(seg -> { - Node node2 = waySegment1.isFirstLastNode(seg.getFirstNode()) ? seg.getFirstNode() + final Node node2 = waySegment1.isFirstLastNode(seg.getFirstNode()) ? seg.getFirstNode() : seg.getSecondNode(); - Node node1 = node2.equals(seg.getFirstNode()) ? seg.getSecondNode() : seg.getFirstNode(); - Node node3 = waySegment1.getNode(0).equals(node2) ? waySegment1.getNode(1) + final Node node1 = node2.equals(seg.getFirstNode()) ? seg.getSecondNode() : seg.getFirstNode(); + final Node node3 = waySegment1.getNode(0).equals(node2) ? waySegment1.getNode(1) : waySegment1.getNode(0); return Math.abs(Geometry.getCornerAngle(node1.getEastNorth(), node2.getEastNorth(), - node3.getEastNorth())) < Math.PI / 4; + node3.getEastNorth())) < (Math.PI / 4); }).collect(Collectors.toList()); - if (replacements.size() != 2 || replacements.parallelStream() + if ((replacements.size() != 2) || replacements.parallelStream() .anyMatch(seg -> waySegment1.getNodes().containsAll(seg.toWay().getNodes()))) { continue; } @@ -389,7 +398,7 @@ public class GetDataRunnable extends RecursiveTask implements CancelLis */ private static DataSet getDataReal(BBox bbox, ProgressMonitor monitor) { final DataSet dataSet = new DataSet(); - List> urlMaps = MapWithAIPreferenceHelper.getMapWithAIUrl().stream() + final List> urlMaps = MapWithAIPreferenceHelper.getMapWithAIUrl().stream() .map(map -> new TreeMap<>(map)).collect(Collectors.toList()); if (DetectTaskingManagerUtils.hasTaskingManagerLayer()) { urlMaps.forEach(map -> map.put("url", map.get("url").concat("&crop_bbox={crop_bbox}"))); @@ -402,11 +411,12 @@ public class GetDataRunnable extends RecursiveTask implements CancelLis clients = new ArrayList<>(); urlMaps.parallelStream().forEach(map -> { try { - HttpClient client = HttpClient.create(new URL(map.get("url").replace("{bbox}", bbox.toStringCSV(",")) - .replace("{crop_bbox}", DetectTaskingManagerUtils.getTaskingManagerBBox().toStringCSV(",")))); + final HttpClient client = HttpClient + .create(new URL(map.get("url").replace("{bbox}", bbox.toStringCSV(",")).replace("{crop_bbox}", + DetectTaskingManagerUtils.getTaskingManagerBBox().toStringCSV(",")))); clients.add(client); clientCall(client, dataSet, map.getOrDefault("source", MapWithAIPlugin.NAME), monitor); - } catch (MalformedURLException e1) { + } catch (final MalformedURLException e1) { Logging.debug(e1); } }); @@ -433,11 +443,11 @@ public class GetDataRunnable extends RecursiveTask implements CancelLis addMapWithAISourceTag(mergeData, source); dataSet.mergeFrom(mergeData); response.disconnect(); - } catch (SocketException e) { + } catch (final SocketException e) { if (!monitor.isCanceled()) { Logging.debug(e); } - } catch (SSLException e) { + } catch (final SSLException e) { Logging.debug(e); new Notification(tr("{0}: Bad SSL Certificate: {1}", MapWithAIPlugin.NAME, client.getURL())) .setDuration(Notification.TIME_DEFAULT).show(); diff --git a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/backend/MapWithAIDataUtils.java b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/backend/MapWithAIDataUtils.java index eaa9e18..2a0bfd9 100644 --- a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/backend/MapWithAIDataUtils.java +++ b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/backend/MapWithAIDataUtils.java @@ -156,7 +156,7 @@ public final class MapWithAIDataUtils { final List realBBoxes = bbox.stream().filter(BBox::isValid).distinct().collect(Collectors.toList()); if (MapWithAIPreferenceHelper.getMapWithAIUrl().parallelStream() .anyMatch(map -> Boolean.valueOf(map.getOrDefault("enabled", "false")))) { - if (realBBoxes.size() < TOO_MANY_BBOXES || ConditionalOptionPaneUtil.showConfirmationDialog( + if ((realBBoxes.size() < TOO_MANY_BBOXES) || ConditionalOptionPaneUtil.showConfirmationDialog( MapWithAIPlugin.NAME.concat(".alwaysdownload"), null, tr("You are going to make {0} requests to the MapWithAI server. This may take some time.
Continue?", realBBoxes.size()), @@ -167,7 +167,7 @@ public final class MapWithAIDataUtils { monitor.close(); } } else { - Notification noUrls = MapWithAIPreferenceHelper.getMapWithAIURLs().isEmpty() + final Notification noUrls = MapWithAIPreferenceHelper.getMapWithAIURLs().isEmpty() ? new Notification(tr("There are no defined URLs. To get the defaults, restart JOSM")) : new Notification(tr("No URLS are enabled")); noUrls.setDuration(Notification.TIME_DEFAULT); @@ -287,7 +287,8 @@ public final class MapWithAIDataUtils { final Lock lock = layer.getLock(); lock.lock(); try { - layer.mergeFrom(newData); + mapWithAISet.mergeFrom(newData); + GetDataRunnable.cleanup(mapWithAISet); } finally { lock.unlock(); } @@ -329,10 +330,11 @@ public final class MapWithAIDataUtils { // to >r15483 private static boolean bboxesAreFunctionallyEqual(BBox bbox1, BBox bbox2, Double maxDifference) { final double diff = Optional.ofNullable(maxDifference).orElse(LatLon.MAX_SERVER_PRECISION); - return (bbox1 != null && bbox2 != null && Math.abs(bbox1.getBottomRightLat() - bbox2.getBottomRightLat()) < diff - && Math.abs(bbox1.getBottomRightLon() - bbox2.getBottomRightLon()) < diff - && Math.abs(bbox1.getTopLeftLat() - bbox2.getTopLeftLat()) < diff - && Math.abs(bbox1.getTopLeftLon() - bbox2.getTopLeftLon()) < diff); + return ((bbox1 != null) && (bbox2 != null) + && (Math.abs(bbox1.getBottomRightLat() - bbox2.getBottomRightLat()) < diff) + && (Math.abs(bbox1.getBottomRightLon() - bbox2.getBottomRightLon()) < diff) + && (Math.abs(bbox1.getTopLeftLat() - bbox2.getTopLeftLat()) < diff) + && (Math.abs(bbox1.getTopLeftLon() - bbox2.getTopLeftLon()) < diff)); } private static boolean bboxesShareSide(BBox bbox1, BBox bbox2) { @@ -372,9 +374,9 @@ public final class MapWithAIDataUtils { final double height = getHeight(bbox); final Double widthDivisions = width / MAXIMUM_SIDE_DIMENSIONS; final Double heightDivisions = height / MAXIMUM_SIDE_DIMENSIONS; - final int widthSplits = widthDivisions.intValue() + (widthDivisions - widthDivisions.intValue() > 0 ? 1 : 0); + final int widthSplits = widthDivisions.intValue() + ((widthDivisions - widthDivisions.intValue()) > 0 ? 1 : 0); final int heightSplits = heightDivisions.intValue() - + (heightDivisions - heightDivisions.intValue() > 0 ? 1 : 0); + + ((heightDivisions - heightDivisions.intValue()) > 0 ? 1 : 0); final double newMinWidths = Math.abs(bbox.getTopLeftLon() - bbox.getBottomRightLon()) / widthSplits; final double newMinHeights = Math.abs(bbox.getBottomRightLat() - bbox.getTopLeftLat()) / heightSplits; @@ -383,8 +385,8 @@ public final class MapWithAIDataUtils { final double miny = bbox.getBottomRightLat(); for (int x = 1; x <= widthSplits; x++) { for (int y = 1; y <= heightSplits; y++) { - final LatLon lowerLeft = new LatLon(miny + newMinHeights * (y - 1), minx + newMinWidths * (x - 1)); - final LatLon upperRight = new LatLon(miny + newMinHeights * y, minx + newMinWidths * x); + final LatLon lowerLeft = new LatLon(miny + (newMinHeights * (y - 1)), minx + (newMinWidths * (x - 1))); + final LatLon upperRight = new LatLon(miny + (newMinHeights * y), minx + (newMinWidths * x)); returnBounds.add(new BBox(lowerLeft, upperRight)); } }