Changeset 18035 in josm for trunk/src/org


Ignore:
Timestamp:
2021-07-15T23:53:07+02:00 (3 years ago)
Author:
Don-vip
Message:

GeoImageLayer : code cleanup, extract Loader class

Location:
trunk/src/org/openstreetmap/josm/gui/layer/geoimage
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java

    r18034 r18035  
    2020import java.awt.image.BufferedImage;
    2121import java.io.File;
    22 import java.io.IOException;
    2322import java.util.ArrayList;
    24 import java.util.Arrays;
    2523import java.util.Collection;
    26 import java.util.HashSet;
    27 import java.util.LinkedHashSet;
    2824import java.util.LinkedList;
    2925import java.util.List;
    30 import java.util.Set;
    3126import java.util.concurrent.ExecutorService;
    3227import java.util.concurrent.Executors;
     
    3429import javax.swing.Action;
    3530import javax.swing.Icon;
    36 import javax.swing.JOptionPane;
    3731
    3832import org.openstreetmap.josm.actions.AutoScaleAction;
     
    5347import org.openstreetmap.josm.gui.MapView;
    5448import org.openstreetmap.josm.gui.NavigatableComponent;
    55 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
    5649import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
    5750import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
    58 import org.openstreetmap.josm.gui.io.importexport.ImageImporter;
    5951import org.openstreetmap.josm.gui.layer.AbstractModifiableLayer;
    6052import org.openstreetmap.josm.gui.layer.GpxLayer;
     
    6557import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
    6658import org.openstreetmap.josm.tools.ImageProvider;
    67 import org.openstreetmap.josm.tools.Logging;
    6859import org.openstreetmap.josm.tools.Utils;
    6960
     
    225216
    226217    /**
    227      * Loads a set of images, while displaying a dialog that indicates what the plugin is currently doing.
    228      * In facts, this object is instantiated with a list of files. These files may be JPEG files or
    229      * directories. In case of directories, they are scanned to find all the images they contain.
    230      * Then all the images that have be found are loaded as ImageEntry instances.
    231      */
    232     static final class Loader extends PleaseWaitRunnable {
    233 
    234         private boolean canceled;
    235         private GeoImageLayer layer;
    236         private final Collection<File> selection;
    237         private final Set<String> loadedDirectories = new HashSet<>();
    238         private final Set<String> errorMessages;
    239         private final GpxLayer gpxLayer;
    240 
    241         Loader(Collection<File> selection, GpxLayer gpxLayer) {
    242             super(tr("Extracting GPS locations from EXIF"));
    243             this.selection = selection;
    244             this.gpxLayer = gpxLayer;
    245             errorMessages = new LinkedHashSet<>();
    246         }
    247 
    248         private void rememberError(String message) {
    249             this.errorMessages.add(message);
    250         }
    251 
    252         @Override
    253         protected void realRun() throws IOException {
    254 
    255             progressMonitor.subTask(tr("Starting directory scan"));
    256             Collection<File> files = new ArrayList<>();
    257             try {
    258                 addRecursiveFiles(files, selection);
    259             } catch (IllegalStateException e) {
    260                 Logging.debug(e);
    261                 rememberError(e.getMessage());
    262             }
    263 
    264             if (canceled)
    265                 return;
    266             progressMonitor.subTask(tr("Read photos..."));
    267             progressMonitor.setTicksCount(files.size());
    268 
    269             // read the image files
    270             List<ImageEntry> entries = new ArrayList<>(files.size());
    271 
    272             for (File f : files) {
    273 
    274                 if (canceled) {
    275                     break;
    276                 }
    277 
    278                 progressMonitor.subTask(tr("Reading {0}...", f.getName()));
    279                 progressMonitor.worked(1);
    280 
    281                 ImageEntry e = new ImageEntry(f);
    282                 e.extractExif();
    283                 entries.add(e);
    284             }
    285             layer = new GeoImageLayer(entries, gpxLayer);
    286             files.clear();
    287         }
    288 
    289         private void addRecursiveFiles(Collection<File> files, Collection<File> sel) {
    290             boolean nullFile = false;
    291 
    292             for (File f : sel) {
    293 
    294                 if (canceled) {
    295                     break;
    296                 }
    297 
    298                 if (f == null) {
    299                     nullFile = true;
    300 
    301                 } else if (f.isDirectory()) {
    302                     String canonical = null;
    303                     try {
    304                         canonical = f.getCanonicalPath();
    305                     } catch (IOException e) {
    306                         Logging.error(e);
    307                         rememberError(tr("Unable to get canonical path for directory {0}\n",
    308                                 f.getAbsolutePath()));
    309                     }
    310 
    311                     if (canonical == null || loadedDirectories.contains(canonical)) {
    312                         continue;
    313                     } else {
    314                         loadedDirectories.add(canonical);
    315                     }
    316 
    317                     File[] children = f.listFiles(ImageImporter.FILE_FILTER_WITH_FOLDERS);
    318                     if (children != null) {
    319                         progressMonitor.subTask(tr("Scanning directory {0}", f.getPath()));
    320                         addRecursiveFiles(files, Arrays.asList(children));
    321                     } else {
    322                         rememberError(tr("Error while getting files from directory {0}\n", f.getPath()));
    323                     }
    324 
    325                 } else {
    326                     files.add(f);
    327                 }
    328             }
    329 
    330             if (nullFile) {
    331                 throw new IllegalStateException(tr("One of the selected files was null"));
    332             }
    333         }
    334 
    335         private String formatErrorMessages() {
    336             StringBuilder sb = new StringBuilder();
    337             sb.append("<html>");
    338             if (errorMessages.size() == 1) {
    339                 sb.append(Utils.escapeReservedCharactersHTML(errorMessages.iterator().next()));
    340             } else {
    341                 sb.append(Utils.joinAsHtmlUnorderedList(errorMessages));
    342             }
    343             sb.append("</html>");
    344             return sb.toString();
    345         }
    346 
    347         @Override protected void finish() {
    348             if (!errorMessages.isEmpty()) {
    349                 JOptionPane.showMessageDialog(
    350                         MainApplication.getMainFrame(),
    351                         formatErrorMessages(),
    352                         tr("Error"),
    353                         JOptionPane.ERROR_MESSAGE
    354                         );
    355             }
    356             if (layer != null) {
    357                 MainApplication.getLayerManager().addLayer(layer);
    358 
    359                 if (!canceled && !layer.getImageData().getImages().isEmpty()) {
    360                     boolean noGeotagFound = true;
    361                     for (ImageEntry e : layer.getImageData().getImages()) {
    362                         if (e.getPos() != null) {
    363                             noGeotagFound = false;
    364                         }
    365                     }
    366                     if (noGeotagFound) {
    367                         new CorrelateGpxWithImages(layer).actionPerformed(null);
    368                     }
    369                 }
    370             }
    371         }
    372 
    373         @Override protected void cancel() {
    374             canceled = true;
    375         }
    376     }
    377 
    378     /**
    379218     * Create a GeoImageLayer asynchronously
    380219     * @param files the list of image files to display
     
    382221     */
    383222    public static void create(Collection<File> files, GpxLayer gpxLayer) {
    384         MainApplication.worker.execute(new Loader(files, gpxLayer));
     223        MainApplication.worker.execute(new ImagesLoader(files, gpxLayer));
    385224    }
    386225
     
    400239    @Override
    401240    public Action[] getMenuEntries() {
    402 
    403241        List<Action> entries = new ArrayList<>();
    404242        entries.add(LayerListDialog.getInstance().createShowHideLayerAction());
     
    421259
    422260        return entries.toArray(new Action[0]);
    423 
    424261    }
    425262
     
    447284    }
    448285
    449     @Override public Object getInfoComponent() {
     286    @Override
     287    public Object getInfoComponent() {
    450288        return infoText();
    451289    }
     
    549387            }
    550388
    551             if (null == offscreenBuffer || offscreenBuffer.getWidth() != width  // reuse the old buffer if possible
     389            if (null == offscreenBuffer
     390                    || offscreenBuffer.getWidth() != width  // reuse the old buffer if possible
    552391                    || offscreenBuffer.getHeight() != height) {
    553                 offscreenBuffer = new BufferedImage(width, height,
    554                         BufferedImage.TYPE_INT_ARGB);
     392                offscreenBuffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    555393                updateOffscreenBuffer = true;
    556394            }
     
    970808        if (gpxFauxLayer == null) {
    971809            GpxData gpxData = new GpxData();
    972             List<ImageEntry> imageList = data.getImages();
    973             for (ImageEntry image : imageList) {
    974                 WayPoint twaypoint = new WayPoint(image.getPos());
    975                 gpxData.addWaypoint(twaypoint);
     810            for (ImageEntry image : data.getImages()) {
     811                gpxData.addWaypoint(new WayPoint(image.getPos()));
    976812            }
    977813            gpxFauxLayer = new GpxLayer(gpxData);
Note: See TracChangeset for help on using the changeset viewer.