Changeset 14300 in josm for trunk/src/org/openstreetmap


Ignore:
Timestamp:
2018-10-06T22:01:03+02:00 (6 years ago)
Author:
Don-vip
Message:

fix #16809 - SlippyMapBBoxChooser: include tile sources from current layers (patch by ris, modified)

Location:
trunk/src/org/openstreetmap/josm/gui
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapBBoxChooser.java

    r14273 r14300  
    1616import java.util.Collections;
    1717import java.util.HashMap;
    18 import java.util.HashSet;
     18import java.util.LinkedHashMap;
    1919import java.util.List;
    2020import java.util.Map;
    21 import java.util.Set;
    2221import java.util.concurrent.CopyOnWriteArrayList;
    2322import java.util.concurrent.TimeUnit;
     23import java.util.stream.Collectors;
    2424
    2525import javax.swing.ButtonModel;
     
    5353import org.openstreetmap.josm.gui.MainApplication;
    5454import org.openstreetmap.josm.gui.layer.AbstractCachedTileSourceLayer;
     55import org.openstreetmap.josm.gui.layer.ImageryLayer;
    5556import org.openstreetmap.josm.gui.layer.MainLayerManager;
    5657import org.openstreetmap.josm.gui.layer.TMSLayer;
     
    6162 * This panel displays a map and lets the user chose a {@link BBox}.
    6263 */
    63 public class SlippyMapBBoxChooser extends JMapViewer implements BBoxChooser, ChangeListener, MainLayerManager.ActiveLayerChangeListener {
    64 
     64public class SlippyMapBBoxChooser extends JMapViewer implements BBoxChooser, ChangeListener,
     65    MainLayerManager.ActiveLayerChangeListener, MainLayerManager.LayerChangeListener {
    6566    /**
    6667     * A list of tile sources that can be used for displaying the map.
     
    7677
    7778    /**
    78      * TMS TileSource provider for the slippymap chooser
    79      */
    80     public static class TMSTileSourceProvider implements TileSourceProvider {
    81         private static final Set<String> existingSlippyMapUrls = new HashSet<>();
    82         static {
    83             // Urls that already exist in the slippymap chooser and shouldn't be copied from TMS layer list
    84             existingSlippyMapUrls.add("https://{switch:a,b,c}.tile.openstreetmap.org/{zoom}/{x}/{y}.png");      // Mapnik
    85         }
     79     * TileSource provider for the slippymap chooser.
     80     * @since 14300
     81     */
     82    public abstract static class AbstractImageryInfoBasedTileSourceProvider implements TileSourceProvider {
     83        /**
     84         * Returns the list of imagery infos backing tile sources.
     85         * @return the list of imagery infos backing tile sources
     86         */
     87        public abstract List<ImageryInfo> getImageryInfos();
    8688
    8789        @Override
     
    8991            if (!TMSLayer.PROP_ADD_TO_SLIPPYMAP_CHOOSER.get()) return Collections.<TileSource>emptyList();
    9092            List<TileSource> sources = new ArrayList<>();
    91             for (ImageryInfo info : ImageryLayerInfo.instance.getLayers()) {
    92                 if (existingSlippyMapUrls.contains(info.getUrl())) {
    93                     continue;
    94                 }
     93            for (ImageryInfo info : this.getImageryInfos()) {
    9594                try {
    9695                    TileSource source = TMSLayer.getTileSourceStatic(info);
     
    112111
    113112    /**
     113     * TileSource provider for the slippymap chooser - providing sources from imagery sources menu
     114     * @since 14300
     115     */
     116    public static class TMSTileSourceProvider extends AbstractImageryInfoBasedTileSourceProvider {
     117        @Override
     118        public List<ImageryInfo> getImageryInfos() {
     119            return ImageryLayerInfo.instance.getLayers();
     120        }
     121    }
     122
     123    /**
     124     * TileSource provider for the slippymap chooser - providing sources from current layers
     125     * @since 14300
     126     */
     127    public static class CurrentLayersTileSourceProvider extends AbstractImageryInfoBasedTileSourceProvider {
     128        @Override
     129        public List<ImageryInfo> getImageryInfos() {
     130            return MainApplication.getLayerManager().getLayers().stream().filter(
     131                layer -> layer instanceof ImageryLayer
     132            ).map(
     133                layer -> ((ImageryLayer) layer).getInfo()
     134            ).collect(Collectors.toList());
     135        }
     136    }
     137
     138    /**
    114139     * Plugins that wish to add custom tile sources to slippy map choose should call this method
    115140     * @param tileSourceProvider new tile source provider
     
    123148        addTileSourceProvider(() -> Arrays.<TileSource>asList(new OsmTileSource.Mapnik()));
    124149        addTileSourceProvider(new TMSTileSourceProvider());
     150        addTileSourceProvider(new CurrentLayersTileSourceProvider());
    125151    }
    126152
     
    178204        setMaxTilesInMemory(Config.getPref().getInt("slippy_map_chooser.max_tiles", 1000));
    179205
    180         List<TileSource> tileSources = getAllTileSources();
     206        List<TileSource> tileSources = new ArrayList<>(getAllTileSources().values());
    181207
    182208        this.showDownloadAreaButtonModel = new JToggleButton.ToggleButtonModel();
     
    211237    }
    212238
    213     private static List<TileSource> getAllTileSources() {
    214         List<TileSource> tileSources = new ArrayList<>();
    215         for (TileSourceProvider provider: providers) {
    216             tileSources.addAll(provider.getTileSources());
    217         }
    218         return tileSources;
     239    private static LinkedHashMap<String, TileSource> getAllTileSources() {
     240        // using a LinkedHashMap of <id, TileSource> to retain ordering but provide deduplication
     241        return providers.stream().flatMap(
     242            provider -> provider.getTileSources().stream()
     243        ).collect(Collectors.toMap(
     244            TileSource::getId,
     245            ts -> ts,
     246            (oldTs, newTs) -> oldTs,
     247            LinkedHashMap::new
     248        ));
    219249    }
    220250
     
    359389        this.setTileSource(tileSource);
    360390        PROP_MAPSTYLE.put(tileSource.getName()); // TODO Is name really unique?
    361         if (this.iSourceButton.getCurrentSource() != tileSource) { // prevent infinite recursion
    362             this.iSourceButton.setCurrentMap(tileSource);
    363         }
     391
     392        // we need to refresh the tile sources in case the deselected source should no longer be present
     393        // (and only remained there because its removal was deferred while the source was still the
     394        // selected one). this should also have the effect of propagating the new selection to the
     395        // iSourceButton & menu: it attempts to re-select the current source when rebuilding its menu.
     396        this.refreshTileSources();
    364397    }
    365398
     
    417450     */
    418451    public final void refreshTileSources() {
    419         iSourceButton.setSources(getAllTileSources());
    420     }
     452        final LinkedHashMap<String, TileSource> newTileSources = getAllTileSources();
     453        final TileSource currentTileSource = this.getTileController().getTileSource();
     454
     455        // re-add the currently active TileSource to prevent inconsistent display of menu
     456        newTileSources.putIfAbsent(currentTileSource.getId(), currentTileSource);
     457
     458        this.iSourceButton.setSources(new ArrayList<>(newTileSources.values()));
     459    }
     460
     461    @Override
     462    public void layerAdded(MainLayerManager.LayerAddEvent e) {
     463        if (e.getAddedLayer() instanceof ImageryLayer) {
     464            this.refreshTileSources();
     465        }
     466    }
     467
     468    @Override
     469    public void layerRemoving(MainLayerManager.LayerRemoveEvent e) {
     470        if (e.getRemovedLayer() instanceof ImageryLayer) {
     471            this.refreshTileSources();
     472        }
     473    }
     474
     475    @Override
     476    public void layerOrderChanged(MainLayerManager.LayerOrderChangeEvent e) {}
    421477}
  • trunk/src/org/openstreetmap/josm/gui/bbox/SourceButton.java

    r12962 r14300  
    8282
    8383            // attempt to initialize button group matching current state of slippyMapBBoxChooser
    84             buttonModel.setSelected(this.slippyMapBBoxChooser.getTileController().getTileSource() == ts);
     84            buttonModel.setSelected(this.slippyMapBBoxChooser.getTileController().getTileSource().getId().equals(ts.getId()));
    8585        }
    8686
  • trunk/src/org/openstreetmap/josm/gui/dialogs/MinimapDialog.java

    r12630 r14300  
    3838        slippyMap.setSizeButtonVisible(false);
    3939        slippyMap.addPropertyChangeListener(BBoxChooser.BBOX_PROP, this);
     40        MainApplication.getLayerManager().addLayerChangeListener(slippyMap);
    4041    }
    4142
Note: See TracChangeset for help on using the changeset viewer.