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.projection.Projection; 016import org.openstreetmap.josm.gui.MainApplication; 017import org.openstreetmap.josm.gui.layer.imagery.TileSourceDisplaySettings; 018import org.openstreetmap.josm.tools.Logging; 019import org.openstreetmap.josm.tools.Utils; 020 021/** 022 * WMTS layer based on AbstractTileSourceLayer. Overrides few methods to align WMTS to Tile based computations 023 * but most magic is done within WMTSTileSource class. 024 * 025 * Full specification of the protocol available at: 026 * http://www.opengeospatial.org/standards/wmts 027 * 028 * @author Wiktor Niesiobędzki 029 * 030 */ 031public class WMTSLayer extends AbstractCachedTileSourceLayer<WMTSTileSource> implements NativeScaleLayer { 032 private static final String PREFERENCE_PREFIX = "imagery.wmts"; 033 034 /** 035 * Registers all setting properties 036 */ 037 static { 038 new TileSourceDisplaySettings(PREFERENCE_PREFIX); 039 } 040 041 private static final String CACHE_REGION_NAME = "WMTS"; 042 043 /** 044 * Creates WMTS layer from ImageryInfo 045 * @param info Imagery Info describing the layer 046 */ 047 public WMTSLayer(ImageryInfo info) { 048 super(info); 049 } 050 051 @Override 052 protected TileSourceDisplaySettings createDisplaySettings() { 053 return new TileSourceDisplaySettings(PREFERENCE_PREFIX); 054 } 055 056 @Override 057 protected WMTSTileSource getTileSource() { 058 try { 059 if (info.getImageryType() == ImageryType.WMTS && info.getUrl() != null) { 060 WMTSTileSource.checkUrl(info.getUrl()); 061 WMTSTileSource tileSource = new WMTSTileSource(info); 062 info.setAttribution(tileSource); 063 return tileSource; 064 } 065 return null; 066 } catch (IOException e) { 067 Logging.warn(e); 068 throw new IllegalArgumentException(e); 069 } 070 } 071 072 @Override 073 public int getBestZoom() { 074 if (!MainApplication.isDisplayingMapView()) 075 return 0; 076 ScaleList scaleList = getNativeScales(); 077 if (scaleList == null) { 078 return getMaxZoomLvl(); 079 } 080 double displayScale = MainApplication.getMap().mapView.getScale(); 081 if (coordinateConverter.requiresReprojection()) { 082 displayScale *= Main.getProjection().getMetersPerUnit(); 083 } 084 Scale snap = scaleList.getSnapScale(displayScale, false); 085 return Utils.clamp(snap != null ? snap.getIndex() : getMaxZoomLvl(), 086 getMinZoomLvl(), getMaxZoomLvl()); 087 } 088 089 @Override 090 protected int getMinZoomLvl() { 091 return 0; 092 } 093 094 @Override 095 public Collection<String> getNativeProjections() { 096 return tileSource.getSupportedProjections(); 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}