Revision 8777

View differences:

org.gvsig.raster.wmts/tags/org.gvsig.raster.wmts-2.2.67/pom.xml
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3
    <modelVersion>4.0.0</modelVersion>
4
    <artifactId>org.gvsig.raster.wmts</artifactId>
5
    <packaging>pom</packaging>
6
    <version>2.2.67</version>
7
    <name>${project.artifactId}</name>
8
    <description>WMTS client</description>
9
    <inceptionYear>2011</inceptionYear>
10
	
11
    <parent>
12
        <groupId>org.gvsig</groupId>
13
        <artifactId>org.gvsig.desktop</artifactId>
14
        <version>2.0.218</version>
15
    </parent>
16

  
17
        <properties>
18
            <!-- El plugin versions:use-latest-versions falla con scope import -->
19
            <!-- asi que toca usar el versions:update-properties que si que funciona -->
20
            <org.gvsig.raster.version>2.2.80</org.gvsig.raster.version>
21
        </properties>
22
    
23
    <repositories>
24
        <repository>
25
            <id>gvsig-public-http-repository</id>
26
            <name>gvSIG maven public HTTP repository</name>
27
            <url>http://devel.gvsig.org/m2repo/j2se</url>
28
            <releases>
29
                <enabled>true</enabled>
30
                <updatePolicy>daily</updatePolicy>
31
                <checksumPolicy>warn</checksumPolicy>
32
            </releases>
33
            <snapshots>
34
                <enabled>true</enabled>
35
                <updatePolicy>daily</updatePolicy>
36
                <checksumPolicy>warn</checksumPolicy>
37
            </snapshots>
38
        </repository>
39
    </repositories>
40
    
41
    <scm>
42
        <connection>scm:svn:https://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.wmts/tags/org.gvsig.raster.wmts-2.2.67</connection>
43
        <developerConnection>scm:svn:https://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.wmts/tags/org.gvsig.raster.wmts-2.2.67</developerConnection>
44
        <url>https://devel.gvsig.org/redmine/projects/gvsig-raster/repository/show/org.gvsig.raster.wmts/tags/org.gvsig.raster.wmts-2.2.67</url>
45
    </scm>
46
    
47
    <dependencyManagement>
48
        <dependencies>
49
                        <dependency>
50
                                <groupId>org.gvsig</groupId>
51
                                <artifactId>org.gvsig.raster</artifactId>
52
                                <version>${org.gvsig.raster.version}</version>
53
                                <type>pom</type>
54
                                <scope>import</scope>
55
                        </dependency>
56

  
57
            <dependency>
58
                <groupId>org.gvsig</groupId>
59
                <artifactId>org.gvsig.raster.wmts.swing.api</artifactId>
60
                <version>2.2.67</version>
61
            </dependency>
62
            <dependency>
63
                <groupId>org.gvsig</groupId>
64
                <artifactId>org.gvsig.raster.wmts.swing.impl</artifactId>
65
                <version>2.2.67</version>
66
            </dependency>
67
            <dependency>
68
                <groupId>org.gvsig</groupId>
69
                <artifactId>org.gvsig.raster.wmts.ogc.api</artifactId>
70
                <version>2.2.67</version>
71
            </dependency>
72
            <dependency>
73
                <groupId>org.gvsig</groupId>
74
                <artifactId>org.gvsig.raster.wmts.ogc.impl</artifactId>
75
                <version>2.2.67</version>
76
            </dependency>
77
            <dependency>
78
                <groupId>org.gvsig</groupId>
79
                <artifactId>org.gvsig.raster.wmts.app.wmtsclient</artifactId>
80
                <version>2.2.67</version>
81
            </dependency>
82
            <dependency>
83
                <groupId>org.gvsig</groupId>
84
                <artifactId>org.gvsig.raster.wmts.io</artifactId>
85
                <version>2.2.67</version>
86
            </dependency>
87

  
88
        </dependencies>
89
    </dependencyManagement>
90
	
91
    <developers>
92
        <developer>
93
            <id>nbrodin</id>
94
            <name>Nacho Brodin</name>
95
            <email>nachobrodin@gmail.com</email>
96
            <roles>
97
                <role>Architect</role>
98
                <role>Developer</role>
99
            </roles>
100
        </developer>
101
    </developers>
102
	
103
    <build>
104
        <plugins>
105
            <plugin>
106
                <groupId>org.apache.maven.plugins</groupId>
107
                <artifactId>maven-release-plugin</artifactId>
108
                <configuration>
109
                    <tagBase>https://devel.gvsig.org/svn/gvsig-raster/org.gvsig.raster.wmts/tags/</tagBase>
110
                    <goals>deploy</goals>
111
                </configuration>
112
            </plugin>
113
        </plugins>
114
    </build>
115
    
116
    <modules>
117
        <module>org.gvsig.raster.wmts.swing</module>
118
        <module>org.gvsig.raster.wmts.io</module>
119
        <module>org.gvsig.raster.wmts.app.wmtsclient</module>
120
        <module>org.gvsig.raster.wmts.ogc</module>
121
    </modules>
122
</project>
0 123

  
org.gvsig.raster.wmts/tags/org.gvsig.raster.wmts-2.2.67/org.gvsig.raster.wmts.io/src/main/java/org/gvsig/raster/wmts/io/WMTSServerExplorer.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

  
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2009 IVER T.I   {{Task}}
26
*/
27

  
28
package org.gvsig.raster.wmts.io;
29

  
30
import java.io.IOException;
31
import java.io.InputStream;
32
import java.net.MalformedURLException;
33
import java.net.URI;
34
import java.net.URISyntaxException;
35
import java.net.URL;
36
import java.net.URLConnection;
37
import java.util.List;
38

  
39
import org.slf4j.Logger;
40
import org.slf4j.LoggerFactory;
41

  
42
import org.gvsig.compat.net.ICancellable;
43
import org.gvsig.fmap.dal.DALLocator;
44
import org.gvsig.fmap.dal.DataManager;
45
import org.gvsig.fmap.dal.DataServerExplorerParameters;
46
import org.gvsig.fmap.dal.DataStoreParameters;
47
import org.gvsig.fmap.dal.NewDataStoreParameters;
48
import org.gvsig.fmap.dal.coverage.exception.ConnectException;
49
import org.gvsig.fmap.dal.coverage.store.RasterDataServerExplorer;
50
import org.gvsig.fmap.dal.coverage.store.parameter.TileDataParameters;
51
import org.gvsig.fmap.dal.exception.DataException;
52
import org.gvsig.fmap.dal.exception.InitializeException;
53
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
54
import org.gvsig.fmap.dal.spi.AbstractDataServerExplorer;
55
import org.gvsig.fmap.dal.spi.DataServerExplorerProvider;
56
import org.gvsig.fmap.dal.spi.DataServerExplorerProviderServices;
57
import org.gvsig.raster.wmts.ogc.WMTSClient;
58
import org.gvsig.raster.wmts.ogc.WMTSOGCLocator;
59

  
60
/**
61
 * Explorer for a WMTS server
62
 * @author Nacho Brodin (nachobrodin@gmail.com)
63
 */
