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.progress.PleaseWaitProgressMonitor; 018import org.openstreetmap.josm.io.OnlineResource; 019import org.openstreetmap.josm.tools.Shortcut; 020 021public class UpdateDataAction extends JosmAction { 022 023 /** 024 * Constructs a new {@code UpdateDataAction}. 025 */ 026 public UpdateDataAction() { 027 super(tr("Update data"), 028 "updatedata", 029 tr("Updates the objects in the active data layer from the server."), 030 Shortcut.registerShortcut("file:updatedata", 031 tr("File: {0}", tr("Update data")), 032 KeyEvent.VK_U, Shortcut.CTRL), 033 true); 034 putValue("help", ht("/Action/UpdateData")); 035 } 036 037 /** 038 * Refreshes the enabled state 039 */ 040 @Override 041 protected void updateEnabledState() { 042 setEnabled(getEditLayer() != null && !Main.isOffline(OnlineResource.OSM_API)); 043 } 044 045 @Override 046 public void actionPerformed(ActionEvent e) { 047 if (!isEnabled()) 048 return; 049 if (getEditLayer() == null) 050 return; 051 052 List<Area> areas = new ArrayList<>(); 053 for (DataSource ds : getEditLayer().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 060 // entirely. 061 for (int i = 0; i < areas.size(); i++) { 062 for (int j = i+1; j < areas.size(); j++) { 063 areas.get(i).subtract(areas.get(j)); 064 } 065 } 066 067 for (int i = areas.size()-1; i > 0; i--) { 068 for (int j = i-1; j > 0; j--) { 069 areas.get(i).subtract(areas.get(j)); 070 } 071 } 072 073 List<Area> areasToDownload = new ArrayList<>(); 074 for (Area a : areas) { 075 if (a.isEmpty()) { 076 continue; 077 } 078 areasToDownload.add(a); 079 } 080 081 if (areasToDownload.isEmpty()) { 082 // no bounds defined in the dataset? we update all primitives in the data set 083 // using a series of multi fetch requests 084 // 085 UpdateSelectionAction.updatePrimitives(getEditLayer().data.allPrimitives()); 086 } else { 087 // bounds defined? => use the bbox downloader 088 // 089 final PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor(tr("Download data")); 090 final Future<?> future = new DownloadTaskList().download(false /* no new layer */, areasToDownload, true, false, monitor); 091 waitFuture(future, monitor); 092 } 093 } 094}