Revision 243

View differences:

org.gvsig.raster.app/trunk/org.gvsig.raster.app/org.gvsig.raster.app.wmtsclient/src/main/java/org/gvsig/raster/app/extension/wmtsclient/gui/wizard/WMTSWizard.java
84 84
	protected int                         firstPage          = 0;
85 85
	private IProjection                   proj               = null;
86 86
	private ICancellable                  cancel             = null;
87
	private WMTSDataParameters           storeParams        = null;
87
	private WMTSDataParameters            storeParams        = null;
88 88
	private WMTSServerExplorer            explorer           = null;
89 89

  
90 90
	/**
org.gvsig.raster/trunk/org.gvsig.raster/org.gvsig.raster.io/org.gvsig.raster.io.base/src/main/java/org/gvsig/fmap/dal/coverage/dataset/io/wmts/WMTSConnector.java
120 120
     * <p>One of the three interfaces that OGC WMTS defines. Request a map.</p> 
121 121
     * @throws ServerErrorException 
122 122
     */
123
    public File getTile(WMTSStatus status, ICancellable cancel) throws WMTSException, ServerErrorException {   
123
    public synchronized File getTile(WMTSStatus status, ICancellable cancel) throws WMTSException, ServerErrorException {   
124 124
        return client.getTile(status, cancel);
125 125
    }
126 126
    
org.gvsig.raster/trunk/org.gvsig.raster/org.gvsig.raster.io/org.gvsig.raster.io.base/src/main/java/org/gvsig/fmap/dal/coverage/dataset/io/wmts/WMTSProvider.java
78 78
import org.gvsig.tools.extensionpoint.ExtensionPoint;
79 79
import org.gvsig.tools.extensionpoint.ExtensionPointManager;
80 80
/**
81
 * Clase que representa al driver de acceso a datos de wmts.
81
 * Provider for WMTS service
82 82
 *
83 83
 * @author Nacho Brodin (nachobrodin@gmail.com)
84 84
 */
......
86 86
	public static String                NAME                     = "Wmts Store";
87 87
	public static String                DESCRIPTION              = "Wmts Raster file";
88 88
	public static final String          METADATA_DEFINITION_NAME = "WmtsStore";
89
	
90
	//Los tiles se piden de forma secuencial y sin lanzar threads para ello (+Lento)
91
	public static int                   SEQUENTIAL               = 0;
92
	//Los tiles se piden en threads y hay un thread manager para gestionar que no se pidan m?s de cierto n?mero
93
	public static int                   LIMITED_THREADS          = 1;
94
	//Los tiles se piden en threads y se lanzan tantos threads como tiles haya
95
	public static int                   UNLIMITED_THREADS        = 2;
96
	private int                         requestType              = LIMITED_THREADS;
97
	
89 98
	private static final double         MTS_X_GRADO              = 111319.490793274;
90 99
	
91 100
	private Extent                      viewRequest              = null;
......
101 110
	private boolean                     gridSubsets              = true;
102 111
	private Extent[]                    extentByLevel            = null; //Only for layers without gridSubsets
103 112
	
113
	/**
114
	 * This thread manages the number of tiles that have been thrown.
115
	 * This number is controlled by the NTHREADS_QUEUE variable.
116
	 * 
117
	 * @author Nacho Brodin (nachobrodin@gmail.com)
118
	 */
119
	class RequestThreadManager extends Thread {
120
		public int                 NTHREADS_QUEUE = 5;
121
		private TilePipe           pipe           = null;
122
		private ArrayList<Tile>    tiles          = null;
123
		private WMTSStatus         status         = null;
124
		
125
		public RequestThreadManager(TilePipe pipe, ArrayList<Tile> tiles, WMTSStatus status) {
126
			this.pipe = pipe;
127
			this.tiles = tiles;
128
			this.status = status;
129
		}
130
		
131
		public void run() {
132
			for (int i = 0; i < tiles.size(); i++) {
133
				Tile tile = tiles.get(i);
134
				WMTSStatus statusCopy = status.cloneStatus();
135
				statusCopy.setTileRow(tile.row);
136
				statusCopy.setTileCol(tile.col);
137
				if (pipe.getSize() > NTHREADS_QUEUE) {
138
					try {
139
						synchronized (this) {
140
							wait();							
141
						}
142
					} catch( InterruptedException e ) {
143
					}
144
				}
145
				new RequestTileLauncher(pipe, statusCopy, tile).start();
146
			}
147
		}
148
	}
149
	
150
	/**
151
	 * Thread to download a tile
152
	 * @author Nacho Brodin (nachobrodin@gmail.com)
153
	 */
154
	class RequestTileLauncher extends Thread {
155
		private TilePipe      pipe    = null;
156
		private WMTSStatus    status  = null;
157
		private Tile          tile    = null;
158

  
159
		public RequestTileLauncher(TilePipe pipe, WMTSStatus status, Tile tile) {
160
			this.pipe = pipe;
161
			this.status = status;
162
			this.tile = tile;
163
		}
164

  
165
		public void run() {
166
			try {
167
				File file = getConnector().getTile(status, null);
168
				tile.file = file;
169
				pipe.setTile(tile);
170
			} catch (WMTSException e) {
171
			} catch (ServerErrorException e) {
172
			}
173
		}
174
	}
175

  
104 176
	public static void register() {
105 177
		ExtensionPointManager extensionPoints = ToolsLocator.getExtensionPointManager();
106 178
		ExtensionPoint point = extensionPoints.get("RasterReader");
......
702 774
	 * @throws ProcessInterruptedException 
703 775
	 */
704 776
	@SuppressWarnings("unchecked")
705
	private Buffer request(WMTSStatus status, BandList bandList, TileListener listener) throws RasterDriverException, ProcessInterruptedException {
706
		WMTSDataParameters p = (WMTSDataParameters)param;
777
	private synchronized Buffer request(WMTSStatus status, BandList bandList, TileListener listener) throws RasterDriverException, ProcessInterruptedException {
778
		//WMTSDataParameters p = (WMTSDataParameters)param;
707 779
		WMTSConnector connector = null;
708 780
		try {
709 781
			connector = getConnector();
......
716 788
		
717 789
		ArrayList<Tile> tiles = status.getTileList();
718 790
		
719
		for (int i = 0; i < tiles.size(); i++) {
720
			Tile tile = tiles.get(i);
721
			status.setTileRow(tile.row);
722
			status.setTileCol(tile.col);
723
			//TODO:Cancelaci?n
724
			try {
725
				File file = connector.getTile(status, null);
726
				
727
				String serverName = bandList.getBand(0).getFileName();
728
				for (int j = 0; j < bandList.getBandCount(); j++) {
729
					bandList.getBand(j).setFileName(file.getPath());
791
		TilePipe pipe = new TilePipe();
792
		
793
		//Caso 1: Lanza un thread que gestiona que no se lancen muchos threads a la vez
794
		if(requestType == LIMITED_THREADS) {
795
			RequestThreadManager threadManager = new RequestThreadManager(pipe, tiles, status);
796
			pipe.setRequestManager(threadManager);
797
			threadManager.start();
798
		//Caso 2: Lanza todos los threads
799
		} else if(requestType == UNLIMITED_THREADS) {
800
			for (int i = 0; i < tiles.size(); i++) {
801
				Tile tile = tiles.get(i);
802
				WMTSStatus statusCopy = status.cloneStatus();
803
				statusCopy.setTileRow(tile.row);
804
				statusCopy.setTileCol(tile.col);
805
				new RequestTileLauncher(pipe, statusCopy, tile).start();
806
			}
807
		}
808
		
809
		if(requestType == LIMITED_THREADS || requestType == UNLIMITED_THREADS) {
810
			int nCollected = 0;
811
			while (nCollected < tiles.size()) {
812
				Tile tile = pipe.getTile();
813
				drawTile(tile, listener, bandList);
814
				nCollected ++;
815
			}
816
		}
817
		
818
		if(requestType == SEQUENTIAL) {
819
			for (int i = 0; i < tiles.size(); i++) {
820
				Tile tile = tiles.get(i);
821
				status.setTileRow(tile.row);
822
				status.setTileCol(tile.col);
823
				//TODO:Cancelaci?n
824
				try {
825
					File file = connector.getTile(status, null);
826
					tile.file = file;
827
					drawTile(tile, listener, bandList);
828
				} catch (WMTSException e) {
829
					throw new RasterDriverException("Error getting tiles", e);
830
				} catch (ServerErrorException e) {
831
					throw new RasterDriverException("Error getting tiles", e);
730 832
				}
731
				
732
				GdalProvider driver = new GdalProvider(file.getPath());
733
				colorTable = driver.getColorTable();
734
				bandCount = driver.getBandCount();
735
				lastFileTransparency = driver.getTransparency();
736
				Buffer rasterBuf = DefaultRasterManager.getInstance().createBuffer(getDataType()[0], tile.wPx, tile.hPx, 3, true);
737
				Buffer buf = driver.getWindowRaster(0, 0, tile.wPx, tile.hPx, bandList, rasterBuf);
738
				
739
				buf.setDataExtent(new Rectangle2D.Double(Math.min(tile.ulx, tile.lrx), Math.min(tile.uly, tile.lry), Math.abs(tile.ulx - tile.lrx), Math.abs(tile.uly - tile.lry)));
740
				
741
				Buffer alphaBand = null;
742
				if(p.getAlphaBand() != -1 && listener != null && p.getAlphaBand() < bandCount) {
743
					alphaBand = DefaultRasterManager.getInstance().createBuffer(getDataType()[0], tile.wPx, tile.hPx, 1, true);
744
					int[] oldDB = bandList.getDrawableBands();
745
					bandList.setDrawableBands(new int[]{p.getAlphaBand()});
746
					alphaBand = driver.getWindowRaster(0, 0, tile.wPx, tile.hPx, bandList, alphaBand);
747
					bandList.setDrawableBands(oldDB);
748
				}
749
				
750
				for (int j = 0; j < bandList.getBandCount(); j++) {
751
					bandList.getBand(j).setFileName(serverName);
752
				}
753
				
754
				driver.close();
755
				
756
				if(listener != null)
757
					listener.nextBuffer(buf, alphaBand, new ExtentImpl(tile.ulx, tile.uly, tile.lrx, tile.lry), getAffineTransform(), null, true);
758
				else
759
					return buf;
760
				
761
			} catch (WMTSException e) {
762
				throw new RasterDriverException("Error getting tiles", e);
763
			} catch (ServerErrorException e) {
764
				throw new RasterDriverException("Error getting tiles", e);
765
			} catch (NotSupportedExtensionException e) {
766
				throw new RasterDriverException("Error getting tiles", e);
767 833
			}
768 834
		}
769 835
		if(listener != null)
770 836
			listener.endReading();
771 837
		return null;
772 838
	}
839
	
840
	/**
841
	 * Reads a tile with gdal and calls the method nextBuffer
842
	 * @param tile
843
	 * @param listener
844
	 * @param bandList
845
	 * @return
846
	 * @throws RasterDriverException
847
	 */
848
	private synchronized Buffer drawTile(Tile tile, TileListener listener, BandList bandList) throws RasterDriverException {
849
		WMTSDataParameters p = (WMTSDataParameters)param;
850
		try {
851
			String serverName = bandList.getBand(0).getFileName();
852
			for (int j = 0; j < bandList.getBandCount(); j++) {
853
				bandList.getBand(j).setFileName(tile.file.getPath());
854
			}
855
			
856
			GdalProvider driver = new GdalProvider(tile.file.getPath());
857
			colorTable = driver.getColorTable();
858
			bandCount = driver.getBandCount();
859
			lastFileTransparency = driver.getTransparency();
860
			Buffer rasterBuf = DefaultRasterManager.getInstance().createBuffer(getDataType()[0], tile.wPx, tile.hPx, 3, true);
861
			Buffer buf = driver.getWindowRaster(0, 0, tile.wPx, tile.hPx, bandList, rasterBuf);
862
			
863
			buf.setDataExtent(new Rectangle2D.Double(Math.min(tile.ulx, tile.lrx), Math.min(tile.uly, tile.lry), Math.abs(tile.ulx - tile.lrx), Math.abs(tile.uly - tile.lry)));
864
			
865
			Buffer alphaBand = null;
866
			if(p.getAlphaBand() != -1 && listener != null && p.getAlphaBand() < bandCount) {
867
				alphaBand = DefaultRasterManager.getInstance().createBuffer(getDataType()[0], tile.wPx, tile.hPx, 1, true);
868
				int[] oldDB = bandList.getDrawableBands();
869
				bandList.setDrawableBands(new int[]{p.getAlphaBand()});
870
				alphaBand = driver.getWindowRaster(0, 0, tile.wPx, tile.hPx, bandList, alphaBand);
871
				bandList.setDrawableBands(oldDB);
872
			}
873
			
874
			for (int j = 0; j < bandList.getBandCount(); j++) {
875
				bandList.getBand(j).setFileName(serverName);
876
			}
877
			
878
			driver.close();
879
			
880
			if(listener != null)
881
				listener.nextBuffer(buf, alphaBand, new ExtentImpl(tile.ulx, tile.uly, tile.lrx, tile.lry), getAffineTransform(), null, true);
882
			else
883
				return buf;
884
			
885
		} catch (NotSupportedExtensionException e) {
886
			throw new RasterDriverException("Error getting tiles", e);
887
		} catch (ProcessInterruptedException e) {
888
		}
889
		return null;
890
	}
773 891

  
774 892
	/*
775 893
	 * (non-Javadoc)
org.gvsig.raster/trunk/org.gvsig.raster/org.gvsig.raster.io/org.gvsig.raster.io.base/src/main/java/org/gvsig/fmap/dal/coverage/dataset/io/wmts/TilePipe.java
1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.fmap.dal.coverage.dataset.io.wmts;
23

  
24
import org.gvsig.fmap.dal.coverage.dataset.io.wmts.WMTSProvider.RequestThreadManager;
25
import org.gvsig.remoteclient.wmts.struct.WMTSTileMatrix.Tile;
26

  
27
/**
28
 * This class manages transactions between the producer and the consumer. The
29
 * producer download tiles from a server and the consumer is a tile provider
30
 * which will return downloaded tiles.
31
 *
32
 * @author Nacho Brodin (nachobrodin@gmail.com)
33
 */
34
public class TilePipe {
35
	private final static int     BUFFER_SIZE    = 10; 
36
	private Tile                 buffer[]       = new Tile[BUFFER_SIZE];
37
	private int                  next           = 0;
38
	private boolean              isFull         = false;
39
	private boolean              isEmpty        = true;
40
	private RequestThreadManager threadManager  = null;
41

  
42
	public void setRequestManager(RequestThreadManager threadManager) {
43
		this.threadManager = threadManager;
44
	}
45
	
46
	/**
47
	 * Sets a tile in the pipe
48
	 * @param tile
49
	 */
50
	public synchronized void setTile(Tile tile) {
51
		while( isFull == true ) {
52
			try {
53
				wait();
54
			} catch( InterruptedException e ) {
55
			}
56
		}
57
		buffer[next] = tile;
58
		next++;
59
		if( next == BUFFER_SIZE )
60
			isFull = true;
61
		isEmpty = false;
62
		notify();
63
	}
64

  
65
	/**
66
	 * Gets a tile from the pipe
67
	 * @return
68
	 */
69
	public synchronized Tile getTile() {
70
		while( isEmpty == true ) {
71
			try {
72
				wait();
73
			} catch( InterruptedException e ) {
74
			}
75
		}
76
        next--;
77
        if( next == 0 )
78
        	isEmpty = true;
79
        isFull = false;
80
        notify();
81
        if(threadManager != null && getSize() <= threadManager.NTHREADS_QUEUE) {
82
        	synchronized(threadManager) {
83
        		threadManager.notify();
84
        	}
85
        }
86
        	
87
        return buffer[next] ;
88
	}
89
	
90
	/**
91
	 * Returns the number of elements in the queue
92
	 * @return
93
	 */
94
	public synchronized int getSize() {
95
		return next;
96
	}
97
}
0 98

  

Also available in: Unified diff