64
public class WMTSServerExplorer extends AbstractDataServerExplorer implements RasterDataServerExplorer, DataServerExplorerProvider {
65
	public static final String           NAME                     = WMTSProvider.NAME;
66
	private WMTSClient                   ogcClient                = null;
67
//	private WMTSServerExplorerParameters parameters               = null;
68
	private static final Logger         logger                    = LoggerFactory.getLogger(WMTSServerExplorer.class);
69

  
70
	public WMTSServerExplorer(
71
			WMTSServerExplorerParameters parameters,
72
			DataServerExplorerProviderServices services)
73
			throws InitializeException {
74
                super(parameters, services);
75
//		this.parameters = parameters;
76
	}
77

  
78
	public String getDataStoreProviderName() {
79
		return WMTSProvider.NAME;
80
	}
81

  
82
	public String getDescription() {
83
		return WMTSProvider.DESCRIPTION;
84
	}
85

  
86
	public boolean add(String provider, NewDataStoreParameters parameters,
87
			boolean overwrite) throws DataException {
88
		return false;
89
	}
90

  
91
	public boolean canAdd() {
92
		return false;
93
	}
94

  
95
	public boolean canAdd(String storeName) throws DataException {
96
		return false;
97
	}
98

  
99
	public NewDataStoreParameters getAddParameters(String storeName)
100
			throws DataException {
101
		return null;
102
	}
103

  
104
	public List<?> getDataStoreProviderNames() {
105
		return null;
106
	}
107

  
108
	public WMTSServerExplorerParameters getParameters() {
109
		return (WMTSServerExplorerParameters) super.getParameters();
110
	}
111

  
112
	public List<?> list() throws DataException {
113
		return null;
114
	}
115

  
116
	public List<?> list(int mode) throws DataException {
117
		return null;
118
	}
119

  
120
	public void remove(DataStoreParameters parameters) throws DataException {
121

  
122
	}
123

  
124
	public String getProviderName() {
125
		return WMTSProvider.NAME;
126
	}
127

  
128
	//**********************************************
129
	//Connector
130
	//**********************************************
131

  
132
	public DataStoreParameters getStoredParameters() {
133
		DataManager manager = DALLocator.getDataManager();
134
		WMTSDataParameters wmtsParams = null;
135
		try {
136
			wmtsParams = (WMTSDataParameters) manager.createStoreParameters(this.getDataStoreProviderName());
137
			String host = getParameters().getHost();
138
            try {
139
                wmtsParams.setURI(new URI(host));
140
            } catch (URISyntaxException e) {
141
                logger.warn("Can't create URI from "+host, e);
142
            }
143
			wmtsParams.setOGCClient(getOGCClient());
144

  
145
			if(WMTSProvider.TILED) {
146
				TileDataParameters tileParams = (TileDataParameters) manager.createStoreParameters("Tile Store");
147
				tileParams.setDataParameters(wmtsParams);
148
				return tileParams;
149
			}
150
		} catch (InitializeException e) {
151
            logger.warn("Can't get DataStoreParameters from WMTSServerExplorer", e);
152
		} catch (ProviderNotRegisteredException e) {
153
            logger.warn("Can't get DataStoreParameters from WMTSServerExplorer", e);
154
		}
155
		return wmtsParams;
156
	}
157

  
158
	public void connect(ICancellable cancellable) throws ConnectException {
159
		URL url = null;
160
		boolean override = false;
161

  
162
		try {
163
			url = new URL(getParameters().getHost());
164
		} catch (Exception e) {
165
			throw new ConnectException("Malformed URL",e);
166
		}
167
        try {
168
        	ogcClient = WMTSOGCLocator.getManager().createWMTSClient(url.toString());
169
        	ogcClient.setForceChangeAxisOrder(getParameters().isLongitudeFirst());
170
        	if (!ogcClient.connect(override, cancellable))
171
        		throw new ConnectException("Error connecting");
172
        } catch (IOException e) {
173
			throw new ConnectException(e.getMessage(), e);
174
		}
175
	}
176

  
177
	public boolean isHostReachable(int timeout) {
178
		URL url = null;
179
		URLConnection con = null;
180
		try {
181
			url = new URL(getParameters().getHost());
182
			con = url.openConnection();
183
			if(con == null)
184
				return false;
185
			con.connect();
186
		} catch (MalformedURLException e) {
187
			return false;
188
		} catch (IOException e) {
189
			return false;
190
		}
191

  
192
		InputStream stream = null;
193
		try {
194
			stream = con.getInputStream();
195
			if(stream == null)
196
				return false;
197
		} catch (IOException e) {
198
		}
199

  
200
		return true;
201
	}
202

  
203
	/**
204
	 * Checks if the network and host are reachable
205
	 * @return true if both are reachable and false if they are not
206
	 */
207
	public boolean isHostReachable() {
208
		return isHostReachable(RasterDataServerExplorer.TIME);
209
	}
210

  
211
	public boolean isConnected() {
212
		if(ogcClient != null)
213
			return true;
214
		return false;
215
	}
216

  
217
	public WMTSClient getOGCClient() {
218
		return ogcClient;
219
	}
220

  
221
	public String getHost() {
222
		return getParameters().getHost();
223
	}
224

  
225
	public DataServerExplorerProviderServices getServerExplorerProviderServices() {
226
		return null;
227
	}
228
}
0 229

  
org.gvsig.raster.wmts/tags/org.gvsig.raster.wmts-2.2.67/org.gvsig.raster.wmts.io/src/main/java/org/gvsig/raster/wmts/io/WMTSProvider.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.raster.wmts.io;
23

  
24
import java.awt.Image;
25
import java.awt.Rectangle;
26
import java.awt.geom.AffineTransform;
27
import java.awt.geom.NoninvertibleTransformException;
28
import java.awt.geom.Point2D;
29
import java.awt.geom.Rectangle2D;
30
import java.io.File;
31
import java.io.IOException;
32
import java.net.ConnectException;
33
import java.net.MalformedURLException;
34
import java.net.URI;
35
import java.net.URISyntaxException;
36
import java.net.URL;
37
import java.util.List;
38

  
39
import javax.swing.ImageIcon;
40

  
41
import org.gvsig.compat.net.ICancellable;
42
import org.gvsig.fmap.dal.DALLocator;
43
import org.gvsig.fmap.dal.DataStore;
44
import org.gvsig.fmap.dal.DataStoreParameters;
45
import org.gvsig.fmap.dal.coverage.RasterLocator;
46
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
47
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
48
import org.gvsig.fmap.dal.coverage.datastruct.DatasetBand;
49
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
50
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
51
import org.gvsig.fmap.dal.coverage.exception.BandAccessException;
52
import org.gvsig.fmap.dal.coverage.exception.BandNotFoundInListException;
53
import org.gvsig.fmap.dal.coverage.exception.FileNotOpenException;
54
import org.gvsig.fmap.dal.coverage.exception.InfoByPointException;
55
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
56
import org.gvsig.fmap.dal.coverage.exception.InvalidSourceException;
57
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
58
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
59
import org.gvsig.fmap.dal.coverage.exception.QueryException;
60
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
61
import org.gvsig.fmap.dal.coverage.exception.RemoteServiceException;
62
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
63
import org.gvsig.fmap.dal.coverage.store.RasterQuery;
64
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
65
import org.gvsig.fmap.dal.coverage.store.props.HistogramComputer;
66
import org.gvsig.fmap.dal.coverage.store.props.Transparency;
67
import org.gvsig.fmap.dal.coverage.util.MathUtils;
68
import org.gvsig.fmap.dal.exception.CloseException;
69
import org.gvsig.fmap.dal.exception.InitializeException;
70
import org.gvsig.fmap.dal.exception.OpenException;
71
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
72
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
73
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
74
import org.gvsig.metadata.MetadataLocator;
75
import org.gvsig.raster.cache.tile.TileCacheLocator;
76
import org.gvsig.raster.cache.tile.TileCacheManager;
77
import org.gvsig.raster.cache.tile.exception.TileGettingException;
78
import org.gvsig.raster.cache.tile.provider.CacheStruct;
79
import org.gvsig.raster.cache.tile.provider.TileListener;
80
import org.gvsig.raster.cache.tile.provider.TileServer;
81
import org.gvsig.raster.impl.buffer.SpiRasterQuery;
82
import org.gvsig.raster.impl.datastruct.BandListImpl;
83
import org.gvsig.raster.impl.datastruct.DatasetBandImpl;
84
import org.gvsig.raster.impl.datastruct.ExtentImpl;
85
import org.gvsig.raster.impl.provider.AbstractRasterProvider;
86
import org.gvsig.raster.impl.provider.MemoryTileMatrixBuffer;
87
import org.gvsig.raster.impl.provider.RasterProvider;
88
import org.gvsig.raster.impl.provider.RemoteRasterProvider;
89
import org.gvsig.raster.impl.provider.TiledRasterProvider;
90
import org.gvsig.raster.impl.store.DefaultRasterStore;
91
import org.gvsig.raster.impl.store.DefaultStoreFactory;
92
import org.gvsig.raster.impl.store.properties.DataStoreColorInterpretation;
93
import org.gvsig.raster.impl.store.properties.DataStoreTransparency;
94
import org.gvsig.raster.impl.store.properties.RemoteStoreHistogram;
95
import org.gvsig.raster.util.DefaultProviderServices;
96
import org.gvsig.raster.wmts.io.downloader.WMTSTileServer;
97
import org.gvsig.raster.wmts.ogc.WMTSClient;
98
import org.gvsig.raster.wmts.ogc.WMTSOGCLocator;
99
import org.gvsig.raster.wmts.ogc.WMTSStatus;
100
import org.gvsig.raster.wmts.ogc.exception.DownloadException;
101
import org.gvsig.raster.wmts.ogc.exception.ServerErrorException;
102
import org.gvsig.raster.wmts.ogc.exception.WMTSException;
103
import org.gvsig.raster.wmts.ogc.struct.WMTSLayer;
104
import org.gvsig.raster.wmts.ogc.struct.WMTSTile;
105
import org.gvsig.raster.wmts.ogc.struct.WMTSTileMatrix;
106
import org.gvsig.raster.wmts.ogc.struct.WMTSTileMatrixLimits;
107
import org.gvsig.raster.wmts.ogc.struct.WMTSTileMatrixSet;
108
import org.gvsig.raster.wmts.ogc.struct.WMTSTileMatrixSetLink;
109
import org.gvsig.tools.ToolsLocator;
110

  
111
import org.apache.commons.io.FilenameUtils;
112
import org.cresques.cts.IProjection;
113
import org.slf4j.Logger;
114
import org.slf4j.LoggerFactory;
115
/**
116
 * Provider for WMTS service
117
 *
118
 * @author Nacho Brodin (nachobrodin@gmail.com)
119
 */
