Initial implementation for setting sources in download

* Add checkbox to main UI download panel
  * For more information, see JOSM-18340
* There have been some modifications so that both JOSM UI panel download
  methods use the same class to download.
* Reuse panel from preferences for setting sources

Signed-off-by: Taylor Smock <taylor.smock@kaart.com>
pull/1/head
Taylor Smock 2020-05-21 12:07:09 -06:00
rodzic 94414ea1b6
commit d7fe108f1f
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 625F6A74A3E4311A
8 zmienionych plików z 208 dodań i 61 usunięć

Wyświetl plik

@ -23,6 +23,7 @@ import org.openstreetmap.josm.gui.MainApplication;
import org.openstreetmap.josm.gui.MainMenu;
import org.openstreetmap.josm.gui.MapFrame;
import org.openstreetmap.josm.gui.download.DownloadDialog;
import org.openstreetmap.josm.gui.download.OSMDownloadSource;
import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
import org.openstreetmap.josm.io.remotecontrol.RequestProcessor;
import org.openstreetmap.josm.plugins.Plugin;
@ -41,7 +42,9 @@ import org.openstreetmap.josm.plugins.mapwithai.data.validation.tests.RoutingIsl
import org.openstreetmap.josm.plugins.mapwithai.data.validation.tests.StreetAddressOrder;
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;
import org.openstreetmap.josm.tools.Destroyable;
@ -101,14 +104,19 @@ public final class MapWithAIPlugin extends Plugin implements Destroyable {
MapWithAIDataUtils.addMapWithAIPaintStyles();
destroyables = new ArrayList<>();
MapWithAIDownloadOptions mapWithAIDownloadOptions = new MapWithAIDownloadOptions();
mapWithAIDownloadOptions.addGui(DownloadDialog.getInstance());
destroyables.add(mapWithAIDownloadOptions);
setVersionInfo(info.localversion);
RequestProcessor.addRequestHandlerClass("mapwithai", MapWithAIRemoteControl.class);
new MapWithAIRemoteControl(); // instantiate to get action into Remote Control Preferences
destroyables = new ArrayList<>();
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));
}
@ -171,6 +179,7 @@ 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();
}

Wyświetl plik

