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