Ignore:
Timestamp:
2010-01-25T21:35:41+01:00 (15 years ago)
Author:
jttt
Message:

Fixed #4385 Error when using josm at higher resolution with WMS

Location:
applications/editors/josm/plugins/wmsplugin
Files:
2 added
2 edited

Legend:

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

    r19507 r19626  
    115115
    116116        private void fallbackDraw(Graphics g, Image img, Point min, Point max) {
    117                 if(reImg != null) reImg.flush();
    118                 reImg = null;
     117                if(reImg != null) {
     118                        reImg.flush();
     119                        reImg = null;
     120                }
    119121                g.drawImage(img,
    120122                                min.x, max.y, max.x, min.y, // dest
  • applications/editors/josm/plugins/wmsplugin/src/wmsplugin/WMSLayer.java

    r19417 r19626  
    4444 */
    4545public 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     @Override public void paint(Graphics2D g, final MapView mv, Bounds bounds) {
    179         if(baseURL == null) return;
    180         if (usesInvalidUrl && !isInvalidUrlConfirmed) return;
    181 
    182         if(pixelPerDegree / getPPD() > minZoom){ //don't download when it's too outzoomed
    183             for(int x = 0; x<dax; ++x) {
    184                 for(int y = 0; y<day; ++y) {
    185                     images[modulo(x,dax)][modulo(y,day)].paint(g, mv, dx, dy);
    186                 }
    187             }
    188         } else {
    189             downloadAndPaintVisible(g, mv);
    190         }
    191     }
    192 
    193     public void displace(double dx, double dy) {
    194         this.dx += dx;
    195         this.dy += dy;
    196     }
    197 
    198     protected boolean confirmMalformedUrl(String url) {
    199         if (isInvalidUrlConfirmed)
    200             return true;
    201         String msg  = tr("<html>The base URL<br>"
    202                         + "''{0}''<br>"
    203                         + "for this WMS layer does neither end with a ''&'' nor with a ''?''.<br>"
    204                         + "This is likely to lead to invalid WMS request. You should check your<br>"
    205                         + "preference settings.<br>"
    206                         + "Do you want to fetch WMS tiles anyway?",
    207                         url);
    208         String [] options = new String[] {
    209             tr("Yes, fetch images"),
    210             tr("No, abort")
    211         };
    212         int ret = JOptionPane.showOptionDialog(
    213                 Main.parent,
    214                 msg,
    215                 tr("Invalid URL?"),
    216                 JOptionPane.YES_NO_OPTION,
    217                 JOptionPane.WARNING_MESSAGE,
    218                 null,
    219                 options, options[1]
    220         );
    221         switch(ret) {
    222         case JOptionPane.YES_OPTION: return true;
    223         default: return false;
    224         }
    225     }
    226     protected void downloadAndPaintVisible(Graphics g, final MapView mv){
    227         if (usesInvalidUrl)
    228             return;
    229         ProjectionBounds bounds = mv.getProjectionBounds();
    230         int bminx= (int)Math.floor (((bounds.min.east() - dx) * pixelPerDegree) / imageSize );
    231         int bminy= (int)Math.floor (((bounds.min.north() - dy) * pixelPerDegree) / imageSize );
    232         int bmaxx= (int)Math.ceil  (((bounds.max.east() - dx) * pixelPerDegree) / imageSize );
    233         int bmaxy= (int)Math.ceil  (((bounds.max.north() - dy) * pixelPerDegree) / imageSize );
    234 
    235         if((bmaxx - bminx > dax) || (bmaxy - bminy > day)){
    236             JOptionPane.showMessageDialog(
    237                     Main.parent,
    238                     tr("The requested area is too big. Please zoom in a little, or change resolution"),
    239                     tr("Error"),
    240                     JOptionPane.ERROR_MESSAGE
    241             );
    242             return;
    243         }
    244 
    245         for(int x = bminx; x<bmaxx; ++x) {
    246             for(int y = bminy; y<bmaxy; ++y){
    247                 GeorefImage img = images[modulo(x,dax)][modulo(y,day)];
    248                 g.drawRect(x, y, dax, bminy);
    249                 if(!img.paint(g, mv, dx, dy) && !img.downloadingStarted){
    250                     img.downloadingStarted = true;
    251                     img.image = null;
    252                     img.flushedResizedCachedInstance();
    253                     Grabber gr = WMSPlugin.getGrabber(XYtoBounds(x,y), img, mv, this);
    254                     if(!gr.loadFromCache()){
    255                        gr.setPriority(1);
    256                        executor.submit(gr);
    257                     }
    258                 }
    259             }
    260         }
    261     }
    262 
    263     @Override public void visitBoundingBox(BoundingXYVisitor v) {
    264         for(int x = 0; x<dax; ++x) {
    265             for(int y = 0; y<day; ++y)
    266                 if(images[x][y].image!=null){
    267                     v.visit(images[x][y].min);
    268                     v.visit(images[x][y].max);
    269                 }
    270         }
    271     }
    272 
    273     @Override public Object getInfoComponent() {
    274         return getToolTipText();
    275     }
    276 
    277     @Override public Component[] getMenuEntries() {
    278         return new Component[]{
    279                 new JMenuItem(LayerListDialog.getInstance().createActivateLayerAction(this)),
    280                 new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
    281                 new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
    282                 new JSeparator(),
    283                 new JMenuItem(new LoadWmsAction()),
    284                 new JMenuItem(new SaveWmsAction()),
    285                 new JMenuItem(new BookmarkWmsAction()),
    286                 new JSeparator(),
    287                 startstop,
    288                 alphaChannel,
    289                 new JMenuItem(new ChangeResolutionAction()),
    290                 new JMenuItem(new ReloadErrorTilesAction()),
    291                 new JMenuItem(new DownloadAction()),
    292                 new JSeparator(),
    293                 new JMenuItem(new LayerListPopup.InfoAction(this))
    294         };
    295     }
    296 
    297     public GeorefImage findImage(EastNorth eastNorth) {
    298         for(int x = 0; x<dax; ++x) {
    299             for(int y = 0; y<day; ++y)
    300                 if(images[x][y].image!=null && images[x][y].min!=null && images[x][y].max!=null)
    301                     if(images[x][y].contains(eastNorth, dx, dy))
    302                         return images[x][y];
    303         }
    304         return null;
    305     }
    306 
    307     public class DownloadAction extends AbstractAction {
    308         public DownloadAction() {
    309             super(tr("Download visible tiles"));
    310         }
    311         public void actionPerformed(ActionEvent ev) {
    312             downloadAndPaintVisible(mv.getGraphics(), mv);
    313         }
    314     }
    315 
    316     public class ChangeResolutionAction extends AbstractAction {
    317         public ChangeResolutionAction() {
    318             super(tr("Change resolution"));
    319         }
    320         public void actionPerformed(ActionEvent ev) {
    321             initializeImages();
    322             resolution = mv.getDist100PixelText();
    323             pixelPerDegree = getPPD();
    324             mv.repaint();
    325         }
    326     }
    327 
    328     public class ReloadErrorTilesAction extends AbstractAction {
    329         public ReloadErrorTilesAction() {
    330             super(tr("Reload erroneous tiles"));
    331         }
    332         public void actionPerformed(ActionEvent ev) {
    333             // Delete small files, because they're probably blank tiles.
    334             // See https://josm.openstreetmap.de/ticket/2307
    335             WMSPlugin.cache.customCleanUp(CacheFiles.CLEAN_SMALL_FILES, 4096);
    336 
    337             for (int x = 0; x < dax; ++x) {
    338                 for (int y = 0; y < day; ++y) {
    339                     GeorefImage img = images[modulo(x,dax)][modulo(y,day)];
    340                     if(img.failed){
    341                         img.image = null;
    342                         img.flushedResizedCachedInstance();
    343                         img.downloadingStarted = false;
    344                         img.failed = false;
    345                         mv.repaint();
    346                     }
    347                 }
    348             }
    349         }
    350     }
    351 
    352     public class ToggleAlphaAction extends AbstractAction {
    353         public ToggleAlphaAction() {
    354             super(tr("Alpha channel"));
    355         }
    356         public void actionPerformed(ActionEvent ev) {
    357             JCheckBoxMenuItem checkbox = (JCheckBoxMenuItem) ev.getSource();
    358             boolean alphaChannel = checkbox.isSelected();
    359             Main.pref.put("wmsplugin.alpha_channel", alphaChannel);
    360 
    361             // clear all resized cached instances and repaint the layer
    362             for (int x = 0; x < dax; ++x) {
    363                 for (int y = 0; y < day; ++y) {
    364                     GeorefImage img = images[modulo(x, dax)][modulo(y, day)];
    365                     img.flushedResizedCachedInstance();
    366                 }
    367             }
    368             mv.repaint();
    369         }
    370     }
    371 
    372     public class SaveWmsAction extends AbstractAction {
    373         public SaveWmsAction() {
    374             super(tr("Save WMS layer to file"), ImageProvider.get("save"));
    375         }
    376         public void actionPerformed(ActionEvent ev) {
    377             File f = SaveActionBase.createAndOpenSaveFileChooser(
    378                     tr("Save WMS layer"), ".wms");
    379             try {
    380                 if (f != null) {
    381                     ObjectOutputStream oos = new ObjectOutputStream(
    382                             new FileOutputStream(f)
    383                     );
    384                     oos.writeInt(serializeFormatVersion);
    385                     oos.writeInt(dax);
    386                     oos.writeInt(day);
    387                     oos.writeInt(imageSize);
    388                     oos.writeDouble(pixelPerDegree);
    389                     oos.writeObject(getName());
    390                     oos.writeObject(baseURL);
    391                     oos.writeObject(images);
    392                     oos.close();
    393                 }
    394             } catch (Exception ex) {
    395                 ex.printStackTrace(System.out);
    396             }
    397         }
    398     }
    399 
    400     public class LoadWmsAction extends AbstractAction {
    401         public LoadWmsAction() {
    402             super(tr("Load WMS layer from file"), ImageProvider.get("load"));
    403         }
    404         public void actionPerformed(ActionEvent ev) {
    405             JFileChooser fc = DiskAccessAction.createAndOpenFileChooser(true,
    406                     false, tr("Load WMS layer"), "wms");
    407             if(fc == null) return;
    408             File f = fc.getSelectedFile();
    409             if (f == null) return;
    410             try
    411             {
    412                 FileInputStream fis = new FileInputStream(f);
    413                 ObjectInputStream ois = new ObjectInputStream(fis);
    414                 int sfv = ois.readInt();
    415                 if (sfv != serializeFormatVersion) {
    416                     JOptionPane.showMessageDialog(Main.parent,
    417                             tr("Unsupported WMS file version; found {0}, expected {1}", sfv, serializeFormatVersion),
    418                             tr("File Format Error"),
    419                             JOptionPane.ERROR_MESSAGE);
    420                     return;
    421                 }
    422                 startstop.setSelected(false);
    423                 dax = ois.readInt();
    424                 day = ois.readInt();
    425                 imageSize = ois.readInt();
    426                 pixelPerDegree = ois.readDouble();
    427                 setName((String)ois.readObject());
    428                 baseURL = (String) ois.readObject();
    429                 images = (GeorefImage[][])ois.readObject();
    430                 ois.close();
    431                 fis.close();
    432                 mv.repaint();
    433             }
    434             catch (Exception ex) {
    435                 // FIXME be more specific
    436                 ex.printStackTrace(System.out);
    437                 JOptionPane.showMessageDialog(Main.parent,
    438                         tr("Error loading file"),
    439                         tr("Error"),
    440                         JOptionPane.ERROR_MESSAGE);
    441                 return;
    442             }
    443         }
    444     }
    445     /**
    446      * This action will add a WMS layer menu entry with the current WMS layer URL and name extended by the current resolution.
    447      * When using the menu entry again, the WMS cache will be used properly.
    448      */
    449     public class BookmarkWmsAction extends AbstractAction {
    450         public BookmarkWmsAction() {
    451             super(tr("Set WMS Bookmark"));
    452         }
    453         public void actionPerformed(ActionEvent ev) {
    454             int i = 0;
    455             while (Main.pref.hasKey("wmsplugin.url."+i+".url")) {
    456                 i++;
    457             }
    458             String baseName;
    459             // cut old parameter
    460             int parameterIndex = getName().indexOf("#PPD=");
    461             if (parameterIndex != -1) {
    462                 baseName = getName().substring(0,parameterIndex);
    463             }
    464             else {
    465                 baseName = getName();
    466             }
    467             Main.pref.put("wmsplugin.url."+ i +".url",baseURL );
    468             Main.pref.put("wmsplugin.url."+String.valueOf(i)+".name", baseName + "#PPD=" + getPPD() );
    469             WMSPlugin.refreshMenu();
    470         }
    471     }
     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                                g.drawRect(x, y, dax, bminy);
     246                                if(!img.paint(g, mv, dx, dy) && !img.downloadingStarted){
     247                                        img.downloadingStarted = true;
     248                                        img.image = null;
     249                                        img.flushedResizedCachedInstance();
     250                                        Grabber gr = WMSPlugin.getGrabber(XYtoBounds(x,y), img, mv, this);
     251                                        if(!gr.loadFromCache()){
     252                                                gr.setPriority(1);
     253                                                executor.submit(gr);
     254                                        }
     255                                }
     256                        }
     257                }
     258        }
     259
     260        @Override public void visitBoundingBox(BoundingXYVisitor v) {
     261                for(int x = 0; x<dax; ++x) {
     262                        for(int y = 0; y<day; ++y)
     263                                if(images[x][y].image!=null){
     264                                        v.visit(images[x][y].min);
     265                                        v.visit(images[x][y].max);
     266                                }
     267                }
     268        }
     269
     270        @Override public Object getInfoComponent() {
     271                return getToolTipText();
     272        }
     273
     274        @Override public Component[] getMenuEntries() {
     275                return new Component[]{
     276                                new JMenuItem(LayerListDialog.getInstance().createActivateLayerAction(this)),
     277                                new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
     278                                new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
     279                                new JSeparator(),
     280                                new JMenuItem(new LoadWmsAction()),
     281                                new JMenuItem(new SaveWmsAction()),
     282                                new JMenuItem(new BookmarkWmsAction()),
     283                                new JSeparator(),
     284                                startstop,
     285                                alphaChannel,
     286                                new JMenuItem(new ChangeResolutionAction()),
     287                                new JMenuItem(new ReloadErrorTilesAction()),
     288                                new JMenuItem(new DownloadAction()),
     289                                new JSeparator(),
     290                                new JMenuItem(new LayerListPopup.InfoAction(this))
     291                };
     292        }
     293
     294        public GeorefImage findImage(EastNorth eastNorth) {
     295                for(int x = 0; x<dax; ++x) {
     296                        for(int y = 0; y<day; ++y)
     297                                if(images[x][y].image!=null && images[x][y].min!=null && images[x][y].max!=null)
     298                                        if(images[x][y].contains(eastNorth, dx, dy))
     299                                                return images[x][y];
     300                }
     301                return null;
     302        }
     303
     304        public class DownloadAction extends AbstractAction {
     305                public DownloadAction() {
     306                        super(tr("Download visible tiles"));
     307                }
     308                public void actionPerformed(ActionEvent ev) {
     309                        if (zoomIsTooBig()) {
     310                                JOptionPane.showMessageDialog(
     311                                                Main.parent,
     312                                                tr("The requested area is too big. Please zoom in a little, or change resolution"),
     313                                                tr("Error"),
     314                                                JOptionPane.ERROR_MESSAGE
     315                                );
     316                        } else {
     317                                downloadAndPaintVisible(mv.getGraphics(), mv);
     318                        }
     319                }
     320        }
     321
     322        public class ChangeResolutionAction extends AbstractAction {
     323                public ChangeResolutionAction() {
     324                        super(tr("Change resolution"));
     325                }
     326                public void actionPerformed(ActionEvent ev) {
     327                        initializeImages();
     328                        resolution = mv.getDist100PixelText();
     329                        pixelPerDegree = getPPD();
     330                        mv.repaint();
     331                }
     332        }
     333
     334        public class ReloadErrorTilesAction extends AbstractAction {
     335                public ReloadErrorTilesAction() {
     336                        super(tr("Reload erroneous tiles"));
     337                }
     338                public void actionPerformed(ActionEvent ev) {
     339                        // Delete small files, because they're probably blank tiles.
     340                        // See https://josm.openstreetmap.de/ticket/2307
     341                        WMSPlugin.cache.customCleanUp(CacheFiles.CLEAN_SMALL_FILES, 4096);
     342
     343                        for (int x = 0; x < dax; ++x) {
     344                                for (int y = 0; y < day; ++y) {
     345                                        GeorefImage img = images[modulo(x,dax)][modulo(y,day)];
     346                                        if(img.failed){
     347                                                img.image = null;
     348                                                img.flushedResizedCachedInstance();
     349                                                img.downloadingStarted = false;
     350                                                img.failed = false;
     351                                                mv.repaint();
     352                                        }
     353                                }
     354                        }
     355                }
     356        }
     357
     358        public class ToggleAlphaAction extends AbstractAction {
     359                public ToggleAlphaAction() {
     360                        super(tr("Alpha channel"));
     361                }
     362                public void actionPerformed(ActionEvent ev) {
     363                        JCheckBoxMenuItem checkbox = (JCheckBoxMenuItem) ev.getSource();
     364                        boolean alphaChannel = checkbox.isSelected();
     365                        Main.pref.put("wmsplugin.alpha_channel", alphaChannel);
     366
     367                        // clear all resized cached instances and repaint the layer
     368                        for (int x = 0; x < dax; ++x) {
     369                                for (int y = 0; y < day; ++y) {
     370                                        GeorefImage img = images[modulo(x, dax)][modulo(y, day)];
     371                                        img.flushedResizedCachedInstance();
     372                                }
     373                        }
     374                        mv.repaint();
     375                }
     376        }
     377
     378        public class SaveWmsAction extends AbstractAction {
     379                public SaveWmsAction() {
     380                        super(tr("Save WMS layer to file"), ImageProvider.get("save"));
     381                }
     382                public void actionPerformed(ActionEvent ev) {
     383                        File f = SaveActionBase.createAndOpenSaveFileChooser(
     384                                        tr("Save WMS layer"), ".wms");
     385                        try {
     386                                if (f != null) {
     387                                        ObjectOutputStream oos = new ObjectOutputStream(
     388                                                        new FileOutputStream(f)
     389                                        );
     390                                        oos.writeInt(serializeFormatVersion);
     391                                        oos.writeInt(dax);
     392                                        oos.writeInt(day);
     393                                        oos.writeInt(imageSize);
     394                                        oos.writeDouble(pixelPerDegree);
     395                                        oos.writeObject(getName());
     396                                        oos.writeObject(baseURL);
     397                                        oos.writeObject(images);
     398                                        oos.close();
     399                                }
     400                        } catch (Exception ex) {
     401                                ex.printStackTrace(System.out);
     402                        }
     403                }
     404        }
     405
     406        public class LoadWmsAction extends AbstractAction {
     407                public LoadWmsAction() {
     408                        super(tr("Load WMS layer from file"), ImageProvider.get("load"));
     409                }
     410                public void actionPerformed(ActionEvent ev) {
     411                        JFileChooser fc = DiskAccessAction.createAndOpenFileChooser(true,
     412                                        false, tr("Load WMS layer"), "wms");
     413                        if(fc == null) return;
     414                        File f = fc.getSelectedFile();
     415                        if (f == null) return;
     416                        try
     417                        {
     418                                FileInputStream fis = new FileInputStream(f);
     419                                ObjectInputStream ois = new ObjectInputStream(fis);
     420                                int sfv = ois.readInt();
     421                                if (sfv != serializeFormatVersion) {
     422                                        JOptionPane.showMessageDialog(Main.parent,
     423                                                        tr("Unsupported WMS file version; found {0}, expected {1}", sfv, serializeFormatVersion),
     424                                                        tr("File Format Error"),
     425                                                        JOptionPane.ERROR_MESSAGE);
     426                                        return;
     427                                }
     428                                startstop.setSelected(false);
     429                                dax = ois.readInt();
     430                                day = ois.readInt();
     431                                imageSize = ois.readInt();
     432                                pixelPerDegree = ois.readDouble();
     433                                setName((String)ois.readObject());
     434                                baseURL = (String) ois.readObject();
     435                                images = (GeorefImage[][])ois.readObject();
     436                                ois.close();
     437                                fis.close();
     438                                mv.repaint();
     439                        }
     440                        catch (Exception ex) {
     441                                // FIXME be more specific
     442                                ex.printStackTrace(System.out);
     443                                JOptionPane.showMessageDialog(Main.parent,
     444                                                tr("Error loading file"),
     445                                                tr("Error"),
     446                                                JOptionPane.ERROR_MESSAGE);
     447                                return;
     448                        }
     449                }
     450        }
     451        /**
     452         * This action will add a WMS layer menu entry with the current WMS layer URL and name extended by the current resolution.
     453         * When using the menu entry again, the WMS cache will be used properly.
     454         */
     455        public class BookmarkWmsAction extends AbstractAction {
     456                public BookmarkWmsAction() {
     457                        super(tr("Set WMS Bookmark"));
     458                }
     459                public void actionPerformed(ActionEvent ev) {
     460                        int i = 0;
     461                        while (Main.pref.hasKey("wmsplugin.url."+i+".url")) {
     462                                i++;
     463                        }
     464                        String baseName;
     465                        // cut old parameter
     466                        int parameterIndex = getName().indexOf("#PPD=");
     467                        if (parameterIndex != -1) {
     468                                baseName = getName().substring(0,parameterIndex);
     469                        }
     470                        else {
     471                                baseName = getName();
     472                        }
     473                        Main.pref.put("wmsplugin.url."+ i +".url",baseURL );
     474                        Main.pref.put("wmsplugin.url."+String.valueOf(i)+".name", baseName + "#PPD=" + getPPD() );
     475                        WMSPlugin.refreshMenu();
     476                }
     477        }
    472478}
Note: See TracChangeset for help on using the changeset viewer.