001 // License: GPL. For details, see LICENSE file. 002 package org.openstreetmap.josm.io.imagery; 003 004 import org.openstreetmap.josm.Main; 005 import org.openstreetmap.josm.data.ProjectionBounds; 006 import org.openstreetmap.josm.data.imagery.GeorefImage.State; 007 import org.openstreetmap.josm.gui.MapView; 008 import org.openstreetmap.josm.gui.layer.WMSLayer; 009 010 abstract public class Grabber implements Runnable { 011 protected final MapView mv; 012 protected final WMSLayer layer; 013 private final boolean localOnly; 014 015 protected ProjectionBounds b; 016 protected volatile boolean canceled; 017 018 Grabber(MapView mv, WMSLayer layer, boolean localOnly) { 019 this.mv = mv; 020 this.layer = layer; 021 this.localOnly = localOnly; 022 } 023 024 abstract void fetch(WMSRequest request, int attempt) throws Exception; // the image fetch code 025 026 int width(){ 027 return layer.getBaseImageWidth(); 028 } 029 int height(){ 030 return layer.getBaseImageHeight(); 031 } 032 033 @Override 034 public void run() { 035 while (true) { 036 if (canceled) 037 return; 038 WMSRequest request = layer.getRequest(localOnly); 039 if (request == null) 040 return; 041 this.b = layer.getBounds(request); 042 if (request.isPrecacheOnly()) { 043 if (!layer.cache.hasExactMatch(Main.getProjection(), request.getPixelPerDegree(), b.minEast, b.minNorth)) { 044 attempt(request); 045 } 046 } else { 047 if(!loadFromCache(request)){ 048 attempt(request); 049 } 050 } 051 layer.finishRequest(request); 052 } 053 } 054 055 protected void attempt(WMSRequest request){ // try to fetch the image 056 int maxTries = 5; // n tries for every image 057 for (int i = 1; i <= maxTries; i++) { 058 if (canceled) 059 return; 060 try { 061 if (!request.isPrecacheOnly() && !layer.requestIsVisible(request)) 062 return; 063 fetch(request, i); 064 break; // break out of the retry loop 065 } catch (Exception e) { 066 try { // sleep some time and then ask the server again 067 Thread.sleep(random(1000, 2000)); 068 } catch (InterruptedException e1) {} 069 070 if(i == maxTries) { 071 e.printStackTrace(); 072 request.finish(State.FAILED, null); 073 } 074 } 075 } 076 } 077 078 public static int random(int min, int max) { 079 return (int)(Math.random() * ((max+1)-min) ) + min; 080 } 081 082 abstract public boolean loadFromCache(WMSRequest request); 083 084 public void cancel() { 085 canceled = true; 086 } 087 088 }