120
public class WMTSProvider extends AbstractRasterProvider implements RemoteRasterProvider, TiledRasterProvider {
121
	public static String                NAME                     = "Wmts Store";
122
	public static String                DESCRIPTION              = "Wmts Raster file";
123
	public static final String          METADATA_DEFINITION_NAME = "WmtsStore";
124
	private static Logger               logger                   = LoggerFactory.getLogger(WMTSProvider.class);
125
	public static boolean               TILED                    = true;
126

  
127
	//Los tiles se piden de forma secuencial y sin lanzar threads para ello (+Lento)
128
	public static int                   SEQUENTIAL               = 0;
129
	//Los tiles se piden en threads y hay un thread manager para gestionar que no se pidan m?s de cierto n?mero
130
	public static int                   LIMITED_THREADS          = 1;
131
	//Los tiles se piden en threads y se lanzan tantos threads como tiles haya
132
	public static int                   UNLIMITED_THREADS        = 2;
133
	private int                         requestType              = LIMITED_THREADS;
134

  
135
	private static final double         MTS_X_GRADO              = 111319.490793274;
136

  
137
	private Extent                      viewRequest              = null;
138
	private WMTSClient                  ogcClient                = null;
139
	//private static Hashtable<URL, WMTSConnector>
140
	//                                    drivers                  = new Hashtable<URL, WMTSConnector> ();
141
	private boolean                     open                     = false;
142
	private File                        lastRequest              = null;
143
	private DataStoreTransparency       lastFileTransparency     = null;
144
	private int                         lastWidthRequest         = 0;
145
	private int                         lastHeightRequest        = 0;
146
	private WMTSStatus                  lastStatus               = null;
147
	private boolean                     gridSubsets              = true;
148
	private Extent[]                    extentByLevel            = null; //Only for layers without gridSubsets
149
	private Extent                      bbox                     = null;
150
	private MathUtils                   math                     = RasterLocator.getManager().getMathUtils();
151

  
152
	/**
153
	 * This thread manages the number of tiles that have been thrown.
154
	 * This number is controlled by the NTHREADS_QUEUE variable.
155
	 *
156
	 * @author Nacho Brodin (nachobrodin@gmail.com)
157
	 */
158
	public class RequestThreadManager extends Thread {
159
		private TilePipe               pipe           = null;
160
		private List<WMTSTile>         tiles          = null;
161
		private WMTSStatus             status         = null;
162

  
163
		public RequestThreadManager(TilePipe pipe, List<WMTSTile> tiles, WMTSStatus status) {
164
			this.pipe = pipe;
165
			this.tiles = tiles;
166
			this.status = status;
167
		}
168

  
169
		public void run() {
170
			for (int i = 0; i < tiles.size(); i++) {
171
				WMTSTile tile = tiles.get(i);
172
				WMTSStatus statusCopy = status.cloneStatus();
173
				statusCopy.setTileRow(tile.getRow());
174
				statusCopy.setTileCol(tile.getCol());
175
				if (pipe.getSize() > TilePipe.NTHREADS_QUEUE) {
176
					try {
177
						synchronized (this) {
178
							wait();
179
						}
180
					} catch( InterruptedException e ) {
181
					}
182
				}
183
				new RequestTileLauncher(pipe, statusCopy, tile).start();
184
			}
185
		}
186
	}
187

  
188
	/**
189
	 * Thread to download a tile
190
	 * @author Nacho Brodin (nachobrodin@gmail.com)
191
	 */
192
	class RequestTileLauncher extends Thread {
193
		private TilePipe      pipe    = null;
194
		private WMTSStatus    status  = null;
195
		private WMTSTile      tile    = null;
196

  
197
		public RequestTileLauncher(TilePipe pipe, WMTSStatus status, WMTSTile tile) {
198
			this.pipe = pipe;
199
			this.status = status;
200
			this.tile = tile;
201
		}
202

  
203
		public void run() {
204
			try {
205
				//File file = getConnector().getTile(status, null);
206
				URL url = getOGCClient().getTileURL(status);
207
				tile.setFile(getOGCClient().downloadFile(url, null));
208
				pipe.setTile(tile);
209
			} catch (DownloadException e) {
210
				logger.info("Error downloading files", e);
211
			} catch (MalformedURLException e) {
212
				logger.info("Malformed URL", e);
213
			} catch (WMTSException e) {
214
				logger.info("", e);
215
			}
216
		}
217
	}
218

  
219
	/**
220
	 * Point information
221
	 * @author Nacho Brodin (nachobrodin@gmail.com)
222
	 */
223
	public class PointInfo {
224
		public Point2D worldCoord;
225
		public Point2D tile;
226
		public Point2D pixelInTile;
227
		public int     level;
228

  
229
		public PointInfo(Point2D worldCoord) {
230
			this.worldCoord = worldCoord;
231
		}
232
	}
233

  
234
	public static void register() {
235
		DataManagerProviderServices dataman = (DataManagerProviderServices) DALLocator.getDataManager();
236
		if (dataman != null && !dataman.getStoreProviders().contains(NAME)) {
237
			dataman.registerStoreProvider(NAME,
238
					WMTSProvider.class, WMTSDataParametersImpl.class);
239
		}
240

  
241
		if (!dataman.getExplorerProviders().contains(WMTSServerExplorer.NAME)) {
242
			dataman.registerExplorerProvider(WMTSServerExplorer.NAME, WMTSServerExplorer.class, WMTSServerExplorerParameters.class);
243
		}
244
		dataman.registerStoreFactory(NAME, DefaultStoreFactory.class);
245
	}
246

  
247
	public WMTSProvider() throws NotSupportedExtensionException {
248
		super();
249
	}
250

  
251
	/**
252
	 * Constructor. Abre el dataset.
253
	 * @param proj Proyecci?n
254
	 * @param fName Nombre del fichero
255
	 * @throws NotSupportedExtensionException
256
	 * @throws OpenException
257
     * @deprecated use {@link #WMTSProvider(URI)}, this constructor will be removed in gvSIG 2.5
258
	 */
259
	public WMTSProvider(String params) throws NotSupportedExtensionException, OpenException {
260
		super(params);
261
        logger.info("Deprecated use of WMTSProvider constructor");
262
		if(params instanceof String) {
263
			WMTSDataParameters p = new WMTSDataParametersImpl();
264
            try {
265
                p.setURI(new URI((String) params));
266
            } catch (URISyntaxException e) {
267
                throw new OpenException("Can't create URI from" + (String) params, e);
268
            }
269
			super.init(p, null, ToolsLocator.getDynObjectManager()
270
					.createDynObject(
271
							MetadataLocator.getMetadataManager().getDefinition(
272
									DataStore.METADATA_DEFINITION_NAME)));
273
			init(p, null);
274
		}
275
	}
276

  
277
	 /**
278
     * Constructor. Abre el dataset.
279
     * @param uri URI del fichero
280
     * @throws NotSupportedExtensionException
281
     */
282
    public WMTSProvider(URI uri) throws NotSupportedExtensionException {
283
        super(uri);
284
        WMTSDataParameters p = new WMTSDataParametersImpl();
285
        p.setURI(uri);
286
        super.init(
287
            p,
288
            null,
289
            ToolsLocator.getDynObjectManager().createDynObject(
290
                MetadataLocator.getMetadataManager().getDefinition(DataStore.METADATA_DEFINITION_NAME)));
291
        init(p, null);
292
    }
293

  
294
    public WMTSProvider(WMTSDataParameters params,
295
			DataStoreProviderServices storeServices) throws NotSupportedExtensionException {
296
		super(params, storeServices, ToolsLocator.getDynObjectManager()
297
				.createDynObject(
298
						MetadataLocator.getMetadataManager().getDefinition(
299
								DataStore.METADATA_DEFINITION_NAME)));
300
		init(params, storeServices);
301
	}
302

  
303
	/**
304
	 * Gets the connector from the URL
305
	 * @return
306
	 * @throws RemoteServiceException
307
	 */
308
	public WMTSClient getOGCClient() throws WMTSException {
309
		if(ogcClient == null) {
310
			WMTSDataParameters p = (WMTSDataParameters)parameters;
311
			ogcClient = p.getOGCClient();
312
			if(ogcClient != null)
313
				return ogcClient;
314

  
315
			URL url = null;
316
			try {
317
				url = p.getURI().toURL();
318
			} catch (Exception e) {
319
				throw new WMTSException("Malformed URL",e);
320
			}
321
			try {
322
				ogcClient = WMTSOGCLocator.getManager().createWMTSClient(url.toString());
323
				ogcClient.connect(true, new ICancellable() {
324

  
325
					public boolean isCanceled() {
326
						return false;
327
					}
328

  
329
					public Object getID() {
330
						return null;
331
					}
332
				});
333
			} catch (ConnectException e) {
334
				throw new WMTSException("Connect exception",e);
335
			} catch (IOException e) {
336
				throw new WMTSException("Connect exception",e);
337
			}
338
		}
339
		return ogcClient;
340
	}
341

  
342
	/**
343
	 * Crea las referencias al fichero y carga
344
	 * las estructuras con la informaci?n y los metadatos.
345
	 * @param proj Proyecci?n
346
	 * @param param Parametros de carga
347
	 * @throws NotSupportedExtensionException
348
	 */
349
	public void init (DataStoreParameters params,
350
			DataStoreProviderServices storeServices) throws NotSupportedExtensionException {
351
		setParam(storeServices, params);
352
		if(((WMTSDataParameters)params).getImageFormat().compareTo("image/gif") == 0) {
353
			setDataType(new int[]{Buffer.TYPE_BYTE});
354
			bandCount = 1;
355
		} else {
356
			setDataType(new int[]{Buffer.TYPE_BYTE, Buffer.TYPE_BYTE, Buffer.TYPE_BYTE, Buffer.TYPE_BYTE});
357
			bandCount = 4;
358
		}
359

  
360
		if(!(param instanceof WMTSDataParameters))
361
			return;
362

  
363
		gridSubsets = hasGridSubsets((WMTSDataParameters)param);
364
		open = true;
365
	}
366

  
367
	/**
368
	 * Returns true if this layer has grid subsets
369
	 * @return
370
	 */
371
	public boolean hasGridSubsets() {
372
		return gridSubsets;
373
	}
374

  
375
	/**
376
	 * Checks if this layer has grid subsets or doesn't
377
	 * @param p
378
	 * @return
379
	 */
380
	private boolean hasGridSubsets(WMTSDataParameters p) {
381
		List<WMTSTileMatrixLimits> tileMatrixSetLimits = null;
382
		List<WMTSTileMatrixSetLink> tileMatrixSetLinkList = p.getLayer().getTileMatrixSetLink();
383
		String srs = p.getSRSCode();
384
		for (int i = 0; i < tileMatrixSetLinkList.size(); i++) {
385
			WMTSTileMatrixSetLink tileMatrixSetLink = (WMTSTileMatrixSetLink)tileMatrixSetLinkList.get(i);
386
			WMTSTileMatrixSet tms = tileMatrixSetLink.getTileMatrixSet();
387
			List<WMTSTileMatrixLimits> tmsl = tileMatrixSetLink.getTileMatrixLimits();
388
			String srsTileSet = tms.getSupportedCRS();
389
			if(areSrsEquals(srsTileSet, srs)) {
390
				tileMatrixSetLimits = tmsl;
391
			}
392
		}
393

  
394
		return (tileMatrixSetLimits == null || tileMatrixSetLimits.size() <= 0) ? false : true;
395
	}
396

  
397
	private boolean areSrsEquals(String sourceSrs, String appSrs) {
398
		if(sourceSrs.compareTo(appSrs) == 0)
399
			return true;
400
		if(sourceSrs.contains("CRS:84") || sourceSrs.contains("CRS84")) {
401
			if(appSrs.equals("EPSG:4326"))
402
				return true;
403
		}
404
		return false;
405
	}
406

  
407
	/*public static final WMTSConnector getConnectorFromURL(URL url) throws IOException {
408
		WMTSConnector drv = (WMTSConnector) drivers.get(url);
409
		if (drv == null) {
410
			drv = new WMTSConnector(url);
411
			drivers.put(url, drv);
412
		}
413
		return drv;
414
	}*/
415

  
416
	/**
417
	 * Obtiene el objeto que contiene que contiene la interpretaci?n de
418
	 * color por banda
419
	 * @return
420
	 */
421
	public ColorInterpretation getColorInterpretation() {
422
		if(super.getColorInterpretation() == null) {
423
			ColorInterpretation colorInterpretation = new DataStoreColorInterpretation(getBandCount());
424

  
425
			if(getBandCount() == 1)
426
				colorInterpretation = DataStoreColorInterpretation.createGrayInterpretation();
427

  
428
			if(getBandCount() == 3)
429
				colorInterpretation = DataStoreColorInterpretation.createRGBInterpretation();
430

  
431
			if(getBandCount() == 4)
432
				colorInterpretation = DataStoreColorInterpretation.createRGBAInterpretation();
433

  
434
			if(getBandCount() > 4 || getBandCount() == 2) {
435
				for (int i = 0; i < getBandCount(); i++) {
436
					colorInterpretation.setColorInterpValue(i, DataStoreColorInterpretation.UNDEF_BAND);
437
				}
438
			}
439
			setColorInterpretation(colorInterpretation);
440
		}
441
		return super.getColorInterpretation();
442
	}
443

  
444
	public boolean isTiled() {
445
		return true;
446
	}
447

  
448
	public AffineTransform getAffineTransform() {
449
		WMTSDataParameters p = (WMTSDataParameters)parameters;
450
		Extent e = getExtent();
451
		double psX = e.width() / (lastWidthRequest <= 0 ? p.getWidth() : lastWidthRequest);
452
		double psY = -(e.height() / (lastHeightRequest <= 0 ? p.getHeight() : lastHeightRequest));
453
		ownTransformation = new AffineTransform(
454
				psX,
455
				0,
456
				0,
457
				psY,
458
				e.getULX() - (psX / 2),
459
				e.getULY() - (psY / 2));
460
		externalTransformation = (AffineTransform) ownTransformation.clone();
461
		return ownTransformation;
462
	}
463

  
464
	/**
465
	 * <p>
466
	 * Gets the bounding box in world coordinates.
467
	 * If the layer has defined the BoundingBox tag, we will take this bounding box as entire
468
	 * extension of this layer, else we'll see if the tag WGS84BoundingBox is defined (it can be approximated).
469
	 * In this case we'll take WGS84BoundingBox as entire extension.
470
	 * </p>
471
	 * <br>
472
	 * Note:
473
	 * <br>
474
	 * <p>
475
	 * If the layer has grid subsets (TileMatrixLimits) then
476
	 * this will have a only extent but if the layer doesn't have grid subsets then this will have a different
477
	 * extent in each level resolution. In this case we need to know the extent for each level.
478
	 * </p>
479
	 * @return Extent
480
	 */
481
	public Extent getExtent() {
482
		WMTSDataParameters p = (WMTSDataParameters)parameters;
483
		WMTSLayer layer = p.getLayer();
484

  
485
		if(layer.getBBox() != null)
486
			return new ExtentImpl(layer.getBBox().toRectangle2D());
487

  
488
		if(layer.getWGS84BBox() != null) {
489
			String crsCode = p.getSRSCode();
490
			Rectangle2D r = layer.getWGS84BBoxTransformed(crsCode);
491
			if(r != null)
492
				return new ExtentImpl(r);
493
		}
494

  
495
		if(bbox == null)
496
			getExtentByResolutionLevel();
497
		return bbox;
498

  
499
		/*if(gridSubsets) {
500
			WMTSBoundingBox bbox = layer.getWGS84BBox();
501
			return new ExtentImpl(bbox.toRectangle2D());
502
		} else {
503
			if(bbox == null)
504
				getExtentByResolutionLevel();
505
			return bbox;
506
		}*/
507
	}
508

  
509
	/**
510
	 * Gets the suffix of the downloaded image
511
	 * @return
512
	 */
513
	public String getFileSuffix() {
514
		WMTSDataParameters p = (WMTSDataParameters)parameters;
515
		String format = p.getImageFormat();
516
		if (format == null){
517
			return "xml";
518
		}
519
		if (format.indexOf("png") >= 0){
520
	        return "png";
521
		}
522
	    if (format.indexOf("xml") >= 0){
523
	        return "xml";
524
	    }
525
	    if (format.indexOf("gif") >= 0){
526
	        return "gif";
527
	    }
528
	    if (format.indexOf("tif") >= 0){
529
	        return "tif";
530
	    }
531
	    if (format.indexOf("bmp") >= 0){
532
	        return "bmp";
533
	    }
534
	    if (format.indexOf("jpg") >= 0
535
	        || format.indexOf("jpeg") >= 0){
536
	        return "jpg";
537
	    }
538
		return "xml";
539
	}
540

  
541
	/**
542
	 * When a layer doesn't have grid subsets this will have a different bounding
543
	 * box by resolution level. This function calculates and returns the array of
544
	 * extents, one by resolution level.
545
	 * @return
546
	 */
547
	public Extent[] getExtentByResolutionLevel() {
548
		if(extentByLevel == null) {
549
			WMTSDataParameters p = (WMTSDataParameters)parameters;
550
			WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
551
			WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
552

  
553
	    	double widthMtsTile = 0;
554
	    	double heightMtsTile = 0;
555
			List<WMTSTileMatrix> tileMatrixList = tileMatrixSet.getTileMatrix();
556
			extentByLevel = new ExtentImpl[tileMatrixList.size()];
557
			double minX = 0;
558
			double minY = 0;
559
			double maxX = 0;
560
			double maxY = 0;
561
			for (int i = 0; i < tileMatrixList.size(); i++) {
562
				WMTSTileMatrix tileMatrix = (WMTSTileMatrix)tileMatrixList.get(i);
563
		    	if(!p.isProjected()) {
564
		    		widthMtsTile = (tileMatrix.getScaleDenominator() * tileMatrix.getTileWidth() * 0.28) / (MTS_X_GRADO * 1000);
565
		    		heightMtsTile = (tileMatrix.getScaleDenominator() * tileMatrix.getTileHeight() * 0.28) / (MTS_X_GRADO * 1000);
566
		    	} else {
567
		    		widthMtsTile = (tileMatrix.getScaleDenominator() * tileMatrix.getTileWidth() * 0.28) / 1000;
568
		    		heightMtsTile = (tileMatrix.getScaleDenominator() * tileMatrix.getTileHeight() * 0.28) / 1000;
569
		    	}
570

  
571
		    	//TODO: Revisar!!! Creo que el top left sale al rev?s en el de la nasa
572

  
573
		    	double h = Math.abs(tileMatrix.getTopLeftCorner()[1] - (tileMatrix.getTopLeftCorner()[1] - (tileMatrix.getMatrixHeight() * heightMtsTile)));
574
		    	Rectangle2D r = new Rectangle2D.Double(
575
		    			tileMatrix.getTopLeftCorner()[0],
576
		    			tileMatrix.getTopLeftCorner()[1] - h,
577
		    			Math.abs(tileMatrix.getTopLeftCorner()[0] - (tileMatrix.getTopLeftCorner()[0] + (tileMatrix.getMatrixWidth() * widthMtsTile))),
578
		    			h);
579
		    	extentByLevel[i] = new ExtentImpl(r);
580
		    	if(i == 0) {
581
		    		minX = extentByLevel[i].getMin().getX();
582
		    		minY = extentByLevel[i].getMin().getY();
583
		    		maxX = extentByLevel[i].getMax().getX();
584
		    		maxY = extentByLevel[i].getMax().getY();
585
		    	} else {
586
		    		minX = Math.min(minX, extentByLevel[i].getMin().getX());
587
		    		minY = Math.min(minY, extentByLevel[i].getMin().getY());
588
		    		maxX = Math.max(maxX, extentByLevel[i].getMax().getX());
589
		    		maxY = Math.max(maxY, extentByLevel[i].getMax().getY());
590
		    	}
591
			}
592
			bbox = new ExtentImpl(minX, maxY, maxX, minY);
593
		}
594
		return extentByLevel;
595
	}
596

  
597
	public Rectangle2D getLayerExtent(String layerName, String srs) throws RemoteServiceException {
598
		return null;
599
	}
600

  
601
	public RasterProvider load() {
602
		return this;
603
	}
604

  
605
	public boolean isOpen() {
606
		return open;
607
	}
608

  
609
	public void close() {
610
		open = false;
611
	}
612

  
613
	public Transparency getTransparency() {
614
		if(lastFileTransparency == null) {
615
			lastFileTransparency = new DataStoreTransparency(getColorInterpretation());
616
			lastFileTransparency.setTransparencyBand(3);
617
		}
618
		return lastFileTransparency;
619
	}
620

  
621
	public NoData getNoDataValue() {
622
		NoData nodata = super.getNoDataValue();
623
		if(nodata != null)
624
			nodata.setNoDataTransparent(false);
625
		return noData;
626
	}
627

  
628
	public URI translateURI(URI uri) {
629
		return uri;
630
	}
631

  
632
	public void setView(Extent e) {
633
		viewRequest = e;
634
	}
635

  
636
	public Extent getView() {
637
		return viewRequest;
638
	}
639

  
640
	public double getWidth() {
641
		WMTSDataParameters p = (WMTSDataParameters)parameters;
642
		if (lastWidthRequest <= 0)
643
			return p.getWidth();
644
		return lastWidthRequest;
645
	}
646

  
647
	public double getHeight() {
648
		WMTSDataParameters p = (WMTSDataParameters)parameters;
649
		if (lastHeightRequest <= 0)
650
			return p.getHeight();
651
		return lastHeightRequest;
652
	}
653

  
654
	public Object readCompleteLine(int line, int band)
655
		throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
656
		return null;
657
	}
