gvsig-raster / 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 @ 234
History | View | Annotate | Download (30.8 KB)
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 java.awt.geom.AffineTransform; |
25 |
import java.awt.geom.NoninvertibleTransformException; |
26 |
import java.awt.geom.Point2D; |
27 |
import java.awt.geom.Rectangle2D; |
28 |
import java.io.File; |
29 |
import java.io.IOException; |
30 |
import java.net.URL; |
31 |
import java.util.ArrayList; |
32 |
import java.util.Hashtable; |
33 |
|
34 |
import org.gvsig.fmap.dal.DALLocator; |
35 |
import org.gvsig.fmap.dal.DataStore; |
36 |
import org.gvsig.fmap.dal.DataStoreParameters; |
37 |
import org.gvsig.fmap.dal.coverage.dataset.Buffer; |
38 |
import org.gvsig.fmap.dal.coverage.dataset.io.GdalProvider; |
39 |
import org.gvsig.fmap.dal.coverage.dataset.io.param.WMTSDataParametersImpl; |
40 |
import org.gvsig.fmap.dal.coverage.dataset.io.server.DefaultWMTSServerExplorerParameters; |
41 |
import org.gvsig.fmap.dal.coverage.dataset.io.server.WMTSServerExplorerImpl; |
42 |
import org.gvsig.fmap.dal.coverage.datastruct.BandList; |
43 |
import org.gvsig.fmap.dal.coverage.datastruct.Extent; |
44 |
import org.gvsig.fmap.dal.coverage.exception.BandAccessException; |
45 |
import org.gvsig.fmap.dal.coverage.exception.FileNotOpenException; |
46 |
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException; |
47 |
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException; |
48 |
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException; |
49 |
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException; |
50 |
import org.gvsig.fmap.dal.coverage.exception.WMSException; |
51 |
import org.gvsig.fmap.dal.coverage.explorer.WMTSServerExplorer; |
52 |
import org.gvsig.fmap.dal.coverage.grid.render.TileListener; |
53 |
import org.gvsig.fmap.dal.coverage.store.parameter.WMTSDataParameters; |
54 |
import org.gvsig.fmap.dal.coverage.store.props.Transparency; |
55 |
import org.gvsig.fmap.dal.spi.DataManagerProviderServices; |
56 |
import org.gvsig.fmap.dal.spi.DataStoreProviderServices; |
57 |
import org.gvsig.metadata.MetadataLocator; |
58 |
import org.gvsig.raster.impl.DefaultRasterManager; |
59 |
import org.gvsig.raster.impl.datastruct.ExtentImpl; |
60 |
import org.gvsig.raster.impl.provider.DefaultRasterProvider; |
61 |
import org.gvsig.raster.impl.provider.RasterProvider; |
62 |
import org.gvsig.raster.impl.provider.RemoteRasterProvider; |
63 |
import org.gvsig.raster.impl.store.AbstractRasterDataStore; |
64 |
import org.gvsig.raster.impl.store.DefaultStoreFactory; |
65 |
import org.gvsig.raster.impl.store.properties.DataStoreColorInterpretation; |
66 |
import org.gvsig.raster.impl.store.properties.DataStoreTransparency; |
67 |
import org.gvsig.remoteclient.exceptions.ServerErrorException; |
68 |
import org.gvsig.remoteclient.wmts.WMTSStatus; |
69 |
import org.gvsig.remoteclient.wmts.exception.WMTSException; |
70 |
import org.gvsig.remoteclient.wmts.struct.WMTSBoundingBox; |
71 |
import org.gvsig.remoteclient.wmts.struct.WMTSLayer; |
72 |
import org.gvsig.remoteclient.wmts.struct.WMTSTileMatrix; |
73 |
import org.gvsig.remoteclient.wmts.struct.WMTSTileMatrixLimits; |
74 |
import org.gvsig.remoteclient.wmts.struct.WMTSTileMatrixSet; |
75 |
import org.gvsig.remoteclient.wmts.struct.WMTSTileMatrixSetLink; |
76 |
import org.gvsig.remoteclient.wmts.struct.WMTSTileMatrix.Tile; |
77 |
import org.gvsig.tools.ToolsLocator; |
78 |
import org.gvsig.tools.extensionpoint.ExtensionPoint; |
79 |
import org.gvsig.tools.extensionpoint.ExtensionPointManager; |
80 |
/**
|
81 |
* Clase que representa al driver de acceso a datos de wmts.
|
82 |
*
|
83 |
* @author Nacho Brodin (nachobrodin@gmail.com)
|
84 |
*/
|
85 |
public class WMTSProvider extends DefaultRasterProvider implements RemoteRasterProvider { |
86 |
public static String NAME = "Wmts Store"; |
87 |
public static String DESCRIPTION = "Wmts Raster file"; |
88 |
public static final String METADATA_DEFINITION_NAME = "WmtsStore"; |
89 |
private static final double MTS_X_GRADO = 111319.490793274; |
90 |
|
91 |
private Extent viewRequest = null; |
92 |
private static Hashtable<URL, WMTSConnector> |
93 |
drivers = new Hashtable<URL, WMTSConnector> (); |
94 |
private boolean open = false; |
95 |
//Only for fixed size. Complete extent and FIXED_SIZE in long side
|
96 |
private File lastRequest = null; |
97 |
private DataStoreTransparency lastFileTransparency = null; |
98 |
private int lastWidthRequest = 0; |
99 |
private int lastHeightRequest = 0; |
100 |
private boolean gridSubsets = true; |
101 |
private Extent[] extentByLevel = null; //Only for layers without gridSubsets |
102 |
|
103 |
public static void register() { |
104 |
ExtensionPointManager extensionPoints = ToolsLocator.getExtensionPointManager(); |
105 |
ExtensionPoint point = extensionPoints.get("RasterReader");
|
106 |
point.append("wmts", "", WMTSProvider.class); |
107 |
|
108 |
DataManagerProviderServices dataman = (DataManagerProviderServices) DALLocator.getDataManager(); |
109 |
if (dataman != null && !dataman.getStoreProviders().contains(NAME)) { |
110 |
dataman.registerStoreProvider(NAME, |
111 |
WMTSProvider.class, WMTSDataParametersImpl.class); |
112 |
} |
113 |
|
114 |
if (!dataman.getExplorerProviders().contains(WMTSServerExplorerImpl.NAME)) {
|
115 |
dataman.registerExplorerProvider(WMTSServerExplorer.NAME, WMTSServerExplorerImpl.class, DefaultWMTSServerExplorerParameters.class); |
116 |
} |
117 |
dataman.registerStoreFactory(NAME, DefaultStoreFactory.class); |
118 |
} |
119 |
|
120 |
public WMTSProvider() throws NotSupportedExtensionException { |
121 |
super();
|
122 |
} |
123 |
|
124 |
/**
|
125 |
* Constructor. Abre el dataset.
|
126 |
* @param proj Proyecci?n
|
127 |
* @param fName Nombre del fichero
|
128 |
* @throws NotSupportedExtensionException
|
129 |
*/
|
130 |
public WMTSProvider(String params) throws NotSupportedExtensionException { |
131 |
super(params);
|
132 |
if(params instanceof String) { |
133 |
WMTSDataParametersImpl p = new WMTSDataParametersImpl();
|
134 |
p.setHost((String)params);
|
135 |
super.init(p, null, ToolsLocator.getDynObjectManager() |
136 |
.createDynObject( |
137 |
MetadataLocator.getMetadataManager().getDefinition( |
138 |
DataStore.METADATA_DEFINITION_NAME))); |
139 |
init(p, null);
|
140 |
} |
141 |
} |
142 |
|
143 |
public WMTSProvider(WMTSDataParametersImpl params,
|
144 |
AbstractRasterDataStore storeServices) throws NotSupportedExtensionException {
|
145 |
super(params, storeServices, ToolsLocator.getDynObjectManager()
|
146 |
.createDynObject( |
147 |
MetadataLocator.getMetadataManager().getDefinition( |
148 |
DataStore.METADATA_DEFINITION_NAME))); |
149 |
init(params, storeServices); |
150 |
} |
151 |
|
152 |
/**
|
153 |
* Gets the connector from the URL
|
154 |
* @return
|
155 |
* @throws WMSException
|
156 |
*/
|
157 |
private WMTSConnector getConnector() throws WMSException { |
158 |
WMTSDataParametersImpl p = (WMTSDataParametersImpl)parameters; |
159 |
URL url = null; |
160 |
try {
|
161 |
url = new URL(p.getHost()); |
162 |
} catch (Exception e) { |
163 |
throw new WMSException("Malformed URL",e); |
164 |
} |
165 |
try {
|
166 |
return WMTSProvider.getConnectorFromURL(url);
|
167 |
} catch (IOException e) { |
168 |
throw new WMSException("Error getting the connector",e); |
169 |
} |
170 |
} |
171 |
|
172 |
/**
|
173 |
* Crea las referencias al fichero y carga
|
174 |
* las estructuras con la informaci?n y los metadatos.
|
175 |
* @param proj Proyecci?n
|
176 |
* @param param Parametros de carga
|
177 |
* @throws NotSupportedExtensionException
|
178 |
*/
|
179 |
public void init (DataStoreParameters params, |
180 |
DataStoreProviderServices storeServices) throws NotSupportedExtensionException {
|
181 |
setParam(params); |
182 |
setDataType(new int[]{Buffer.TYPE_BYTE, Buffer.TYPE_BYTE, Buffer.TYPE_BYTE, Buffer.TYPE_BYTE}); |
183 |
bandCount = 4;
|
184 |
|
185 |
if(!(param instanceof WMTSDataParameters)) |
186 |
return;
|
187 |
|
188 |
gridSubsets = hasGridSubsets((WMTSDataParameters)param); |
189 |
} |
190 |
|
191 |
/**
|
192 |
* Checks if this layer has grid subsets or doesn't
|
193 |
* @param p
|
194 |
* @return
|
195 |
*/
|
196 |
@SuppressWarnings("unchecked") |
197 |
private boolean hasGridSubsets(WMTSDataParameters p) { |
198 |
ArrayList tileMatrixSetLimits = null; |
199 |
ArrayList<?> tileMatrixSetLinkList = p.getLayer().getTileMatrixSetLink();
|
200 |
String srs = p.getSRSCode();
|
201 |
for (int i = 0; i < tileMatrixSetLinkList.size(); i++) { |
202 |
WMTSTileMatrixSetLink tileMatrixSetLink = (WMTSTileMatrixSetLink)tileMatrixSetLinkList.get(i); |
203 |
WMTSTileMatrixSet tms = tileMatrixSetLink.getTileMatrixSet(); |
204 |
ArrayList tmsl = tileMatrixSetLink.getTileMatrixLimits();
|
205 |
String srsTileSet = tms.getSupportedCRS();
|
206 |
if(srsTileSet.compareTo(srs) == 0) { |
207 |
tileMatrixSetLimits = tmsl; |
208 |
} |
209 |
} |
210 |
|
211 |
return tileMatrixSetLimits.size() <= 0 ? false : true; |
212 |
} |
213 |
|
214 |
public static final WMTSConnector getConnectorFromURL(URL url) throws IOException { |
215 |
WMTSConnector drv = (WMTSConnector) drivers.get(url); |
216 |
if (drv == null) { |
217 |
drv = new WMTSConnector(url);
|
218 |
drivers.put(url, drv); |
219 |
} |
220 |
return drv;
|
221 |
} |
222 |
|
223 |
/**
|
224 |
* Obtiene el objeto que contiene que contiene la interpretaci?n de
|
225 |
* color por banda
|
226 |
* @return
|
227 |
*/
|
228 |
public DataStoreColorInterpretation getColorInterpretation() {
|
229 |
if(colorInterpretation == null) { |
230 |
colorInterpretation = new DataStoreColorInterpretation();
|
231 |
colorInterpretation.initColorInterpretation(getBandCount()); |
232 |
colorInterpretation.setColorInterpValue(0, DataStoreColorInterpretation.RED_BAND);
|
233 |
colorInterpretation.setColorInterpValue(1, DataStoreColorInterpretation.GREEN_BAND);
|
234 |
colorInterpretation.setColorInterpValue(2, DataStoreColorInterpretation.BLUE_BAND);
|
235 |
} |
236 |
return colorInterpretation;
|
237 |
} |
238 |
|
239 |
/*
|
240 |
* (non-Javadoc)
|
241 |
* @see org.gvsig.raster.impl.provider.RasterProvider#isTiled()
|
242 |
*/
|
243 |
public boolean isTiled() { |
244 |
return true; |
245 |
} |
246 |
|
247 |
/*
|
248 |
* (non-Javadoc)
|
249 |
* @see org.gvsig.fmap.dal.coverage.dataset.RasterDataSet#getAffineTransform()
|
250 |
*/
|
251 |
public AffineTransform getAffineTransform() { |
252 |
WMTSDataParametersImpl p = (WMTSDataParametersImpl)parameters; |
253 |
Extent e = getExtent(); |
254 |
double psX = e.width() / (lastWidthRequest <= 0 ? p.getWidth() : lastWidthRequest); |
255 |
double psY = -(e.height() / (lastHeightRequest <= 0 ? p.getHeight() : lastHeightRequest)); |
256 |
ownTransformation = new AffineTransform( |
257 |
psX, |
258 |
0,
|
259 |
0,
|
260 |
psY, |
261 |
e.getULX() - (psX / 2),
|
262 |
e.getULY() - (psY / 2));
|
263 |
externalTransformation = (AffineTransform) ownTransformation.clone();
|
264 |
return ownTransformation;
|
265 |
} |
266 |
|
267 |
/**
|
268 |
* Gets the bounding box in world coordinates. If the layer has grid subsets (TileMatrixLimits) then
|
269 |
* this will have a only extent but if the layer doesn't have grid subsets then this will have a different
|
270 |
* extent in each level resolution. In this case we need to know the extent for each level.
|
271 |
* @return Extent
|
272 |
*/
|
273 |
public Extent getExtent() {
|
274 |
WMTSDataParametersImpl p = (WMTSDataParametersImpl)parameters; |
275 |
if(gridSubsets) {
|
276 |
WMTSLayer layer = p.getLayer(); |
277 |
WMTSBoundingBox bbox = layer.getWGS84BBox(); |
278 |
return new ExtentImpl(bbox.toRectangle2D()); |
279 |
} else {
|
280 |
WMTSTileMatrixSet tileMatrixSet = getTileMatrixSetLink().getTileMatrixSet(); |
281 |
|
282 |
//Si ya se han calculado los niveles es q el extent es v?lido sino el nivel ser? el 0
|
283 |
double scale = 0D; |
284 |
int level = 0; |
285 |
if(extentByLevel != null && p.getExtent() != null) { |
286 |
scale = getScale(p.getExtent(), p.getWidth()); |
287 |
try {
|
288 |
level = getLevelFromScale(scale, tileMatrixSet); |
289 |
} catch (RasterDriverException e) {
|
290 |
e.printStackTrace(); |
291 |
} |
292 |
} |
293 |
|
294 |
Extent[] ext = getExtentByResolutionLevel();
|
295 |
|
296 |
if(ext != null && level >= 0 && level < ext.length) |
297 |
return ext[level];
|
298 |
} |
299 |
return null; |
300 |
} |
301 |
|
302 |
/**
|
303 |
* When a layer doesn't have grid subsets this will have a different bounding
|
304 |
* box by resolution level. This function calculates and returns the array of
|
305 |
* extents, one by resolution level.
|
306 |
* @return
|
307 |
*/
|
308 |
private Extent[] getExtentByResolutionLevel() { |
309 |
if(extentByLevel == null) { |
310 |
WMTSDataParametersImpl p = (WMTSDataParametersImpl)parameters; |
311 |
WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink(); |
312 |
WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet(); |
313 |
|
314 |
double widthMtsTile = 0; |
315 |
double heightMtsTile = 0; |
316 |
ArrayList<?> tileMatrixList = tileMatrixSet.getTileMatrix();
|
317 |
extentByLevel = new ExtentImpl[tileMatrixList.size()];
|
318 |
for (int i = 0; i < tileMatrixList.size(); i++) { |
319 |
WMTSTileMatrix tileMatrix = (WMTSTileMatrix)tileMatrixList.get(i); |
320 |
if(!p.getSRS().isProjected()) {
|
321 |
widthMtsTile = (tileMatrix.getScaleDenominator() * tileMatrix.getTileWidth() * 0.28) / (MTS_X_GRADO * 1000); |
322 |
heightMtsTile = (tileMatrix.getScaleDenominator() * tileMatrix.getTileWidth() * 0.28) / (MTS_X_GRADO * 1000); |
323 |
} else {
|
324 |
widthMtsTile = (tileMatrix.getScaleDenominator() * tileMatrix.getTileWidth() * 0.28) / 1000; |
325 |
heightMtsTile = (tileMatrix.getScaleDenominator() * tileMatrix.getTileWidth() * 0.28) / 1000; |
326 |
} |
327 |
|
328 |
double h = Math.abs(tileMatrix.getTopLeftCorner()[0] - (tileMatrix.getTopLeftCorner()[0] - (tileMatrix.getMatrixHeight() * heightMtsTile))); |
329 |
Rectangle2D r = new Rectangle2D.Double( |
330 |
tileMatrix.getTopLeftCorner()[1],
|
331 |
tileMatrix.getTopLeftCorner()[0] - h,
|
332 |
Math.abs(tileMatrix.getTopLeftCorner()[1] - (tileMatrix.getTopLeftCorner()[1] + (tileMatrix.getMatrixWidth() * widthMtsTile))), |
333 |
h); |
334 |
extentByLevel[i] = new ExtentImpl(r);
|
335 |
} |
336 |
|
337 |
} |
338 |
return extentByLevel;
|
339 |
} |
340 |
|
341 |
/*
|
342 |
* (non-Javadoc)
|
343 |
* @see org.gvsig.raster.impl.provider.RemoteRasterProvider#getLayerExtent(java.lang.String, java.lang.String)
|
344 |
*/
|
345 |
public Rectangle2D getLayerExtent(String layerName, String srs) throws WMSException { |
346 |
return null; |
347 |
} |
348 |
|
349 |
/*
|
350 |
* (non-Javadoc)
|
351 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#load()
|
352 |
*/
|
353 |
public RasterProvider load() {
|
354 |
return this; |
355 |
} |
356 |
|
357 |
/*
|
358 |
* (non-Javadoc)
|
359 |
* @see org.gvsig.raster.impl.provider.RasterProvider#isOpen()
|
360 |
*/
|
361 |
public boolean isOpen() { |
362 |
return open;
|
363 |
} |
364 |
|
365 |
/*
|
366 |
* (non-Javadoc)
|
367 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#close()
|
368 |
*/
|
369 |
public void close() { |
370 |
open = false;
|
371 |
} |
372 |
|
373 |
/*
|
374 |
* (non-Javadoc)
|
375 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getTransparency()
|
376 |
*/
|
377 |
public Transparency getTransparency() { |
378 |
if(lastFileTransparency == null) |
379 |
lastFileTransparency = new DataStoreTransparency();
|
380 |
return lastFileTransparency;
|
381 |
} |
382 |
|
383 |
/*
|
384 |
* (non-Javadoc)
|
385 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#translateFileName(java.lang.String)
|
386 |
*/
|
387 |
public String translateFileName(String fileName) { |
388 |
return fileName;
|
389 |
} |
390 |
|
391 |
/*
|
392 |
* (non-Javadoc)
|
393 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#setView(org.gvsig.fmap.dal.coverage.datastruct.Extent)
|
394 |
*/
|
395 |
public void setView(Extent e) { |
396 |
viewRequest = e; |
397 |
} |
398 |
|
399 |
/*
|
400 |
* (non-Javadoc)
|
401 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getView()
|
402 |
*/
|
403 |
public Extent getView() {
|
404 |
return viewRequest;
|
405 |
} |
406 |
|
407 |
/*
|
408 |
* (non-Javadoc)
|
409 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWidth()
|
410 |
*/
|
411 |
public double getWidth() { |
412 |
WMTSDataParametersImpl p = (WMTSDataParametersImpl)parameters; |
413 |
if (lastWidthRequest <= 0) |
414 |
return p.getWidth();
|
415 |
return lastWidthRequest;
|
416 |
} |
417 |
|
418 |
/*
|
419 |
* (non-Javadoc)
|
420 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getHeight()
|
421 |
*/
|
422 |
public double getHeight() { |
423 |
WMTSDataParametersImpl p = (WMTSDataParametersImpl)parameters; |
424 |
if (lastHeightRequest <= 0) |
425 |
return p.getHeight();
|
426 |
return lastHeightRequest;
|
427 |
} |
428 |
|
429 |
/*
|
430 |
* (non-Javadoc)
|
431 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#readCompleteLine(int, int)
|
432 |
*/
|
433 |
public Object readCompleteLine(int line, int band) |
434 |
throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
|
435 |
return null; |
436 |
} |
437 |
|
438 |
/**
|
439 |
* When the remote layer has fixed size this method downloads the file and return its reference.
|
440 |
* File layer has in the long side FIXED_SIZE pixels and the bounding box is complete. This file could be
|
441 |
* useful to build an histogram or calculate statistics. This represents a sample of data.
|
442 |
* @return
|
443 |
* @throws RasterDriverException
|
444 |
*/
|
445 |
public File getFileLayer() throws RasterDriverException { |
446 |
return null; |
447 |
} |
448 |
|
449 |
/**
|
450 |
* Reads a complete block of data and returns an tridimensional array of the right type. This function is useful
|
451 |
* to read a file very fast without setting a view. In a WMS service when the size is fixed then it will read the
|
452 |
* entire image but when the source hasn't pixel size it will read a sample of data. This set of data will have
|
453 |
* the size defined in FIXED_SIZE.
|
454 |
*
|
455 |
* @param pos Posici?n donde se empieza a leer
|
456 |
* @param blockHeight Altura m?xima del bloque leido
|
457 |
* @return Object que es un array tridimendional del tipo de datos del raster. (Bandas X Filas X Columnas)
|
458 |
* @throws InvalidSetViewException
|
459 |
* @throws FileNotOpenException
|
460 |
* @throws RasterDriverException
|
461 |
*/
|
462 |
public Object readBlock(int pos, int blockHeight) |
463 |
throws InvalidSetViewException, FileNotOpenException, RasterDriverException, ProcessInterruptedException {
|
464 |
return null; |
465 |
} |
466 |
|
467 |
/*
|
468 |
* (non-Javadoc)
|
469 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getData(int, int, int)
|
470 |
*/
|
471 |
public Object getData(int x, int y, int band) |
472 |
throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
|
473 |
return null; |
474 |
} |
475 |
|
476 |
/**
|
477 |
* Assigns the list of bands RGB and read a window of data
|
478 |
* @param rasterBuf
|
479 |
* @param bandList
|
480 |
* @param lastFile
|
481 |
* @param ulx
|
482 |
* @param uly
|
483 |
* @param lrx
|
484 |
* @param lry
|
485 |
* @return
|
486 |
* @throws RasterDriverException
|
487 |
* @throws ProcessInterruptedException
|
488 |
*/
|
489 |
public Buffer getBuffer(Buffer rasterBuf, BandList bandList, File lastFile, |
490 |
double ulx, double uly, double lrx, double lry) throws RasterDriverException, ProcessInterruptedException { |
491 |
return null; |
492 |
} |
493 |
|
494 |
/*
|
495 |
* (non-Javadoc)
|
496 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWindowRaster(double, double, double, double, int, int, org.gvsig.fmap.dal.coverage.datastruct.BandList, org.gvsig.fmap.dal.coverage.dataset.Buffer, org.gvsig.fmap.dal.coverage.grid.render.TileListener, int)
|
497 |
*/
|
498 |
public void getWindowRaster(double minX, double minY, double maxX, double maxY, |
499 |
int bufWidth, int bufHeight, BandList bandList, TileListener listener)throws ProcessInterruptedException, RasterDriverException { |
500 |
Rectangle2D r = new Rectangle2D.Double(Math.min(minX, maxX), Math.min(minY, maxY), Math.abs(maxX - minX), Math.abs(maxY - minY)); |
501 |
WMTSStatus status = buildWMTSStatus(r, bufWidth, bufHeight); |
502 |
request(status, bandList, listener); |
503 |
} |
504 |
|
505 |
/**
|
506 |
* Builds the WMTSStatus object using the parameters and the request bounding box.
|
507 |
* @param r
|
508 |
* @param bufWidth
|
509 |
* @return
|
510 |
* @throws RasterDriverException
|
511 |
*/
|
512 |
@SuppressWarnings("unchecked") |
513 |
private WMTSStatus buildWMTSStatus(Rectangle2D r, int bufWidth, int bufHeight) throws RasterDriverException { |
514 |
WMTSDataParameters p = (WMTSDataParameters)param; |
515 |
|
516 |
//Mantiene actualizados los par?metros del WMTSStoreParameters con la ?ltima petici?n hecha
|
517 |
p.setExtent(r); |
518 |
p.setWidth(bufWidth); |
519 |
p.setHeight(bufHeight); |
520 |
|
521 |
lastWidthRequest = bufWidth; |
522 |
lastHeightRequest = bufHeight; |
523 |
|
524 |
//1-Selecci?n de WMTSTileMatrixSet por srs
|
525 |
WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink(); |
526 |
WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet(); |
527 |
ArrayList tileMatrixSetLimits = tileMatrixSetLink.getTileMatrixLimits();
|
528 |
|
529 |
//2-Calculo de la escala
|
530 |
double scale = getScale(r, bufWidth);
|
531 |
|
532 |
//3-Selecci?n del nivel a partir de la escala
|
533 |
int level = getLevelFromScale(scale, tileMatrixSet);
|
534 |
|
535 |
//4-Obtenemos la matriz de tiles y los l?mites si tiene subsets
|
536 |
WMTSTileMatrixLimits tileMatrixLimits = null;
|
537 |
WMTSTileMatrix tileMatrix = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(level); |
538 |
if(gridSubsets)
|
539 |
tileMatrixLimits = (WMTSTileMatrixLimits)tileMatrixSetLimits.get(level); |
540 |
|
541 |
//5-Selecci?n de tiles que entran en esta bounding box
|
542 |
ArrayList<Tile> tiles = null; |
543 |
if(gridSubsets)
|
544 |
tiles = tileMatrix.intersects(p.getSRS().isProjected(), tileMatrixLimits, r, getExtent().toRectangle2D()); |
545 |
else
|
546 |
tiles = tileMatrix.intersects(p.getSRS().isProjected(), r, getExtent().toRectangle2D()); |
547 |
|
548 |
//6-Petici?n
|
549 |
WMTSStatus status = new WMTSStatus();
|
550 |
status.setTileList(tiles); |
551 |
status.setLayer(p.getLayer().getIdentifier()); |
552 |
status.setFormat(p.getImageFormat()); |
553 |
status.setStyle(p.getStyle() != null ? p.getStyle().getIdentifier() : ""); |
554 |
status.setTileMatrixSet(tileMatrixSet.getIdentifier()); |
555 |
status.setTileMatrix(tileMatrix.getIdentifier()); |
556 |
return status;
|
557 |
} |
558 |
|
559 |
/**
|
560 |
* Gets the resolution level from the scale
|
561 |
* @param scale
|
562 |
* @param tileMatrixSet
|
563 |
* @return
|
564 |
* @throws RasterDriverException
|
565 |
*/
|
566 |
public int getLevelFromScale(double scale, WMTSTileMatrixSet tileMatrixSet) throws RasterDriverException { |
567 |
//Recorremos los tileMatrix para obtener la escala m?s aproximada
|
568 |
int levelModifier = 0; |
569 |
try {
|
570 |
for (int resolutionLevel = 0; resolutionLevel < tileMatrixSet.getTileMatrix().size(); resolutionLevel++) { |
571 |
WMTSTileMatrix tm = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(resolutionLevel); |
572 |
double scaleDenominator = tm.getScaleDenominator();
|
573 |
if(scale >= scaleDenominator) {
|
574 |
return Math.max(resolutionLevel + levelModifier, 0); |
575 |
} |
576 |
} |
577 |
} catch (IndexOutOfBoundsException e) { |
578 |
throw new RasterDriverException("Error in this resolution level", e); |
579 |
} |
580 |
return 0; |
581 |
} |
582 |
|
583 |
/**
|
584 |
* Get the tile matrix set using the crs
|
585 |
* @param srs
|
586 |
* @return
|
587 |
*/
|
588 |
private WMTSTileMatrixSetLink getTileMatrixSetLink() {
|
589 |
WMTSDataParameters p = (WMTSDataParameters)param; |
590 |
ArrayList<?> tileMatrixSetLinkList = p.getLayer().getTileMatrixSetLink();
|
591 |
for (int i = 0; i < tileMatrixSetLinkList.size(); i++) { |
592 |
WMTSTileMatrixSetLink tileMatrixSetLink = (WMTSTileMatrixSetLink)tileMatrixSetLinkList.get(i); |
593 |
String srsTileSet = tileMatrixSetLink.getTileMatrixSet().getSupportedCRS();
|
594 |
if(srsTileSet.compareTo(p.getSRSCode()) == 0) { |
595 |
return tileMatrixSetLink;
|
596 |
} |
597 |
} |
598 |
if(tileMatrixSetLinkList != null && tileMatrixSetLinkList.size() > 0) |
599 |
return (WMTSTileMatrixSetLink)tileMatrixSetLinkList.get(0); |
600 |
return null; |
601 |
} |
602 |
|
603 |
/**
|
604 |
* Gets the scale using the extent and the width in pixels.
|
605 |
* @param r
|
606 |
* @param width
|
607 |
* @return
|
608 |
*/
|
609 |
private double getScale(Rectangle2D r, int width) { |
610 |
WMTSDataParameters p = (WMTSDataParameters)param; |
611 |
if(!p.getSRS().isProjected()) {
|
612 |
return (1000 * r.getWidth() * MTS_X_GRADO) / (width * 0.28); |
613 |
} else
|
614 |
return (1000 * r.getWidth()) / (width * 0.28); |
615 |
} |
616 |
|
617 |
/**
|
618 |
* Throw a request
|
619 |
* @param status
|
620 |
* @param bandList
|
621 |
* @param listener
|
622 |
* @param alphaBandNumber
|
623 |
* @return returns a buffer if the listener is null. In any other case it return null.
|
624 |
* @throws RasterDriverException
|
625 |
* @throws ProcessInterruptedException
|
626 |
*/
|
627 |
@SuppressWarnings("unchecked") |
628 |
private Buffer request(WMTSStatus status, BandList bandList, TileListener listener) throws RasterDriverException, ProcessInterruptedException { |
629 |
WMTSDataParameters p = (WMTSDataParameters)param; |
630 |
WMTSConnector connector = null;
|
631 |
try {
|
632 |
connector = getConnector(); |
633 |
} catch (WMSException e) {
|
634 |
throw new RasterDriverException("Error getting the connector object", e); |
635 |
} |
636 |
|
637 |
if(connector == null) |
638 |
throw new RasterDriverException("Error getting the connector object"); |
639 |
|
640 |
ArrayList<Tile> tiles = status.getTileList();
|
641 |
|
642 |
for (int i = 0; i < tiles.size(); i++) { |
643 |
Tile tile = tiles.get(i); |
644 |
status.setTileRow(tile.row); |
645 |
status.setTileCol(tile.col); |
646 |
//TODO:Cancelaci?n
|
647 |
try {
|
648 |
File file = connector.getTile(status, null); |
649 |
|
650 |
String serverName = bandList.getBand(0).getFileName(); |
651 |
for (int j = 0; j < bandList.getBandCount(); j++) { |
652 |
bandList.getBand(j).setFileName(file.getPath()); |
653 |
} |
654 |
|
655 |
GdalProvider driver = new GdalProvider(file.getPath());
|
656 |
bandCount = driver.getBandCount(); |
657 |
lastFileTransparency = driver.getTransparency(); |
658 |
Buffer rasterBuf = DefaultRasterManager.getInstance().createBuffer(getDataType()[0], tile.wPx, tile.hPx, 3, true); |
659 |
Buffer buf = driver.getWindowRaster(0, 0, tile.wPx, tile.hPx, bandList, rasterBuf); |
660 |
|
661 |
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))); |
662 |
|
663 |
Buffer alphaBand = null; |
664 |
if(p.getAlphaBand() != -1 && listener != null) { |
665 |
alphaBand = DefaultRasterManager.getInstance().createBuffer(getDataType()[0], tile.wPx, tile.hPx, 1, true); |
666 |
int[] oldDB = bandList.getDrawableBands(); |
667 |
bandList.setDrawableBands(new int[]{p.getAlphaBand()}); |
668 |
alphaBand = driver.getWindowRaster(0, 0, tile.wPx, tile.hPx, bandList, alphaBand); |
669 |
bandList.setDrawableBands(oldDB); |
670 |
} |
671 |
|
672 |
for (int j = 0; j < bandList.getBandCount(); j++) { |
673 |
bandList.getBand(j).setFileName(serverName); |
674 |
} |
675 |
|
676 |
driver.close(); |
677 |
|
678 |
if(listener != null) |
679 |
listener.nextBuffer(buf, alphaBand, new ExtentImpl(tile.ulx, tile.uly, tile.lrx, tile.lry), getAffineTransform(), null, true); |
680 |
else
|
681 |
return buf;
|
682 |
|
683 |
} catch (WMTSException e) {
|
684 |
throw new RasterDriverException("Error getting tiles", e); |
685 |
} catch (ServerErrorException e) {
|
686 |
throw new RasterDriverException("Error getting tiles", e); |
687 |
} catch (NotSupportedExtensionException e) {
|
688 |
throw new RasterDriverException("Error getting tiles", e); |
689 |
} |
690 |
} |
691 |
if(listener != null) |
692 |
listener.endReading(); |
693 |
return null; |
694 |
} |
695 |
|
696 |
/*
|
697 |
* (non-Javadoc)
|
698 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWindowRaster(double, double, double, double, org.gvsig.fmap.dal.coverage.datastruct.BandList, org.gvsig.fmap.dal.coverage.dataset.Buffer)
|
699 |
*/
|
700 |
public Buffer getWindowRaster(double ulx, double uly, double lrx, double lry, |
701 |
BandList bandList, Buffer rasterBuf) throws ProcessInterruptedException, RasterDriverException { |
702 |
lastWidthRequest = rasterBuf.getWidth(); |
703 |
lastHeightRequest = rasterBuf.getHeight(); |
704 |
return null; |
705 |
} |
706 |
|
707 |
/*
|
708 |
* (non-Javadoc)
|
709 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWindowRaster(double, double, double, double, org.gvsig.fmap.dal.coverage.datastruct.BandList, org.gvsig.fmap.dal.coverage.dataset.Buffer, boolean)
|
710 |
*/
|
711 |
public Buffer getWindowRaster(double ulx, double uly, double w, double h, |
712 |
BandList bandList, Buffer rasterBuf, boolean adjustToExtent) throws ProcessInterruptedException, RasterDriverException { |
713 |
lastWidthRequest = rasterBuf.getWidth(); |
714 |
lastHeightRequest = rasterBuf.getHeight(); |
715 |
return null; |
716 |
} |
717 |
|
718 |
/*
|
719 |
* (non-Javadoc)
|
720 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWindowRaster(double, double, double, double, int, int, org.gvsig.fmap.dal.coverage.datastruct.BandList, org.gvsig.fmap.dal.coverage.dataset.Buffer, boolean)
|
721 |
*/
|
722 |
public Buffer getWindowRaster(double ulx, double uly, double lrx, double lry, |
723 |
int bufWidth, int bufHeight, BandList bandList, Buffer rasterBuf, boolean adjustToExtent) throws ProcessInterruptedException, RasterDriverException { |
724 |
Rectangle2D r = new Rectangle2D.Double(Math.min(ulx, lrx), Math.min(lry, uly), Math.abs(lrx - ulx), Math.abs(uly - lry)); |
725 |
WMTSStatus status = buildWMTSStatus(r, bufWidth, bufHeight); |
726 |
return request(status, bandList, null); |
727 |
} |
728 |
|
729 |
/*
|
730 |
* (non-Javadoc)
|
731 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWindowRaster(int, int, int, int, org.gvsig.fmap.dal.coverage.datastruct.BandList, org.gvsig.fmap.dal.coverage.dataset.Buffer)
|
732 |
*/
|
733 |
public Buffer getWindowRaster(int x, int y, int w, int h, BandList bandList, Buffer rasterBuf) throws ProcessInterruptedException, RasterDriverException { |
734 |
lastWidthRequest = rasterBuf.getWidth(); |
735 |
lastHeightRequest = rasterBuf.getHeight(); |
736 |
return null; |
737 |
} |
738 |
|
739 |
/*
|
740 |
* (non-Javadoc)
|
741 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWindowRaster(int, int, int, int, int, int, org.gvsig.fmap.dal.coverage.datastruct.BandList, org.gvsig.fmap.dal.coverage.dataset.Buffer)
|
742 |
*/
|
743 |
public Buffer getWindowRaster(int x, int y, int w, int h, int bufWidth, int bufHeight, BandList bandList, Buffer rasterBuf) throws ProcessInterruptedException, RasterDriverException { |
744 |
lastWidthRequest = rasterBuf.getWidth(); |
745 |
lastHeightRequest = rasterBuf.getHeight(); |
746 |
return null; |
747 |
} |
748 |
|
749 |
/*
|
750 |
* (non-Javadoc)
|
751 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getBlockSize()
|
752 |
*/
|
753 |
public int getBlockSize() { |
754 |
return 0; |
755 |
} |
756 |
|
757 |
/*
|
758 |
* (non-Javadoc)
|
759 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#setAffineTransform(java.awt.geom.AffineTransform)
|
760 |
*/
|
761 |
public void setAffineTransform(AffineTransform t){ |
762 |
|
763 |
} |
764 |
|
765 |
/*
|
766 |
* (non-Javadoc)
|
767 |
* @see org.gvsig.raster.impl.provider.RasterProvider#getOverviewCount(int)
|
768 |
*/
|
769 |
public int getOverviewCount(int band) throws BandAccessException, RasterDriverException { |
770 |
return 0; |
771 |
} |
772 |
|
773 |
/*
|
774 |
* (non-Javadoc)
|
775 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getOverviewWidth(int, int)
|
776 |
*/
|
777 |
public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException { |
778 |
return 0; |
779 |
} |
780 |
|
781 |
/*
|
782 |
* (non-Javadoc)
|
783 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getOverviewHeight(int, int)
|
784 |
*/
|
785 |
public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException { |
786 |
return 0; |
787 |
} |
788 |
|
789 |
/*
|
790 |
* (non-Javadoc)
|
791 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#overviewsSupport()
|
792 |
*/
|
793 |
public boolean overviewsSupport() { |
794 |
return false; |
795 |
} |
796 |
|
797 |
/*
|
798 |
* (non-Javadoc)
|
799 |
* @see org.gvsig.raster.impl.provider.DefaultRasterProvider#isReproyectable()
|
800 |
*/
|
801 |
public boolean isReproyectable() { |
802 |
return false; |
803 |
} |
804 |
|
805 |
/*
|
806 |
* (non-Javadoc)
|
807 |
* @see org.gvsig.fmap.dal.raster.spi.CoverageStoreProvider#getName()
|
808 |
*/
|
809 |
public String getName() { |
810 |
return NAME;
|
811 |
} |
812 |
|
813 |
/**
|
814 |
* Convierte un punto desde coordenadas pixel a coordenadas del mundo.
|
815 |
* @param pt Punto a transformar
|
816 |
* @return punto transformado en coordenadas del mundo
|
817 |
*/
|
818 |
public Point2D rasterToWorld(Point2D pt) { |
819 |
Point2D p = new Point2D.Double(); |
820 |
getAffineTransform().transform(pt, p); |
821 |
return p;
|
822 |
} |
823 |
|
824 |
/**
|
825 |
* Convierte un punto desde del mundo a coordenadas pixel.
|
826 |
* @param pt Punto a transformar
|
827 |
* @return punto transformado en coordenadas pixel
|
828 |
*/
|
829 |
public Point2D worldToRaster(Point2D pt) { |
830 |
Point2D p = new Point2D.Double(); |
831 |
try {
|
832 |
getAffineTransform().inverseTransform(pt, p); |
833 |
} catch (NoninvertibleTransformException e) { |
834 |
return pt;
|
835 |
} |
836 |
return p;
|
837 |
} |
838 |
|
839 |
/*
|
840 |
* (non-Javadoc)
|
841 |
* @see org.gvsig.raster.impl.provider.RasterProvider#setStatus(org.gvsig.raster.impl.provider.RasterProvider)
|
842 |
*/
|
843 |
public void setStatus(RasterProvider provider) { |
844 |
if(provider instanceof WMTSProvider) { |
845 |
} |
846 |
} |
847 |
|
848 |
/*
|
849 |
* (non-Javadoc)
|
850 |
* @see org.gvsig.raster.impl.provider.RemoteRasterProvider#getLastRequest()
|
851 |
*/
|
852 |
public File getLastRequest() { |
853 |
return lastRequest;
|
854 |
} |
855 |
|
856 |
/**
|
857 |
* ASigna el par?metro de inicializaci?n del driver.
|
858 |
*/
|
859 |
@Override
|
860 |
public void setParam(DataStoreParameters param) { |
861 |
if(param instanceof WMTSDataParameters) |
862 |
this.name = ((WMTSDataParameters)param).getHost();
|
863 |
this.param = param;
|
864 |
} |
865 |
|
866 |
} |