Changeset 4745 in josm for trunk/src/org
- Timestamp:
- 2011-12-29T18:07:04+01:00 (13 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/imagery/WmsCache.java
r4186 r4745 62 62 final double north; 63 63 final ProjectionBounds bounds; 64 final String filename; 64 65 65 66 long lastUsed; 66 67 long lastModified; 67 String filename; 68 69 CacheEntry(double pixelPerDegree, double east, double north, int tileSize) { 68 69 CacheEntry(double pixelPerDegree, double east, double north, int tileSize, String filename) { 70 70 this.pixelPerDegree = pixelPerDegree; 71 71 this.east = east; 72 72 this.north = north; 73 73 this.bounds = new ProjectionBounds(east, north, east + tileSize / pixelPerDegree, north + tileSize / pixelPerDegree); 74 this.filename = filename; 74 75 } 75 76 } … … 201 202 ProjectionEntries projection = getProjectionEntries(projectionType.getName(), projectionType.getCacheDirectory()); 202 203 for (EntryType entry: projectionType.getEntry()) { 203 CacheEntry ce = new CacheEntry(entry.getPixelPerDegree(), entry.getEast(), entry.getNorth(), tileSize );204 CacheEntry ce = new CacheEntry(entry.getPixelPerDegree(), entry.getEast(), entry.getNorth(), tileSize, entry.getFilename()); 204 205 ce.lastUsed = entry.getLastUsed().getTimeInMillis(); 205 ce.filename = entry.getFilename();206 206 ce.lastModified = entry.getLastModified().getTimeInMillis(); 207 207 projection.entries.add(ce); … … 315 315 } 316 316 317 317 318 private BufferedImage loadImage(ProjectionEntries projectionEntries, CacheEntry entry) throws IOException { 318 entry.lastUsed = System.currentTimeMillis(); 319 320 SoftReference<BufferedImage> memCache = memoryCache.get(entry); 321 if (memCache != null) { 322 BufferedImage result = memCache.get(); 323 if (result != null) 319 320 synchronized (this) { 321 entry.lastUsed = System.currentTimeMillis(); 322 323 SoftReference<BufferedImage> memCache = memoryCache.get(entry); 324 if (memCache != null) { 325 BufferedImage result = memCache.get(); 326 if (result != null) 327 return result; 328 } 329 } 330 331 try { 332 // Reading can't be in synchronized section, it's too slow 333 BufferedImage result = ImageIO.read(getImageFile(projectionEntries, entry)); 334 synchronized (this) { 335 if (result == null) { 336 projectionEntries.entries.remove(entry); 337 totalFileSizeDirty = true; 338 } 324 339 return result; 325 } 326 327 try { 328 BufferedImage result = ImageIO.read(getImageFile(projectionEntries, entry)); 329 if (result == null) { 340 } 341 } catch (IOException e) { 342 synchronized (this) { 330 343 projectionEntries.entries.remove(entry); 331 344 totalFileSizeDirty = true; 332 } 333 return result; 334 } catch (IOException e) { 335 projectionEntries.entries.remove(entry); 336 totalFileSizeDirty = true; 337 throw e; 345 throw e; 346 } 338 347 } 339 348 } … … 347 356 } 348 357 349 public synchronized BufferedImage getExactMatch(Projection projection, double pixelPerDegree, double east, double north) {358 public synchronized boolean hasExactMatch(Projection projection, double pixelPerDegree, double east, double north) { 350 359 ProjectionEntries projectionEntries = getProjectionEntries(projection); 351 360 CacheEntry entry = findEntry(projectionEntries, pixelPerDegree, east, north); 361 return (entry != null); 362 } 363 364 public BufferedImage getExactMatch(Projection projection, double pixelPerDegree, double east, double north) { 365 CacheEntry entry = null; 366 ProjectionEntries projectionEntries = null; 367 synchronized (this) { 368 projectionEntries = getProjectionEntries(projection); 369 entry = findEntry(projectionEntries, pixelPerDegree, east, north); 370 } 352 371 if (entry != null) { 353 372 try { 354 entry.lastUsed = System.currentTimeMillis();355 373 return loadImage(projectionEntries, entry); 356 374 } catch (IOException e) { … … 363 381 } 364 382 365 public synchronized BufferedImage getPartialMatch(Projection projection, double pixelPerDegree, double east, double north) { 366 List<CacheEntry> matches = new ArrayList<WmsCache.CacheEntry>(); 367 368 double minPPD = pixelPerDegree / 5; 369 double maxPPD = pixelPerDegree * 5; 370 ProjectionEntries projectionEntries = getProjectionEntries(projection); 371 372 ProjectionBounds bounds = new ProjectionBounds(east, north, 373 east + tileSize / pixelPerDegree, north + tileSize / pixelPerDegree); 374 375 //TODO Do not load tile if it is completely overlapped by other tile with better ppd 376 for (CacheEntry entry: projectionEntries.entries) { 377 if (entry.pixelPerDegree >= minPPD && entry.pixelPerDegree <= maxPPD && entry.bounds.intersects(bounds)) { 378 entry.lastUsed = System.currentTimeMillis(); 379 matches.add(entry); 380 } 381 } 382 383 if (matches.isEmpty()) 384 return null; 385 386 387 Collections.sort(matches, new Comparator<CacheEntry>() { 388 @Override 389 public int compare(CacheEntry o1, CacheEntry o2) { 390 return Double.compare(o2.pixelPerDegree, o1.pixelPerDegree); 391 } 392 }); 383 public BufferedImage getPartialMatch(Projection projection, double pixelPerDegree, double east, double north) { 384 ProjectionEntries projectionEntries; 385 List<CacheEntry> matches; 386 synchronized (this) { 387 matches = new ArrayList<WmsCache.CacheEntry>(); 388 389 double minPPD = pixelPerDegree / 5; 390 double maxPPD = pixelPerDegree * 5; 391 projectionEntries = getProjectionEntries(projection); 392 393 double size2 = tileSize / pixelPerDegree; 394 double border = tileSize * 0.01; // Make sure not to load neighboring tiles that intersects this tile only slightly 395 ProjectionBounds bounds = new ProjectionBounds(east + border, north + border, 396 east + size2 - border, north + size2 - border); 397 398 //TODO Do not load tile if it is completely overlapped by other tile with better ppd 399 for (CacheEntry entry: projectionEntries.entries) { 400 if (entry.pixelPerDegree >= minPPD && entry.pixelPerDegree <= maxPPD && entry.bounds.intersects(bounds)) { 401 entry.lastUsed = System.currentTimeMillis(); 402 matches.add(entry); 403 } 404 } 405 406 if (matches.isEmpty()) 407 return null; 408 409 410 Collections.sort(matches, new Comparator<CacheEntry>() { 411 @Override 412 public int compare(CacheEntry o1, CacheEntry o2) { 413 return Double.compare(o2.pixelPerDegree, o1.pixelPerDegree); 414 } 415 }); 416 } 393 417 394 418 //TODO Use alpha layer only when enabled on wms layer … … 396 420 Graphics2D g = result.createGraphics(); 397 421 422 398 423 boolean drawAtLeastOnce = false; 424 Map<CacheEntry, SoftReference<BufferedImage>> localCache = new HashMap<WmsCache.CacheEntry, SoftReference<BufferedImage>>(); 399 425 for (CacheEntry ce: matches) { 400 426 BufferedImage img; 401 427 try { 402 428 img = loadImage(projectionEntries, ce); 403 memoryCache.put(ce, new SoftReference<BufferedImage>(img));429 localCache.put(ce, new SoftReference<BufferedImage>(img)); 404 430 } catch (IOException e) { 405 431 continue; … … 418 444 } 419 445 420 if (drawAtLeastOnce) 446 if (drawAtLeastOnce) { 447 synchronized (this) { 448 memoryCache.putAll(localCache); 449 } 421 450 return result; 422 else451 } else 423 452 return null; 424 453 } … … 461 490 462 491 /** 463 * 492 * 464 493 * @param img Used only when overlapping is used, when not used, used raw from imageData 465 494 * @param imageData … … 475 504 File imageFile; 476 505 if (entry == null) { 477 entry = new CacheEntry(pixelPerDegree, east, north, tileSize);478 entry.lastUsed = System.currentTimeMillis();479 entry.lastModified = entry.lastUsed;480 506 481 507 String mimeType; … … 485 511 mimeType = URLConnection.guessContentTypeFromStream(imageData); 486 512 } 487 entry.filename = generateFileName(projectionEntries, pixelPerDegree, projection, east, north, mimeType); 513 entry = new CacheEntry(pixelPerDegree, east, north, tileSize,generateFileName(projectionEntries, pixelPerDegree, projection, east, north, mimeType)); 514 entry.lastUsed = System.currentTimeMillis(); 515 entry.lastModified = entry.lastUsed; 488 516 projectionEntries.entries.add(entry); 489 517 imageFile = getImageFile(projectionEntries, entry); -
trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
r4718 r4745 24 24 import java.awt.geom.Rectangle2D; 25 25 import java.io.File; 26 import java.io.IOException; 26 27 import java.net.MalformedURLException; 27 28 import java.net.URL; … … 39 40 import javax.swing.AbstractAction; 40 41 import javax.swing.Action; 42 import javax.swing.DefaultComboBoxModel; 41 43 import javax.swing.Icon; 44 import javax.swing.JComboBox; 42 45 import javax.swing.JComponent; 43 46 import javax.swing.JFileChooser; … … 57 60 58 61 import org.openstreetmap.josm.Main; 62 import org.openstreetmap.josm.actions.AbstractMergeAction.LayerListCellRenderer; 59 63 import org.openstreetmap.josm.actions.RenameLayerAction; 60 64 import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTaskList; … … 80 84 import org.openstreetmap.josm.gui.dialogs.LayerListDialog; 81 85 import org.openstreetmap.josm.gui.dialogs.LayerListPopup; 86 import org.openstreetmap.josm.gui.layer.WMSLayer.PrecacheTask; 82 87 import org.openstreetmap.josm.gui.layer.markerlayer.AudioMarker; 83 88 import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer; … … 86 91 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor; 87 92 import org.openstreetmap.josm.gui.progress.ProgressMonitor; 93 import org.openstreetmap.josm.gui.progress.ProgressTaskId; 94 import org.openstreetmap.josm.gui.progress.ProgressTaskIds; 88 95 import org.openstreetmap.josm.gui.widgets.HtmlPanel; 89 96 import org.openstreetmap.josm.io.JpgImporter; 97 import org.openstreetmap.josm.io.OsmTransferException; 90 98 import org.openstreetmap.josm.tools.AudioUtil; 91 99 import org.openstreetmap.josm.tools.DateUtils; … … 96 104 import org.openstreetmap.josm.tools.Utils; 97 105 import org.openstreetmap.josm.tools.WindowGeometry; 106 import org.xml.sax.SAXException; 98 107 99 108 public class GpxLayer extends Layer { … … 297 306 new ConvertToDataLayerAction(), 298 307 new DownloadAlongTrackAction(), 308 new DownloadWmsAlongTrackAction(), 299 309 SeparatorLayerAction.INSTANCE, 300 310 new ChooseTrackVisibilityAction(), … … 1245 1255 } 1246 1256 1257 1247 1258 /** 1248 1259 * Area "a" contains the hull that we would like to download data for. however we … … 1309 1320 } 1310 1321 ); 1322 } 1323 } 1324 1325 1326 public class DownloadWmsAlongTrackAction extends AbstractAction { 1327 public DownloadWmsAlongTrackAction() { 1328 super(tr("Precache imagery tiles along this track"), ImageProvider.get("downloadalongtrack")); 1329 } 1330 1331 public void actionPerformed(ActionEvent e) { 1332 1333 final List<LatLon> points = new ArrayList<LatLon>(); 1334 1335 for (GpxTrack trk : data.tracks) { 1336 for (GpxTrackSegment segment : trk.getSegments()) { 1337 for (WayPoint p : segment.getWayPoints()) { 1338 points.add(p.getCoor()); 1339 } 1340 } 1341 } 1342 for (WayPoint p : data.waypoints) { 1343 points.add(p.getCoor()); 1344 } 1345 1346 1347 final WMSLayer layer = askWMSLayer(); 1348 if (layer != null) { 1349 PleaseWaitRunnable task = new PleaseWaitRunnable(tr("Precaching WMS")) { 1350 1351 private PrecacheTask precacheTask; 1352 1353 @Override 1354 protected void realRun() throws SAXException, IOException, OsmTransferException { 1355 precacheTask = new PrecacheTask(progressMonitor); 1356 layer.downloadAreaToCache(precacheTask, points, 0, 0); 1357 while (!precacheTask.isFinished() && !progressMonitor.isCanceled()) { 1358 synchronized (this) { 1359 try { 1360 wait(200); 1361 } catch (InterruptedException e) { 1362 e.printStackTrace(); 1363 } 1364 } 1365 } 1366 } 1367 1368 @Override 1369 protected void finish() { 1370 } 1371 1372 @Override 1373 protected void cancel() { 1374 precacheTask.cancel(); 1375 } 1376 1377 @Override 1378 public ProgressTaskId canRunInBackground() { 1379 return ProgressTaskIds.PRECACHE_WMS; 1380 } 1381 }; 1382 Main.worker.execute(task); 1383 } 1384 1385 1386 } 1387 1388 protected WMSLayer askWMSLayer() { 1389 List<WMSLayer> targetLayers = Main.map.mapView.getLayersOfType(WMSLayer.class); 1390 1391 if (targetLayers.isEmpty()) { 1392 warnNoImageryLayers(); 1393 return null; 1394 } 1395 1396 JComboBox layerList = new JComboBox(); 1397 layerList.setRenderer(new LayerListCellRenderer()); 1398 layerList.setModel(new DefaultComboBoxModel(targetLayers.toArray())); 1399 layerList.setSelectedIndex(0); 1400 1401 JPanel pnl = new JPanel(); 1402 pnl.setLayout(new GridBagLayout()); 1403 pnl.add(new JLabel(tr("Please select the imagery layer.")), GBC.eol()); 1404 pnl.add(layerList, GBC.eol()); 1405 1406 ExtendedDialog ed = new ExtendedDialog(Main.parent, 1407 tr("Select imagery layer"), 1408 new String[] { tr("Download"), tr("Cancel") }); 1409 ed.setButtonIcons(new String[] { "dialogs/down", "cancel" }); 1410 ed.setContent(pnl); 1411 ed.showDialog(); 1412 if (ed.getValue() != 1) 1413 return null; 1414 1415 WMSLayer targetLayer = (WMSLayer) layerList.getSelectedItem(); 1416 return targetLayer; 1417 } 1418 1419 protected void warnNoImageryLayers() { 1420 JOptionPane.showMessageDialog(Main.parent, 1421 tr("There are no imagery layers."), 1422 tr("No imagery layers"), JOptionPane.WARNING_MESSAGE); 1311 1423 } 1312 1424 } -
trunk/src/org/openstreetmap/josm/gui/layer/WMSLayer.java
r4633 r4745 8 8 import java.awt.Graphics2D; 9 9 import java.awt.Image; 10 import java.awt.Point; 10 11 import java.awt.event.ActionEvent; 11 12 import java.awt.event.MouseAdapter; … … 45 46 import org.openstreetmap.josm.data.ProjectionBounds; 46 47 import org.openstreetmap.josm.data.coor.EastNorth; 48 import org.openstreetmap.josm.data.coor.LatLon; 47 49 import org.openstreetmap.josm.data.imagery.GeorefImage; 48 50 import org.openstreetmap.josm.data.imagery.GeorefImage.State; … … 61 63 import org.openstreetmap.josm.gui.dialogs.LayerListDialog; 62 64 import org.openstreetmap.josm.gui.dialogs.LayerListPopup; 65 import org.openstreetmap.josm.gui.progress.ProgressMonitor; 63 66 import org.openstreetmap.josm.io.imagery.Grabber; 64 67 import org.openstreetmap.josm.io.imagery.HTMLGrabber; … … 67 70 import org.openstreetmap.josm.tools.ImageProvider; 68 71 72 69 73 /** 70 74 * This is a layer that grabs the current screen from an WMS server. The data … … 72 76 */ 73 77 public class WMSLayer extends ImageryLayer implements ImageObserver, PreferenceChangedListener { 78 79 public static class PrecacheTask { 80 private final ProgressMonitor progressMonitor; 81 private volatile int totalCount; 82 private volatile int processedCount; 83 private volatile boolean isCancelled; 84 85 public PrecacheTask(ProgressMonitor progressMonitor) { 86 this.progressMonitor = progressMonitor; 87 } 88 89 boolean isFinished() { 90 return totalCount == processedCount; 91 } 92 93 public int getTotalCount() { 94 return totalCount; 95 } 96 97 public void cancel() { 98 isCancelled = true; 99 } 100 } 74 101 75 102 private static final ObjectFactory OBJECT_FACTORY = null; // Fake reference to keep build scripts from removing ObjectFactory class. This class is not used directly but it's necessary for jaxb to work … … 159 186 } 160 187 188 161 189 Main.pref.addPreferenceChangeListener(this); 162 190 … … 205 233 public boolean hasAutoDownload(){ 206 234 return autoDownloadEnabled; 235 } 236 237 public void downloadAreaToCache(PrecacheTask precacheTask, List<LatLon> points, double bufferX, double bufferY) { 238 Set<Point> requestedTiles = new HashSet<Point>(); 239 for (LatLon point: points) { 240 EastNorth minEn = Main.getProjection().latlon2eastNorth(new LatLon(point.lat() - bufferY, point.lon() - bufferX)); 241 EastNorth maxEn = Main.getProjection().latlon2eastNorth(new LatLon(point.lat() + bufferY, point.lon() + bufferX)); 242 int minX = getImageXIndex(minEn.east()); 243 int maxX = getImageXIndex(maxEn.east()); 244 int minY = getImageYIndex(minEn.north()); 245 int maxY = getImageYIndex(maxEn.north()); 246 247 for (int x=minX; x<=maxX; x++) { 248 for (int y=minY; y<=maxY; y++) { 249 requestedTiles.add(new Point(x, y)); 250 } 251 } 252 } 253 254 for (Point p: requestedTiles) { 255 addRequest(new WMSRequest(p.x, p.y, info.getPixelPerDegree(), true, false, precacheTask)); 256 } 257 258 precacheTask.progressMonitor.setTicksCount(precacheTask.getTotalCount()); 259 precacheTask.progressMonitor.setCustomText(tr("Downloaded {0}/{1} tiles", 0, precacheTask.totalCount)); 207 260 } 208 261 … … 472 525 int dy = request.getYIndex() - mouseY; 473 526 474 return dx * dx + dy * dy; 475 } 476 477 public WMSRequest getRequest() { 527 return 1 + dx * dx + dy * dy; 528 } 529 530 private void sortRequests(boolean localOnly) { 531 Iterator<WMSRequest> it = requestQueue.iterator(); 532 while (it.hasNext()) { 533 WMSRequest item = it.next(); 534 535 if (item.getPrecacheTask() != null && item.getPrecacheTask().isCancelled) { 536 it.remove(); 537 continue; 538 } 539 540 int priority = getRequestPriority(item); 541 if (priority == -1 && item.isPrecacheOnly()) { 542 priority = Integer.MAX_VALUE; // Still download, but prefer requests in current view 543 } 544 545 if (localOnly && !item.hasExactMatch()) { 546 priority = Integer.MAX_VALUE; // Only interested in tiles that can be loaded from file immediately 547 } 548 549 if ( priority == -1 550 || finishedRequests.contains(item) 551 || processingRequests.contains(item)) { 552 it.remove(); 553 } else { 554 item.setPriority(priority); 555 } 556 } 557 Collections.sort(requestQueue); 558 } 559 560 public WMSRequest getRequest(boolean localOnly) { 478 561 requestQueueLock.lock(); 479 562 try { 480 563 workingThreadCount--; 481 Iterator<WMSRequest> it = requestQueue.iterator(); 482 while (it.hasNext()) { 483 WMSRequest item = it.next(); 484 int priority = getRequestPriority(item); 485 if (priority == -1 || finishedRequests.contains(item) || processingRequests.contains(item)) { 486 it.remove(); 487 } else { 488 item.setPriority(priority); 489 } 490 } 491 Collections.sort(requestQueue); 492 493 EastNorth cursorEastNorth = mv.getEastNorth(mv.lastMEvent.getX(), mv.lastMEvent.getY()); 494 int mouseX = getImageXIndex(cursorEastNorth.east()); 495 int mouseY = getImageYIndex(cursorEastNorth.north()); 496 boolean isOnMouse = requestQueue.size() > 0 && requestQueue.get(0).getXIndex() == mouseX && requestQueue.get(0).getYIndex() == mouseY; 497 498 // If there is only one thread left then keep it in case we need to download other tile urgently 499 while (!canceled && 500 (requestQueue.isEmpty() || (!isOnMouse && threadCount - workingThreadCount == 0 && threadCount > 1))) { 564 565 sortRequests(localOnly); 566 while (!canceled && (requestQueue.isEmpty() || (localOnly && !requestQueue.get(0).hasExactMatch()))) { 501 567 try { 502 568 queueEmpty.await(); 569 sortRequests(localOnly); 503 570 } catch (InterruptedException e) { 504 571 // Shouldn't happen … … 523 590 requestQueueLock.lock(); 524 591 try { 592 PrecacheTask task = request.getPrecacheTask(); 593 if (task != null) { 594 task.processedCount++; 595 if (!task.progressMonitor.isCanceled()) { 596 task.progressMonitor.worked(1); 597 task.progressMonitor.setCustomText(tr("Downloaded {0}/{1} tiles", task.processedCount, task.totalCount)); 598 } 599 } 525 600 processingRequests.remove(request); 526 if (request.getState() != null ) {601 if (request.getState() != null && !request.isPrecacheOnly()) { 527 602 finishedRequests.add(request); 528 603 mv.repaint(); … … 536 611 requestQueueLock.lock(); 537 612 try { 613 614 ProjectionBounds b = getBounds(request); 615 // Checking for exact match is fast enough, no need to do it in separated thread 616 request.setHasExactMatch(cache.hasExactMatch(Main.getProjection(), request.getPixelPerDegree(), b.minEast, b.minNorth)); 617 if (request.isPrecacheOnly() && request.hasExactMatch()) 618 return; // We already have this tile cached 619 538 620 if (!requestQueue.contains(request) && !finishedRequests.contains(request) && !processingRequests.contains(request)) { 539 621 requestQueue.add(request); 622 if (request.getPrecacheTask() != null) { 623 request.getPrecacheTask().totalCount++; 624 } 540 625 queueEmpty.signalAll(); 541 626 } … … 545 630 } 546 631 547 public boolean requestIsV alid(WMSRequest request) {632 public boolean requestIsVisible(WMSRequest request) { 548 633 return bminx <= request.getXIndex() && bmaxx >= request.getXIndex() && bminy <= request.getYIndex() && bmaxy >= request.getYIndex(); 549 634 } … … 871 956 grabberThreads.clear(); 872 957 for (int i=0; i<threadCount; i++) { 873 Grabber grabber = getGrabber( );958 Grabber grabber = getGrabber(i == 0 && threadCount > 1); 874 959 grabbers.add(grabber); 875 960 Thread t = new Thread(grabber, "WMS " + getName() + " " + i); … … 914 999 } 915 1000 916 protected Grabber getGrabber( ){1001 protected Grabber getGrabber(boolean localOnly){ 917 1002 if(getInfo().getImageryType() == ImageryType.HTML) 918 return new HTMLGrabber(mv, this );1003 return new HTMLGrabber(mv, this, localOnly); 919 1004 else if(getInfo().getImageryType() == ImageryType.WMS) 920 return new WMSGrabber(mv, this );1005 return new WMSGrabber(mv, this, localOnly); 921 1006 else throw new IllegalStateException("getGrabber() called for non-WMS layer type"); 1007 } 1008 1009 public ProjectionBounds getBounds(WMSRequest request) { 1010 ProjectionBounds result = new ProjectionBounds( 1011 getEastNorth(request.getXIndex(), request.getYIndex()), 1012 getEastNorth(request.getXIndex() + 1, request.getYIndex() + 1)); 1013 1014 if (WMSLayer.PROP_OVERLAP.get()) { 1015 double eastSize = result.maxEast - result.minEast; 1016 double northSize = result.maxNorth - result.minNorth; 1017 1018 double eastCoef = WMSLayer.PROP_OVERLAP_EAST.get() / 100.0; 1019 double northCoef = WMSLayer.PROP_OVERLAP_NORTH.get() / 100.0; 1020 1021 result = new ProjectionBounds(result.getMin(), 1022 new EastNorth(result.maxEast + eastCoef * eastSize, 1023 result.maxNorth + northCoef * northSize)); 1024 } 1025 return result; 922 1026 } 923 1027 -
trunk/src/org/openstreetmap/josm/gui/progress/ProgressTaskIds.java
r4718 r4745 5 5 6 6 ProgressTaskId DOWNLOAD_GPS = new ProgressTaskId("core", "downloadGps"); 7 ProgressTaskId PRECACHE_WMS = new ProgressTaskId("core", "precacheWms"); 7 8 8 9 } -
trunk/src/org/openstreetmap/josm/io/imagery/Grabber.java
r4126 r4745 4 4 import org.openstreetmap.josm.Main; 5 5 import org.openstreetmap.josm.data.ProjectionBounds; 6 import org.openstreetmap.josm.data.coor.EastNorth;7 6 import org.openstreetmap.josm.data.imagery.GeorefImage.State; 8 import org.openstreetmap.josm.data.projection.Projection;9 7 import org.openstreetmap.josm.gui.MapView; 10 8 import org.openstreetmap.josm.gui.layer.WMSLayer; … … 13 11 protected final MapView mv; 14 12 protected final WMSLayer layer; 13 private final boolean localOnly; 15 14 16 15 protected ProjectionBounds b; 17 protected Projection proj;18 protected double pixelPerDegree;19 protected WMSRequest request;20 16 protected volatile boolean canceled; 21 17 22 Grabber(MapView mv, WMSLayer layer ) {18 Grabber(MapView mv, WMSLayer layer, boolean localOnly) { 23 19 this.mv = mv; 24 20 this.layer = layer; 25 } 26 27 private void updateState(WMSRequest request) { 28 b = new ProjectionBounds( 29 layer.getEastNorth(request.getXIndex(), request.getYIndex()), 30 layer.getEastNorth(request.getXIndex() + 1, request.getYIndex() + 1)); 31 if (WMSLayer.PROP_OVERLAP.get()) { 32 double eastSize = b.maxEast - b.minEast; 33 double northSize = b.maxNorth - b.minNorth; 34 35 double eastCoef = WMSLayer.PROP_OVERLAP_EAST.get() / 100.0; 36 double northCoef = WMSLayer.PROP_OVERLAP_NORTH.get() / 100.0; 37 38 this.b = new ProjectionBounds(b.getMin(), 39 new EastNorth(b.maxEast + eastCoef * eastSize, 40 b.maxNorth + northCoef * northSize)); 41 } 42 43 this.proj = Main.getProjection(); 44 this.pixelPerDegree = request.getPixelPerDegree(); 45 this.request = request; 21 this.localOnly = localOnly; 46 22 } 47 23 … … 60 36 if (canceled) 61 37 return; 62 WMSRequest request = layer.getRequest( );38 WMSRequest request = layer.getRequest(localOnly); 63 39 if (request == null) 64 40 return; 65 updateState(request); 66 if(!loadFromCache(request)){ 67 attempt(request); 41 this.b = layer.getBounds(request); 42 if (request.isPrecacheOnly()) { 43 if (!layer.cache.hasExactMatch(Main.getProjection(), request.getPixelPerDegree(), b.minEast, b.minNorth)) { 44 attempt(request); 45 } 46 } else { 47 if(!loadFromCache(request)){ 48 attempt(request); 49 } 68 50 } 69 51 layer.finishRequest(request); … … 77 59 return; 78 60 try { 79 if (! layer.requestIsValid(request))61 if (!request.isPrecacheOnly() && !layer.requestIsVisible(request)) 80 62 return; 81 63 fetch(request, i); -
trunk/src/org/openstreetmap/josm/io/imagery/HTMLGrabber.java
r4126 r4745 22 22 public static final StringProperty PROP_BROWSER = new StringProperty("imagery.wms.browser", "webkit-image {0}"); 23 23 24 public HTMLGrabber(MapView mv, WMSLayer layer ) {25 super(mv, layer );24 public HTMLGrabber(MapView mv, WMSLayer layer, boolean localOnly) { 25 super(mv, layer, localOnly); 26 26 } 27 27 28 28 @Override 29 protected BufferedImage grab( URL url, int attempt) throws IOException {29 protected BufferedImage grab(WMSRequest request, URL url, int attempt) throws IOException { 30 30 String urlstring = url.toExternalForm(); 31 31 … … 52 52 BufferedImage img = layer.normalizeImage(ImageIO.read(bais)); 53 53 bais.reset(); 54 layer.cache.saveToCache(layer.isOverlapEnabled()?img:null, bais, Main.getProjection(), pixelPerDegree, b.minEast, b.minNorth);54 layer.cache.saveToCache(layer.isOverlapEnabled()?img:null, bais, Main.getProjection(), request.getPixelPerDegree(), b.minEast, b.minNorth); 55 55 56 56 return img; -
trunk/src/org/openstreetmap/josm/io/imagery/WMSGrabber.java
r4432 r4745 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.io.imagery; 3 4 import static org.openstreetmap.josm.tools.I18n.tr;5 3 6 4 import java.awt.image.BufferedImage; … … 18 16 import java.text.DecimalFormatSymbols; 19 17 import java.text.NumberFormat; 20 import java.util.ArrayList; 21 import java.util.List; 22 import java.util.Map.Entry; 18 import java.util.HashMap; 23 19 import java.util.Locale; 24 20 import java.util.Map; 25 import java.util. HashMap;21 import java.util.Map.Entry; 26 22 import java.util.regex.Matcher; 27 23 import java.util.regex.Pattern; 28 24 29 25 import javax.imageio.ImageIO; 30 import javax.swing.JOptionPane;31 26 32 27 import org.openstreetmap.josm.Main; … … 50 45 private Map<String, String> props = new HashMap<String, String>(); 51 46 52 public WMSGrabber(MapView mv, WMSLayer layer ) {53 super(mv, layer );47 public WMSGrabber(MapView mv, WMSLayer layer, boolean localOnly) { 48 super(mv, layer, localOnly); 54 49 this.info = layer.getInfo(); 55 50 this.baseURL = info.getUrl(); … … 77 72 b.maxEast, b.maxNorth, 78 73 width(), height()); 79 request.finish(State.IMAGE, grab( url, attempt));74 request.finish(State.IMAGE, grab(request, url, attempt)); 80 75 81 76 } catch(Exception e) { … … 102 97 103 98 return new URL(baseURL.replaceAll("\\{proj(\\([^})]+\\))?\\}", myProj) 104 .replaceAll("\\{bbox\\}", latLonFormat.format(w) + ","105 + latLonFormat.format(s) + ","106 + latLonFormat.format(e) + ","107 + latLonFormat.format(n))108 .replaceAll("\\{w\\}", latLonFormat.format(w))109 .replaceAll("\\{s\\}", latLonFormat.format(s))110 .replaceAll("\\{e\\}", latLonFormat.format(e))111 .replaceAll("\\{n\\}", latLonFormat.format(n))112 .replaceAll("\\{width\\}", String.valueOf(wi))113 .replaceAll("\\{height\\}", String.valueOf(ht))114 .replace(" ", "%20"));99 .replaceAll("\\{bbox\\}", latLonFormat.format(w) + "," 100 + latLonFormat.format(s) + "," 101 + latLonFormat.format(e) + "," 102 + latLonFormat.format(n)) 103 .replaceAll("\\{w\\}", latLonFormat.format(w)) 104 .replaceAll("\\{s\\}", latLonFormat.format(s)) 105 .replaceAll("\\{e\\}", latLonFormat.format(e)) 106 .replaceAll("\\{n\\}", latLonFormat.format(n)) 107 .replaceAll("\\{width\\}", String.valueOf(wi)) 108 .replaceAll("\\{height\\}", String.valueOf(ht)) 109 .replace(" ", "%20")); 115 110 } 116 111 117 112 @Override 118 113 public boolean loadFromCache(WMSRequest request) { 119 BufferedImage cached = layer.cache.getExactMatch(Main.getProjection(), pixelPerDegree, b.minEast, b.minNorth);114 BufferedImage cached = layer.cache.getExactMatch(Main.getProjection(), request.getPixelPerDegree(), b.minEast, b.minNorth); 120 115 121 116 if (cached != null) { … … 123 118 return true; 124 119 } else if (request.isAllowPartialCacheMatch()) { 125 BufferedImage partialMatch = layer.cache.getPartialMatch(Main.getProjection(), pixelPerDegree, b.minEast, b.minNorth);120 BufferedImage partialMatch = layer.cache.getPartialMatch(Main.getProjection(), request.getPixelPerDegree(), b.minEast, b.minNorth); 126 121 if (partialMatch != null) { 127 122 request.finish(State.PARTLY_IN_CACHE, partialMatch); … … 138 133 } 139 134 140 protected BufferedImage grab( URL url, int attempt) throws IOException, OsmTransferException {135 protected BufferedImage grab(WMSRequest request, URL url, int attempt) throws IOException, OsmTransferException { 141 136 System.out.println("Grabbing WMS " + (attempt > 1? "(attempt " + attempt + ") ":"") + url); 142 137 … … 164 159 BufferedImage img = layer.normalizeImage(ImageIO.read(bais)); 165 160 bais.reset(); 166 layer.cache.saveToCache(layer.isOverlapEnabled()?img:null, bais, Main.getProjection(), pixelPerDegree, b.minEast, b.minNorth);161 layer.cache.saveToCache(layer.isOverlapEnabled()?img:null, bais, Main.getProjection(), request.getPixelPerDegree(), b.minEast, b.minNorth); 167 162 return img; 168 163 } -
trunk/src/org/openstreetmap/josm/io/imagery/WMSRequest.java
r4065 r4745 5 5 6 6 import org.openstreetmap.josm.data.imagery.GeorefImage.State; 7 import org.openstreetmap.josm.gui.layer.WMSLayer.PrecacheTask; 7 8 8 9 public class WMSRequest implements Comparable<WMSRequest> { … … 11 12 private final double pixelPerDegree; 12 13 private final boolean real; // Download even if autodownloading is disabled 14 private final PrecacheTask precacheTask; // Download even when wms tile is not currently visible (precache) 13 15 private final boolean allowPartialCacheMatch; 14 16 private int priority; 17 private boolean hasExactMatch; 15 18 // Result 16 19 private State state; … … 18 21 19 22 public WMSRequest(int xIndex, int yIndex, double pixelPerDegree, boolean real, boolean allowPartialCacheMatch) { 23 this(xIndex, yIndex, pixelPerDegree, real, allowPartialCacheMatch, null); 24 } 25 26 public WMSRequest(int xIndex, int yIndex, double pixelPerDegree, boolean real, boolean allowPartialCacheMatch, PrecacheTask precacheTask) { 20 27 this.xIndex = xIndex; 21 28 this.yIndex = yIndex; 22 29 this.pixelPerDegree = pixelPerDegree; 23 30 this.real = real; 31 this.precacheTask = precacheTask; 24 32 this.allowPartialCacheMatch = allowPartialCacheMatch; 25 33 } 34 26 35 27 36 public void finish(State state, BufferedImage image) { … … 99 108 public String toString() { 100 109 return "WMSRequest [xIndex=" + xIndex + ", yIndex=" + yIndex 101 + ", pixelPerDegree=" + pixelPerDegree + "]";110 + ", pixelPerDegree=" + pixelPerDegree + "]"; 102 111 } 103 112 … … 106 115 } 107 116 117 public boolean isPrecacheOnly() { 118 return precacheTask != null; 119 } 120 121 public PrecacheTask getPrecacheTask() { 122 return precacheTask; 123 } 124 108 125 public boolean isAllowPartialCacheMatch() { 109 126 return allowPartialCacheMatch; 110 127 } 128 129 public boolean hasExactMatch() { 130 return hasExactMatch; 131 } 132 133 public void setHasExactMatch(boolean hasExactMatch) { 134 this.hasExactMatch = hasExactMatch; 135 } 111 136 }
Note:
See TracChangeset
for help on using the changeset viewer.