Changeset 10820 in josm
- Timestamp:
- 2016-08-16T09:12:51+02:00 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java
r10809 r10820 35 35 import java.util.Map; 36 36 import java.util.Map.Entry; 37 import java.util.Objects; 37 38 import java.util.Set; 38 39 import java.util.concurrent.ConcurrentSkipListSet; 39 40 import java.util.concurrent.atomic.AtomicInteger; 41 import java.util.function.Consumer; 42 import java.util.function.Function; 43 import java.util.stream.Collectors; 44 import java.util.stream.IntStream; 40 45 import java.util.stream.Stream; 41 46 … … 958 963 } 959 964 965 private Tile getOrCreateTile(TilePosition tilePosition) { 966 return getOrCreateTile(tilePosition.getX(), tilePosition.getY(), tilePosition.getZoom()); 967 } 968 960 969 private Tile getOrCreateTile(int x, int y, int zoom) { 961 970 Tile tile = getTile(x, y, zoom); … … 969 978 } 970 979 return tile; 980 } 981 982 private Tile getTile(TilePosition tilePosition) { 983 return getTile(tilePosition.getX(), tilePosition.getY(), tilePosition.getZoom()); 971 984 } 972 985 … … 1125 1138 ((Graphics2D) g).fill(target); 1126 1139 } 1140 } 1141 1142 private List<Tile> paintTileImages(Graphics g, TileSet ts) { 1143 Object paintMutex = new Object(); 1144 List<TilePosition> missed = Collections.synchronizedList(new ArrayList<>()); 1145 ts.visitTiles(tile -> { 1146 Image img = getLoadedTileImage(tile); 1147 if (img == null) { 1148 missed.add(new TilePosition(tile)); 1149 } 1150 img = applyImageProcessors((BufferedImage) img); 1151 Rectangle2D sourceRect = coordinateConverter.getRectangleForTile(tile); 1152 synchronized (paintMutex) { 1153 //cannot paint in parallel 1154 drawImageInside(g, img, sourceRect, null); 1155 } 1156 }, missed::add); 1157 1158 return missed.stream().map(this::getOrCreateTile).collect(Collectors.toList()); 1127 1159 } 1128 1160 … … 1138 1170 private List<Tile> paintTileImages(Graphics g, TileSet ts, int zoom, Tile border) { 1139 1171 if (zoom <= 0) return Collections.emptyList(); 1140 Rectangle2D borderRect = null; 1141 if (border != null) { 1142 borderRect = coordinateConverter.getRectangleForTile(border); 1143 } 1172 Rectangle2D borderRect = coordinateConverter.getRectangleForTile(border); 1144 1173 List<Tile> missedTiles = new LinkedList<>(); 1145 1174 // The callers of this code *require* that we return any tiles … … 1295 1324 return xSpan * ySpan; 1296 1325 } 1326 1327 /** 1328 * Gets a stream of all tile positions in this set 1329 * @return A stream of all positions 1330 */ 1331 public Stream<TilePosition> tilePositions() { 1332 if (zoom == 0) { 1333 return Stream.empty(); 1334 } else { 1335 return IntStream.rangeClosed(minX, maxX).mapToObj( 1336 x -> IntStream.rangeClosed(minY, maxY).mapToObj(y -> new TilePosition(x, y, zoom)) 1337 ).flatMap(Function.identity()); 1338 } 1339 } 1340 } 1341 1342 /** 1343 * The position of a single tile. 1344 * @author Michael Zangl 1345 * @since xxx 1346 */ 1347 private static class TilePosition { 1348 private final int x; 1349 private final int y; 1350 private final int zoom; 1351 TilePosition(int x, int y, int zoom) { 1352 super(); 1353 this.x = x; 1354 this.y = y; 1355 this.zoom = zoom; 1356 } 1357 1358 TilePosition(Tile tile) { 1359 this(tile.getXtile(), tile.getYtile(), tile.getZoom()); 1360 } 1361 1362 /** 1363 * @return the x position 1364 */ 1365 public int getX() { 1366 return x; 1367 } 1368 1369 /** 1370 * @return the y position 1371 */ 1372 public int getY() { 1373 return y; 1374 } 1375 1376 /** 1377 * @return the zoom 1378 */ 1379 public int getZoom() { 1380 return zoom; 1381 } 1382 1383 @Override 1384 public String toString() { 1385 return "TilePosition [x=" + x + ", y=" + y + ", zoom=" + zoom + "]"; 1386 } 1297 1387 } 1298 1388 … … 1308 1398 */ 1309 1399 private TileSet() { 1310 return;1400 // default 1311 1401 } 1312 1402 … … 1338 1428 } 1339 1429 1340 /* 1341 * Get all tiles represented by this TileSet that are 1342 * already in the tileCache. 1430 /** 1431 * Get all tiles represented by this TileSet that are already in the tileCache. 1343 1432 */ 1344 1433 private List<Tile> allExistingTiles() { 1345 return this.findAllTiles(false);1434 return allTiles(p -> getTile(p)); 1346 1435 } 1347 1436 1348 1437 private List<Tile> allTilesCreate() { 1349 return this.findAllTiles(true); 1350 } 1351 1352 private List<Tile> findAllTiles(boolean create) { 1353 // Tileset is either empty or too large 1354 if (zoom == 0 || this.insane()) 1355 return Collections.emptyList(); 1356 List<Tile> ret = new ArrayList<>(); 1357 for (int x = minX; x <= maxX; x++) { 1358 for (int y = minY; y <= maxY; y++) { 1359 Tile t; 1360 if (create) { 1361 t = getOrCreateTile(x, y, zoom); 1362 } else { 1363 t = getTile(x, y, zoom); 1364 } 1365 if (t != null) { 1366 ret.add(t); 1367 } 1368 } 1369 } 1370 return ret; 1438 return allTiles(p -> getOrCreateTile(p)); 1439 } 1440 1441 private List<Tile> allTiles(Function<TilePosition, Tile> mapper) { 1442 return tilePositions().map(mapper).filter(Objects::nonNull).collect(Collectors.toList()); 1443 } 1444 1445 @Override 1446 public Stream<TilePosition> tilePositions() { 1447 if (this.insane()) { 1448 // Tileset is either empty or too large 1449 return Stream.empty(); 1450 } else { 1451 return super.tilePositions(); 1452 } 1371 1453 } 1372 1454 1373 1455 private List<Tile> allLoadedTiles() { 1374 List<Tile> ret = new ArrayList<>(); 1375 for (Tile t : this.allExistingTiles()) { 1376 if (t.isLoaded()) 1377 ret.add(t); 1378 } 1379 return ret; 1456 return allExistingTiles().stream().filter(Tile::isLoaded).collect(Collectors.toList()); 1380 1457 } 1381 1458 … … 1386 1463 final int centerX = (int) Math.ceil((minX + maxX) / 2d); 1387 1464 final int centerY = (int) Math.ceil((minY + maxY) / 2d); 1388 return new Comparator<Tile>() { 1389 private int getDistance(Tile t) { 1390 return Math.abs(t.getXtile() - centerX) + Math.abs(t.getYtile() - centerY); 1391 } 1392 1393 @Override 1394 public int compare(Tile o1, Tile o2) { 1395 int distance1 = getDistance(o1); 1396 int distance2 = getDistance(o2); 1397 return Integer.compare(distance1, distance2); 1398 } 1399 }; 1465 return Comparator.comparingInt(t -> Math.abs(t.getXtile() - centerX) + Math.abs(t.getYtile() - centerY)); 1400 1466 } 1401 1467 … … 1417 1483 tileLoader.createTileLoaderJob(t).submit(force); 1418 1484 } 1485 } 1486 } 1487 1488 /** 1489 * Call the given paint method for all tiles in this tile set. 1490 * <p> 1491 * Uses a parallel stream. 1492 * @param visitor A visitor to call for each tile. 1493 * @param missed a consumer to call for each missed tile. 1494 */ 1495 public void visitTiles(Consumer<Tile> visitor, Consumer<TilePosition> missed) { 1496 tilePositions().parallel().forEach(tp -> visitTilePosition(visitor, tp, missed)); 1497 } 1498 1499 private void visitTilePosition(Consumer<Tile> visitor, TilePosition tp, Consumer<TilePosition> missed) { 1500 Tile tile = getTile(tp); 1501 if (tile == null) { 1502 missed.accept(tp); 1503 } else { 1504 visitor.accept(tile); 1419 1505 } 1420 1506 } … … 1592 1678 g.setColor(Color.DARK_GRAY); 1593 1679 1594 List<Tile> missedTiles = this.paintTileImages(g, ts , displayZoomLevel, null);1680 List<Tile> missedTiles = this.paintTileImages(g, ts); 1595 1681 int[] otherZooms = {-1, 1, -2, 2, -3, -4, -5}; 1596 1682 for (int zoomOffset : otherZooms) {
Note:
See TracChangeset
for help on using the changeset viewer.