diff --git a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/MapWithAIPlugin.java b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/MapWithAIPlugin.java index d97fc98..5278fc8 100644 --- a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/MapWithAIPlugin.java +++ b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/MapWithAIPlugin.java @@ -43,7 +43,6 @@ import org.openstreetmap.josm.plugins.mapwithai.data.validation.tests.StreetAddr import org.openstreetmap.josm.plugins.mapwithai.data.validation.tests.StreetAddressTest; import org.openstreetmap.josm.plugins.mapwithai.data.validation.tests.StubEndsTest; import org.openstreetmap.josm.plugins.mapwithai.gui.download.MapWithAIDownloadOptions; -import org.openstreetmap.josm.plugins.mapwithai.gui.download.MapWithAIDownloadReader; import org.openstreetmap.josm.plugins.mapwithai.gui.download.MapWithAIDownloadSourceType; import org.openstreetmap.josm.plugins.mapwithai.gui.preferences.MapWithAIPreferences; import org.openstreetmap.josm.spi.preferences.Config; @@ -59,8 +58,6 @@ public final class MapWithAIPlugin extends Plugin implements Destroyable { private final PreferenceSetting preferenceSetting; - private final MapWithAIDownloadReader mapWithAIDownloadReader; - private final List destroyables; private static final Map, Boolean> MENU_ENTRIES = new LinkedHashMap<>(); @@ -114,8 +111,6 @@ public final class MapWithAIPlugin extends Plugin implements Destroyable { new MapWithAIRemoteControl(); // instantiate to get action into Remote Control Preferences destroyables.add(new MapWithAIUploadHook(info)); mapFrameInitialized(null, MainApplication.getMap()); - mapWithAIDownloadReader = new MapWithAIDownloadReader(); - DownloadDialog.addDownloadSource(mapWithAIDownloadReader); OSMDownloadSource.addDownloadType(new MapWithAIDownloadSourceType()); MainApplication.worker.execute(() -> UpdateProd.doProd(info.mainversion)); } @@ -178,7 +173,6 @@ public final class MapWithAIPlugin extends Plugin implements Destroyable { } destroyables.forEach(Destroyable::destroy); - DownloadDialog.removeDownloadSource(mapWithAIDownloadReader); OSMDownloadSource.removeDownloadType(OSMDownloadSource.getDownloadType(MapWithAIDownloadSourceType.class)); VALIDATORS.forEach(OsmValidator::removeTest); DownloadListener.destroyAll(); diff --git a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/gui/download/MapWithAIDownloadReader.java b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/gui/download/MapWithAIDownloadReader.java deleted file mode 100644 index 8a59eab..0000000 --- a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/gui/download/MapWithAIDownloadReader.java +++ /dev/null @@ -1,189 +0,0 @@ -// License: GPL. For details, see LICENSE file. -package org.openstreetmap.josm.plugins.mapwithai.gui.download; - -import static org.openstreetmap.josm.tools.I18n.tr; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.function.Consumer; - -import javax.swing.Icon; -import javax.swing.JLabel; -import javax.swing.JOptionPane; - -import org.openstreetmap.josm.actions.downloadtasks.DownloadParams; -import org.openstreetmap.josm.data.Bounds; -import org.openstreetmap.josm.data.coor.LatLon; -import org.openstreetmap.josm.gui.download.AbstractDownloadSourcePanel; -import org.openstreetmap.josm.gui.download.DownloadDialog; -import org.openstreetmap.josm.gui.download.DownloadSettings; -import org.openstreetmap.josm.gui.download.DownloadSource; -import org.openstreetmap.josm.plugins.mapwithai.MapWithAIPlugin; -import org.openstreetmap.josm.plugins.mapwithai.backend.DownloadMapWithAITask; -import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAIDataUtils; -import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAIPreferenceHelper; -import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAIInfo; -import org.openstreetmap.josm.tools.GBC; -import org.openstreetmap.josm.tools.ImageProvider; -import org.openstreetmap.josm.tools.Logging; - -public class MapWithAIDownloadReader implements DownloadSource { - - @Override - public AbstractDownloadSourcePanel createPanel(DownloadDialog dialog) { - return new MapWithAIDownloadPanel(this); - } - - @Override - public void doDownload(MapWithAIDownloadData data, DownloadSettings settings) { - Bounds area = settings.getDownloadBounds().orElse(new Bounds(0, 0, 0, 0)); - DownloadMapWithAITask task = new DownloadMapWithAITask(); - task.setZoomAfterDownload(settings.zoomToData()); - DownloadParams params = new DownloadParams(); - params.withNewLayer(settings.asNewLayer()); - MapWithAIDataUtils.getForkJoinPool().execute(() -> { - try { - task.download(params, area, null).get(300, TimeUnit.SECONDS); - } catch (InterruptedException e) { - Logging.error(e); - Thread.currentThread().interrupt(); - } catch (ExecutionException | TimeoutException e) { - Logging.error(e); - } - }); - } - - @Override - public String getLabel() { - return tr("Download from {0} API", MapWithAIPlugin.NAME); - } - - @Override - public boolean onlyExpert() { - return false; - } - - /** - * Encapsulates data that is required to perform download from MapWithAI API - */ - static class MapWithAIDownloadData { - private final List url; - private final Consumer> errorReporter; - - MapWithAIDownloadData(List list, Consumer> errorReporter) { - this.url = list; - this.errorReporter = errorReporter; - } - - List getUrls() { - return url; - } - - Consumer> getErrorReporter() { - return errorReporter; - } - } - - public static class MapWithAIDownloadPanel extends AbstractDownloadSourcePanel { - private static final long serialVersionUID = -6934457612643307520L; - private final JLabel sizeCheck = new JLabel(); - - public MapWithAIDownloadPanel(MapWithAIDownloadReader downloadReader) { - super(downloadReader); - setLayout(new GridBagLayout()); - - Font labelFont = sizeCheck.getFont(); - sizeCheck.setFont(labelFont.deriveFont(Font.PLAIN, labelFont.getSize())); - add(sizeCheck, GBC.eol().anchor(GridBagConstraints.EAST).insets(5, 5, 5, 2)); - setMinimumSize(new Dimension(450, 115)); - - } - - @Override - public MapWithAIDownloadData getData() { - Consumer> errorReporter = errors -> { - }; - return new MapWithAIDownloadData(MapWithAIPreferenceHelper.getMapWithAIUrl(), errorReporter); - } - - @Override - public void rememberSettings() { - // Do nothing - } - - @Override - public void restoreSettings() { - // Do nothing - } - - @Override - public boolean checkDownload(DownloadSettings settings) { - if (!settings.getDownloadBounds().isPresent()) { - JOptionPane.showMessageDialog(this.getParent(), tr("Please select a download area first."), tr("Error"), - JOptionPane.ERROR_MESSAGE); - } - return settings.getDownloadBounds().isPresent(); - } - - @Override - public String getSimpleName() { - return "mapwithaidownloadpanel"; - } - - @Override - public Icon getIcon() { - return new ImageProvider("dialogs", "mapwithai") - .setMaxHeight(ImageProvider.ImageSizes.SIDEBUTTON.getVirtualHeight()).setOptional(true).get(); - } - - @Override - public void boundingBoxChanged(Bounds bbox) { - updateSizeCheck(bbox); - } - - private void updateSizeCheck(Bounds bbox) { - if (bbox == null) { - sizeCheck.setText(tr("No area selected yet")); - sizeCheck.setForeground(Color.darkGray); - return; - } - - displaySizeCheckResult(isDownloadAreaTooLarge(bbox)); - } - - /** - * Check if the download area is too large - * - * @param bound The bound to check - * @return {@code true} if the area is too large - */ - public static boolean isDownloadAreaTooLarge(Bounds bound) { - double width = Math.max( - bound.getMin().greatCircleDistance(new LatLon(bound.getMinLat(), bound.getMaxLon())), - bound.getMax().greatCircleDistance(new LatLon(bound.getMaxLat(), bound.getMinLon()))); - double height = Math.max( - bound.getMin().greatCircleDistance(new LatLon(bound.getMaxLat(), bound.getMinLon())), - bound.getMax().greatCircleDistance(new LatLon(bound.getMinLat(), bound.getMaxLon()))); - return height > MapWithAIDataUtils.MAXIMUM_SIDE_DIMENSIONS - || width > MapWithAIDataUtils.MAXIMUM_SIDE_DIMENSIONS; - } - - private void displaySizeCheckResult(boolean isAreaTooLarge) { - if (isAreaTooLarge) { - sizeCheck.setText(tr("Download area too large; will probably be rejected by server")); - sizeCheck.setForeground(Color.red); - } else { - sizeCheck.setText(tr("Download area ok, size probably acceptable to server")); - sizeCheck.setForeground(Color.darkGray); - } - } - } -} diff --git a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/gui/download/MapWithAIDownloadSourceType.java b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/gui/download/MapWithAIDownloadSourceType.java index 03622f2..1fd0e0d 100644 --- a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/gui/download/MapWithAIDownloadSourceType.java +++ b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/gui/download/MapWithAIDownloadSourceType.java @@ -8,9 +8,11 @@ import javax.swing.event.ChangeListener; import org.openstreetmap.josm.actions.downloadtasks.AbstractDownloadTask; import org.openstreetmap.josm.data.Bounds; +import org.openstreetmap.josm.data.coor.LatLon; import org.openstreetmap.josm.data.preferences.BooleanProperty; import org.openstreetmap.josm.gui.download.IDownloadSourceType; import org.openstreetmap.josm.plugins.mapwithai.backend.DownloadMapWithAITask; +import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAIDataUtils; public class MapWithAIDownloadSourceType implements IDownloadSourceType { static final BooleanProperty IS_ENABLED = new BooleanProperty("download.mapwithai.data", false); @@ -42,7 +44,22 @@ public class MapWithAIDownloadSourceType implements IDownloadSourceType { @Override public boolean isDownloadAreaTooLarge(Bounds bound) { - return MapWithAIDownloadReader.MapWithAIDownloadPanel.isDownloadAreaTooLarge(bound); + return isDownloadAreaTooLargeStatic(bound); + } + + /** + * Check if the download area is too large + * + * @param bound The bound to check + * @return {@code true} if the area is too large + */ + public static boolean isDownloadAreaTooLargeStatic(Bounds bound) { + double width = Math.max(bound.getMin().greatCircleDistance(new LatLon(bound.getMinLat(), bound.getMaxLon())), + bound.getMax().greatCircleDistance(new LatLon(bound.getMaxLat(), bound.getMinLon()))); + double height = Math.max(bound.getMin().greatCircleDistance(new LatLon(bound.getMaxLat(), bound.getMinLon())), + bound.getMax().greatCircleDistance(new LatLon(bound.getMinLat(), bound.getMaxLon()))); + return height > MapWithAIDataUtils.MAXIMUM_SIDE_DIMENSIONS + || width > MapWithAIDataUtils.MAXIMUM_SIDE_DIMENSIONS; } } diff --git a/test/unit/org/openstreetmap/josm/plugins/mapwithai/gui/download/MapWithAIDownloadReaderTest.java b/test/unit/org/openstreetmap/josm/plugins/mapwithai/gui/download/MapWithAIDownloadReaderTest.java deleted file mode 100644 index 7956e45..0000000 --- a/test/unit/org/openstreetmap/josm/plugins/mapwithai/gui/download/MapWithAIDownloadReaderTest.java +++ /dev/null @@ -1,146 +0,0 @@ -// License: GPL. For details, see LICENSE file. -package org.openstreetmap.josm.plugins.mapwithai.gui.download; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.openstreetmap.josm.tools.I18n.tr; - -import java.lang.reflect.Field; -import java.util.concurrent.TimeUnit; - -import javax.swing.JLabel; - -import org.junit.Assume; -import org.junit.Rule; -import org.junit.Test; -import org.openstreetmap.josm.data.Bounds; -import org.openstreetmap.josm.gui.download.DownloadSettings; -import org.openstreetmap.josm.plugins.mapwithai.MapWithAIPlugin; -import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAIDataUtils; -import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAIDataUtilsTest; -import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAIPreferenceHelper; -import org.openstreetmap.josm.plugins.mapwithai.gui.download.MapWithAIDownloadReader.MapWithAIDownloadData; -import org.openstreetmap.josm.plugins.mapwithai.testutils.MapWithAITestRules; -import org.openstreetmap.josm.testutils.JOSMTestRules; -import org.openstreetmap.josm.testutils.mockers.WindowMocker; -import org.openstreetmap.josm.tools.ImageProvider; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - -public class MapWithAIDownloadReaderTest { - @Rule - @SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") - public JOSMTestRules rules = new MapWithAITestRules().wiremock().projection().territories(); - - @Test - public void testGetLabel() { - assertEquals(tr("Download from {0} API", MapWithAIPlugin.NAME), new MapWithAIDownloadReader().getLabel()); - } - - @Test - public void testIsExpert() { - assertFalse(new MapWithAIDownloadReader().onlyExpert()); - } - - @Test - public void testDoDownload() { - new WindowMocker(); - MapWithAIDownloadReader reader = new MapWithAIDownloadReader(); - // TODO revert commit that adds these lines as soon as MapWithAI fixes timeout - // issue see - // https://mapwith.ai/maps/ml_roads?conflate_with_osm=true&theme=ml_road_vector&collaborator=josm&token=ASb3N5o9HbX8QWn8G_NtHIRQaYv3nuG2r7_f3vnGld3KhZNCxg57IsaQyssIaEw5rfRNsPpMwg4TsnrSJtIJms5m&hash=ASawRla3rBcwEjY4HIY&bbox=-108.4522247,39.0239848,-108.3368683,39.1066201&result_type=road_building_vector_xml - DownloadSettings settings = new DownloadSettings(new Bounds(39.095376, -108.4495519, 39.0987811, -108.4422314), - false, false); - MapWithAIDownloadReader.MapWithAIDownloadData data = new MapWithAIDownloadReader.MapWithAIDownloadData( - MapWithAIPreferenceHelper.getMapWithAIUrl(), errors -> { - }); - reader.doDownload(data, settings); - MapWithAIDataUtils.getForkJoinPool().awaitQuiescence(1000, TimeUnit.SECONDS); - assertNotNull(MapWithAIDataUtils.getLayer(false)); - assertFalse(MapWithAIDataUtils.getLayer(false).getDataSet().getDataSourceBounds().isEmpty()); - assertTrue(settings.getDownloadBounds().get().toBBox().bboxIsFunctionallyEqual( - MapWithAIDataUtils.getLayer(false).getDataSet().getDataSourceBounds().get(0).toBBox(), 0.0001)); - } - - @Test - public void testMapWithAIDownloadDataGetData() { - MapWithAIDownloadReader reader = new MapWithAIDownloadReader(); - MapWithAIDownloadReader.MapWithAIDownloadPanel panel = new MapWithAIDownloadReader.MapWithAIDownloadPanel( - reader); - MapWithAIDownloadData data = panel.getData(); - assertFalse(data.getUrls().isEmpty()); - } - - /** - * This rememberSettings method is blank, so just make certain nothing gets - * thrown - */ - @Test - public void testMapWithAIDownloadDataRememberSettings() { - MapWithAIDownloadReader reader = new MapWithAIDownloadReader(); - MapWithAIDownloadReader.MapWithAIDownloadPanel panel = new MapWithAIDownloadReader.MapWithAIDownloadPanel( - reader); - assertDoesNotThrow(() -> panel.rememberSettings()); - } - - /** - * This restoreSettings method is blank, so just make certain nothing gets - * thrown - */ - @Test - public void testMapWithAIDownloadDataRestoreSettings() { - MapWithAIDownloadReader reader = new MapWithAIDownloadReader(); - MapWithAIDownloadReader.MapWithAIDownloadPanel panel = new MapWithAIDownloadReader.MapWithAIDownloadPanel( - reader); - assertDoesNotThrow(() -> panel.restoreSettings()); - } - - @Test - public void testMapWithAIDownloadDataSizeCheck() - throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - MapWithAIDownloadReader reader = new MapWithAIDownloadReader(); - MapWithAIDownloadReader.MapWithAIDownloadPanel panel = new MapWithAIDownloadReader.MapWithAIDownloadPanel( - reader); - Field sizeCheckField = MapWithAIDownloadReader.MapWithAIDownloadPanel.class.getDeclaredField("sizeCheck"); - sizeCheckField.setAccessible(true); - JLabel sizeCheck = (JLabel) sizeCheckField.get(panel); - assertTrue(sizeCheck.getText().isEmpty()); - panel.boundingBoxChanged(null); - assertEquals(tr("No area selected yet"), sizeCheck.getText()); - panel.boundingBoxChanged(MapWithAIDataUtilsTest.getTestBounds()); - assertEquals(tr("Download area ok, size probably acceptable to server"), sizeCheck.getText()); - panel.boundingBoxChanged(new Bounds(0, 0, 0.0001, 10)); - assertEquals(tr("Download area too large; will probably be rejected by server"), sizeCheck.getText()); - panel.boundingBoxChanged(MapWithAIDataUtilsTest.getTestBounds()); - assertEquals(tr("Download area ok, size probably acceptable to server"), sizeCheck.getText()); - panel.boundingBoxChanged(new Bounds(0, 0, 10, 0.0001)); - assertEquals(tr("Download area too large; will probably be rejected by server"), sizeCheck.getText()); - panel.boundingBoxChanged(MapWithAIDataUtilsTest.getTestBounds()); - assertEquals(tr("Download area ok, size probably acceptable to server"), sizeCheck.getText()); - } - - @Test - public void testMapWithAIDownloadDataGetSimpleName() { - MapWithAIDownloadReader reader = new MapWithAIDownloadReader(); - MapWithAIDownloadReader.MapWithAIDownloadPanel panel = new MapWithAIDownloadReader.MapWithAIDownloadPanel( - reader); - assertFalse(panel.getSimpleName().isEmpty()); - } - - @Test - public void testMapWithAIDownloadDataGetIcon() { - // Eclipse doesn't have dialogs/mapwithai when running tests - try { - ImageProvider.get("dialogs", "mapwithai"); - } catch (Exception e) { - Assume.assumeNoException(e); - } - MapWithAIDownloadReader reader = new MapWithAIDownloadReader(); - MapWithAIDownloadReader.MapWithAIDownloadPanel panel = new MapWithAIDownloadReader.MapWithAIDownloadPanel( - reader); - assertNotNull(panel.getIcon()); - } -} diff --git a/test/unit/org/openstreetmap/josm/plugins/mapwithai/gui/download/MapWithAIDownloadSourceTypeTest.java b/test/unit/org/openstreetmap/josm/plugins/mapwithai/gui/download/MapWithAIDownloadSourceTypeTest.java new file mode 100644 index 0000000..4476373 --- /dev/null +++ b/test/unit/org/openstreetmap/josm/plugins/mapwithai/gui/download/MapWithAIDownloadSourceTypeTest.java @@ -0,0 +1,35 @@ +// License: GPL. For details, see LICENSE file. +package org.openstreetmap.josm.plugins.mapwithai.gui.download; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.openstreetmap.josm.data.Bounds; +import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAIDataUtilsTest; +import org.openstreetmap.josm.testutils.JOSMTestRules; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + +public class MapWithAIDownloadSourceTypeTest { + @Rule + @SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") + public JOSMTestRules rules = new JOSMTestRules().projection(); + + /** + * Check that we are appropriately checking that downloads are the correct size + */ + @Test + public void testMapWithAIDownloadDataSizeCheck() { + MapWithAIDownloadSourceType type = new MapWithAIDownloadSourceType(); + assertFalse(type.isDownloadAreaTooLarge(MapWithAIDataUtilsTest.getTestBounds()), + "The download area shouldn't be too large"); + assertTrue(type.isDownloadAreaTooLarge(new Bounds(0, 0, 0.0001, 10)), "The download area should be too large"); + assertFalse(type.isDownloadAreaTooLarge(MapWithAIDataUtilsTest.getTestBounds()), + "The download area shouldn't be too large"); + assertTrue(type.isDownloadAreaTooLarge(new Bounds(0, 0, 10, 0.0001)), "The download area should be too large"); + assertFalse(type.isDownloadAreaTooLarge(MapWithAIDataUtilsTest.getTestBounds()), + "The download area shouldn't be too large"); + } +}