658

  
659
	/**
660
	 * When the remote layer has fixed size this method downloads the file and return its reference.
661
	 * File layer has in the long side FIXED_SIZE pixels and the bounding box is complete. This file could be
662
	 * useful to build an histogram or calculate statistics. This represents a sample of data.
663
	 * @return
664
	 * @throws RasterDriverException
665
	 */
666
	public File getFileLayer() throws RasterDriverException {
667
		return null;
668
	}
669

  
670
	/**
671
	 * Reads a complete block of data and returns an tridimensional array of the right type. This function is useful
672
	 * to read a file very fast without setting a view. In a WMTS service when the size is fixed then it will read the
673
	 * entire image but when the source hasn't pixel size it will read a sample of data. This set of data will have
674
	 * the size defined in FIXED_SIZE.
675
	 *
676
	 * @param pos Posici?n donde se empieza  a leer
677
	 * @param blockHeight Altura m?xima del bloque leido
678
	 * @return Object que es un array tridimendional del tipo de datos del raster. (Bandas X Filas X Columnas)
679
	 * @throws InvalidSetViewException
680
	 * @throws FileNotOpenException
681
	 * @throws RasterDriverException
682
	 */
683
	public Object readBlock(int pos, int blockHeight, double scale)
684
	throws InvalidSetViewException, FileNotOpenException, RasterDriverException, ProcessInterruptedException {
685
		return null;
686
	}
