001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.actions; 003 004import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 005import static org.openstreetmap.josm.tools.I18n.tr; 006 007import java.awt.event.ActionEvent; 008import java.awt.event.KeyEvent; 009import java.awt.geom.Area; 010import java.util.ArrayList; 011import java.util.List; 012import java.util.concurrent.Future; 013 014import org.openstreetmap.josm.Main; 015import org.openstreetmap.josm.actions.downloadtasks.DownloadTaskList; 016import org.openstreetmap.josm.data.DataSource; 017import org.openstreetmap.josm.gui.layer.OsmDataLayer; 018import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor; 019import org.openstreetmap.josm.io.OnlineResource; 020import org.openstreetmap.josm.tools.Shortcut; 021 022public class UpdateDataAction extends JosmAction { 023 024 /** 025 * Constructs a new {@code UpdateDataAction}. 026 */ 027 public UpdateDataAction() { 028 super(tr("Update data"), 029 "updatedata", 030 tr("Updates the objects in the active data layer from the server."), 031 Shortcut.registerShortcut("file:updatedata", 032 tr("File: {0}", tr("Update data")), 033 KeyEvent.VK_U, Shortcut.CTRL), 034 true); 035 putValue("help", ht("/Action/UpdateData")); 036 } 037 038 /** 039 * Refreshes the enabled state 040 */ 041 @Override 042 protected void updateEnabledState() { 043 setEnabled(getLayerManager().getEditLayer() != null && !Main.isOffline(OnlineResource.OSM_API)); 044 } 045 046 @Override 047 public void actionPerformed(ActionEvent e) { 048 OsmDataLayer editLayer = getLayerManager().getEditLayer(); 049 if (!isEnabled() || editLayer == null) 050 return; 051 052 List<Area> areas = new ArrayList<>(); 053 for (DataSource ds : editLayer.data.dataSources) { 054 areas.add(new Area(ds.bounds.asRect())); 055 } 056 057 // The next two blocks removes every intersection from every DataSource Area 058 // This prevents downloading the same data numerous times at intersections 059 // and also skips smaller bounding boxes that are contained within larger ones entirely. 060 for (int i = 0; i < areas.size(); i++) { 061 for (int j = i+1; j < areas.size(); j++) { 062 areas.get(i).subtract(areas.get(j)); 063 } 064 } 065 066 for (int i = areas.size()-1; i > 0; i--) { 067 for (int j = i-1; j > 0; j--) { 068 areas.get(i).subtract(areas.get(j)); 069 } 070 } 071 072 List<Area> areasToDownload = new ArrayList<>(); 073 for (Area a : areas) { 074 if (a.isEmpty()) { 075 continue; 076 } 077 areasToDownload.add(a); 078 } 079 080 if (areasToDownload.isEmpty()) { 081 // no bounds defined in the dataset? we update all primitives in the data set using a series of multi fetch requests 082 UpdateSelectionAction.updatePrimitives(editLayer.data.allPrimitives()); 083 } else { 084 // bounds defined? => use the bbox downloader 085 final PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor(tr("Download data")); 086 final Future<?> future = new DownloadTaskList().download(false /* no new layer */, areasToDownload, true, false, monitor); 087 waitFuture(future, monitor); 088 } 089 } 090}