Changeset 17474 in josm


Ignore:
Timestamp:
2021-01-21T23:33:21+01:00 (7 weeks ago)
Author:
Don-vip
Message:

test all WMS projections

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/test/unit/org/openstreetmap/josm/gui/preferences/imagery/ImageryPreferenceTestIT.java

    r17398 r17474  
    22package org.openstreetmap.josm.gui.preferences.imagery;
    33
     4import static java.util.Collections.singletonList;
     5import static java.util.Collections.synchronizedList;
     6import static java.util.Collections.synchronizedMap;
     7import static java.util.stream.Collectors.toList;
    48import static org.junit.jupiter.api.Assertions.assertFalse;
    59import static org.junit.jupiter.api.Assertions.assertTrue;
     
    1115import java.nio.charset.StandardCharsets;
    1216import java.util.ArrayList;
    13 import java.util.Collections;
    1417import java.util.List;
    1518import java.util.Locale;
    1619import java.util.Map;
     20import java.util.Objects;
    1721import java.util.Optional;
    1822import java.util.TreeMap;
    1923import java.util.concurrent.TimeUnit;
    20 import java.util.stream.Collectors;
    2124import java.util.stream.Stream;
    2225
     
    8689
    8790    /** Entry to test */
    88     private final Map<String, Map<ImageryInfo, List<String>>> errors = Collections.synchronizedMap(new TreeMap<>());
    89     private final Map<String, Map<ImageryInfo, List<String>>> ignoredErrors = Collections.synchronizedMap(new TreeMap<>());
    90     private static final Map<String, byte[]> workingURLs = Collections.synchronizedMap(new TreeMap<>());
     91    private final Map<String, Map<ImageryInfo, List<String>>> errors = synchronizedMap(new TreeMap<>());
     92    private final Map<String, Map<ImageryInfo, List<String>>> ignoredErrors = synchronizedMap(new TreeMap<>());
     93    private static final Map<String, byte[]> workingURLs = synchronizedMap(new TreeMap<>());
    9194
    9295    private static TMSCachedTileLoaderJob helper;
     
    124127        return ImageryLayerInfo.instance.getDefaultLayers()
    125128                .stream()
     129                //.filter(i -> "OGDLidarZH-DOM-2017".equals(i.getId())) // enable to test one specific entry
    126130                .map(i -> Arguments.of(i.getCountryCode().isEmpty() ? i.getId() : i.getCountryCode() + '-' + i.getId(), i))
    127                 .collect(Collectors.toList());
     131                .collect(toList());
    128132    }
    129133
     
    144148
    145149    private static boolean addError(Map<String, Map<ImageryInfo, List<String>>> map, ImageryInfo info, String errorMsg) {
    146         return map.computeIfAbsent(info.getCountryCode(), x -> Collections.synchronizedMap(new TreeMap<>()))
    147                   .computeIfAbsent(info, x -> Collections.synchronizedList(new ArrayList<>()))
     150        return map.computeIfAbsent(info.getCountryCode(), x -> synchronizedMap(new TreeMap<>()))
     151                  .computeIfAbsent(info, x -> synchronizedList(new ArrayList<>()))
    148152                  .add(errorMsg);
    149153    }
     
    187191    private void checkLinkUrl(ImageryInfo info, String url) {
    188192        checkUrl(info, url).filter(x -> x.length == 0).ifPresent(x -> addError(info, url + " -> returned empty contents"));
     193    }
     194
     195    private List<String> checkTileUrls(ImageryInfo info, List<AbstractTileSource> tileSources, ICoordinate center, int zoom)
     196            throws IOException {
     197        List<String> errors = new ArrayList<>();
     198        for (AbstractTileSource tileSource : tileSources) {
     199            String error = checkTileUrl(info, tileSource, center, zoom);
     200            if (!error.isEmpty()) {
     201                errors.add(error);
     202            }
     203        }
     204        return errors;
    189205    }
    190206
     
    307323            // Some imagery sources do not define tiles at (0,0). So pickup Greenwich Royal Observatory for global sources
    308324            ICoordinate center = CoordinateConversion.llToCoor(bounds != null ? getCenter(bounds) : GREENWICH);
    309             AbstractTileSource tileSource = getTileSource(info);
     325            List<AbstractTileSource> tileSources = getTileSources(info);
    310326            // test min zoom and try to detect the correct value in case of error
    311327            int maxZoom = info.getMaxZoom() > 0 ? Math.min(DEFAULT_ZOOM, info.getMaxZoom()) : DEFAULT_ZOOM;
    312328            for (int zoom = info.getMinZoom(); zoom < maxZoom; zoom++) {
    313                 if (!isZoomError(checkTileUrl(info, tileSource, center, zoom))) {
     329                if (!isZoomError(checkTileUrls(info, tileSources, center, zoom))) {
    314330                    break;
    315331                }
     
    317333            // checking max zoom for real is complex, see https://josm.openstreetmap.de/ticket/16073#comment:27
    318334            if (info.getMaxZoom() > 0 && info.getImageryType() != ImageryType.SCANEX) {
    319                 checkTileUrl(info, tileSource, center, Utils.clamp(DEFAULT_ZOOM, info.getMinZoom() + 1, info.getMaxZoom()));
    320             }
    321         } catch (IOException | RuntimeException | WMSGetCapabilitiesException | WMTSGetCapabilitiesException e) {
     335                checkTileUrls(info, tileSources, center, Utils.clamp(DEFAULT_ZOOM, info.getMinZoom() + 1, info.getMaxZoom()));
     336            }
     337        } catch (IOException | RuntimeException | WMSGetCapabilitiesException e) {
    322338            addError(info, info.getUrl() + ERROR_SEP + e.toString());
    323339        }
     
    328344    }
    329345
    330     private static boolean isZoomError(String error) {
    331         String[] parts = error.split(ERROR_SEP, -1);
    332         String lastPart = parts.length > 0 ? parts[parts.length - 1].toLowerCase(Locale.ENGLISH) : "";
    333         return lastPart.contains("bbox")
    334             || lastPart.contains("bounding box");
    335     }
    336 
    337     private static Projection getProjection(ImageryInfo info) {
    338         for (String code : info.getServerProjections()) {
    339             Projection proj = Projections.getProjectionByCode(code);
    340             if (proj != null) {
    341                 return proj;
    342             }
    343         }
    344         return ProjectionRegistry.getProjection();
    345     }
    346 
    347     @SuppressWarnings("fallthrough")
    348     private static AbstractTileSource getTileSource(ImageryInfo info)
    349             throws IOException, WMTSGetCapabilitiesException, WMSGetCapabilitiesException {
     346    private static boolean isZoomError(List<String> errors) {
     347        return errors.stream().anyMatch(error -> {
     348            String[] parts = error.split(ERROR_SEP, -1);
     349            String lastPart = parts.length > 0 ? parts[parts.length - 1].toLowerCase(Locale.ENGLISH) : "";
     350            return lastPart.contains("bbox")
     351                || lastPart.contains("bounding box");
     352        });
     353    }
     354
     355    private static List<Projection> getProjections(ImageryInfo info) {
     356        List<Projection> projs = info.getServerProjections().stream()
     357                .map(Projections::getProjectionByCode).filter(Objects::nonNull).collect(toList());
     358        return projs.isEmpty() ? singletonList(ProjectionRegistry.getProjection()) : projs;
     359    }
     360
     361    private List<AbstractTileSource> getTileSources(ImageryInfo info)
     362            throws IOException, WMSGetCapabilitiesException {
    350363        switch (info.getImageryType()) {
    351364            case BING:
    352                 return new BingAerialTileSource(info);
     365                return singletonList(new BingAerialTileSource(info));
    353366            case SCANEX:
    354                 return new ScanexTileSource(info);
     367                return singletonList(new ScanexTileSource(info));
    355368            case TMS:
    356                 return new JosmTemplatedTMSTileSource(info);
     369                return singletonList(new JosmTemplatedTMSTileSource(info));
    357370            case WMS_ENDPOINT:
    358                 info = convertWmsEndpointToWms(info); // fall-through
     371                return getWmsTileSources(convertWmsEndpointToWms(info));
    359372            case WMS:
    360                 return new TemplatedWMSTileSource(info, getProjection(info));
     373                return getWmsTileSources(info);
    361374            case WMTS:
    362                 return new WMTSTileSource(info, getProjection(info));
     375                return getWmtsTileSources(info);
    363376            default:
    364377                throw new UnsupportedOperationException(info.toString());
    365378        }
     379    }
     380
     381    private static List<AbstractTileSource> getWmsTileSources(ImageryInfo info) {
     382        return getProjections(info).stream().map(proj -> new TemplatedWMSTileSource(info, proj)).collect(toList());
     383    }
     384
     385    private List<AbstractTileSource> getWmtsTileSources(ImageryInfo info) {
     386        return getProjections(info).stream().map(proj -> {
     387            try {
     388                return new WMTSTileSource(info, proj);
     389            } catch (IOException | WMTSGetCapabilitiesException e) {
     390                addError(info, info.getUrl() + ERROR_SEP + e.toString());
     391                return null;
     392            }
     393        }).filter(Objects::nonNull).collect(toList());
    366394    }
    367395
     
    376404            boolean hasNoChildren = layer.getChildren().isEmpty();
    377405            if (hasNoChildren && layer.getName() != null) {
    378                 return Collections.singletonList(layer);
     406                return singletonList(layer);
    379407            } else if (!hasNoChildren) {
    380408                return firstLeafLayer(layer.getChildren());
Note: See TracChangeset for help on using the changeset viewer.