687

  
688
	public Object getData(int x, int y, int band)
689
		throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
690
		return null;
691
	}
692

  
693
	/**
694
	 * Assigns the list of bands RGB and read a window of data
695
	 * @param rasterBuf
696
	 * @param bandList
697
	 * @param lastFile
698
	 * @param ulx
699
	 * @param uly
700
	 * @param lrx
701
	 * @param lry
702
	 * @return
703
	 * @throws RasterDriverException
704
	 * @throws ProcessInterruptedException
705
	 */
706
	public Buffer getBuffer(Buffer rasterBuf, BandList bandList, File lastFile,
707
			double ulx, double uly, double lrx, double lry) throws RasterDriverException, ProcessInterruptedException {
708
		return null;
709
	}
710

  
711
	/**
712
	 * Gets the tile matrix from the selected level
713
	 * @param level
714
	 * @return
715
	 */
716
	private WMTSTileMatrix getTileMatrixByLevel(int level) {
717
		level = adjustLevel(level);
718

  
719
		WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
720
		WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
721
		List<WMTSTileMatrixLimits> tileMatrixSetLimits = tileMatrixSetLink.getTileMatrixLimits();
722

  
723
		WMTSTileMatrixLimits tileMatrixLimits = null;
724
		WMTSTileMatrix tileMatrix = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(level);
725
		if(hasGridSubsets()) {
726
			tileMatrixLimits = (WMTSTileMatrixLimits)tileMatrixSetLimits.get(level);
727
			tileMatrix = tileMatrixLimits.getTileMatrix();
728
		}
729
		return tileMatrix;
730
	}
