- Timestamp:
- 2017-09-11T17:59:33+02:00 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java
r12671 r12824 1143 1143 protected class TileSet extends TileRange { 1144 1144 1145 private volatile TileSetInfo info; 1146 1145 1147 protected TileSet(TileXY t1, TileXY t2, int zoom) { 1146 1148 super(t1, t2, zoom); … … 1269 1271 } 1270 1272 1273 /** 1274 * Check if there is any tile fully loaded without error. 1275 * @return true if there is any tile fully loaded without error 1276 */ 1277 public boolean hasVisibleTiles() { 1278 return getTileSetInfo().hasVisibleTiles; 1279 } 1280 1281 /** 1282 * Check if there there is a tile that is overzoomed. 1283 * <p> 1284 * I.e. the server response for one tile was "there is no tile here". 1285 * This usually happens when zoomed in too much. The limit depends on 1286 * the region, so at the edge of such a region, some tiles may be 1287 * available and some not. 1288 * @return true if there there is a tile that is overzoomed 1289 */ 1290 public boolean hasOverzoomedTiles() { 1291 return getTileSetInfo().hasOverzoomedTiles; 1292 } 1293 1294 /** 1295 * Check if there are tiles still loading. 1296 * <p> 1297 * This is the case if there is a tile not yet in the cache, or in the 1298 * cache but marked as loading ({@link Tile#isLoading()}. 1299 * @return true if there are tiles still loading 1300 */ 1301 public boolean hasLoadingTiles() { 1302 return getTileSetInfo().hasLoadingTiles; 1303 } 1304 1305 /** 1306 * Check if all tiles in the range are fully loaded. 1307 * <p> 1308 * A tile is considered to be fully loaded even if the result of loading 1309 * the tile was an error. 1310 * @return true if all tiles in the range are fully loaded 1311 */ 1312 public boolean hasAllLoadedTiles() { 1313 return getTileSetInfo().hasAllLoadedTiles; 1314 } 1315 1316 private TileSetInfo getTileSetInfo() { 1317 if (info == null) { 1318 synchronized (this) { 1319 if (info == null) { 1320 List<Tile> allTiles = this.allExistingTiles(); 1321 info = new TileSetInfo(); 1322 info.hasLoadingTiles = allTiles.size() < this.size(); 1323 info.hasAllLoadedTiles = true; 1324 for (Tile t : allTiles) { 1325 if ("no-tile".equals(t.getValue("tile-info"))) { 1326 info.hasOverzoomedTiles = true; 1327 } 1328 if (t.isLoaded()) { 1329 if (!t.hasError()) { 1330 info.hasVisibleTiles = true; 1331 } 1332 } else { 1333 info.hasAllLoadedTiles = false; 1334 if (t.isLoading()) { 1335 info.hasLoadingTiles = true; 1336 } 1337 } 1338 } 1339 } 1340 } 1341 } 1342 return info; 1343 } 1344 1271 1345 @Override 1272 1346 public String toString() { 1273 1347 return getClass().getName() + ": zoom: " + zoom + " X(" + minX + ", " + maxX + ") Y(" + minY + ", " + maxY + ") size: " + size(); 1274 1348 } 1349 } 1350 1351 /** 1352 * Data container to hold information about a {@link TileSet} class. 1353 */ 1354 private static class TileSetInfo { 1355 boolean hasVisibleTiles; 1356 boolean hasOverzoomedTiles; 1357 boolean hasLoadingTiles; 1358 boolean hasAllLoadedTiles; 1275 1359 } 1276 1360 … … 1302 1386 } 1303 1387 1304 private static class TileSetInfo {1305 boolean hasVisibleTiles;1306 boolean hasOverzoomedTiles;1307 boolean hasLoadingTiles;1308 boolean hasAllLoadedTiles;1309 }1310 1311 private static <S extends AbstractTMSTileSource> TileSetInfo getTileSetInfo(AbstractTileSourceLayer<S>.TileSet ts) {1312 List<Tile> allTiles = ts.allExistingTiles();1313 TileSetInfo result = new TileSetInfo();1314 result.hasLoadingTiles = allTiles.size() < ts.size();1315 result.hasAllLoadedTiles = true;1316 for (Tile t : allTiles) {1317 if ("no-tile".equals(t.getValue("tile-info"))) {1318 result.hasOverzoomedTiles = true;1319 }1320 if (t.isLoaded()) {1321 if (!t.hasError()) {1322 result.hasVisibleTiles = true;1323 }1324 } else {1325 result.hasAllLoadedTiles = false;1326 if (t.isLoading()) {1327 result.hasLoadingTiles = true;1328 }1329 }1330 }1331 return result;1332 }1333 1334 1388 private class DeepTileSet { 1335 1389 private final ProjectionBounds bounds; 1336 1390 private final int minZoom, maxZoom; 1337 1391 private final TileSet[] tileSets; 1338 private final TileSetInfo[] tileSetInfos;1339 1392 1340 1393 @SuppressWarnings("unchecked") … … 1344 1397 this.maxZoom = maxZoom; 1345 1398 this.tileSets = new AbstractTileSourceLayer.TileSet[maxZoom - minZoom + 1]; 1346 this.tileSetInfos = new TileSetInfo[maxZoom - minZoom + 1];1347 1399 } 1348 1400 … … 1359 1411 } 1360 1412 } 1361 1362 public TileSetInfo getTileSetInfo(int zoom) {1363 if (zoom < minZoom)1364 return new TileSetInfo();1365 synchronized (tileSetInfos) {1366 TileSetInfo tsi = tileSetInfos[zoom-minZoom];1367 if (tsi == null) {1368 tsi = AbstractTileSourceLayer.getTileSetInfo(getTileSet(zoom));1369 tileSetInfos[zoom-minZoom] = tsi;1370 }1371 return tsi;1372 }1373 }1374 1413 } 1375 1414 … … 1386 1425 1387 1426 DeepTileSet dts = new DeepTileSet(pb, getMinZoomLvl(), zoom); 1388 TileSet ts = dts.getTileSet(zoom);1389 1427 1390 1428 int displayZoomLevel = zoom; … … 1393 1431 if (getDisplaySettings().isAutoZoom() && getDisplaySettings().isAutoLoad()) { 1394 1432 // Auto-detection of tilesource maxzoom (currently fully works only for Bing) 1395 TileSet Info tsi = dts.getTileSetInfo(zoom);1396 if (!ts i.hasVisibleTiles && (!tsi.hasLoadingTiles || tsi.hasOverzoomedTiles)) {1433 TileSet ts0 = dts.getTileSet(zoom); 1434 if (!ts0.hasVisibleTiles() && (!ts0.hasLoadingTiles() || ts0.hasOverzoomedTiles())) { 1397 1435 noTilesAtZoom = true; 1398 1436 } 1399 1437 // Find highest zoom level with at least one visible tile 1400 1438 for (int tmpZoom = zoom; tmpZoom > dts.minZoom; tmpZoom--) { 1401 if (dts.getTileSet Info(tmpZoom).hasVisibleTiles) {1439 if (dts.getTileSet(tmpZoom).hasVisibleTiles()) { 1402 1440 displayZoomLevel = tmpZoom; 1403 1441 break; … … 1405 1443 } 1406 1444 // Do binary search between currentZoomLevel and displayZoomLevel 1407 while (zoom > displayZoomLevel && !ts i.hasVisibleTiles && tsi.hasOverzoomedTiles) {1445 while (zoom > displayZoomLevel && !ts0.hasVisibleTiles() && ts0.hasOverzoomedTiles()) { 1408 1446 zoom = (zoom + displayZoomLevel)/2; 1409 ts i = dts.getTileSetInfo(zoom);1447 ts0 = dts.getTileSet(zoom); 1410 1448 } 1411 1449 … … 1415 1453 // to make sure there're really no more zoom levels 1416 1454 // loading is done in the next if section 1417 if (zoom == displayZoomLevel && !ts i.hasLoadingTiles&& zoom < dts.maxZoom) {1455 if (zoom == displayZoomLevel && !ts0.hasLoadingTiles() && zoom < dts.maxZoom) { 1418 1456 zoom++; 1419 ts i = dts.getTileSetInfo(zoom);1457 ts0 = dts.getTileSet(zoom); 1420 1458 } 1421 1459 // When we have overzoomed tiles and all tiles at current zoomlevel is loaded, 1422 1460 // load tiles at previovus zoomlevels until we have all tiles on screen is loaded. 1423 1461 // loading is done in the next if section 1424 while (zoom > dts.minZoom && ts i.hasOverzoomedTiles && !tsi.hasLoadingTiles) {1462 while (zoom > dts.minZoom && ts0.hasOverzoomedTiles() && !ts0.hasLoadingTiles()) { 1425 1463 zoom--; 1426 tsi = dts.getTileSetInfo(zoom); 1427 } 1428 ts = dts.getTileSet(zoom); 1464 ts0 = dts.getTileSet(zoom); 1465 } 1429 1466 } else if (getDisplaySettings().isAutoZoom()) { 1430 1467 setZoomLevel(zoom, false); 1431 1468 } 1469 TileSet ts = dts.getTileSet(zoom); 1432 1470 1433 1471 // Too many tiles... refuse to download … … 1440 1478 if (displayZoomLevel != zoom) { 1441 1479 ts = dts.getTileSet(displayZoomLevel); 1442 if (!dts.getTileSet Info(displayZoomLevel).hasAllLoadedTiles&& displayZoomLevel < zoom) {1480 if (!dts.getTileSet(displayZoomLevel).hasAllLoadedTiles() && displayZoomLevel < zoom) { 1443 1481 // if we are showing tiles from lower zoom level, ensure that all tiles are loaded as they are few, 1444 1482 // and should not trash the tile cache
Note:
See TracChangeset
for help on using the changeset viewer.