Ignore:
Timestamp:
2010-06-19T14:11:57+02:00 (15 years ago)
Author:
stoecker
Message:

fix josm 5152

Location:
applications/editors/josm/plugins/wmsplugin/src/wmsplugin
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSLayer.java

    r21795 r21796  
    3838import org.openstreetmap.josm.io.CacheFiles;
    3939import org.openstreetmap.josm.tools.ImageProvider;
     40import org.openstreetmap.josm.data.Preferences.PreferenceChangeEvent;
     41import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
    4042
    4143/**
     
    4345 * fetched this way is tiled and managed to the disc to reduce server load.
    4446 */
    45 public class WMSLayer extends Layer {
    46         protected static final Icon icon =
    47                 new ImageIcon(Toolkit.getDefaultToolkit().createImage(WMSPlugin.class.getResource("/images/wms_small.png")));
    48 
    49         public int messageNum = 5; //limit for messages per layer
    50         protected MapView mv;
    51         protected String resolution;
    52         protected boolean stopAfterPaint = false;
    53         protected int imageSize = 500;
    54         protected int dax = 10;
    55         protected int day = 10;
    56         protected int minZoom = 3;
    57         protected double dx = 0.0;
    58         protected double dy = 0.0;
    59         protected double pixelPerDegree;
    60         protected GeorefImage[][] images = new GeorefImage[dax][day];
    61         JCheckBoxMenuItem startstop = new JCheckBoxMenuItem(tr("Automatic downloading"), true);
    62         protected JCheckBoxMenuItem alphaChannel = new JCheckBoxMenuItem(new ToggleAlphaAction());
    63         protected String baseURL;
    64         protected String cookies;
    65         protected final int serializeFormatVersion = 5;
    66 
    67         private ExecutorService executor = null;
    68 
    69         /** set to true if this layer uses an invalid base url */
    70         private boolean usesInvalidUrl = false;
    71         /** set to true if the user confirmed to use an potentially invalid WMS base url */
    72         private boolean isInvalidUrlConfirmed = false;
    73 
    74         public WMSLayer() {
    75                 this(tr("Blank Layer"), null, null);
    76                 initializeImages();
    77                 mv = Main.map.mapView;
    78         }
    79 
    80         public WMSLayer(String name, String baseURL, String cookies) {
    81                 super(name);
    82                 alphaChannel.setSelected(Main.pref.getBoolean("wmsplugin.alpha_channel"));
    83                 setBackgroundLayer(true); /* set global background variable */
    84                 initializeImages();
    85                 this.baseURL = baseURL;
    86                 this.cookies = cookies;
    87                 WMSGrabber.getProjection(baseURL, true);
    88                 mv = Main.map.mapView;
    89 
    90                 // quick hack to predefine the PixelDensity to reuse the cache
    91                 int codeIndex = getName().indexOf("#PPD=");
    92                 if (codeIndex != -1) {
    93                         pixelPerDegree = Double.valueOf(getName().substring(codeIndex+5));
    94                 } else {
    95                         pixelPerDegree = getPPD();
    96                 }
    97                 resolution = mv.getDist100PixelText();
    98 
    99                 executor = Executors.newFixedThreadPool(3);
    100                 if (baseURL != null && !baseURL.startsWith("html:") && !WMSGrabber.isUrlWithPatterns(baseURL)) {
    101                         if (!(baseURL.endsWith("&") || baseURL.endsWith("?"))) {
    102                                 if (!confirmMalformedUrl(baseURL)) {
    103                                         System.out.println(tr("Warning: WMS layer deactivated because of malformed base url ''{0}''", baseURL));
    104                                         usesInvalidUrl = true;
    105                                         setName(getName() + tr("(deactivated)"));
    106                                         return;
    107                                 } else {
    108                                         isInvalidUrlConfirmed = true;
    109                                 }
    110                         }
    111                 }
    112         }
    113 
    114         public boolean hasAutoDownload(){
    115                 return startstop.isSelected();
    116         }
    117 
    118         public double getDx(){
    119                 return dx;
    120         }
    121 
    122         public double getDy(){
    123                 return dy;
    124         }
    125 
    126         @Override
    127         public void destroy() {
    128                 try {
    129                         executor.shutdownNow();
    130                         // Might not be initialized, so catch NullPointer as well
    131                 } catch(Exception x) {
    132                         x.printStackTrace();
    133                 }
    134         }
    135 
    136         public double getPPD(){
    137                 ProjectionBounds bounds = mv.getProjectionBounds();
    138                 return mv.getWidth() / (bounds.max.east() - bounds.min.east());
    139         }
    140 
    141         public void initializeImages() {
    142                 images = new GeorefImage[dax][day];
    143                 for(int x = 0; x<dax; ++x) {
    144                         for(int y = 0; y<day; ++y) {
    145                                 images[x][y]= new GeorefImage(false);
    146                         }
    147                 }
    148         }
    149 
    150         @Override public Icon getIcon() {
    151                 return icon;
    152         }
    153 
    154         @Override public String getToolTipText() {
    155                 if(startstop.isSelected())
    156                         return tr("WMS layer ({0}), automatically downloading in zoom {1}", getName(), resolution);
    157                 else
    158                         return tr("WMS layer ({0}), downloading in zoom {1}", getName(), resolution);
    159         }
    160 
    161         @Override public boolean isMergable(Layer other) {
    162                 return false;
    163         }
    164 
    165         @Override public void mergeFrom(Layer from) {
    166         }
    167 
    168         private ProjectionBounds XYtoBounds (int x, int y) {
    169                 return new ProjectionBounds(
    170                                 new EastNorth(      x * imageSize / pixelPerDegree,       y * imageSize / pixelPerDegree),
    171                                 new EastNorth((x + 1) * imageSize / pixelPerDegree, (y + 1) * imageSize / pixelPerDegree));
    172         }
    173 
    174         private int modulo (int a, int b) {
    175                 return a % b >= 0 ? a%b : a%b+b;
    176         }
    177 
    178         private boolean zoomIsTooBig() {
    179                 //don't download when it's too outzoomed
    180                 return pixelPerDegree / getPPD() > minZoom;
    181         }
    182 
    183         @Override public void paint(Graphics2D g, final MapView mv, Bounds bounds) {
    184                 if(baseURL == null) return;
    185                 if (usesInvalidUrl && !isInvalidUrlConfirmed) return;
    186 
    187                 if (zoomIsTooBig()) {
    188                         for(int x = 0; x<dax; ++x) {
    189                                 for(int y = 0; y<day; ++y) {
    190                                         images[modulo(x,dax)][modulo(y,day)].paint(g, mv, dx, dy);
    191                                 }
    192                         }
    193                 } else {
    194                         downloadAndPaintVisible(g, mv);
    195                 }
    196         }
    197 
    198         public void displace(double dx, double dy) {
    199                 this.dx += dx;
    200                 this.dy += dy;
    201         }
    202 
    203         protected boolean confirmMalformedUrl(String url) {
    204                 if (isInvalidUrlConfirmed)
    205                         return true;
    206                 String msg  = tr("<html>The base URL<br>"
    207                                 + "''{0}''<br>"
    208                                 + "for this WMS layer does neither end with a ''&'' nor with a ''?''.<br>"
    209                                 + "This is likely to lead to invalid WMS request. You should check your<br>"
    210                                 + "preference settings.<br>"
    211                                 + "Do you want to fetch WMS tiles anyway?",
    212                                 url);
    213                 String [] options = new String[] {
    214                                 tr("Yes, fetch images"),
    215                                 tr("No, abort")
    216                 };
    217                 int ret = JOptionPane.showOptionDialog(
    218                                 Main.parent,
    219                                 msg,
    220                                 tr("Invalid URL?"),
    221                                 JOptionPane.YES_NO_OPTION,
    222                                 JOptionPane.WARNING_MESSAGE,
    223                                 null,
    224                                 options, options[1]
    225                 );
    226                 switch(ret) {
    227                 case JOptionPane.YES_OPTION: return true;
    228                 default: return false;
    229                 }
    230         }
    231 
    232         protected void downloadAndPaintVisible(Graphics g, final MapView mv){
    233                 if (usesInvalidUrl)
    234                         return;
    235 
    236                 ProjectionBounds bounds = mv.getProjectionBounds();
    237                 int bminx= (int)Math.floor (((bounds.min.east() - dx) * pixelPerDegree) / imageSize );
    238                 int bminy= (int)Math.floor (((bounds.min.north() - dy) * pixelPerDegree) / imageSize );
    239                 int bmaxx= (int)Math.ceil  (((bounds.max.east() - dx) * pixelPerDegree) / imageSize );
    240                 int bmaxy= (int)Math.ceil  (((bounds.max.north() - dy) * pixelPerDegree) / imageSize );
    241 
    242                 for(int x = bminx; x<bmaxx; ++x) {
    243                         for(int y = bminy; y<bmaxy; ++y){
    244                                 GeorefImage img = images[modulo(x,dax)][modulo(y,day)];
    245                                 if(!img.paint(g, mv, dx, dy) && !img.downloadingStarted){
    246                                         img.downloadingStarted = true;
    247                                         img.image = null;
    248                                         img.flushedResizedCachedInstance();
    249                                         Grabber gr = WMSPlugin.getGrabber(XYtoBounds(x,y), img, mv, this);
    250                                         if(!gr.loadFromCache()){
    251                                                 gr.setPriority(1);
    252                                                 executor.submit(gr);
    253                                         }
    254                                 }
    255                         }
    256                 }
    257         }
    258 
    259         @Override public void visitBoundingBox(BoundingXYVisitor v) {
    260                 for(int x = 0; x<dax; ++x) {
    261                         for(int y = 0; y<day; ++y)
    262                                 if(images[x][y].image!=null){
    263                                         v.visit(images[x][y].min);
    264                                         v.visit(images[x][y].max);
    265                                 }
    266                 }
    267         }
    268 
    269         @Override public Object getInfoComponent() {
    270                 return getToolTipText();
    271         }
    272 
    273         @Override public Component[] getMenuEntries() {
    274                 return new Component[]{
    275                                 new JMenuItem(LayerListDialog.getInstance().createActivateLayerAction(this)),
    276                                 new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
    277                                 new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
    278                                 new JSeparator(),
    279                                 new JMenuItem(new LoadWmsAction()),
    280                                 new JMenuItem(new SaveWmsAction()),
    281                                 new JMenuItem(new BookmarkWmsAction()),
    282                                 new JSeparator(),
    283                                 startstop,
    284                                 alphaChannel,
    285                                 new JMenuItem(new ChangeResolutionAction()),
    286                                 new JMenuItem(new ReloadErrorTilesAction()),
    287                                 new JMenuItem(new DownloadAction()),
    288                                 new JSeparator(),
    289                                 new JMenuItem(new LayerListPopup.InfoAction(this))
    290                 };
    291         }
    292 
    293         public GeorefImage findImage(EastNorth eastNorth) {
    294                 for(int x = 0; x<dax; ++x) {
    295                         for(int y = 0; y<day; ++y)
    296                                 if(images[x][y].image!=null && images[x][y].min!=null && images[x][y].max!=null)
    297                                         if(images[x][y].contains(eastNorth, dx, dy))
    298                                                 return images[x][y];
    299                 }
    300                 return null;
    301         }
    302 
    303         public class DownloadAction extends AbstractAction {
    304                 public DownloadAction() {
    305                         super(tr("Download visible tiles"));
    306                 }
    307                 public void actionPerformed(ActionEvent ev) {
    308                         if (zoomIsTooBig()) {
    309                                 JOptionPane.showMessageDialog(
    310                                                 Main.parent,
    311                                                 tr("The requested area is too big. Please zoom in a little, or change resolution"),
    312                                                 tr("Error"),
    313                                                 JOptionPane.ERROR_MESSAGE
    314                                 );
    315                         } else {
    316                                 downloadAndPaintVisible(mv.getGraphics(), mv);
    317                         }
    318                 }
    319         }
    320 
    321         public class ChangeResolutionAction extends AbstractAction {
    322                 public ChangeResolutionAction() {
    323                         super(tr("Change resolution"));
    324                 }
    325                 public void actionPerformed(ActionEvent ev) {
    326                         initializeImages();
    327                         resolution = mv.getDist100PixelText();
    328                         pixelPerDegree = getPPD();
    329                         mv.repaint();
    330                 }
    331         }
    332 
    333         public class ReloadErrorTilesAction extends AbstractAction {
    334                 public ReloadErrorTilesAction() {
    335                         super(tr("Reload erroneous tiles"));
    336                 }
    337                 public void actionPerformed(ActionEvent ev) {
    338                         // Delete small files, because they're probably blank tiles.
    339                         // See https://josm.openstreetmap.de/ticket/2307
    340                         WMSPlugin.cache.customCleanUp(CacheFiles.CLEAN_SMALL_FILES, 4096);
    341 
    342                         for (int x = 0; x < dax; ++x) {
    343                                 for (int y = 0; y < day; ++y) {
    344                                         GeorefImage img = images[modulo(x,dax)][modulo(y,day)];
    345                                         if(img.failed){
    346                                                 img.image = null;
    347                                                 img.flushedResizedCachedInstance();
    348                                                 img.downloadingStarted = false;
    349                                                 img.failed = false;
    350                                                 mv.repaint();
    351                                         }
    352                                 }
    353                         }
    354                 }
    355         }
    356 
    357         public class ToggleAlphaAction extends AbstractAction {
    358                 public ToggleAlphaAction() {
    359                         super(tr("Alpha channel"));
    360                 }
    361                 public void actionPerformed(ActionEvent ev) {
    362                         JCheckBoxMenuItem checkbox = (JCheckBoxMenuItem) ev.getSource();
    363                         boolean alphaChannel = checkbox.isSelected();
    364                         Main.pref.put("wmsplugin.alpha_channel", alphaChannel);
    365 
    366                         // clear all resized cached instances and repaint the layer
    367                         for (int x = 0; x < dax; ++x) {
    368                                 for (int y = 0; y < day; ++y) {
    369                                         GeorefImage img = images[modulo(x, dax)][modulo(y, day)];
    370                                         img.flushedResizedCachedInstance();
    371                                 }
    372                         }
    373                         mv.repaint();
    374                 }
    375         }
    376 
    377         public class SaveWmsAction extends AbstractAction {
    378                 public SaveWmsAction() {
    379                         super(tr("Save WMS layer to file"), ImageProvider.get("save"));
    380                 }
    381                 public void actionPerformed(ActionEvent ev) {
    382                         File f = SaveActionBase.createAndOpenSaveFileChooser(
    383                                         tr("Save WMS layer"), ".wms");
    384                         try {
    385                                 if (f != null) {
    386                                         ObjectOutputStream oos = new ObjectOutputStream(
    387                                                         new FileOutputStream(f)
    388                                         );
    389                                         oos.writeInt(serializeFormatVersion);
    390                                         oos.writeInt(dax);
    391                                         oos.writeInt(day);
    392                                         oos.writeInt(imageSize);
    393                                         oos.writeDouble(pixelPerDegree);
    394                                         oos.writeObject(getName());
    395                                         oos.writeObject(baseURL);
    396                                         oos.writeObject(images);
    397                                         oos.close();
    398                                 }
    399                         } catch (Exception ex) {
    400                                 ex.printStackTrace(System.out);
    401                         }
    402                 }
    403         }
    404 
    405         public class LoadWmsAction extends AbstractAction {
    406                 public LoadWmsAction() {
    407                         super(tr("Load WMS layer from file"), ImageProvider.get("load"));
    408                 }
    409                 public void actionPerformed(ActionEvent ev) {
    410                         JFileChooser fc = DiskAccessAction.createAndOpenFileChooser(true,
    411                                         false, tr("Load WMS layer"), "wms");
    412                         if(fc == null) return;
    413                         File f = fc.getSelectedFile();
    414                         if (f == null) return;
    415                         try
    416                         {
    417                                 FileInputStream fis = new FileInputStream(f);
    418                                 ObjectInputStream ois = new ObjectInputStream(fis);
    419                                 int sfv = ois.readInt();
    420                                 if (sfv != serializeFormatVersion) {
    421                                         JOptionPane.showMessageDialog(Main.parent,
    422                                                         tr("Unsupported WMS file version; found {0}, expected {1}", sfv, serializeFormatVersion),
    423                                                         tr("File Format Error"),
    424                                                         JOptionPane.ERROR_MESSAGE);
    425                                         return;
    426                                 }
    427                                 startstop.setSelected(false);
    428                                 dax = ois.readInt();
    429                                 day = ois.readInt();
    430                                 imageSize = ois.readInt();
    431                                 pixelPerDegree = ois.readDouble();
    432                                 setName((String)ois.readObject());
    433                                 baseURL = (String) ois.readObject();
    434                                 images = (GeorefImage[][])ois.readObject();
    435                                 ois.close();
    436                                 fis.close();
    437                                 mv.repaint();
    438                         }
    439                         catch (Exception ex) {
    440                                 // FIXME be more specific
    441                                 ex.printStackTrace(System.out);
    442                                 JOptionPane.showMessageDialog(Main.parent,
    443                                                 tr("Error loading file"),
    444                                                 tr("Error"),
    445                                                 JOptionPane.ERROR_MESSAGE);
    446                                 return;
    447                         }
    448                 }
    449         }
    450         /**
    451          * This action will add a WMS layer menu entry with the current WMS layer URL and name extended by the current resolution.
    452          * When using the menu entry again, the WMS cache will be used properly.
    453          */
    454         public class BookmarkWmsAction extends AbstractAction {
    455                 public BookmarkWmsAction() {
    456                         super(tr("Set WMS Bookmark"));
    457                 }
    458                 public void actionPerformed(ActionEvent ev) {
    459                         int i = 0;
    460                         while (Main.pref.hasKey("wmsplugin.url."+i+".url")) {
    461                                 i++;
    462                         }
    463                         String baseName;
    464                         // cut old parameter
    465                         int parameterIndex = getName().indexOf("#PPD=");
    466                         if (parameterIndex != -1) {
    467                                 baseName = getName().substring(0,parameterIndex);
    468                         }
    469                         else {
    470                                 baseName = getName();
    471                         }
    472                         Main.pref.put("wmsplugin.url."+ i +".url",baseURL );
    473                         Main.pref.put("wmsplugin.url."+String.valueOf(i)+".name", baseName + "#PPD=" + pixelPerDegree );
    474                         WMSPlugin.refreshMenu();
    475                 }
    476         }
     47public class WMSLayer extends Layer implements PreferenceChangedListener {
     48    protected static final Icon icon =
     49        new ImageIcon(Toolkit.getDefaultToolkit().createImage(WMSPlugin.class.getResource("/images/wms_small.png")));
     50
     51    public int messageNum = 5; //limit for messages per layer
     52    protected MapView mv;
     53    protected String resolution;
     54    protected boolean stopAfterPaint = false;
     55    protected int imageSize = 500;
     56    protected int dax = 10;
     57    protected int day = 10;
     58    protected int minZoom = 3;
     59    protected double dx = 0.0;
     60    protected double dy = 0.0;
     61    protected double pixelPerDegree;
     62    protected GeorefImage[][] images = new GeorefImage[dax][day];
     63    JCheckBoxMenuItem startstop = new JCheckBoxMenuItem(tr("Automatic downloading"), true);
     64    protected JCheckBoxMenuItem alphaChannel = new JCheckBoxMenuItem(new ToggleAlphaAction());
     65    protected String baseURL;
     66    protected String cookies;
     67    protected final int serializeFormatVersion = 5;
     68
     69    private ExecutorService executor = null;
     70
     71    /** set to true if this layer uses an invalid base url */
     72    private boolean usesInvalidUrl = false;
     73    /** set to true if the user confirmed to use an potentially invalid WMS base url */
     74    private boolean isInvalidUrlConfirmed = false;
     75
     76    public WMSLayer() {
     77        this(tr("Blank Layer"), null, null);
     78        initializeImages();
     79        mv = Main.map.mapView;
     80    }
     81
     82    public WMSLayer(String name, String baseURL, String cookies) {
     83        super(name);
     84        alphaChannel.setSelected(Main.pref.getBoolean("wmsplugin.alpha_channel"));
     85        setBackgroundLayer(true); /* set global background variable */
     86        initializeImages();
     87        this.baseURL = baseURL;
     88        this.cookies = cookies;
     89        WMSGrabber.getProjection(baseURL, true);
     90        mv = Main.map.mapView;
     91
     92        // quick hack to predefine the PixelDensity to reuse the cache
     93        int codeIndex = getName().indexOf("#PPD=");
     94        if (codeIndex != -1) {
     95            pixelPerDegree = Double.valueOf(getName().substring(codeIndex+5));
     96        } else {
     97            pixelPerDegree = getPPD();
     98        }
     99        resolution = mv.getDist100PixelText();
     100
     101        executor = Executors.newFixedThreadPool(
     102            Main.pref.getInteger("wmsplugin.numThreads",
     103            WMSPlugin.simultaneousConnections));
     104        if (baseURL != null && !baseURL.startsWith("html:") && !WMSGrabber.isUrlWithPatterns(baseURL)) {
     105            if (!(baseURL.endsWith("&") || baseURL.endsWith("?"))) {
     106                if (!confirmMalformedUrl(baseURL)) {
     107                    System.out.println(tr("Warning: WMS layer deactivated because of malformed base url ''{0}''", baseURL));
     108                    usesInvalidUrl = true;
     109                    setName(getName() + tr("(deactivated)"));
     110                    return;
     111                } else {
     112                    isInvalidUrlConfirmed = true;
     113                }
     114            }
     115        }
     116
     117        Main.pref.addPreferenceChangeListener(this);
     118    }
     119
     120    public boolean hasAutoDownload(){
     121        return startstop.isSelected();
     122    }
     123
     124    public double getDx(){
     125        return dx;
     126    }
     127
     128    public double getDy(){
     129        return dy;
     130    }
     131
     132    @Override
     133    public void destroy() {
     134        try {
     135            executor.shutdownNow();
     136            // Might not be initialized, so catch NullPointer as well
     137        } catch(Exception x) {
     138            x.printStackTrace();
     139        }
     140    }
     141
     142    public double getPPD(){
     143        ProjectionBounds bounds = mv.getProjectionBounds();
     144        return mv.getWidth() / (bounds.max.east() - bounds.min.east());
     145    }
     146
     147    public void initializeImages() {
     148        images = new GeorefImage[dax][day];
     149        for(int x = 0; x<dax; ++x) {
     150            for(int y = 0; y<day; ++y) {
     151                images[x][y]= new GeorefImage(false);
     152            }
     153        }
     154    }
     155
     156    @Override public Icon getIcon() {
     157        return icon;
     158    }
     159
     160    @Override public String getToolTipText() {
     161        if(startstop.isSelected())
     162            return tr("WMS layer ({0}), automatically downloading in zoom {1}", getName(), resolution);
     163        else
     164            return tr("WMS layer ({0}), downloading in zoom {1}", getName(), resolution);
     165    }
     166
     167    @Override public boolean isMergable(Layer other) {
     168        return false;
     169    }
     170
     171    @Override public void mergeFrom(Layer from) {
     172    }
     173
     174    private ProjectionBounds XYtoBounds (int x, int y) {
     175        return new ProjectionBounds(
     176            new EastNorth(      x * imageSize / pixelPerDegree,       y * imageSize / pixelPerDegree),
     177            new EastNorth((x + 1) * imageSize / pixelPerDegree, (y + 1) * imageSize / pixelPerDegree));
     178    }
     179
     180    private int modulo (int a, int b) {
     181        return a % b >= 0 ? a%b : a%b+b;
     182    }
     183
     184    private boolean zoomIsTooBig() {
     185        //don't download when it's too outzoomed
     186        return pixelPerDegree / getPPD() > minZoom;
     187    }
     188
     189    @Override public void paint(Graphics2D g, final MapView mv, Bounds bounds) {
     190        if(baseURL == null) return;
     191        if (usesInvalidUrl && !isInvalidUrlConfirmed) return;
     192
     193        if (zoomIsTooBig()) {
     194            for(int x = 0; x<dax; ++x) {
     195                for(int y = 0; y<day; ++y) {
     196                    images[modulo(x,dax)][modulo(y,day)].paint(g, mv, dx, dy);
     197                }
     198            }
     199        } else {
     200            downloadAndPaintVisible(g, mv);
     201        }
     202    }
     203
     204    public void displace(double dx, double dy) {
     205        this.dx += dx;
     206        this.dy += dy;
     207    }
     208
     209    protected boolean confirmMalformedUrl(String url) {
     210        if (isInvalidUrlConfirmed)
     211            return true;
     212        String msg  = tr("<html>The base URL<br>"
     213            + "''{0}''<br>"
     214            + "for this WMS layer does neither end with a ''&'' nor with a ''?''.<br>"
     215            + "This is likely to lead to invalid WMS request. You should check your<br>"
     216            + "preference settings.<br>"
     217            + "Do you want to fetch WMS tiles anyway?",
     218            url);
     219        String [] options = new String[] {
     220            tr("Yes, fetch images"),
     221            tr("No, abort")
     222        };
     223        int ret = JOptionPane.showOptionDialog(
     224            Main.parent,
     225            msg,
     226            tr("Invalid URL?"),
     227            JOptionPane.YES_NO_OPTION,
     228            JOptionPane.WARNING_MESSAGE,
     229            null,
     230            options, options[1]
     231        );
     232        switch(ret) {
     233        case JOptionPane.YES_OPTION: return true;
     234        default: return false;
     235        }
     236    }
     237
     238    protected void downloadAndPaintVisible(Graphics g, final MapView mv){
     239        if (usesInvalidUrl)
     240            return;
     241
     242        ProjectionBounds bounds = mv.getProjectionBounds();
     243        int bminx= (int)Math.floor (((bounds.min.east() - dx) * pixelPerDegree) / imageSize );
     244        int bminy= (int)Math.floor (((bounds.min.north() - dy) * pixelPerDegree) / imageSize );
     245        int bmaxx= (int)Math.ceil  (((bounds.max.east() - dx) * pixelPerDegree) / imageSize );
     246        int bmaxy= (int)Math.ceil  (((bounds.max.north() - dy) * pixelPerDegree) / imageSize );
     247
     248        for(int x = bminx; x<bmaxx; ++x) {
     249            for(int y = bminy; y<bmaxy; ++y){
     250                GeorefImage img = images[modulo(x,dax)][modulo(y,day)];
     251                if(!img.paint(g, mv, dx, dy) && !img.downloadingStarted){
     252                    img.downloadingStarted = true;
     253                    img.image = null;
     254                    img.flushedResizedCachedInstance();
     255                    Grabber gr = WMSPlugin.getGrabber(XYtoBounds(x,y), img, mv, this);
     256                    if(!gr.loadFromCache()){
     257                        gr.setPriority(1);
     258                        executor.submit(gr);
     259                    }
     260                }
     261            }
     262        }
     263    }
     264
     265    @Override public void visitBoundingBox(BoundingXYVisitor v) {
     266        for(int x = 0; x<dax; ++x) {
     267            for(int y = 0; y<day; ++y)
     268                if(images[x][y].image!=null){
     269                    v.visit(images[x][y].min);
     270                    v.visit(images[x][y].max);
     271                }
     272        }
     273    }
     274
     275    @Override public Object getInfoComponent() {
     276        return getToolTipText();
     277    }
     278
     279    @Override public Component[] getMenuEntries() {
     280        return new Component[]{
     281            new JMenuItem(LayerListDialog.getInstance().createActivateLayerAction(this)),
     282            new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
     283            new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
     284            new JSeparator(),
     285            new JMenuItem(new LoadWmsAction()),
     286            new JMenuItem(new SaveWmsAction()),
     287            new JMenuItem(new BookmarkWmsAction()),
     288            new JSeparator(),
     289            startstop,
     290            alphaChannel,
     291            new JMenuItem(new ChangeResolutionAction()),
     292            new JMenuItem(new ReloadErrorTilesAction()),
     293            new JMenuItem(new DownloadAction()),
     294            new JSeparator(),
     295            new JMenuItem(new LayerListPopup.InfoAction(this))
     296        };
     297    }
     298
     299    public GeorefImage findImage(EastNorth eastNorth) {
     300        for(int x = 0; x<dax; ++x) {
     301            for(int y = 0; y<day; ++y)
     302                if(images[x][y].image!=null && images[x][y].min!=null && images[x][y].max!=null)
     303                    if(images[x][y].contains(eastNorth, dx, dy))
     304                        return images[x][y];
     305        }
     306        return null;
     307    }
     308
     309    public class DownloadAction extends AbstractAction {
     310        public DownloadAction() {
     311            super(tr("Download visible tiles"));
     312        }
     313        public void actionPerformed(ActionEvent ev) {
     314            if (zoomIsTooBig()) {
     315                JOptionPane.showMessageDialog(
     316                    Main.parent,
     317                    tr("The requested area is too big. Please zoom in a little, or change resolution"),
     318                    tr("Error"),
     319                    JOptionPane.ERROR_MESSAGE
     320                );
     321            } else {
     322                downloadAndPaintVisible(mv.getGraphics(), mv);
     323            }
     324        }
     325    }
     326
     327    public class ChangeResolutionAction extends AbstractAction {
     328        public ChangeResolutionAction() {
     329            super(tr("Change resolution"));
     330        }
     331        public void actionPerformed(ActionEvent ev) {
     332            initializeImages();
     333            resolution = mv.getDist100PixelText();
     334            pixelPerDegree = getPPD();
     335            mv.repaint();
     336        }
     337    }
     338
     339    public class ReloadErrorTilesAction extends AbstractAction {
     340        public ReloadErrorTilesAction() {
     341            super(tr("Reload erroneous tiles"));
     342        }
     343        public void actionPerformed(ActionEvent ev) {
     344            // Delete small files, because they're probably blank tiles.
     345            // See https://josm.openstreetmap.de/ticket/2307
     346            WMSPlugin.cache.customCleanUp(CacheFiles.CLEAN_SMALL_FILES, 4096);
     347
     348            for (int x = 0; x < dax; ++x) {
     349                for (int y = 0; y < day; ++y) {
     350                    GeorefImage img = images[modulo(x,dax)][modulo(y,day)];
     351                    if(img.failed){
     352                        img.image = null;
     353                        img.flushedResizedCachedInstance();
     354                        img.downloadingStarted = false;
     355                        img.failed = false;
     356                        mv.repaint();
     357                    }
     358                }
     359            }
     360        }
     361    }
     362
     363    public class ToggleAlphaAction extends AbstractAction {
     364        public ToggleAlphaAction() {
     365            super(tr("Alpha channel"));
     366        }
     367        public void actionPerformed(ActionEvent ev) {
     368            JCheckBoxMenuItem checkbox = (JCheckBoxMenuItem) ev.getSource();
     369            boolean alphaChannel = checkbox.isSelected();
     370            Main.pref.put("wmsplugin.alpha_channel", alphaChannel);
     371
     372            // clear all resized cached instances and repaint the layer
     373            for (int x = 0; x < dax; ++x) {
     374                for (int y = 0; y < day; ++y) {
     375                    GeorefImage img = images[modulo(x, dax)][modulo(y, day)];
     376                    img.flushedResizedCachedInstance();
     377                }
     378            }
     379            mv.repaint();
     380        }
     381    }
     382
     383    public class SaveWmsAction extends AbstractAction {
     384        public SaveWmsAction() {
     385            super(tr("Save WMS layer to file"), ImageProvider.get("save"));
     386        }
     387        public void actionPerformed(ActionEvent ev) {
     388            File f = SaveActionBase.createAndOpenSaveFileChooser(
     389                tr("Save WMS layer"), ".wms");
     390            try {
     391                if (f != null) {
     392                    ObjectOutputStream oos = new ObjectOutputStream(
     393                        new FileOutputStream(f)
     394                    );
     395                    oos.writeInt(serializeFormatVersion);
     396                    oos.writeInt(dax);
     397                    oos.writeInt(day);
     398                    oos.writeInt(imageSize);
     399                    oos.writeDouble(pixelPerDegree);
     400                    oos.writeObject(getName());
     401                    oos.writeObject(baseURL);
     402                    oos.writeObject(images);
     403                    oos.close();
     404                }
     405            } catch (Exception ex) {
     406                ex.printStackTrace(System.out);
     407            }
     408        }
     409    }
     410
     411    public class LoadWmsAction extends AbstractAction {
     412        public LoadWmsAction() {
     413            super(tr("Load WMS layer from file"), ImageProvider.get("load"));
     414        }
     415        public void actionPerformed(ActionEvent ev) {
     416            JFileChooser fc = DiskAccessAction.createAndOpenFileChooser(true,
     417                false, tr("Load WMS layer"), "wms");
     418            if(fc == null) return;
     419            File f = fc.getSelectedFile();
     420            if (f == null) return;
     421            try
     422            {
     423                FileInputStream fis = new FileInputStream(f);
     424                ObjectInputStream ois = new ObjectInputStream(fis);
     425                int sfv = ois.readInt();
     426                if (sfv != serializeFormatVersion) {
     427                    JOptionPane.showMessageDialog(Main.parent,
     428                        tr("Unsupported WMS file version; found {0}, expected {1}", sfv, serializeFormatVersion),
     429                        tr("File Format Error"),
     430                        JOptionPane.ERROR_MESSAGE);
     431                    return;
     432                }
     433                startstop.setSelected(false);
     434                dax = ois.readInt();
     435                day = ois.readInt();
     436                imageSize = ois.readInt();
     437                pixelPerDegree = ois.readDouble();
     438                setName((String)ois.readObject());
     439                baseURL = (String) ois.readObject();
     440                images = (GeorefImage[][])ois.readObject();
     441                ois.close();
     442                fis.close();
     443                mv.repaint();
     444            }
     445            catch (Exception ex) {
     446                // FIXME be more specific
     447                ex.printStackTrace(System.out);
     448                JOptionPane.showMessageDialog(Main.parent,
     449                        tr("Error loading file"),
     450                        tr("Error"),
     451                        JOptionPane.ERROR_MESSAGE);
     452                return;
     453            }
     454        }
     455    }
     456    /**
     457     * This action will add a WMS layer menu entry with the current WMS layer
     458     * URL and name extended by the current resolution.
     459     * When using the menu entry again, the WMS cache will be used properly.
     460     */
     461    public class BookmarkWmsAction extends AbstractAction {
     462        public BookmarkWmsAction() {
     463            super(tr("Set WMS Bookmark"));
     464        }
     465        public void actionPerformed(ActionEvent ev) {
     466            int i = 0;
     467            while (Main.pref.hasKey("wmsplugin.url."+i+".url")) {
     468                i++;
     469            }
     470            String baseName;
     471            // cut old parameter
     472            int parameterIndex = getName().indexOf("#PPD=");
     473            if (parameterIndex != -1) {
     474                baseName = getName().substring(0,parameterIndex);
     475            }
     476            else {
     477                baseName = getName();
     478            }
     479            Main.pref.put("wmsplugin.url."+ i +".url",baseURL );
     480            Main.pref.put("wmsplugin.url."+String.valueOf(i)+".name",
     481                baseName + "#PPD=" + pixelPerDegree );
     482            WMSPlugin.refreshMenu();
     483        }
     484    }
     485
     486    public void preferenceChanged(PreferenceChangeEvent event) {
     487        if (event.getKey().equals("wmsplugin.simultaneousConnections")) {
     488            executor.shutdownNow();
     489            executor = Executors.newFixedThreadPool(
     490                Main.pref.getInteger("wmsplugin.numThreads",
     491                WMSPlugin.simultaneousConnections));
     492        }
     493    }
    477494}
  • applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSPlugin.java

    r19415 r21796  
    5353    static int overlapEast = 14;
    5454    static int overlapNorth = 4;
     55    static int simultaneousConnections = 3;
    5556
    5657    // remember state of menu item to restore on changed preferences
     
    110111            overlapNorth = Integer.valueOf(prefs.get("wmsplugin.url.overlapNorth"));
    111112        } catch (Exception e) {} // If sth fails, we drop to default settings.
     113               
     114        // Load the settings for number of simultaneous connections
     115        try {
     116            simultaneousConnections = Integer.valueOf(prefs.get("wmsplugin.simultanousConnections"));
     117        } catch (Exception e) {} // If sth fails, we drop to default settings.
    112118
    113119        // And then the names+urls of WMS servers
  • applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSPreferenceEditor.java

    r19417 r21796  
    3939    JSpinner spinEast;
    4040    JSpinner spinNorth;
     41    JSpinner spinSimConn;
    4142
    4243    public void addGui(final PreferenceTabbedPane gui) {
     
    163164        p.add(browser);
    164165
    165 
    166166        //Overlap
    167167        p.add(Box.createHorizontalGlue(), GBC.eol().fill(GridBagConstraints.HORIZONTAL));
     
    181181
    182182        p.add(overlapPanel);
     183               
     184        // Simultaneous connections
     185        p.add(Box.createHorizontalGlue(), GBC.eol().fill(GridBagConstraints.HORIZONTAL));
     186        JLabel labelSimConn = new JLabel(tr("Simultaneous connections"));
     187        spinSimConn = new JSpinner(new SpinnerNumberModel(WMSPlugin.simultaneousConnections, 1, 30, 1));
     188        JPanel overlapPanelSimConn = new JPanel(new FlowLayout());
     189        overlapPanelSimConn.add(labelSimConn);
     190        overlapPanelSimConn.add(spinSimConn);
     191        p.add(overlapPanelSimConn);
    183192    }
    184193
     
    223232        WMSPlugin.overlapEast = (Integer) spinEast.getModel().getValue();
    224233        WMSPlugin.overlapNorth = (Integer) spinNorth.getModel().getValue();
     234        WMSPlugin.simultaneousConnections = (Integer) spinSimConn.getModel().getValue();
    225235
    226236        Main.pref.put("wmsplugin.url.overlap",    String.valueOf(WMSPlugin.doOverlap));
     
    228238        Main.pref.put("wmsplugin.url.overlapNorth", String.valueOf(WMSPlugin.overlapNorth));
    229239
    230         Main.pref.put("wmsplugin.browser", browser.getEditor().getItem().toString());
     240        Main.pref.put("wmsplugin.simultaneousConnections", String.valueOf(WMSPlugin.simultaneousConnections));
    231241        return false;
    232242    }
Note: See TracChangeset for help on using the changeset viewer.