Changeset 7425 in josm for trunk/src/org/openstreetmap/josm/io/imagery
- Timestamp:
- 2014-08-16T23:50:43+02:00 (10 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/io/imagery
- Files:
-
- 1 added
- 1 deleted
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/io/imagery/WMSGrabber.java
r7132 r7425 9 9 import java.io.InputStream; 10 10 import java.io.InputStreamReader; 11 import java.io.StringReader; 11 12 import java.net.HttpURLConnection; 12 13 import java.net.MalformedURLException; … … 17 18 import java.text.DecimalFormatSymbols; 18 19 import java.text.NumberFormat; 20 import java.util.ArrayList; 19 21 import java.util.HashMap; 22 import java.util.List; 20 23 import java.util.Locale; 21 24 import java.util.Map; … … 24 27 import java.util.regex.Pattern; 25 28 29 import javax.xml.parsers.DocumentBuilder; 30 import javax.xml.parsers.DocumentBuilderFactory; 31 import javax.xml.parsers.ParserConfigurationException; 32 26 33 import org.openstreetmap.josm.Main; 34 import org.openstreetmap.josm.data.ProjectionBounds; 27 35 import org.openstreetmap.josm.data.coor.EastNorth; 28 36 import org.openstreetmap.josm.data.coor.LatLon; … … 35 43 import org.openstreetmap.josm.tools.ImageProvider; 36 44 import org.openstreetmap.josm.tools.Utils; 37 38 public class WMSGrabber extends Grabber { 45 import org.w3c.dom.Document; 46 import org.w3c.dom.NodeList; 47 import org.xml.sax.InputSource; 48 import org.xml.sax.SAXException; 49 50 /** 51 * WMS grabber, fetching tiles from WMS server. 52 * @since 3715 53 */ 54 public class WMSGrabber implements Runnable { 55 56 protected final MapView mv; 57 protected final WMSLayer layer; 58 private final boolean localOnly; 59 60 protected ProjectionBounds b; 61 protected volatile boolean canceled; 39 62 40 63 protected String baseURL; … … 42 65 private Map<String, String> props = new HashMap<>(); 43 66 67 /** 68 * Constructs a new {@code WMSGrabber}. 69 * @param mv Map view 70 * @param layer WMS layer 71 */ 44 72 public WMSGrabber(MapView mv, WMSLayer layer, boolean localOnly) { 45 super(mv, layer, localOnly); 73 this.mv = mv; 74 this.layer = layer; 75 this.localOnly = localOnly; 46 76 this.info = layer.getInfo(); 47 77 this.baseURL = info.getUrl(); 48 if (layer.getInfo().getCookies() != null && !layer.getInfo().getCookies().isEmpty()) {78 if (layer.getInfo().getCookies() != null && !layer.getInfo().getCookies().isEmpty()) { 49 79 props.put("Cookie", layer.getInfo().getCookies()); 50 80 } … … 60 90 } 61 91 92 int width() { 93 return layer.getBaseImageWidth(); 94 } 95 96 int height() { 97 return layer.getBaseImageHeight(); 98 } 99 62 100 @Override 63 void fetch(WMSRequest request, int attempt) throws Exception{ 101 public void run() { 102 while (true) { 103 if (canceled) 104 return; 105 WMSRequest request = layer.getRequest(localOnly); 106 if (request == null) 107 return; 108 this.b = layer.getBounds(request); 109 if (request.isPrecacheOnly()) { 110 if (!layer.cache.hasExactMatch(Main.getProjection(), request.getPixelPerDegree(), b.minEast, b.minNorth)) { 111 attempt(request); 112 } else if (Main.isDebugEnabled()) { 113 Main.debug("Ignoring "+request+" (precache only + exact match)"); 114 } 115 } else if (!loadFromCache(request)){ 116 attempt(request); 117 } else if (Main.isDebugEnabled()) { 118 Main.debug("Ignoring "+request+" (loaded from cache)"); 119 } 120 layer.finishRequest(request); 121 } 122 } 123 124 protected void attempt(WMSRequest request){ // try to fetch the image 125 int maxTries = 5; // n tries for every image 126 for (int i = 1; i <= maxTries; i++) { 127 if (canceled) 128 return; 129 try { 130 if (!request.isPrecacheOnly() && !layer.requestIsVisible(request)) 131 return; 132 fetch(request, i); 133 break; // break out of the retry loop 134 } catch (IOException e) { 135 try { // sleep some time and then ask the server again 136 Thread.sleep(random(1000, 2000)); 137 } catch (InterruptedException e1) { 138 Main.debug("InterruptedException in "+getClass().getSimpleName()+" during WMS request"); 139 } 140 if (i == maxTries) { 141 Main.error(e); 142 request.finish(State.FAILED, null, null); 143 } 144 } catch (WMSException e) { 145 // Fail fast in case of WMS Service exception: useless to retry: 146 // either the URL is wrong or the server suffers huge problems 147 Main.error("WMS service exception while requesting "+e.getUrl()+":\n"+e.getMessage().trim()); 148 request.finish(State.FAILED, null, e); 149 break; // break out of the retry loop 150 } 151 } 152 } 153 154 public static int random(int min, int max) { 155 return (int)(Math.random() * ((max+1)-min) ) + min; 156 } 157 158 public final void cancel() { 159 canceled = true; 160 } 161 162 private void fetch(WMSRequest request, int attempt) throws IOException, WMSException { 64 163 URL url = null; 65 164 try { … … 68 167 b.maxEast, b.maxNorth, 69 168 width(), height()); 70 request.finish(State.IMAGE, grab(request, url, attempt) );71 72 } catch (Exception e) {169 request.finish(State.IMAGE, grab(request, url, attempt), null); 170 171 } catch (IOException | OsmTransferException e) { 73 172 Main.error(e); 74 throw new Exception(e.getMessage() + "\nImage couldn't be fetched: " + (url != null ? url.toString() : ""), e); 75 } 76 } 77 78 public static final NumberFormat latLonFormat = new DecimalFormat("###0.0000000", 79 new DecimalFormatSymbols(Locale.US)); 173 throw new IOException(e.getMessage() + "\nImage couldn't be fetched: " + (url != null ? url.toString() : ""), e); 174 } 175 } 176 177 public static final NumberFormat latLonFormat = new DecimalFormat("###0.0000000", new DecimalFormatSymbols(Locale.US)); 80 178 81 179 protected URL getURL(double w, double s,double e,double n, … … 133 231 } 134 232 135 @Override136 233 public boolean loadFromCache(WMSRequest request) { 137 234 BufferedImage cached = layer.cache.getExactMatch( … … 139 236 140 237 if (cached != null) { 141 request.finish(State.IMAGE, cached );238 request.finish(State.IMAGE, cached, null); 142 239 return true; 143 240 } else if (request.isAllowPartialCacheMatch()) { … … 145 242 Main.getProjection(), request.getPixelPerDegree(), b.minEast, b.minNorth); 146 243 if (partialMatch != null) { 147 request.finish(State.PARTLY_IN_CACHE, partialMatch );244 request.finish(State.PARTLY_IN_CACHE, partialMatch, null); 148 245 return true; 149 246 } 150 247 } 151 248 152 if ((!request.isReal() && !layer.hasAutoDownload())){153 request.finish(State.NOT_IN_CACHE, null );249 if ((!request.isReal() && !layer.hasAutoDownload())){ 250 request.finish(State.NOT_IN_CACHE, null, null); 154 251 return true; 155 252 } … … 158 255 } 159 256 160 protected BufferedImage grab(WMSRequest request, URL url, int attempt) throws IOException, OsmTransferException {257 protected BufferedImage grab(WMSRequest request, URL url, int attempt) throws WMSException, IOException, OsmTransferException { 161 258 Main.info("Grabbing WMS " + (attempt > 1? "(attempt " + attempt + ") ":"") + url); 162 259 163 260 HttpURLConnection conn = Utils.openHttpConnection(url); 164 for (Entry<String, String> e : props.entrySet()) {261 for (Entry<String, String> e : props.entrySet()) { 165 262 conn.setRequestProperty(e.getKey(), e.getValue()); 166 263 } … … 169 266 170 267 String contentType = conn.getHeaderField("Content-Type"); 171 if( conn.getResponseCode() != 200 172 || contentType != null && !contentType.startsWith("image") ) 173 throw new IOException(readException(conn)); 268 if (conn.getResponseCode() != 200 269 || contentType != null && !contentType.startsWith("image") ) { 270 String xml = readException(conn); 271 try { 272 DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 273 InputSource is = new InputSource(new StringReader(xml)); 274 Document doc = db.parse(is); 275 NodeList nodes = doc.getElementsByTagName("ServiceException"); 276 List<String> exceptions = new ArrayList<>(nodes.getLength()); 277 for (int i = 0; i < nodes.getLength(); i++) { 278 exceptions.add(nodes.item(i).getTextContent()); 279 } 280 throw new WMSException(request, url, exceptions); 281 } catch (SAXException | ParserConfigurationException ex) { 282 throw new IOException(xml, ex); 283 } 284 } 174 285 175 286 ByteArrayOutputStream baos = new ByteArrayOutputStream(); -
trunk/src/org/openstreetmap/josm/io/imagery/WMSRequest.java
r4745 r7425 19 19 private State state; 20 20 private BufferedImage image; 21 private WMSException exception; 21 22 22 23 public WMSRequest(int xIndex, int yIndex, double pixelPerDegree, boolean real, boolean allowPartialCacheMatch) { … … 33 34 } 34 35 35 36 public void finish(State state, BufferedImage image) { 36 public void finish(State state, BufferedImage image, WMSException exception) { 37 37 this.state = state; 38 38 this.image = image; 39 this.exception = exception; 39 40 } 40 41 … … 97 98 } 98 99 100 /** 101 * Replies the resulting state. 102 * @return the resulting state 103 */ 99 104 public State getState() { 100 105 return state; 101 106 } 102 107 108 /** 109 * Replies the resulting image, if any. 110 * @return the resulting image, or {@code null} 111 */ 103 112 public BufferedImage getImage() { 104 113 return image; 114 } 115 116 /** 117 * Replies the resulting exception, if any. 118 * @return the resulting exception, or {@code null} 119 * @since 7425 120 */ 121 public WMSException getException() { 122 return exception; 105 123 } 106 124
Note:
See TracChangeset
for help on using the changeset viewer.