731

  
732
	/**
733
	 * Returns the number of levels
734
	 * @return
735
	 */
736
	public int getZoomLevels() {
737
		WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
738
		WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
739
		if(hasGridSubsets()) {
740
			List<WMTSTileMatrixLimits> tileMatrixSetLimits = tileMatrixSetLink.getTileMatrixLimits();
741
			return Math.min(tileMatrixSet.getTileMatrix().size(), tileMatrixSetLimits.size());
742
		}
743
		return tileMatrixSet.getTileMatrix().size();
744

  
745
	}
746

  
747
	public Extent getCoordsInTheNearestLevel(Extent extent, int w, int h) {
748
		double[] pixelSizes = getPixelSizeByLevel();
749
		double currentPixelSize = extent.width() / (double)w;
750

  
751
		int level = 0;
752
		for (int i = 0; i < (pixelSizes.length - 1); i++) {
753
			if(currentPixelSize < pixelSizes[i] && currentPixelSize >= pixelSizes[i + 1]) {
754
				level = i + 1;
755
				break;
756
			}
757
		}
758

  
759
		return getZoomLevelCoordinates(level, extent, w, h);
760
	}
761

  
762
	public Extent getCoordsInLevel(Point2D viewCenter, int level, int w, int h) {
763
		WMTSDataParameters p = (WMTSDataParameters)param;
764
		level = adjustLevel(level);
765
		WMTSTileMatrix tileMatrix = getTileMatrixByLevel(level);
766

  
767
		boolean proj = p.isProjected();
768

  
769
		double psX = tileMatrix.getWidthWCTile(proj) / tileMatrix.getTileWidth();
770
		double psY = tileMatrix.getHeightWCTile(proj) / tileMatrix.getTileHeight();
771

  
772
		double ulx = viewCenter.getX() - ((w / 2) * psX);
773
		double uly = viewCenter.getY() - ((h / 2) * psY);
774
		double lrx = ulx + (w * psX);
775
		double lry = uly + (h * psY);
776
		return new ExtentImpl(ulx, uly, lrx, lry);
777
	}
778

  
779
	/**
780
	 * Calculates the extent of a zoom level using other extent as a reference. The new extent is
781
	 * calculated with the same coordinate at the center.
782
	 * @param level
783
	 * @param extent
784
	 * @param w
785
	 * @param h
786
	 * @return
787
	 */
788
	public Extent getZoomLevelCoordinates(int level, Extent extent, int w, int h) {
789
		double centerX = extent.getCenterX();
790
		double centerY = extent.getCenterY();
791
		return getCoordsInLevel(new Point2D.Double(centerX, centerY), level, w, h);
792
	}
793

  
794
	/**
795
	 * Returns a list of pixel sizes by level
796
	 * @return
797
	 */
798
	public double[] getPixelSizeByLevel() {
799
		WMTSDataParameters p = (WMTSDataParameters)param;
800
		double[] list = new double[getZoomLevels()];
801

  
802
		for (int i = 0; i < getZoomLevels(); i++) {
803
			WMTSTileMatrix tileMatrix = getTileMatrixByLevel(i);
804
			list[i] = math.adjustDouble(tileMatrix.getWidthWCTile(p.isProjected()) / tileMatrix.getTileWidth());
805
		}
806
		return list;
807
	}
808

  
809
	/**
810
	 * Adjust de level to the range
811
	 * @param level
812
	 * @return
813
	 */
814
	private int adjustLevel(int level) {
815
		if(level < 0)
816
			level = 0;
817
		if(level > getZoomLevels())
818
			level = getZoomLevels();
819
		return level;
820
	}
