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