@ -3,28 +3,41 @@ package org.openstreetmap.josm.plugins.mapwithai.backend;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Future;
import java.util.stream.Collectors;
import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask;
import org.openstreetmap.josm.actions.downloadtasks.DownloadParams;
import org.openstreetmap.josm.data.Bounds;
import org.openstreetmap.josm.data.ViewportData;
import org.openstreetmap.josm.data.osm.OsmPrimitive;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.gui.MainApplication;
import org.openstreetmap.josm.gui.MapFrame;
import org.openstreetmap.josm.gui.io.UpdatePrimitivesTask;
import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
import org.openstreetmap.josm.gui.progress.ProgressMonitor;
import org.openstreetmap.josm.io.OsmServerReader;
import org.openstreetmap.josm.io.OsmTransferException;
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAIInfo;
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAILayerInfo;
import org.openstreetmap.josm.tools.Utils;
import org.xml.sax.SAXException;
public class DownloadMapWithAITask extends DownloadOsmTask {
private List<MapWithAIInfo> urls;
public DownloadMapWithAITask() {
urls = MapWithAILayerInfo.getInstance().getLayers();
}
@Override
public Future<?> download(OsmServerReader reader, DownloadParams settings, Bounds downloadArea,
ProgressMonitor progressMonitor) {
return download(new MapWithAIDownloadTask(settings, reader, progressMonitor, zoomAfterDownload), downloadArea);
DownloadTask task = new DownloadTask(settings, tr("MapWithAI Download"), progressMonitor, false, false,
downloadArea);
return MainApplication.worker.submit(task);
}
@Override
@ -41,49 +54,58 @@ public class DownloadMapWithAITask extends DownloadOsmTask {
return null;
}
protected class MapWithAIDownloadTask extends DownloadOsmTask.DownloadTask {
protected class DownloadTask extends AbstractInternalTask {
BoundingBoxMapWithAIDownloader downloader;
final Bounds bounds;
/**
* Constructs a new {@code DownloadTask}.
*
* @param settings download settings
* @param reader OSM data reader
* @param progressMonitor progress monitor
*/
public MapWithAIDownloadTask(DownloadParams settings, OsmServerReader reader, ProgressMonitor progressMonitor) {
this(settings, reader, progressMonitor, true);
public DownloadTask(DownloadParams settings, String title, boolean ignoreException, boolean zoomAfterDownload,
Bounds bounds) {
this(settings, title, NullProgressMonitor.INSTANCE, ignoreException, zoomAfterDownload, bounds);
}
/**
* Constructs a new {@code DownloadTask}.
*
* @param settings download settings
* @param reader OSM data reader
* @param progressMonitor progress monitor
* @param zoomAfterDownload If true, the map view will zoom to download area
* after download
*/
public MapWithAIDownloadTask(DownloadParams settings, OsmServerReader reader, ProgressMonitor progressMonitor,
boolean zoomAfterDownload) {
super(settings, reader, progressMonitor, zoomAfterDownload);
public DownloadTask(DownloadParams settings, String title, ProgressMonitor progressMonitor,
boolean ignoreException, boolean zoomAfterDownload, Bounds bounds) {
super(settings, title, progressMonitor, ignoreException, zoomAfterDownload);
this.bounds = bounds;
}
@Override
protected void loadData(String newLayerName, Bounds bounds) {
MapWithAILayer layer = MapWithAIDataUtils.getLayer(true);
Collection<OsmPrimitive> primitivesToUpdate = searchPrimitivesToUpdate(bounds, layer.getDataSet());
layer.mergeFrom(dataSet);
MapFrame map = MainApplication.getMap();
if (map != null && (zoomAfterDownload
|| MainApplication.getLayerManager().getLayers().parallelStream().allMatch(layer::equals))) {
computeBbox(bounds).map(ViewportData::new).ifPresent(map.mapView::zoomTo);
protected void cancel() {
setCanceled(true);
if (downloader != null) {
downloader.cancel();
}
if (!primitivesToUpdate.isEmpty()) {
MainApplication.worker.execute(new UpdatePrimitivesTask(layer, primitivesToUpdate));
}
@Override
protected void realRun() throws SAXException, IOException, OsmTransferException {
Collection<MapWithAIInfo> relevantUrls = urls.stream()
.filter(i -> i.getBounds() == null || i.getBounds().intersects(bounds))
.collect(Collectors.toList());
ProgressMonitor monitor = getProgressMonitor();
if (relevantUrls.size() < 5) {
monitor.indeterminateSubTask(tr("MapWithAI Download"));
} else {
monitor.setTicksCount(relevantUrls.size());
}
for (MapWithAIInfo info : relevantUrls) {
if (isCanceled()) {
break;
}
downloader = new BoundingBoxMapWithAIDownloader(bounds, info, false);
DataSet ds = downloader.parseOsm(monitor.createSubTaskMonitor(1, true));
synchronized (DownloadMapWithAITask.DownloadTask.class) {
MapWithAIDataUtils.getLayer(true).getDataSet().mergeFrom(ds);
}
}
}
@Override
protected void finish() {
if (!isCanceled() && !isFailed()) {
GetDataRunnable.cleanup(MapWithAIDataUtils.getLayer(true).getDataSet(), null);
}
layer.onPostDownloadFromServer(bounds);
}
}
}

Wyświetl plik

@ -67,6 +67,10 @@ public class MapWithAILayerInfo {
/** Unique instance -- MUST be after DEFAULT_LAYER_SITES */
public static final MapWithAILayerInfo instance = new MapWithAILayerInfo();
public static MapWithAILayerInfo getInstance() {
return instance;
}
/**
* Returns the list of source layers sites.
*

Wyświetl plik

@ -0,0 +1,53 @@
// 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.GridBagLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.openstreetmap.josm.data.Bounds;
import org.openstreetmap.josm.gui.bbox.JosmMapViewer;
import org.openstreetmap.josm.gui.download.DownloadDialog;
import org.openstreetmap.josm.gui.download.DownloadSelection;
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAILayerInfo;
import org.openstreetmap.josm.plugins.mapwithai.gui.preferences.mapwithai.MapWithAIProvidersPanel;
import org.openstreetmap.josm.tools.Destroyable;
import org.openstreetmap.josm.tools.GBC;
public class MapWithAIDownloadOptions extends JPanel implements DownloadSelection, Destroyable {
private final JPanel optionPanel;
private DownloadDialog iGui;
private JosmMapViewer defaultMap;
private MapWithAIProvidersPanel mapwithaiProvidersPanel;
public MapWithAIDownloadOptions() {
optionPanel = new JPanel(new GridBagLayout());
JPanel favorites = new JPanel();
favorites.add(new JLabel("TODO: Favorites go here!")); // TODO
optionPanel.add(favorites, GBC.eol().fill(GBC.HORIZONTAL).anchor(GBC.NORTH));
mapwithaiProvidersPanel = new MapWithAIProvidersPanel(this, MapWithAILayerInfo.getInstance());
optionPanel.add(mapwithaiProvidersPanel);
}
@Override
public void addGui(DownloadDialog gui) {
iGui = gui;
iGui.addDownloadAreaSelector(optionPanel, tr("Browse Data Sources"));
}
@Override
public void setDownloadArea(Bounds area) {
// TODO
}
@Override
public void destroy() {
if (this.iGui != null) {
this.iGui.remove(this);
}
}
}

Wyświetl plik

@ -10,7 +10,6 @@ import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Future;
import java.util.function.Consumer;
import javax.swing.Icon;
@ -18,17 +17,13 @@ import javax.swing.JLabel;
import javax.swing.JOptionPane;
import org.openstreetmap.josm.actions.downloadtasks.DownloadParams;
import org.openstreetmap.josm.actions.downloadtasks.PostDownloadHandler;
import org.openstreetmap.josm.data.Bounds;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.gui.MainApplication;
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.BoundingBoxMapWithAIDownloader;
import org.openstreetmap.josm.plugins.mapwithai.backend.DetectTaskingManagerUtils;
import org.openstreetmap.josm.plugins.mapwithai.backend.DownloadMapWithAITask;
import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAIDataUtils;
import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAIPreferenceHelper;
@ -48,12 +43,9 @@ public class MapWithAIDownloadReader implements DownloadSource<MapWithAIDownload
Bounds area = settings.getDownloadBounds().orElse(new Bounds(0, 0, 0, 0));
DownloadMapWithAITask task = new DownloadMapWithAITask();
task.setZoomAfterDownload(settings.zoomToData());
data.getUrls().stream().filter(i -> i.getBounds() == null || i.getBounds().intersects(area)).forEach(url -> {
Future<?> future = task.download(
new BoundingBoxMapWithAIDownloader(area, url, DetectTaskingManagerUtils.hasTaskingManagerLayer()),
new DownloadParams(), area, null);
MainApplication.worker.execute(new PostDownloadHandler(task, future, data.getErrorReporter()));
});
DownloadParams params = new DownloadParams();
params.withNewLayer(settings.asNewLayer());
task.download(params, area, null);
}
@Override
@ -151,12 +143,24 @@ public class MapWithAIDownloadReader implements DownloadSource<MapWithAIDownload
return;
}
double width = Math.max(bbox.getMin().greatCircleDistance(new LatLon(bbox.getMinLat(), bbox.getMaxLon())),
bbox.getMax().greatCircleDistance(new LatLon(bbox.getMaxLat(), bbox.getMinLon())));
double height = Math.max(bbox.getMin().greatCircleDistance(new LatLon(bbox.getMaxLat(), bbox.getMinLon())),
bbox.getMax().greatCircleDistance(new LatLon(bbox.getMinLat(), bbox.getMaxLon())));
displaySizeCheckResult(height > MapWithAIDataUtils.MAXIMUM_SIDE_DIMENSIONS
|| width > MapWithAIDataUtils.MAXIMUM_SIDE_DIMENSIONS);
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) {

Wyświetl plik

@ -0,0 +1,48 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.mapwithai.gui.download;
import static org.openstreetmap.josm.tools.I18n.tr;
import javax.swing.JCheckBox;
import javax.swing.event.ChangeListener;
import org.openstreetmap.josm.actions.downloadtasks.AbstractDownloadTask;
import org.openstreetmap.josm.data.Bounds;
import org.openstreetmap.josm.data.preferences.BooleanProperty;
import org.openstreetmap.josm.gui.download.IDownloadSourceType;
import org.openstreetmap.josm.plugins.mapwithai.backend.DownloadMapWithAITask;
public class MapWithAIDownloadSourceType implements IDownloadSourceType {
static final BooleanProperty IS_ENABLED = new BooleanProperty("download.mapwithai.data", false);
JCheckBox cbDownloadMapWithAIData;
@Override
public JCheckBox getCheckBox(ChangeListener checkboxChangeListener) {
if (cbDownloadMapWithAIData == null) {
cbDownloadMapWithAIData = new JCheckBox(tr("MapWithAI data"), true);
cbDownloadMapWithAIData
.setToolTipText(tr("Select to download MapWithAI data in the selected download area."));
cbDownloadMapWithAIData.getModel().addChangeListener(checkboxChangeListener);
}
if (checkboxChangeListener != null) {
cbDownloadMapWithAIData.getModel().addChangeListener(checkboxChangeListener);
}
return cbDownloadMapWithAIData;
}
@Override
public Class<? extends AbstractDownloadTask<?>> getDownloadClass() {
return DownloadMapWithAITask.class;
}
@Override
public BooleanProperty getBooleanProperty() {
return IS_ENABLED;
}
@Override
public boolean isDownloadAreaTooLarge(Bounds bound) {
return MapWithAIDownloadReader.MapWithAIDownloadPanel.isDownloadAreaTooLarge(bound);
}
}

Wyświetl plik

@ -29,6 +29,7 @@ import java.util.function.Function;
import javax.swing.AbstractAction;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
@ -107,7 +108,7 @@ public class MapWithAIProvidersPanel extends JPanel {
public final JToolBar defaultToolbar;
// Private members
private final PreferenceTabbedPane gui;
private final JComponent gui;
private final transient MapWithAILayerInfo layerInfo;
/**
@ -227,7 +228,7 @@ public class MapWithAIProvidersPanel extends JPanel {
* @param gui The parent preference tab pane
* @param layerInfoArg The list of imagery entries to display
*/
public MapWithAIProvidersPanel(final PreferenceTabbedPane gui, MapWithAILayerInfo layerInfoArg) {
public MapWithAIProvidersPanel(final JComponent gui, MapWithAILayerInfo layerInfoArg) {
super(new GridBagLayout());
this.gui = gui;
this.layerInfo = layerInfoArg;
@ -474,7 +475,14 @@ public class MapWithAIProvidersPanel extends JPanel {
if (addDialog.getValue() == 1) {
try {
activeModel.addRow(p.getSourceInfo());
MapWithAIInfo info = p.getSourceInfo();
if (MapWithAIInfo.MapWithAIType.ESRI.equals(info.getSourceType())) {
for (MapWithAIInfo i : MapWithAILayerInfo.addEsriLayer(info)) {
activeModel.addRow(i);
}
} else {
activeModel.addRow(info);
}
} catch (IllegalArgumentException ex) {
if (ex.getMessage() == null || ex.getMessage().isEmpty()) {
throw ex;

Wyświetl plik

@ -23,7 +23,6 @@ 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;
import org.openstreetmap.josm.plugins.mapwithai.gui.download.MapWithAIDownloadReader.MapWithAIDownloadData;
import org.openstreetmap.josm.plugins.mapwithai.testutils.MapWithAITestRules;
import org.openstreetmap.josm.testutils.JOSMTestRules;