821

  
822
	public org.gvsig.raster.cache.tile.Tile getTile(SpiRasterQuery q) throws TileGettingException {
823
		//q.getResolutionLevel(), q.getTileCol(), q.getTileRow(), q.getBBox(), q.getCacheStruct()!
824

  
825
		CacheStruct str = getTileServer().getStruct();
826

  
827
		//1-Selecci?n de WMTSTileMatrixSet por srs
828
		WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
829
		WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
830
		List<WMTSTileMatrixLimits> tileMatrixSetLimits = tileMatrixSetLink.getTileMatrixLimits();
831

  
832
		WMTSTileMatrix tileMatrix = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(q.getResolutionLevel());
833
		if(gridSubsets) {
834
			WMTSTileMatrixLimits tileMatrixLimits = (WMTSTileMatrixLimits)tileMatrixSetLimits.get(q.getResolutionLevel());
835
			tileMatrix = tileMatrixLimits.getTileMatrix();
836
		}
837
		int bufWidth = tileMatrix.getTileWidth();
838
		int bufHeight = tileMatrix.getTileHeight();
839

  
840
		try {
841
			Extent adjBbox = q.getAdjustedRequestBoundingBox();
842
			Rectangle2D r = adjBbox.toRectangle2D();//new Rectangle2D.Double(Math.min(minX, maxX), Math.min(minY, maxY), Math.abs(maxX - minX), Math.abs(maxY - minY));
843
			WMTSStatus status = buildWMTSStatus(r, bufWidth , bufHeight);
844

  
845
			int[] size = str.getTileSizeByLevel(q.getResolutionLevel());
846
			WMTSTile tile = WMTSOGCLocator.getManager().createTile(
847
					size,
848
					new int[]{q.getTileRow(), q.getTileCol()},
849
					new double[]{adjBbox.getULX(), adjBbox.getULY(), adjBbox.getLRX(), adjBbox.getLRY()});
850

  
851
			File file = getOGCClient().getTile(status, null);
852
			tile.setFile(file);
853
			//Creamos un BandList con todas las bandas del fichero
854
			BandList bandList = new BandListImpl();
855
			for(int i = 0; i < getBandCount(); i++) {
856
				try {
857
					DatasetBand band = new DatasetBandImpl(getURIOfFirstProvider().getPath(), i, getDataType()[i], getBandCount());
858
					bandList.addBand(band);
859
				} catch(BandNotFoundInListException e) {
860
					//No a?adimos la banda
861
				}
862
			}
863
			return drawTile(tile, null, bandList);
864
		} catch (WMTSException e) {
865
			throw new TileGettingException("Error getting tiles", e);
866
		} catch (ServerErrorException e) {
867
			throw new TileGettingException("Error getting tiles", e);
868
		} catch (RasterDriverException e) {
869
			throw new TileGettingException("Error getting tiles", e);
870
		}
871
	}
872

  
873
	@Override
874
	public void loadBuffer(SpiRasterQuery q)
875
			throws ProcessInterruptedException, RasterDriverException {
876
		Rectangle2D r = q.getAdjustedRequestBoundingBox().toRectangle2D();//new Rectangle2D.Double(Math.min(minX, maxX), Math.min(minY, maxY), Math.abs(maxX - minX), Math.abs(maxY - minY));
877
		WMTSStatus status = buildWMTSStatus(r, q.getAdjustedWidth(), q.getAdjustedBufHeight());
878
		request(status, q.getBandList(), q.getTileListener(), requestType);
879
		org.gvsig.raster.cache.tile.Tile[] tileList = request(status, q.getBandList(), null, requestType);
880
		MemoryTileMatrixBuffer matrixBuffer = new MemoryTileMatrixBuffer(tileList);
881
		Buffer b = matrixBuffer.getWindow(q.getAdjustedRequestBoundingBox(), q.getBufWidth(), q.getBufHeight(), q.getBandList().getDrawableBandsCount());
882
		q.setBufferResult(b);
883
	}
884

  
885
	/**
886
	 * Gets the information from a point
887
	 * @param wcx
888
	 * @param wcy
889
	 * @param level
890
	 * @return
891
	 * @throws RasterDriverException
892
	 */
893
	public String getFeatureInfo(double wcx, double wcy, int level) throws RasterDriverException {
894
		PointInfo pointInfo = new PointInfo(new Point2D.Double(wcx, wcy));
895
		pointInfo.level = level;
896
		getTileInfo(pointInfo);
897

  
898
		WMTSClient ogcClient = null;
899
		try {
900
			ogcClient = getOGCClient();
901
			lastStatus.setTileRow((int)pointInfo.tile.getX());
902
			lastStatus.setTileCol((int)pointInfo.tile.getY());
903

  
904
			String fi = ogcClient.getFeatureInfo(lastStatus, (int)pointInfo.pixelInTile.getX(), (int)pointInfo.pixelInTile.getY(), null);
905
			return fi;
906
		} catch (WMTSException e) {
907
			throw new RasterDriverException("Error getting the connector object", e);
908
		}
909
	}
910

  
911
	/**
912
	 * Gets a tile position from a world coordinates point and a resolution level
913
	 * @param point
914
	 * @param level
915
	 * @return An array with two elements. The first is the row and the second the column
916
	 * of the tile in the tile matrix
917
	 */
918
	private void getTileInfo(PointInfo pointInfo) {
919
		WMTSDataParameters p = (WMTSDataParameters)param;
920

  
921
		WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
922
		WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
923
		List<WMTSTileMatrixLimits> tileMatrixSetLimits = tileMatrixSetLink.getTileMatrixLimits();
924

  
925
		WMTSTileMatrixLimits tileMatrixLimits = null;
926
		WMTSTileMatrix tileMatrix = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(pointInfo.level);
927
		if(hasGridSubsets()) {
928
			tileMatrixLimits = (WMTSTileMatrixLimits)tileMatrixSetLimits.get(pointInfo.level);
929
			tileMatrix = tileMatrixLimits.getTileMatrix();
930
		}
931

  
932
		List<WMTSTile> tiles = null;
933
		if(hasGridSubsets())
934
			tiles = tileMatrix.contains(p.isProjected(), tileMatrixLimits, pointInfo.worldCoord, getExtent().toRectangle2D());
935
		else
936
			tiles = tileMatrix.contains(p.isProjected(), pointInfo.worldCoord, getExtent().toRectangle2D());
937

  
938
		//Tile row and column
939
		pointInfo.tile = new Point2D.Double(tiles.get(0).getRow(), tiles.get(0).getCol());
940

  
941
		//Desplazamiento en pixels dentro del tile
942
		Point2D rasterPoint = tiles.get(0).worldToRaster(pointInfo.worldCoord);
943
		pointInfo.pixelInTile = new Point2D.Double(rasterPoint.getX(), rasterPoint.getY());
944
	}
945

  
946
	/**
947
	 * Builds the WMTSStatus object using the parameters and the request bounding box.
948
	 * @param r
949
	 * @param bufWidth
950
	 * @return
951
	 * @throws RasterDriverException
952
	 */
