package org.geotools.tile; import java.io.IOException; import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.geotools.tile.cache.SimpleTileCache; import org.geotools.tile.cache.TileCache; import org.geotools.tile.nasa.WorldWindTileProtocolFactory; import org.geotools.tile.osgeo.OSGeoTileProtocolFactory; import org.geotools.util.ProgressListener; /** * Represents a TileServer, allows connection and retreval of TileSets. * <p> * This class makes use of a "stratagy" object depending on the protocol * used by the TileService. Currently the following protocols are supported: * <ul> * <li>WorldWind: url points to a xml file conformat to the LayerSet.xsd schema * <li>OSGeo: url points to an xml file conformant to WMS Tile Server specification * </ul> * </p> * @author Jody Garnett, Refractions Research, Inc. */ public final class TileServer { private TileServiceInfo info; /** Map<URI,TileMap> each representing a different data layer */ private Map layers = new HashMap(); TileProtocol protocol; TileCache cache; static private TileProtocol negotiateProtocol( URL server, ProgressListener monitor ) throws IOException{ List factories = listAvailableProtocols(); Throwable cause = null; for( Iterator i=factories.iterator();i.hasNext();){ TileProtocolFactory factory = (TileProtocolFactory) i.next(); try { if( factory.canTile( server )){ return factory.createTileStratagy( server ); } } catch( Throwable t ){ // could not support protocol cause = t; } } if( cause != null ){ throw (IOException) new IOException("Could not connet to "+server ).initCause( cause ); } else { throw new IOException("No protocol available for "+server ); } } static private List listAvailableProtocols() { List available = new ArrayList(2); available.add( new WorldWindTileProtocolFactory() ); available.add( new OSGeoTileProtocolFactory() ); return available; } /** * Connect to provided URL, blocking operation. * @param server Location of server to connect to * @param monitor Used to monitor (and cancel) the connection process * @throws IOException If server is unavailable, or protocol not supported. */ public TileServer( URL server, ProgressListener monitor ) throws IOException { protocol = negotiateProtocol( server, null ); info = protocol.getInfo( monitor ); cache = new SimpleTileCache(); } /** Incase info was created beforehand */ public TileServer( TileServiceInfo info ){ this.info = info; this.protocol = info.getTileStratagy(); this.cache = new SimpleTileCache(); } /** * Used to provide a custom implementation of tileCache. * <p> * By default TileServer will use "SimpleTileCache", this method * allows you to configure a more approriate implemntation * for you application. * </p> * @param cache TileCache implementation to use. */ public void setTileCache( TileCache cache ){ this.cache = cache; } public TileServiceInfo getInfo(){ return info; } public List getTileMapIds( ProgressListener monitor ){ return protocol.getTileMapIds( info, monitor ); } public TileMapInfo getTileMapInfo( URI id ){ return getTileMap( id ).getInfo(); } public synchronized TileMap getTileMap( URI id ){ if( layers.containsKey( id )){ return (TileMap) layers.get( id ); } TileMapInfo tileMapInfo = protocol.getTileMapInfo( info, id, null ); TileMap tileMap = new TileMap( this, tileMapInfo ); layers.put( id , tileMap ); return tileMap; } }