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