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.preferences.BooleanProperty; 016import org.openstreetmap.josm.data.projection.Projection; 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 /** 030 * default setting of autozoom per layer 031 */ 032 public static final BooleanProperty PROP_DEFAULT_AUTOZOOM_WMTS = new BooleanProperty("imagery.wmts.default_autozoom", true); 033 private static final String CACHE_REGION_NAME = "WMTS"; 034 035 /** 036 * Creates WMTS layer from ImageryInfo 037 * @param info Imagery Info describing the layer 038 */ 039 public WMTSLayer(ImageryInfo info) { 040 super(info); 041 autoZoom = PROP_DEFAULT_AUTOZOOM_WMTS.get(); 042 } 043 044 @Override 045 protected WMTSTileSource getTileSource(ImageryInfo info) { 046 try { 047 if (info.getImageryType() == ImageryType.WMTS && info.getUrl() != null) { 048 WMTSTileSource.checkUrl(info.getUrl()); 049 WMTSTileSource tileSource = new WMTSTileSource(info); 050 info.setAttribution(tileSource); 051 return tileSource; 052 } 053 return null; 054 } catch (IOException e) { 055 Main.warn(e); 056 throw new IllegalArgumentException(e); 057 } 058 } 059 060 @Override 061 protected int getBestZoom() { 062 if (!Main.isDisplayingMapView()) 063 return 0; 064 ScaleList scaleList = getNativeScales(); 065 if (scaleList == null) { 066 return getMaxZoomLvl(); 067 } 068 Scale snap = scaleList.getSnapScale(Main.map.mapView.getScale(), false); 069 return Math.max( 070 getMinZoomLvl(), 071 Math.min( 072 snap != null ? snap.getIndex() : getMaxZoomLvl(), 073 getMaxZoomLvl() 074 ) 075 ); 076 } 077 078 @Override 079 protected int getMinZoomLvl() { 080 return 0; 081 } 082 083 @Override 084 public boolean isProjectionSupported(Projection proj) { 085 Set<String> supportedProjections = tileSource.getSupportedProjections(); 086 return supportedProjections.contains(proj.toCode()); 087 } 088 089 @Override 090 public String nameSupportedProjections() { 091 StringBuilder ret = new StringBuilder(); 092 for (String e: tileSource.getSupportedProjections()) { 093 ret.append(e).append(", "); 094 } 095 return ret.length() > 2 ? ret.substring(0, ret.length()-2) : ret.toString(); 096 } 097 098 @Override 099 public void projectionChanged(Projection oldValue, Projection newValue) { 100 super.projectionChanged(oldValue, newValue); 101 tileSource.initProjection(newValue); 102 } 103 104 @Override 105 protected Class<? extends TileLoader> getTileLoaderClass() { 106 return WMSCachedTileLoader.class; 107 } 108 109 @Override 110 protected String getCacheName() { 111 return CACHE_REGION_NAME; 112 } 113 114 /** 115 * @return cache region for WMTS layer 116 */ 117 public static CacheAccess<String, BufferedImageCacheEntry> getCache() { 118 return AbstractCachedTileSourceLayer.getCache(CACHE_REGION_NAME); 119 } 120 121 @Override 122 public ScaleList getNativeScales() { 123 return tileSource.getNativeScales(); 124 } 125}