001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/ogcwebservices/wms/GetMapServiceInvokerForNL.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2001-2008 by:
006: EXSE, Department of Geography, University of Bonn
007: http://www.giub.uni-bonn.de/deegree/
008: lat/lon GmbH
009: http://www.lat-lon.de
010:
011: This library is free software; you can redistribute it and/or
012: modify it under the terms of the GNU Lesser General Public
013: License as published by the Free Software Foundation; either
014: version 2.1 of the License, or (at your option) any later version.
015:
016: This library is distributed in the hope that it will be useful,
017: but WITHOUT ANY WARRANTY; without even the implied warranty of
018: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: Lesser General Public License for more details.
020:
021: You should have received a copy of the GNU Lesser General Public
022: License along with this library; if not, write to the Free Software
023: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024:
025: Contact:
026:
027: Andreas Poth
028: lat/lon GmbH
029: Aennchenstr. 19
030: 53177 Bonn
031: Germany
032: E-Mail: poth@lat-lon.de
033:
034: Prof. Dr. Klaus Greve
035: Department of Geography
036: University of Bonn
037: Meckenheimer Allee 166
038: 53115 Bonn
039: Germany
040: E-Mail: greve@giub.uni-bonn.de
041:
042: ---------------------------------------------------------------------------*/
043: package org.deegree.ogcwebservices.wms;
044:
045: import java.awt.Color;
046: import java.awt.Graphics;
047: import java.awt.image.BufferedImage;
048: import java.io.StringReader;
049: import java.net.URI;
050: import java.util.ArrayList;
051: import java.util.Iterator;
052: import java.util.List;
053: import java.util.Map;
054: import java.util.concurrent.Callable;
055: import java.util.concurrent.CancellationException;
056:
057: import org.deegree.datatypes.QualifiedName;
058: import org.deegree.datatypes.Types;
059: import org.deegree.framework.concurrent.DoServiceTask;
060: import org.deegree.framework.concurrent.Executor;
061: import org.deegree.framework.log.ILogger;
062: import org.deegree.framework.log.LoggerFactory;
063: import org.deegree.framework.util.CharsetUtils;
064: import org.deegree.framework.util.IDGenerator;
065: import org.deegree.framework.xml.XMLFragment;
066: import org.deegree.framework.xml.XMLTools;
067: import org.deegree.graphics.MapFactory;
068: import org.deegree.graphics.Theme;
069: import org.deegree.graphics.sld.NamedLayer;
070: import org.deegree.graphics.sld.StyleUtils;
071: import org.deegree.graphics.sld.UserStyle;
072: import org.deegree.i18n.Messages;
073: import org.deegree.model.coverage.grid.GridCoverage;
074: import org.deegree.model.coverage.grid.ImageGridCoverage;
075: import org.deegree.model.coverage.grid.WorldFile;
076: import org.deegree.model.crs.CRSFactory;
077: import org.deegree.model.crs.CRSTransformationException;
078: import org.deegree.model.crs.GeoTransformer;
079: import org.deegree.model.crs.UnknownCRSException;
080: import org.deegree.model.feature.Feature;
081: import org.deegree.model.feature.FeatureCollection;
082: import org.deegree.model.feature.FeatureProperty;
083: import org.deegree.model.feature.schema.FeatureType;
084: import org.deegree.model.feature.schema.PropertyType;
085: import org.deegree.model.filterencoding.ComplexFilter;
086: import org.deegree.model.filterencoding.FeatureFilter;
087: import org.deegree.model.filterencoding.FeatureId;
088: import org.deegree.model.filterencoding.Filter;
089: import org.deegree.model.spatialschema.Envelope;
090: import org.deegree.model.spatialschema.GMLGeometryAdapter;
091: import org.deegree.model.spatialschema.Geometry;
092: import org.deegree.model.spatialschema.GeometryException;
093: import org.deegree.model.spatialschema.WKTAdapter;
094: import org.deegree.ogcbase.PropertyPath;
095: import org.deegree.ogcbase.PropertyPathFactory;
096: import org.deegree.ogcwebservices.InconsistentRequestException;
097: import org.deegree.ogcwebservices.OGCWebServiceException;
098: import org.deegree.ogcwebservices.OGCWebServiceRequest;
099: import org.deegree.ogcwebservices.wcs.WCSException;
100: import org.deegree.ogcwebservices.wcs.getcoverage.GetCoverage;
101: import org.deegree.ogcwebservices.wcs.getcoverage.ResultCoverage;
102: import org.deegree.ogcwebservices.wfs.WFService;
103: import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities;
104: import org.deegree.ogcwebservices.wfs.capabilities.WFSFeatureType;
105: import org.deegree.ogcwebservices.wfs.operation.FeatureResult;
106: import org.deegree.ogcwebservices.wfs.operation.GetFeature;
107: import org.deegree.ogcwebservices.wfs.operation.Query;
108: import org.deegree.ogcwebservices.wms.configuration.AbstractDataSource;
109: import org.deegree.ogcwebservices.wms.configuration.LocalWCSDataSource;
110: import org.deegree.ogcwebservices.wms.configuration.LocalWFSDataSource;
111: import org.deegree.ogcwebservices.wms.configuration.RemoteWMSDataSource;
112: import org.deegree.ogcwebservices.wms.operation.GetMap;
113: import org.deegree.ogcwebservices.wms.operation.GetMapResult;
114: import org.w3c.dom.Document;
115:
116: /**
117: * Class for accessing the data of one layers datasource and creating a <tt>Theme</tt> from it.
118: *
119: * @version $Revision: 9894 $
120: * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
121: * @author last edited by: $Author: otonnhofer $
122: *
123: * @version 1.0. $Revision: 9894 $, $Date: 2008-02-05 05:17:08 -0800 (Tue, 05 Feb 2008) $
124: *
125: * @since 2.0
126: */
127: public class GetMapServiceInvokerForNL extends GetMapServiceInvoker
128: implements Callable<Object> {
129:
130: private static final ILogger LOG = LoggerFactory
131: .getLogger(GetMapServiceInvokerForNL.class);
132:
133: private final GetMap request;
134:
135: private NamedLayer layer = null;
136:
137: private UserStyle style = null;
138:
139: private AbstractDataSource datasource = null;
140:
141: /**
142: * Creates a new ServiceInvokerForNL object.
143: *
144: * @param handler
145: * @param layer
146: * @param datasource
147: * @param style
148: * @param index
149: */
150: GetMapServiceInvokerForNL(DefaultGetMapHandler handler,
151: NamedLayer layer, AbstractDataSource datasource,
152: UserStyle style, double scale) {
153:
154: super (handler, scale);
155:
156: this .layer = layer;
157: this .request = handler.getRequest();
158: this .style = style;
159: this .datasource = datasource;
160: }
161:
162: public Object call() {
163:
164: Object response = null;
165: if (datasource != null) {
166: OGCWebServiceRequest request = null;
167: try {
168: int type = datasource.getType();
169: switch (type) {
170: case AbstractDataSource.LOCALWFS:
171: case AbstractDataSource.REMOTEWFS: {
172: request = createGetFeatureRequest((LocalWFSDataSource) datasource);
173: break;
174: }
175: case AbstractDataSource.LOCALWCS:
176: case AbstractDataSource.REMOTEWCS: {
177: request = createGetCoverageRequest(datasource,
178: this .request);
179: break;
180: }
181: case AbstractDataSource.REMOTEWMS: {
182: String styleName = null;
183:
184: if (style != null) {
185: styleName = style.getName();
186: }
187:
188: request = GetMap.createGetMapRequest(datasource,
189: handler.getRequest(), styleName, layer
190: .getName());
191: LOG.logDebug("GetMap request: "
192: + request.toString());
193: break;
194: }
195: }
196: } catch (Exception e) {
197: e.printStackTrace();
198: OGCWebServiceException exce = new OGCWebServiceException(
199: getClass().getName(), Messages.getMessage(
200: "WMS_ERRORQUERYCREATE", e));
201: // exception can't be re-thrown because responsible GetMapHandler
202: // must collect all responses of all datasources
203: response = exce;
204: LOG.logError(e.getMessage(), e);
205: }
206:
207: try {
208: // start reading data with a limited time frame. The time limit
209: // readed from the datasource muts be multiplied by 1000 because
210: // the method expects milliseconds as timelimit
211: Executor executor = Executor.getInstance();
212: DoServiceTask<Object> task = new DoServiceTask<Object>(
213: datasource.getOGCWebService(), request);
214: Object o = executor.performSynchronously(task,
215: datasource.getRequestTimeLimit() * 1000);
216: response = handleResponse(o);
217: } catch (CancellationException e) {
218: // exception can't be re-thrown because responsible GetMapHandler
219: // must collect all responses of all datasources
220: String s = Messages.getMessage("WMS_TIMEOUTDATASOURCE",
221: new Integer(datasource.getRequestTimeLimit()));
222: LOG.logError(s, e);
223: if (datasource.isFailOnException()) {
224: OGCWebServiceException exce = new OGCWebServiceException(
225: getClass().getName(), s);
226: response = exce;
227: } else {
228: response = null;
229: }
230: } catch (Throwable e) {
231: // exception can't be re-thrown because responsible GetMapHandler
232: // must collect all responses of all datasources
233: String s = Messages.getMessage("WMS_ERRORDOSERVICE", e
234: .getMessage());
235: LOG.logError(s, e);
236: if (datasource.isFailOnException()) {
237: OGCWebServiceException exce = new OGCWebServiceException(
238: getClass().getName(), s);
239: response = exce;
240: } else {
241: response = null;
242: }
243: }
244: }
245:
246: LOG.logDebug("Layer " + layer.getName() + " returned.");
247:
248: return response;
249: }
250:
251: /**
252: * creates a getFeature request considering the getMap request and the filterconditions defined
253: * in the submitted <tt>DataSource</tt> object. The request will be encapsualted within a
254: * <tt>OGCWebServiceEvent</tt>.
255: *
256: * @param ds
257: * @return GetFeature request object
258: * @throws Exception
259: */
260: private GetFeature createGetFeatureRequest(LocalWFSDataSource ds)
261: throws Exception {
262:
263: Envelope bbox = transformBBOX(ds);
264:
265: List<PropertyPath> pp = null;
266: if (style != null) {
267: List<UserStyle> styleList = new ArrayList<UserStyle>();
268: styleList.add(style);
269: pp = StyleUtils.extractRequiredProperties(styleList,
270: scaleDen);
271: } else {
272: pp = new ArrayList<PropertyPath>();
273: }
274: PropertyPath geomPP = PropertyPathFactory.createPropertyPath(ds
275: .getGeometryProperty());
276: if (!pp.contains(geomPP)) {
277: pp.add(geomPP);
278: }
279:
280: LOG.logDebug("required properties: ", pp);
281: Map<String, URI> namesp = extractNameSpaceDef(pp);
282:
283: // no filter condition has been defined
284: StringBuffer sb = new StringBuffer(5000);
285: sb.append("<?xml version='1.0' encoding='"
286: + CharsetUtils.getSystemCharset() + "'?>");
287: sb.append("<GetFeature xmlns='http://www.opengis.net/wfs' ");
288: sb.append("xmlns:ogc='http://www.opengis.net/ogc' ");
289: sb.append("xmlns:gml='http://www.opengis.net/gml' ");
290: sb.append("xmlns:").append(ds.getName().getPrefix())
291: .append('=');
292: sb.append("'").append(ds.getName().getNamespace()).append("' ");
293: Iterator<String> iter = namesp.keySet().iterator();
294: while (iter.hasNext()) {
295: String pre = iter.next();
296: URI nsp = namesp.get(pre);
297: if (!pre.equals("xmlns")
298: && !pre.equals(ds.getName().getPrefix())) {
299: sb.append("xmlns:").append(pre).append("='");
300: sb.append(nsp.toASCIIString()).append("' ");
301: }
302: }
303:
304: sb.append("service='WFS' version='1.1.0' ");
305: if (ds.getType() == AbstractDataSource.LOCALWFS) {
306: sb.append("outputFormat='FEATURECOLLECTION'>");
307: } else {
308: sb.append("outputFormat='text/xml; subtype=gml/3.1.1'>");
309: }
310: sb.append("<Query typeName='" + ds.getName().getPrefixedName()
311: + "'>");
312:
313: for (int j = 0; j < pp.size(); j++) {
314: if (!pp.get(j).getAsString().endsWith("$SCALE")) {
315: // $SCALE is a dynamicly created property of each feature
316: // and can not be requested
317: sb.append("<PropertyName>").append(
318: pp.get(j).getAsString());
319: sb.append("</PropertyName>");
320: }
321: }
322:
323: Query query = ds.getQuery();
324: if (query == null) {
325: sb.append("<ogc:Filter><ogc:BBOX>");
326: sb.append("<PropertyName>");
327: sb.append(ds.getGeometryProperty().getPrefixedName());
328: sb.append("</PropertyName>");
329: sb.append(GMLGeometryAdapter.exportAsBox(bbox));
330: sb.append("</ogc:BBOX>");
331: sb.append("</ogc:Filter></Query></GetFeature>");
332: } else {
333: Filter filter = query.getFilter();
334: sb.append("<ogc:Filter>");
335: if (filter instanceof ComplexFilter) {
336: sb.append("<ogc:And>");
337: sb.append("<ogc:BBOX>");
338: sb.append("<PropertyName>");
339: sb.append(ds.getGeometryProperty().getPrefixedName());
340: sb.append("</PropertyName>");
341: sb.append(GMLGeometryAdapter.exportAsBox(bbox));
342: sb.append("</ogc:BBOX>");
343:
344: // add filter as defined in the layers datasource description
345: // to the filter expression
346: org.deegree.model.filterencoding.Operation op = ((ComplexFilter) filter)
347: .getOperation();
348: sb.append(op.toXML()).append("</ogc:And>");
349: } else {
350: ArrayList<FeatureId> featureIds = ((FeatureFilter) filter)
351: .getFeatureIds();
352: if (featureIds.size() > 1) {
353: sb.append("<ogc:And>");
354: }
355: for (int i = 0; i < featureIds.size(); i++) {
356: FeatureId fid = featureIds.get(i);
357: sb.append(fid.toXML());
358: }
359: if (featureIds.size() > 1) {
360: sb.append("</ogc:And>");
361: }
362: }
363: sb.append("</ogc:Filter></Query></GetFeature>");
364: }
365:
366: // create dom representation of the request
367: Document doc = XMLTools.parse(new StringReader(sb.toString()));
368:
369: LOG.logDebug("GetFeature request: "
370: + new XMLFragment(doc, "http://www.systemid.org")
371: .getAsPrettyString());
372:
373: // create OGCWebServiceEvent object
374: IDGenerator idg = IDGenerator.getInstance();
375: GetFeature gfr = GetFeature.create("" + idg.generateUniqueID(),
376: doc.getDocumentElement());
377:
378: return gfr;
379: }
380:
381: /**
382: * transforms the requested BBOX into the DefaultSRS of the assigend feature type
383: *
384: * @param ds
385: * @return the envelope
386: * @throws OGCWebServiceException
387: * @throws CRSTransformationException
388: * @throws UnknownCRSException
389: * @throws Proj4Exception
390: */
391: private Envelope transformBBOX(LocalWFSDataSource ds)
392: throws OGCWebServiceException, CRSTransformationException,
393: UnknownCRSException {
394: Envelope bbox = request.getBoundingBox();
395: // transform request bounding box to the coordinate reference
396: // system the WFS holds the data if requesting CRS and WFS-Data
397: // crs are different
398: WFService wfs = (WFService) ds.getOGCWebService();
399: // WFSCapabilities capa = (WFSCapabilities)wfs.getWFSCapabilities();
400: WFSCapabilities capa = wfs.getCapabilities();
401: QualifiedName gn = ds.getName();
402: WFSFeatureType ft = capa.getFeatureTypeList()
403: .getFeatureType(gn);
404:
405: if (ft == null) {
406: throw new OGCWebServiceException(Messages.getMessage(
407: "WMS_UNKNOWNFT", ds.getName()));
408: }
409:
410: // enable different formatations of the crs encoding for GML geometries
411: String GML_SRS = "http://www.opengis.net/gml/srs/";
412: String old_gml_srs = ft.getDefaultSRS().toASCIIString();
413: String old_srs;
414: if (old_gml_srs.startsWith(GML_SRS)) {
415: old_srs = old_gml_srs.substring(31).replace('#', ':')
416: .toUpperCase();
417: } else {
418: old_srs = old_gml_srs;
419: }
420:
421: String new_srs = request.getSrs();
422: String new_gml_srs;
423: if (old_gml_srs.startsWith(GML_SRS)) {
424: new_gml_srs = GML_SRS
425: + new_srs.replace(':', '#').toLowerCase();
426: } else {
427: new_gml_srs = new_srs;
428: }
429:
430: if (!(old_srs.equalsIgnoreCase(new_gml_srs))) {
431: GeoTransformer transformer = new GeoTransformer(CRSFactory
432: .create(old_srs));
433: bbox = transformer.transform(bbox, this .handler
434: .getRequestCRS());
435: }
436: return bbox;
437: }
438:
439: /**
440: * creates a getCoverage request considering the getMap request and the filterconditions defined
441: * in the submitted <tt>DataSource</tt> object The request will be encapsualted within a
442: * <tt>OGCWebServiceEvent</tt>.
443: *
444: * @param ds
445: * @return GetCoverage request object
446: * @throws InconsistentRequestException
447: */
448: protected static GetCoverage createGetCoverageRequest(
449: AbstractDataSource ds, GetMap request)
450: throws InconsistentRequestException {
451:
452: Envelope bbox = request.getBoundingBox();
453:
454: double xres = bbox.getWidth() / request.getWidth();
455: double yres = bbox.getHeight() / request.getHeight();
456:
457: WorldFile tmpWorldFile = new WorldFile(xres, yres, 0.0, 0.0,
458: bbox, WorldFile.TYPE.OUTER);
459: bbox = tmpWorldFile.getEnvelope(WorldFile.TYPE.CENTER);
460:
461: GetCoverage gcr = ((LocalWCSDataSource) ds)
462: .getGetCoverageRequest();
463:
464: String crs = request.getSrs();
465: // if (gcr != null && gcr.getDomainSubset().getRequestSRS() != null) {
466: // crs = gcr.getDomainSubset().getRequestSRS().getCode();
467: // }
468: String format = request.getFormat();
469: int pos = format.indexOf('/');
470: if (pos > -1)
471: format = format.substring(pos + 1, format.length());
472: if (gcr != null
473: && !"%default%".equals(gcr.getOutput().getFormat()
474: .getCode())) {
475: format = gcr.getOutput().getFormat().getCode();
476: }
477: if (format.indexOf("svg") > -1) {
478: format = "tiff";
479: }
480:
481: String version = "1.0.0";
482: if (gcr != null && gcr.getVersion() != null) {
483: version = gcr.getVersion();
484: }
485: String lay = ds.getName().getPrefixedName();
486: if (gcr != null && !"%default%".equals(gcr.getSourceCoverage())) {
487: lay = gcr.getSourceCoverage();
488: }
489: String ipm = null;
490: if (gcr != null && gcr.getInterpolationMethod() != null) {
491: ipm = gcr.getInterpolationMethod().value;
492: }
493:
494: // TODO
495: // handle rangesets e.g. time and elevation
496: StringBuffer sb = new StringBuffer(1000);
497: sb.append("service=WCS&request=GetCoverage");
498: sb.append("&version=").append(version);
499: sb.append("&COVERAGE=").append(lay);
500: sb.append("&crs=").append(crs);
501: sb.append("&response_crs=").append(crs);
502: sb.append("&BBOX=").append(bbox.getMin().getX()).append(',');
503: sb.append(bbox.getMin().getY()).append(',').append(
504: bbox.getMax().getX());
505: sb.append(',').append(bbox.getMax().getY());
506: sb.append("&WIDTH=").append(request.getWidth() - 1);
507: sb.append("&HEIGHT=").append(request.getHeight() - 1);
508: sb.append("&FORMAT=").append(format);
509: sb.append("&INTERPOLATIONMETHOD=").append(ipm);
510: try {
511: IDGenerator idg = IDGenerator.getInstance();
512: gcr = GetCoverage.create("id" + idg.generateUniqueID(), sb
513: .toString());
514: } catch (WCSException e) {
515: throw new InconsistentRequestException(e.getMessage());
516: } catch (org.deegree.ogcwebservices.OGCWebServiceException e) {
517: throw new InconsistentRequestException(e.getMessage());
518: }
519:
520: LOG.logDebug("GetCoverage request: " + sb.toString());
521:
522: return gcr;
523:
524: }
525:
526: /**
527: *
528: * @param result
529: * @return the response objects
530: * @throws Exception
531: */
532: private Object handleResponse(Object result) throws Exception {
533:
534: Object theme = null;
535: if (result instanceof ResultCoverage) {
536: theme = handleGetCoverageResponse((ResultCoverage) result);
537: } else if (result instanceof FeatureResult) {
538: theme = handleGetFeatureResponse((FeatureResult) result);
539: } else if (result instanceof GetMapResult) {
540: theme = handleGetMapResponse((GetMapResult) result);
541: } else {
542: String s = Messages.getMessage("WMS_UNKNOWNRESPONSEFORMAT");
543: if (datasource.isFailOnException()) {
544: OGCWebServiceException exce = new OGCWebServiceException(
545: getClass().getName(), s);
546: theme = exce;
547: } else {
548: theme = null;
549: }
550: }
551: return theme;
552: }
553:
554: /**
555: * replaces all pixels within the passed image having a color that is defined to be transparent
556: * within their datasource with a transparent color.
557: *
558: * @param img
559: * @return modified image
560: */
561: private BufferedImage setTransparentColors(BufferedImage img) {
562:
563: Color[] colors = null;
564: if (datasource.getType() == AbstractDataSource.LOCALWCS) {
565: LocalWCSDataSource ds = (LocalWCSDataSource) datasource;
566: colors = ds.getTransparentColors();
567: } else {
568: RemoteWMSDataSource ds = (RemoteWMSDataSource) datasource;
569: colors = ds.getTransparentColors();
570: }
571:
572: if (colors != null && colors.length > 0) {
573:
574: int[] clrs = new int[colors.length];
575: for (int i = 0; i < clrs.length; i++) {
576: clrs[i] = colors[i].getRGB();
577: }
578:
579: if (img.getType() != BufferedImage.TYPE_INT_ARGB) {
580: // if the incoming image does not allow transparency
581: // it must be copyed to a image of ARGB type
582: BufferedImage tmp = new BufferedImage(img.getWidth(),
583: img.getHeight(), BufferedImage.TYPE_INT_ARGB);
584: Graphics g = tmp.getGraphics();
585: g.drawImage(img, 0, 0, null);
586: g.dispose();
587: img = tmp;
588: }
589:
590: // TODO
591: // should be replaced by a JAI operation
592: int w = img.getWidth();
593: int h = img.getHeight();
594: for (int i = 0; i < w; i++) {
595: for (int j = 0; j < h; j++) {
596: int col = img.getRGB(i, j);
597: if (shouldBeTransparent(colors, col)) {
598: img.setRGB(i, j, 0x00FFFFFF);
599: }
600: }
601: }
602:
603: }
604:
605: return img;
606: }
607:
608: /**
609: * @return true if the distance between the image color and at least of the colors to be truned
610: * to be transparent is less than 3 in an int RGB cube
611: *
612: * @param colors
613: * @param color
614: */
615: private boolean shouldBeTransparent(Color[] colors, int color) {
616: Color c2 = new Color(color);
617: int r = c2.getRed();
618: int g = c2.getGreen();
619: int b = c2.getBlue();
620: for (int i = 0; i < colors.length; i++) {
621: int r1 = colors[i].getRed();
622: int g1 = colors[i].getGreen();
623: int b1 = colors[i].getBlue();
624: if (Math.sqrt((r1 - r) * (r1 - r) + (g1 - g) * (g1 - g)
625: + (b1 - b) * (b1 - b)) < 3) {
626: return true;
627: }
628: }
629: return false;
630: }
631:
632: /**
633: * handles the response of a cascaded WMS and calls a factory to create <tt>DisplayElement</tt>
634: * and a <tt>Theme</tt> from it
635: *
636: * @param response
637: * @return the response objects
638: * @throws Exception
639: */
640: private Object handleGetMapResponse(GetMapResult response)
641: throws Exception {
642:
643: BufferedImage bi = (BufferedImage) response.getMap();
644:
645: bi = setTransparentColors(bi);
646: GridCoverage gc = new ImageGridCoverage(null, request
647: .getBoundingBox(), bi);
648: org.deegree.graphics.Layer rl = MapFactory.createRasterLayer(
649: layer.getName(), gc);
650: Theme theme = MapFactory.createTheme(datasource.getName()
651: .getPrefixedName(), rl, new UserStyle[] { style });
652: return theme;
653:
654: }
655:
656: /**
657: * handles the response of a WFS and calls a factory to create <tt>DisplayElement</tt> and a
658: * <tt>Theme</tt> from it
659: *
660: * @param response
661: * @return the response objects
662: * @throws Exception
663: */
664: private Object handleGetFeatureResponse(FeatureResult response)
665: throws Exception {
666:
667: FeatureCollection fc = null;
668:
669: Object o = response.getResponse();
670: if (o instanceof FeatureCollection) {
671: fc = (FeatureCollection) o;
672: } else {
673: throw new Exception(Messages
674: .getMessage("WMS_UNKNOWNDATAFORMATFT"));
675: }
676: if (LOG.getLevel() == ILogger.LOG_DEBUG) {
677: LOG.logDebug("result: " + fc);
678: for (int i = 0; i < fc.size(); ++i) {
679: outputGeometries(fc.getFeature(i));
680: }
681: }
682:
683: org.deegree.graphics.Layer fl = MapFactory.createFeatureLayer(
684: layer.getName(), this .handler.getRequestCRS(), fc);
685:
686: return MapFactory.createTheme(datasource.getName()
687: .getPrefixedName(), fl, new UserStyle[] { style });
688: }
689:
690: private void outputGeometries(Feature feature) {
691: if (feature == null) {
692: return;
693: }
694: FeatureType ft = feature.getFeatureType();
695: PropertyType[] propertyTypes = ft.getProperties();
696: for (PropertyType pt : propertyTypes) {
697: if (pt.getType() == Types.FEATURE) {
698: FeatureProperty[] fp = feature.getProperties(pt
699: .getName());
700: if (fp != null) {
701: for (int i = 0; i < fp.length; i++) {
702: outputGeometries((Feature) fp[i].getValue());
703: }
704: }
705: } else if (pt.getType() == Types.GEOMETRY) {
706: Geometry g = feature.getDefaultGeometryPropertyValue();
707: if (g != null) {
708: try {
709: LOG.logDebug("geometrie: "
710: + WKTAdapter.export(g).toString());
711: } catch (GeometryException e) {
712: LOG
713: .logDebug("Geometry couldn't be converted to Well Known Text: "
714: + g);
715: }
716: }
717: }
718: }
719: }
720:
721: /**
722: * handles the response of a WCS and calls a factory to create <tt>DisplayElement</tt> and a
723: * <tt>Theme</tt> from it
724: *
725: * @param response
726: * @return the response objects
727: * @throws Exception
728: */
729: private Object handleGetCoverageResponse(ResultCoverage response)
730: throws Exception {
731: ImageGridCoverage gc = (ImageGridCoverage) response
732: .getCoverage();
733: Object ro = null;
734: if (gc != null) {
735: BufferedImage bi = gc.getAsImage(-1, -1);
736:
737: bi = setTransparentColors(bi);
738:
739: gc = new ImageGridCoverage(null, request.getBoundingBox(),
740: bi);
741:
742: org.deegree.graphics.Layer rl = MapFactory
743: .createRasterLayer(layer.getName(), gc);
744:
745: ro = MapFactory.createTheme(datasource.getName()
746: .getPrefixedName(), rl, new UserStyle[] { style });
747: } else {
748: throw new OGCWebServiceException(getClass().getName(),
749: Messages.getMessage("WMS_NOCOVERAGE", datasource
750: .getName()));
751: }
752: return ro;
753: }
754:
755: }
|