953
	public WMTSStatus buildWMTSStatus(Rectangle2D r, int bufWidth, int bufHeight) throws RasterDriverException {
954
		WMTSDataParameters p = (WMTSDataParameters)param;
955

  
956
		//Mantiene actualizados los par?metros del WMTSStoreParameters con la ?ltima petici?n hecha
957
		p.setExtent(r);
958
		p.setWidth(bufWidth);
959
		p.setHeight(bufHeight);
960

  
961
		lastWidthRequest = bufWidth;
962
		lastHeightRequest = bufHeight;
963

  
964
		//1-Selecci?n de WMTSTileMatrixSet por srs
965
		WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
966
		WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
967
		List<WMTSTileMatrixLimits> tileMatrixSetLimits = tileMatrixSetLink.getTileMatrixLimits();
968
		int initialLevel = p.getLayer().getInitialLevel(tileMatrixSet.getIdentifier());
969

  
970
		//Esto hace lo mismo que getScale y getLevelFromScale
971
		/*int level = 0;
972
		double[] pixelSizes = getPixelSizeByLevel();
973
		double psViewPort = math.adjustDouble(r.getWidth() / (double)bufWidth);
974
		for (int i = 0; i < pixelSizes.length - 1; i++) {
975
			if(psViewPort <= pixelSizes[i] && psViewPort > pixelSizes[i + 1]) {
976
				level = i;
977
				break;
978
			}
979
		}*/
980

  
981
		//2-Calculo de la escala
982
		double scale = getScale(r, bufWidth);
983

  
984
		//3-Selecci?n del nivel a partir de la escala
985
		int level = getLevelFromScale(scale, tileMatrixSet);
986

  
987
		//Para evitar que se salga del array si la capa tiene menos niveles que el tilematrixset
988
		int dif = 0;
989
		if(gridSubsets)
990
			dif = (level - initialLevel) >= tileMatrixSetLimits.size() ?  (level - initialLevel) - tileMatrixSetLimits.size() + 1 : 0;
991

  
992
		//4-Obtenemos la matriz de tiles y los l?mites si tiene subsets
993
		@SuppressWarnings("unused")
994
		WMTSTileMatrixLimits tileMatrixLimits = null;
995
		WMTSTileMatrix tileMatrix = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(level - dif);
996
		if(gridSubsets)
997
			tileMatrixLimits = (WMTSTileMatrixLimits)tileMatrixSetLimits.get(level - initialLevel - dif);
998

  
999
		//5-Selecci?n de tiles que entran en esta bounding box
1000
		List<WMTSTile> tiles = null;
1001
		/*if(gridSubsets)
1002
			tiles = tileMatrix.intersects(p.isProjected(), tileMatrixLimits, r, getExtent().toRectangle2D());
1003
		else*/
1004
		Extent[] extList = getExtentByResolutionLevel();
1005
		tiles = tileMatrix.intersects(p.isProjected(), r, extList[level].toRectangle2D());
1006

  
1007
		//6-Petici?n
1008
		WMTSStatus status = null;
1009
		try {
1010
			status = getOGCClient().createStatus();
1011
		} catch (WMTSException e) {
1012
			throw new RasterDriverException("Error creating WMTSStatus", e);
1013
		}
1014
		WMTSLayer wmtsLayer = p.getLayer();
1015
		status.setTileList(tiles);
1016
		status.setLayer(wmtsLayer.getIdentifier());//.substring(p.getLayer().getIdentifier().indexOf("_") + 1));
1017

  
1018
		status.setFormat(p.getImageFormat());
1019
		status.setInfoFormat(p.getInfoFormat());
1020
		status.setStyle(p.getStyle() != null ? p.getStyle().getIdentifier() : "");
1021
		status.setTileMatrixSet(tileMatrixSet.getIdentifier());
1022
		status.setTileMatrix(tileMatrix.getIdentifier());
1023
		status.setLevel(level - dif);
1024
		status.setDimension(p.getDimension());
1025
		status.setValueForDimension(p.getDimensionSelectedValue());
1026

  
1027
		wmtsLayer.buildResourceURLListFromTemplate(status);
1028
		this.lastStatus = status;
1029

  
1030
		return status;
1031
	}
1032

  
1033
	/**
1034
	 * Gets the resolution level from the real coordinates
1035
	 * @param r
1036
	 * @param
1037
	 * @return
1038
	 * @throws RasterDriverException
1039
	 */
1040
	public int getLevelFromRealCoords(Rectangle2D r, int width) throws RasterDriverException {
1041
		double scale = getScale(r, width);
1042
		WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
1043
		WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
1044
		return getLevelFromScale(scale, tileMatrixSet);
1045
	}
1046

  
1047
	/**
1048
	 * Gets the resolution level from the scale
1049
	 * @param scale
1050
	 * @param tileMatrixSet
1051
	 * @return
1052
	 * @throws RasterDriverException
1053
	 */
1054
	public int getLevelFromScale(double scale, WMTSTileMatrixSet tileMatrixSet) throws RasterDriverException {
1055
		//Recorremos los tileMatrix para obtener la escala m?s aproximada
1056
		int levelModifier = 0;
1057
		scale = math.adjustDouble(scale);
1058
		try {
1059
			for (int resolutionLevel = 0; resolutionLevel < tileMatrixSet.getTileMatrix().size(); resolutionLevel++) {
1060
				WMTSTileMatrix tm = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(resolutionLevel);
1061
				double scaleDenominator = math.adjustDouble(tm.getScaleDenominator());
1062
				if(scale >= scaleDenominator) {
1063
					return Math.max(resolutionLevel + levelModifier, 0);
1064
				}
1065
			}
1066
		} catch (IndexOutOfBoundsException e) {
1067
			throw new RasterDriverException("Error in this resolution level", e);
1068
		}
1069
		return 0;
1070
	}
1071

  
1072
	/**
1073
	 * Get the tile matrix set using the crs
1074
	 * @param srs
1075
	 * @return
1076
	 */
1077
	public WMTSTileMatrixSetLink getTileMatrixSetLink() {
1078
		WMTSDataParameters p = (WMTSDataParameters)param;
1079
		List<WMTSTileMatrixSetLink> tileMatrixSetLinkList = p.getLayer().getTileMatrixSetLink();
1080
		for (int i = 0; i < tileMatrixSetLinkList.size(); i++) {
1081
			WMTSTileMatrixSetLink tileMatrixSetLink = (WMTSTileMatrixSetLink)tileMatrixSetLinkList.get(i);
1082
			String srsTileSet = tileMatrixSetLink.getTileMatrixSet().getSupportedCRS();
1083
			if(srsTileSet.compareTo(p.getSRSCode()) == 0) {
1084
				return tileMatrixSetLink;
1085
			}
1086
		}
1087
		if(tileMatrixSetLinkList != null && tileMatrixSetLinkList.size() > 0)
1088
			return (WMTSTileMatrixSetLink)tileMatrixSetLinkList.get(0);
1089
		return null;
1090
	}
1091

  
1092
	/**
1093
	 * Gets the scale using the extent and the width in pixels.
1094
	 * @param r
1095
	 * @param width
1096
	 * @return
1097
	 */
1098
	private double getScale(Rectangle2D r, int width) {
1099
		WMTSDataParameters p = (WMTSDataParameters)param;
1100
		if(!p.isProjected()) {
1101
			return (r.getWidth() * MTS_X_GRADO) / (width * 0.00028);
1102
		} else
1103
			return (r.getWidth()) / (width * 0.00028);
1104
	}
1105

  
1106
	/**
1107
	 * Throw a request
1108
	 * @param status
1109
	 * @param bandList
1110
	 * @param listener
1111
	 * @param alphaBandNumber
1112
	 * @return returns a buffer if the listener is null. In any other case it return null.
1113
	 * @throws RasterDriverException
1114
	 * @throws ProcessInterruptedException
1115
	 */
1116
	private synchronized org.gvsig.raster.cache.tile.Tile[] request(
1117
			WMTSStatus status, BandList bandList, TileListener listener, int requestType) throws RasterDriverException, ProcessInterruptedException {
1118
		//WMTSDataParameters p = (WMTSDataParameters)param;
1119
		WMTSClient ogcClient = null;
1120
		try {
1121
			ogcClient = getOGCClient();
1122
		} catch (WMTSException e) {
1123
			throw new RasterDriverException("Error getting the connector object", e);
1124
		}
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff