001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.layer; 003 004import java.io.IOException; 005import java.util.Collection; 006 007import org.apache.commons.jcs.access.CacheAccess; 008import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader; 009import org.openstreetmap.josm.Main; 010import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry; 011import org.openstreetmap.josm.data.imagery.ImageryInfo; 012import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType; 013import org.openstreetmap.josm.data.imagery.WMSCachedTileLoader; 014import org.openstreetmap.josm.data.imagery.WMTSTileSource; 015import org.openstreetmap.josm.data.imagery.WMTSTileSource.WMTSGetCapabilitiesException; 016import org.openstreetmap.josm.data.projection.Projection; 017import org.openstreetmap.josm.gui.MainApplication; 018import org.openstreetmap.josm.gui.layer.imagery.TileSourceDisplaySettings; 019import org.openstreetmap.josm.tools.Logging; 020import org.openstreetmap.josm.tools.Utils; 021 022/** 023 * WMTS layer based on AbstractTileSourceLayer. Overrides few methods to align WMTS to Tile based computations 024 * but most magic is done within WMTSTileSource class. 025 * 026 * Full specification of the protocol available at: 027 * http://www.opengeospatial.org/standards/wmts 028 * 029 * @author Wiktor Niesiobędzki 030 * 031 */ 032public class WMTSLayer extends AbstractCachedTileSourceLayer<WMTSTileSource> implements NativeScaleLayer { 033 private static final String PREFERENCE_PREFIX = "imagery.wmts"; 034 035 /** 036 * Registers all setting properties 037 */ 038 static { 039 new TileSourceDisplaySettings(PREFERENCE_PREFIX); 040 } 041 042 private static final String CACHE_REGION_NAME = "WMTS"; 043 044 /** 045 * Creates WMTS layer from ImageryInfo 046 * @param info Imagery Info describing the layer 047 */ 048 public WMTSLayer(ImageryInfo info) { 049 super(info); 050 } 051 052 @Override 053 protected TileSourceDisplaySettings createDisplaySettings() { 054 return new TileSourceDisplaySettings(PREFERENCE_PREFIX); 055 } 056 057 @Override 058 protected WMTSTileSource getTileSource() { 059 try { 060 if (info.getImageryType() == ImageryType.WMTS && info.getUrl() != null) { 061 WMTSTileSource.checkUrl(info.getUrl()); 062 WMTSTileSource tileSource = new WMTSTileSource(info); 063 info.setAttribution(tileSource); 064 return tileSource; 065 } 066 return null; 067 } catch (IOException | WMTSGetCapabilitiesException e) { 068 Logging.warn(e); 069 throw new IllegalArgumentException(e); 070 } 071 } 072 073 @Override 074 public int getBestZoom() { 075 if (!MainApplication.isDisplayingMapView()) 076 return 0; 077 ScaleList scaleList = getNativeScales(); 078 if (scaleList == null) { 079 return getMaxZoomLvl(); 080 } 081 double displayScale = MainApplication.getMap().mapView.getScale(); 082 if (coordinateConverter.requiresReprojection()) { 083 displayScale *= Main.getProjection().getMetersPerUnit(); 084 } 085 Scale snap = scaleList.getSnapScale(displayScale, false); 086 return Utils.clamp(snap != null ? snap.getIndex() : getMaxZoomLvl(), 087 getMinZoomLvl(), getMaxZoomLvl()); 088 } 089 090 @Override 091 protected int getMinZoomLvl() { 092 return 0; 093 } 094 095 @Override 096 public Collection<String> getNativeProjections() { 097 return tileSource.getSupportedProjections(); 098 } 099 100 @Override 101 public void projectionChanged(Projection oldValue, Projection newValue) { 102 super.projectionChanged(oldValue, newValue); 103 tileSource.initProjection(newValue); 104 } 105 106 @Override 107 protected Class<? extends TileLoader> getTileLoaderClass() { 108 return WMSCachedTileLoader.class; 109 } 110 111 @Override 112 protected String getCacheName() { 113 return CACHE_REGION_NAME; 114 } 115 116 /** 117 * @return cache region for WMTS layer 118 */ 119 public static CacheAccess<String, BufferedImageCacheEntry> getCache() { 120 return AbstractCachedTileSourceLayer.getCache(CACHE_REGION_NAME); 121 } 122 123 @Override 124 public ScaleList getNativeScales() { 125 return tileSource.getNativeScales(); 126 } 127}