gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster.2.4 / org.gvsig.wms / org.gvsig.wms.provider / src / main / java / org / gvsig / wms / provider / WMSRasterProvider.java @ 8841
History | View | Annotate | Download (17.4 KB)
1 |
package org.gvsig.wms.provider; |
---|---|
2 |
|
3 |
import java.awt.Image; |
4 |
import java.awt.geom.Rectangle2D; |
5 |
import java.awt.image.BufferedImage; |
6 |
import java.io.File; |
7 |
import java.io.IOException; |
8 |
import java.net.URL; |
9 |
import java.util.HashMap; |
10 |
import java.util.Iterator; |
11 |
import java.util.List; |
12 |
import java.util.Map; |
13 |
import java.util.Vector; |
14 |
|
15 |
import javax.imageio.ImageIO; |
16 |
|
17 |
import org.cresques.cts.ICoordTrans; |
18 |
import org.cresques.cts.IProjection; |
19 |
import org.slf4j.Logger; |
20 |
import org.slf4j.LoggerFactory; |
21 |
|
22 |
import org.gvsig.compat.CompatLocator; |
23 |
import org.gvsig.compat.net.Downloader; |
24 |
import org.gvsig.fmap.crs.CRSFactory; |
25 |
import org.gvsig.fmap.dal.DALLocator; |
26 |
import org.gvsig.fmap.dal.DataManager; |
27 |
import org.gvsig.fmap.dal.DataServerExplorer; |
28 |
import org.gvsig.fmap.dal.DataServerExplorerParameters; |
29 |
import org.gvsig.fmap.dal.DataStore; |
30 |
import org.gvsig.fmap.dal.DataStoreParameters; |
31 |
import org.gvsig.fmap.dal.FileHelper; |
32 |
import org.gvsig.fmap.dal.exception.InitializeException; |
33 |
import org.gvsig.fmap.dal.exception.OpenException; |
34 |
import org.gvsig.fmap.dal.exception.ReadException; |
35 |
import org.gvsig.fmap.dal.exception.ValidateDataParametersException; |
36 |
import org.gvsig.fmap.dal.raster.api.BandQuery; |
37 |
import org.gvsig.fmap.dal.raster.api.RasterQuery; |
38 |
import org.gvsig.fmap.dal.raster.spi.AbstractRasterStoreProvider; |
39 |
import org.gvsig.fmap.dal.raster.spi.BandDescriptorServices; |
40 |
import org.gvsig.fmap.dal.resource.spi.ResourceProvider; |
41 |
import org.gvsig.fmap.dal.spi.DataStoreProviderServices; |
42 |
import org.gvsig.fmap.geom.Geometry.DIMENSIONS; |
43 |
import org.gvsig.fmap.geom.Geometry.SUBTYPES; |
44 |
import org.gvsig.fmap.geom.GeometryLocator; |
45 |
import org.gvsig.fmap.geom.GeometryManager; |
46 |
import org.gvsig.fmap.geom.exception.CreateEnvelopeException; |
47 |
import org.gvsig.fmap.geom.primitive.Envelope; |
48 |
import org.gvsig.metadata.MetadataLocator; |
49 |
import org.gvsig.metadata.MetadataManager; |
50 |
import org.gvsig.metadata.exceptions.MetadataException; |
51 |
import org.gvsig.raster.lib.buffer.api.Buffer; |
52 |
import org.gvsig.raster.lib.buffer.api.BufferDimensions; |
53 |
import org.gvsig.raster.lib.buffer.api.BufferLocator; |
54 |
import org.gvsig.raster.lib.buffer.api.BufferManager; |
55 |
import org.gvsig.raster.lib.buffer.api.NoData; |
56 |
import org.gvsig.raster.lib.buffer.api.TileStruct; |
57 |
import org.gvsig.raster.lib.buffer.api.exceptions.BufferException; |
58 |
import org.gvsig.raster.lib.buffer.spi.DefaultTileStruct; |
59 |
import org.gvsig.remoteclient.exceptions.ServerErrorException; |
60 |
import org.gvsig.remoteclient.exceptions.WMSException; |
61 |
import org.gvsig.remoteclient.wms.WMSClient; |
62 |
import org.gvsig.remoteclient.wms.WMSStatus; |
63 |
import org.gvsig.remoteclient.wms.WMSStyle; |
64 |
import org.gvsig.tools.dataTypes.DataTypes; |
65 |
import org.gvsig.tools.dispose.Disposable; |
66 |
import org.gvsig.tools.dispose.DisposeUtils; |
67 |
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException; |
68 |
import org.gvsig.tools.exception.BaseException; |
69 |
import org.gvsig.tools.locator.LocatorException; |
70 |
|
71 |
/**
|
72 |
* @author fdiaz
|
73 |
*
|
74 |
*/
|
75 |
public class WMSRasterProvider extends AbstractRasterStoreProvider { |
76 |
|
77 |
private static final Logger logger = LoggerFactory.getLogger(WMSRasterProvider.class); |
78 |
|
79 |
public static String NAME = "WMS"; |
80 |
public static String DESCRIPTION = "WMS Raster Provider"; |
81 |
public static final String METADATA_DEFINITION_NAME = "WMS"; |
82 |
|
83 |
public static final int DEFAULT_BUFFER_SIZE = 1024; |
84 |
public static final int MAX_ZOOM_LEVEL = 22; |
85 |
|
86 |
// WMS Parameters
|
87 |
private WMSClient wmsClient;
|
88 |
private WMSStatus wmsStatus;
|
89 |
|
90 |
private Envelope envelope = null; |
91 |
|
92 |
private IProjection projection = null; |
93 |
|
94 |
private int calculatedMaxZoomLevel = MAX_ZOOM_LEVEL; |
95 |
|
96 |
private TileStruct tileStruct;
|
97 |
|
98 |
protected WMSRasterProvider(DataStoreParameters params, DataStoreProviderServices storeServices) throws InitializeException { |
99 |
super(params, storeServices, FileHelper.newMetadataContainer(METADATA_DEFINITION_NAME));
|
100 |
initParams(); |
101 |
} |
102 |
|
103 |
private void initParams() throws InitializeException { |
104 |
WMSRasterProviderParameters parameters = (WMSRasterProviderParameters) getParameters(); |
105 |
|
106 |
URL service = parameters.getService();
|
107 |
boolean override = (Boolean)(parameters.getDynValue(WMSRasterProviderParameters.WMS_OVERRIDE_CAPABILITIES_PARAMETER_NAME)); |
108 |
|
109 |
try {
|
110 |
wmsClient = new WMSClient(service.toString());
|
111 |
} catch (IOException e) { |
112 |
throw new InitializeException("Can't create WMSClient with host '"+service+"'", e); |
113 |
} |
114 |
wmsStatus = new WMSStatus();
|
115 |
|
116 |
// Setting the envelope for the layer
|
117 |
wmsClient.getCapabilities(wmsStatus, override, null);
|
118 |
|
119 |
@SuppressWarnings("unchecked") |
120 |
List<String> layerNames = |
121 |
(List<String>) parameters.getDynValue(WMSRasterProviderParameters.WMS_LAYERS_PARAMETER_NAME); |
122 |
for (Iterator<String> iterator = layerNames.iterator(); iterator.hasNext();) { |
123 |
String layerName = (String) iterator.next(); |
124 |
wmsStatus.addLayerName(layerName); |
125 |
} |
126 |
|
127 |
String[] arrayLayerNames = layerNames.toArray(new String[layerNames.size()]); |
128 |
Rectangle2D extent = wmsClient.getLayersExtent(arrayLayerNames, getProjection().getAbrev());
|
129 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
130 |
if (extent == null) { |
131 |
String latLonID = "EPSG:4326"; |
132 |
extent = wmsClient.getLayersExtent(arrayLayerNames, latLonID); |
133 |
if (extent == null) { |
134 |
extent = wmsClient.getLayersExtent(arrayLayerNames, "CRS:84");
|
135 |
} |
136 |
|
137 |
IProjection reqProj = getProjection(); //CRSFactory.getCRS(p.getSRSCode());
|
138 |
IProjection latLonProj = CRSFactory.getCRS(latLonID); |
139 |
if ((reqProj != null) && (latLonProj != null)) { |
140 |
ICoordTrans ct = latLonProj.getCT(reqProj); |
141 |
Rectangle2D reprojectedRect = ct.convert(extent);
|
142 |
extent = reprojectedRect; |
143 |
} |
144 |
} |
145 |
|
146 |
if (extent != null) { |
147 |
try {
|
148 |
this.envelope =
|
149 |
geomManager.createEnvelope(extent.getMinX(), extent.getMinY(), extent.getMaxX(), extent.getMaxY(), |
150 |
SUBTYPES.GEOM2D); |
151 |
} catch (CreateEnvelopeException e) {
|
152 |
throw new InitializeException("Can't create envenlope.", e); |
153 |
|
154 |
} |
155 |
} |
156 |
|
157 |
@SuppressWarnings("unchecked") |
158 |
List<WMSStyle> wmsStyles =
|
159 |
(List<WMSStyle>) parameters.getDynValue(WMSRasterProviderParameters.WMS_STYLES_PARAMETER_NAME);
|
160 |
wmsStatus.setStyles(new Vector<WMSStyle>(wmsStyles)); |
161 |
wmsStatus.setFormat((String) parameters.getDynValue(WMSRasterProviderParameters.WMS_FORMAT_PARAMETER_NAME));
|
162 |
wmsStatus.setInfoFormat((String) parameters.getDynValue(WMSRasterProviderParameters.WMS_INFO_FORMAT_PARAMETER_NAME));
|
163 |
Boolean xyAxisOrder = (Boolean) parameters.getDynValue(WMSRasterProviderParameters.WMS_XYAXISORDER_PARAMETER_NAME); |
164 |
if(xyAxisOrder!=null && xyAxisOrder.booleanValue()){ |
165 |
wmsStatus.setXyAxisOrder(xyAxisOrder); |
166 |
} |
167 |
projection = (IProjection) (parameters.getDynValue(WMSRasterProviderParameters.WMS_CRS_PARAMETER_NAME)); |
168 |
wmsStatus.setSrs(projection.getAbrev()); |
169 |
Boolean transparency = (Boolean) parameters.getDynValue(WMSRasterProviderParameters.WMS_TRANSPARENCY_PARAMETER_NAME); |
170 |
if(transparency!=null && transparency.booleanValue()){ |
171 |
wmsStatus.setTransparency(transparency); |
172 |
} |
173 |
|
174 |
} |
175 |
|
176 |
protected static void registerMetadataDefinition() throws MetadataException { |
177 |
MetadataManager manager = MetadataLocator.getMetadataManager(); |
178 |
if (manager.getDefinition(METADATA_DEFINITION_NAME) == null) { |
179 |
manager.addDefinition(METADATA_DEFINITION_NAME, |
180 |
WMSRasterProviderParameters.class.getResourceAsStream("WMSRasterMetadata.xml"),
|
181 |
WMSRasterProviderParameters.class.getClassLoader()); |
182 |
} |
183 |
} |
184 |
|
185 |
@Override
|
186 |
public Buffer createBuffer(RasterQuery rasterQuery) throws BufferException { |
187 |
|
188 |
BufferManager bufferManager = BufferLocator.getBufferManager(); |
189 |
int[] bandDataTypes; |
190 |
NoData[] bandNoData;
|
191 |
//
|
192 |
if (!rasterQuery.getBands().isEmpty()) {
|
193 |
List<BandQuery> bands;
|
194 |
bands = rasterQuery.getBands(); |
195 |
bandDataTypes = new int[bands.size()]; |
196 |
bandNoData = new NoData[bands.size()];
|
197 |
|
198 |
for (BandQuery bandQuery : bands) {
|
199 |
int band = bandQuery.getBand();
|
200 |
bandDataTypes[band] = this.getBandDescriptor(band).getDataType();
|
201 |
bandNoData[band] = null;
|
202 |
} |
203 |
} else {
|
204 |
int bands = getBands();
|
205 |
bandDataTypes = new int[bands]; |
206 |
bandNoData = new NoData[bands];
|
207 |
for (int i = 0; i < bands; i++) { |
208 |
bandDataTypes[i] = this.getBandDescriptor(i).getDataType();
|
209 |
bandNoData[i] = null;
|
210 |
} |
211 |
} |
212 |
Envelope envelope = getEnvelope(); |
213 |
if (rasterQuery.getClip() != null) { |
214 |
envelope = rasterQuery.getClip(); |
215 |
} |
216 |
wmsStatus.setExtent( |
217 |
new Rectangle2D.Double( |
218 |
envelope.getMinimum(DIMENSIONS.X), |
219 |
envelope.getMinimum(DIMENSIONS.Y), |
220 |
envelope.getLength(DIMENSIONS.X), |
221 |
envelope.getLength(DIMENSIONS.Y))); |
222 |
|
223 |
double ratio = Math.abs(envelope.getLength(DIMENSIONS.X)/envelope.getLength(DIMENSIONS.Y)); |
224 |
|
225 |
double pixelSize = rasterQuery.getPixelSize();
|
226 |
int columns = WMSRasterProvider.DEFAULT_BUFFER_SIZE;
|
227 |
int rows = WMSRasterProvider.DEFAULT_BUFFER_SIZE;
|
228 |
if(pixelSize == 0){ |
229 |
if(ratio >= 1){ |
230 |
wmsStatus.setWidth(columns); |
231 |
rows = (int)Math.round(WMSRasterProvider.DEFAULT_BUFFER_SIZE/ratio); |
232 |
wmsStatus.setHeight((int)Math.round(WMSRasterProvider.DEFAULT_BUFFER_SIZE/ratio)); |
233 |
} else {
|
234 |
columns = (int)Math.round(WMSRasterProvider.DEFAULT_BUFFER_SIZE/ratio); |
235 |
wmsStatus.setWidth(columns); |
236 |
wmsStatus.setHeight(rows); |
237 |
} |
238 |
} else {
|
239 |
columns = (int)Math.round(envelope.getLength(DIMENSIONS.X)/pixelSize); |
240 |
wmsStatus.setWidth(columns); |
241 |
rows = (int)Math.round(envelope.getLength(DIMENSIONS.Y)/pixelSize); |
242 |
wmsStatus.setHeight(rows); |
243 |
} |
244 |
|
245 |
URL url;
|
246 |
Downloader downloader = CompatLocator.getDownloader(); |
247 |
BufferedImage img;
|
248 |
try {
|
249 |
url = wmsClient.getGetMapURL(wmsStatus, null);
|
250 |
logger.info("URL: "+url.toString());
|
251 |
File file = downloader.downloadFile(url, "WMS_map", null); |
252 |
img = ImageIO.read(file);
|
253 |
} catch (Exception e) { |
254 |
throw new BufferException(e); |
255 |
} |
256 |
|
257 |
Buffer buffer = bufferManager.createRGBABuffer(img, projection, envelope);
|
258 |
|
259 |
return buffer;
|
260 |
} |
261 |
|
262 |
@Override
|
263 |
public BandDescriptorServices getBandDescriptor(int band) { |
264 |
BandDescriptorServices descriptor = super.getBandDescriptor(band);
|
265 |
switch (band) {
|
266 |
case 0: |
267 |
descriptor.setName("RED");
|
268 |
descriptor.setDescription("RED");
|
269 |
descriptor.setDataType(BufferManager.TYPE_BYTE); |
270 |
case 1: |
271 |
descriptor.setName("GREEN");
|
272 |
descriptor.setDescription("GREEN");
|
273 |
descriptor.setDataType(BufferManager.TYPE_BYTE); |
274 |
case 2: |
275 |
descriptor.setName("BLUE");
|
276 |
descriptor.setDescription("BLUE");
|
277 |
descriptor.setDataType(BufferManager.TYPE_BYTE); |
278 |
case 3: |
279 |
descriptor.setName("ALPHA");
|
280 |
descriptor.setDescription("ALPHA");
|
281 |
descriptor.setDataType(BufferManager.TYPE_BYTE); |
282 |
} |
283 |
return descriptor;
|
284 |
|
285 |
} |
286 |
|
287 |
@Override
|
288 |
public int getBands() { |
289 |
return 4; |
290 |
} |
291 |
|
292 |
@Override
|
293 |
public DataServerExplorer getExplorer() throws ReadException, ValidateDataParametersException { |
294 |
DataManager manager = DALLocator.getDataManager(); |
295 |
WMSRasterServerExplorerParameters params; |
296 |
try {
|
297 |
params = |
298 |
(WMSRasterServerExplorerParameters) manager |
299 |
.createServerExplorerParameters(WMSRasterServerExplorer.NAME); |
300 |
params.setService(((WMSRasterProviderParameters) getParameters()).getService()); |
301 |
// params.setXYAxisOrder(((WMSRasterProviderParameters) getParameters()).getXYAxisOrder());
|
302 |
return manager.openServerExplorer(WMSRasterServerExplorer.NAME, (DataServerExplorerParameters) params);
|
303 |
} catch (Exception e) { |
304 |
throw new ReadException(this.getName(), e); |
305 |
} |
306 |
} |
307 |
|
308 |
@Override
|
309 |
public void open() throws OpenException { |
310 |
for(int i=0; i<getBands(); i++){ |
311 |
this.getBandDescriptor(i).setDataType(DataTypes.BYTE);
|
312 |
} |
313 |
} |
314 |
|
315 |
@Override
|
316 |
public ResourceProvider getResource() {
|
317 |
return null; |
318 |
} |
319 |
|
320 |
@Override
|
321 |
public Object getSourceId() { |
322 |
return getParameters().getDynValue(WMSRasterProviderParameters.WMS_SERVICE_PARAMETER_NAME);
|
323 |
} |
324 |
|
325 |
@Override
|
326 |
public String getProviderName() { |
327 |
return NAME;
|
328 |
} |
329 |
|
330 |
@Override
|
331 |
public String getName() { //lista de capas |
332 |
@SuppressWarnings("unchecked") |
333 |
List<String> layers = (List<String>) getParameters().getDynValue("layers"); |
334 |
StringBuilder builder = new StringBuilder(); |
335 |
for (int i = 0; i < layers.size(); i++) { |
336 |
if (i != 0) { |
337 |
builder.append(",");
|
338 |
} |
339 |
builder.append(layers.get(i)); |
340 |
} |
341 |
return builder.toString();
|
342 |
} |
343 |
|
344 |
@Override
|
345 |
public String getFullName() { // host:port - lista de capas |
346 |
|
347 |
StringBuilder builder = new StringBuilder(); |
348 |
URL service = (URL)this.getParameters().getDynValue(WMSRasterProviderParameters.WMS_SERVICE_PARAMETER_NAME); |
349 |
builder.append(service.getHost()); |
350 |
int port = service.getPort();
|
351 |
if(port < 0){ |
352 |
int defaultPort = service.getDefaultPort();
|
353 |
if(defaultPort>=0){ |
354 |
builder.append(":");
|
355 |
builder.append(service.getDefaultPort()); |
356 |
} |
357 |
} else {
|
358 |
builder.append(":");
|
359 |
builder.append(port); |
360 |
} |
361 |
builder.append(" - ");
|
362 |
builder.append(getName()); |
363 |
return builder.toString();
|
364 |
} |
365 |
|
366 |
@Override
|
367 |
public Object getDynValue(String name) throws DynFieldNotFoundException { |
368 |
if (DataStore.METADATA_CRS.equalsIgnoreCase(name)) {
|
369 |
return this.getParameters().getDynValue(name); |
370 |
} |
371 |
if (DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name)) {
|
372 |
return this.getEnvelope(); |
373 |
} |
374 |
return super.getDynValue(name); |
375 |
} |
376 |
|
377 |
private Envelope getEnvelope() {
|
378 |
return this.envelope; |
379 |
} |
380 |
|
381 |
private IProjection getProjection() {
|
382 |
return (IProjection) this.getParameters().getDynValue(WMSRasterProviderParameters.WMS_CRS_PARAMETER_NAME); |
383 |
} |
384 |
|
385 |
@Override
|
386 |
public TileStruct getTileStruct() {
|
387 |
if (tileStruct == null) { |
388 |
tileStruct = new DefaultTileStruct();
|
389 |
tileStruct.setColumnsPerTile(DEFAULT_BUFFER_SIZE); |
390 |
tileStruct.setRowsPerTile(DEFAULT_BUFFER_SIZE); |
391 |
|
392 |
try {
|
393 |
Envelope envelope = getEnvelope(); |
394 |
tileStruct.setEnvelope(envelope); |
395 |
|
396 |
Map<Integer, Double> zoomLevels = new HashMap<Integer, Double>(); |
397 |
double pixelSize;
|
398 |
double length;
|
399 |
if (envelope.getLength(DIMENSIONS.X) >= envelope.getLength(DIMENSIONS.Y)) {
|
400 |
length = envelope.getLength(DIMENSIONS.X); |
401 |
} else {
|
402 |
length = envelope.getLength(DIMENSIONS.Y); |
403 |
} |
404 |
pixelSize = length / DEFAULT_BUFFER_SIZE; |
405 |
for (int zoomLevel = 0; (zoomLevel <= MAX_ZOOM_LEVEL) && ((length / pixelSize) < Integer.MAX_VALUE); zoomLevel++) { |
406 |
zoomLevels.put(zoomLevel, pixelSize); |
407 |
pixelSize = pixelSize / 2;
|
408 |
calculatedMaxZoomLevel = zoomLevel; |
409 |
} |
410 |
|
411 |
tileStruct.setPixelSizePerZoomLevel(zoomLevels); |
412 |
} catch (LocatorException e) {
|
413 |
logger.warn("Can't create world extent of GoogleMaps", e);
|
414 |
} |
415 |
} |
416 |
return tileStruct;
|
417 |
} |
418 |
|
419 |
@Override
|
420 |
public Image getImageLegend() { |
421 |
Vector layerNames = wmsStatus.getLayerNames();
|
422 |
if(layerNames.size()>1){ |
423 |
return null; |
424 |
} |
425 |
|
426 |
File file;
|
427 |
BufferedImage img=null; |
428 |
try {
|
429 |
file = wmsClient.getLegendGraphic(wmsStatus, layerNames.get(0).toString(), null); |
430 |
img = ImageIO.read(file);
|
431 |
} catch (WMSException | ServerErrorException | IOException e) { |
432 |
logger.warn("Can't read image legend of WMS Provider", e);
|
433 |
} |
434 |
return img;
|
435 |
} |
436 |
|
437 |
@Override
|
438 |
public BufferDimensions getDimensions() throws InitializeException { |
439 |
if(this.dimensions==null){; |
440 |
Double pixelSize = getTileStruct().getPixelSizePerZoomLevel().get(calculatedMaxZoomLevel);
|
441 |
Envelope envelope = getEnvelope(); |
442 |
int rows = (int)Math.round(envelope.getLength(DIMENSIONS.Y)/pixelSize); |
443 |
int columns = (int)Math.round(envelope.getLength(DIMENSIONS.X)/pixelSize); |
444 |
this.dimensions = BufferLocator.getBufferManager().createBufferDimensions(rows, columns, envelope);
|
445 |
} |
446 |
return this.dimensions; |
447 |
} |
448 |
|
449 |
@Override
|
450 |
protected void doDispose() throws BaseException { |
451 |
super.doDispose();
|
452 |
if(this.tileStruct!=null) { |
453 |
DisposeUtils.dispose((Disposable) this.tileStruct);
|
454 |
this.tileStruct = null; |
455 |
} |
456 |
} |
457 |
|
458 |
} |