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 = 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.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 Scale snap = null; 066 if (scaleList == null) { 067 return getMaxZoomLvl(); 068 } 069 snap = scaleList.getSnapScale(Main.map.mapView.getScale(), false); 070 return Math.max( 071 getMinZoomLvl(), 072 Math.min( 073 snap != null ? snap.getIndex() : getMaxZoomLvl(), 074 getMaxZoomLvl() 075 ) 076 ); 077 } 078 079 @Override 080 protected int getMinZoomLvl() { 081 return 0; 082 } 083 084 @Override 085 public boolean isProjectionSupported(Projection proj) { 086 Set<String> supportedProjections = tileSource.getSupportedProjections(); 087 return supportedProjections.contains(proj.toCode()); 088 } 089 090 @Override 091 public String nameSupportedProjections() { 092 StringBuilder ret = new StringBuilder(); 093 for (String e: tileSource.getSupportedProjections()) { 094 ret.append(e).append(", "); 095 } 096 return ret.length() > 2 ? ret.substring(0, ret.length()-2) : ret.toString(); 097 } 098 099 @Override 100 public void projectionChanged(Projection oldValue, Projection newValue) { 101 super.projectionChanged(oldValue, newValue); 102 tileSource.initProjection(newValue); 103 } 104 105 @Override 106 protected Class<? extends TileLoader> getTileLoaderClass() { 107 return WMSCachedTileLoader.class; 108 } 109 110 @Override 111 protected String getCacheName() { 112 return CACHE_REGION_NAME; 113 } 114 115 /** 116 * @return cache region for WMTS layer 117 */ 118 public static CacheAccess<String, BufferedImageCacheEntry> getCache() { 119 return AbstractCachedTileSourceLayer.getCache(CACHE_REGION_NAME); 120 } 121 122 @Override 123 public ScaleList getNativeScales() { 124 return tileSource.getNativeScales(); 125 } 126}