001: /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
002: * This code is licensed under the GPL 2.0 license, availible at the root
003: * application directory.
004: */
005: package org.vfny.geoserver.wms.requests;
006:
007: import com.vividsolutions.jts.geom.Envelope;
008: import org.geoserver.ows.util.CaseInsensitiveMap;
009: import org.geotools.styling.Style;
010: import org.geotools.styling.StyledLayerDescriptor;
011: import org.opengis.filter.Filter;
012: import org.opengis.referencing.crs.CoordinateReferenceSystem;
013: import org.vfny.geoserver.global.MapLayerInfo;
014: import org.vfny.geoserver.wms.responses.palette.InverseColorMapOp;
015: import org.vfny.geoserver.global.WMS;
016: import org.vfny.geoserver.wms.servlets.WMService;
017: import java.awt.Color;
018: import java.awt.geom.Point2D;
019: import java.awt.image.IndexColorModel;
020: import java.net.URL;
021: import java.util.HashMap;
022: import java.util.Iterator;
023: import java.util.List;
024: import java.util.Map;
025:
026: /**
027: * Represents a WMS GetMap request. as a extension to the WMS spec 1.1.
028: *
029: * @author Gabriel Roldan, Axios Engineering
030: * @author Simone Giannecchini
031: * @version $Id: GetMapRequest.java 7639 2007-10-22 15:18:58Z aaime $
032: */
033: public class GetMapRequest extends WMSRequest {
034: /** DOCUMENT ME! */
035: static final Color DEFAULT_BG = Color.white;
036:
037: /** DOCUMENT ME! */
038: public static final String SE_XML = "SE_XML";
039: private static final String TRANSACTION_REQUEST_TYPE = "GetMap";
040:
041: /** set of mandatory request's parameters */
042: private MandatoryParameters mandatoryParams = new MandatoryParameters();
043:
044: /** set of optionals request's parameters */
045: private OptionalParameters optionalParams = new OptionalParameters();
046:
047: /** format options */
048: private Map /*<String,Object>*/formatOptions = new CaseInsensitiveMap(
049: new HashMap());
050:
051: /** raw kvp parameters non-parsed */
052: private Map /*<String,String>*/rawKvp;
053:
054: /**
055: * Creates a GetMapRequest request.
056: *
057: * @param service The service handling the request.
058: */
059: public GetMapRequest(WMService service) {
060: super (TRANSACTION_REQUEST_TYPE, service);
061: }
062:
063: /**
064: * DOCUMENT ME!
065: *
066: * @return DOCUMENT ME!
067: */
068: public Envelope getBbox() {
069: return this .mandatoryParams.bbox;
070: }
071:
072: /**
073: * DOCUMENT ME!
074: *
075: * @return DOCUMENT ME!
076: */
077: public java.awt.Color getBgColor() {
078: return this .optionalParams.bgColor;
079: }
080:
081: /**
082: * DJB: spec says SRS is *required*, so if they dont specify one, we should throw an error
083: * instead we use "NONE" - which is no-projection.
084: * Previous behavior was to the WSG84 lat/long (4326)
085: *
086: * @return request CRS, or <code>null</code> if not set.
087: * TODO: make CRS manditory as for spec conformance
088: */
089: public CoordinateReferenceSystem getCrs() {
090: return this .optionalParams.crs;
091: }
092:
093: public String getSRS() {
094: return this .optionalParams.srs;
095: }
096:
097: /**
098: * DOCUMENT ME!
099: *
100: * @return DOCUMENT ME!
101: */
102: public String getExceptions() {
103: return this .optionalParams.exceptions;
104: }
105:
106: /**
107: * DOCUMENT ME!
108: *
109: * @return DOCUMENT ME!
110: */
111: public String getFormat() {
112: return this .mandatoryParams.format;
113: }
114:
115: /**
116: * Map of String,Object which contains kvp's which are specific to a
117: * particular output format.
118: */
119: public Map getFormatOptions() {
120: return formatOptions;
121: }
122:
123: /**
124: * DOCUMENT ME!
125: *
126: * @return DOCUMENT ME!
127: */
128: public int getHeight() {
129: return this .mandatoryParams.height;
130: }
131:
132: /**
133: * DOCUMENT ME!
134: *
135: * @return DOCUMENT ME!
136: */
137: public MapLayerInfo[] getLayers() {
138: return this .mandatoryParams.layers;
139: }
140:
141: /**
142: * Gets a list of the names of the styles to be returned by the server.
143: *
144: * @return A list of Strings of the names of the styles.
145: */
146: public List getStyles() {
147: return this .mandatoryParams.styles;
148: }
149:
150: /**
151: * Gets the url specified by the "SLD" parameter.
152: */
153: public URL getSld() {
154: return this .optionalParams.sld;
155: }
156:
157: /**
158: * Gets the string specified the "SLD_BODY" parameter.
159: */
160: public String getSldBody() {
161: return this .optionalParams.sldBody;
162: }
163:
164: /**
165: * Gets the value of the "VALIDATESCHEMA" parameter which controls wether
166: * the value of the "SLD paramter is schema validated.
167: */
168: public Boolean getValidateSchema() {
169: return this .optionalParams.validateSLD;
170: }
171:
172: /**
173: * Gets a list of the the filters that will be applied to each layer before rendering
174: *
175: * @return -
176: * @deprecated use {@link #getFilter()}.
177: */
178: public List getFilters() {
179: return this .optionalParams.filters;
180: }
181:
182: /**
183: * Gets a list of the the filters that will be applied to each layer before rendering
184: *
185: * @return A list of {@link Filter}.
186: *
187: */
188: public List getFilter() {
189: return this .optionalParams.filters;
190: }
191:
192: /**
193: * Gets a list of the cql filtesr that will be applied to each layer before
194: * rendering.
195: *
196: * @return A list of {@link Filter}.
197: *
198: */
199: public List getCQLFilter() {
200: return this .optionalParams.cqlFilters;
201: }
202:
203: /**
204: * Gets a list of the feature ids that will be used to filter each layer
205: * before rendering.
206: *
207: * @return A list of {@link String}.
208: */
209: public List getFeatureId() {
210: return this .optionalParams.featureIds;
211: }
212:
213: /**
214: * DOCUMENT ME!
215: *
216: * @return DOCUMENT ME!
217: *
218: */
219: public boolean isTransparent() {
220: return this .optionalParams.transparent;
221: }
222:
223: /**
224: * <a href="http://wiki.osgeo.org/index.php/WMS_Tiling_Client_Recommendation">WMS-C specification</a> tiling hint
225: *
226: */
227: public boolean isTiled() {
228: return this .optionalParams.tiled;
229: }
230:
231: public Point2D getTilesOrigin() {
232: return this .optionalParams.tilesOrigin;
233: }
234:
235: public int getBuffer() {
236: return this .optionalParams.buffer;
237: }
238:
239: public InverseColorMapOp getPalette() {
240: return this .optionalParams.paletteInverter;
241: }
242:
243: /**
244: * DOCUMENT ME!
245: *
246: * @return DOCUMENT ME!
247: */
248: public int getWidth() {
249: return this .mandatoryParams.width;
250: }
251:
252: /**
253: * @return the KML/KMZ score value for image vs. vector response
254: * @deprecated use <code>getFormatOptions().get( "kmscore" )</code>
255: */
256: public int getKMScore() {
257: Integer kmscore = (Integer) getFormatOptions().get("kmscore");
258:
259: if (kmscore != null) {
260: return kmscore.intValue();
261: }
262:
263: return 40; //old default
264: }
265:
266: /**
267: * @return true: return full attribution for placemark <description>
268: * @deprecated use <code>getFormatOptions().get( "kmattr" )</code>
269: */
270: public boolean getKMattr() {
271: Boolean kmattr = (Boolean) getFormatOptions().get("kmattr");
272:
273: if (kmattr != null) {
274: return kmattr.booleanValue();
275: }
276:
277: return true; //old default
278: }
279:
280: /**
281: * @return super overlay flag, <code>true</code> if super overlay requested.
282: * @deprecated use <code>getFormatOptions().get( "superoverlay" )</code>
283: */
284: public boolean getSuperOverlay() {
285: Boolean super Overlay = (Boolean) getFormatOptions().get(
286: "superoverlay");
287:
288: if (super Overlay != null) {
289: return super Overlay.booleanValue();
290: }
291:
292: return false; //old default
293: }
294:
295: /**
296: * @return kml legend flag, <code>true</code> if legend is enabled.
297: * @deprecated use <code>getFormatOptions().get( "legend" )</code>
298: */
299: public boolean getLegend() {
300: Boolean legend = (Boolean) getFormatOptions().get("legend");
301:
302: if (legend != null) {
303: return legend.booleanValue();
304: }
305:
306: return false; //old default
307: }
308:
309: /**
310: * @return The time request parameter.
311: */
312: public List getTime() {
313: return this .optionalParams.time;
314: }
315:
316: /**
317: * @return The elevation request parameter.
318: */
319: public Integer getElevation() {
320: return this .optionalParams.elevation;
321: }
322:
323: /**
324: * Returs the feature version optional parameter
325: * @return
326: */
327: public String getFeatureVersion() {
328: return this .optionalParams.featureVersion;
329: }
330:
331: /**
332: * Returns the remote OWS type
333: * @return
334: */
335: public String getRemoteOwsType() {
336: return optionalParams.remoteOwsType;
337: }
338:
339: /**
340: * Returs the remote OWS URL
341: * @return
342: */
343: public URL getRemoteOwsURL() {
344: return optionalParams.remoteOwsURL;
345: }
346:
347: /**
348: * Gets the raw kvp parameters which were used to create the request.
349: */
350: public Map getRawKvp() {
351: return rawKvp;
352: }
353:
354: /**
355: * DOCUMENT ME!
356: *
357: * @param bbox DOCUMENT ME!
358: */
359: public void setBbox(Envelope bbox) {
360: this .mandatoryParams.bbox = bbox;
361: }
362:
363: /**
364: * DOCUMENT ME!
365: *
366: * @param bgColor DOCUMENT ME!
367: */
368: public void setBgColor(java.awt.Color bgColor) {
369: this .optionalParams.bgColor = bgColor;
370: }
371:
372: /**
373: * DOCUMENT ME!
374: *
375: * @param crs DOCUMENT ME!
376: */
377: public void setCrs(CoordinateReferenceSystem crs) {
378: this .optionalParams.crs = crs;
379: }
380:
381: /**
382: * DOCUMENT ME!
383: *
384: * @param crs DOCUMENT ME!
385: */
386: public void setSRS(String srs) {
387: this .optionalParams.srs = srs;
388: }
389:
390: /**
391: * DOCUMENT ME!
392: *
393: * @param exceptions DOCUMENT ME!
394: */
395: public void setExceptions(String exceptions) {
396: this .optionalParams.exceptions = exceptions;
397: }
398:
399: /**
400: * DOCUMENT ME!
401: *
402: * @param format DOCUMENT ME!
403: */
404: public void setFormat(String format) {
405: this .mandatoryParams.format = format;
406: }
407:
408: /**
409: * Sets the format options.
410: *
411: * @param formatOptions A map of String,Object
412: * @see #getFormatOptions()
413: */
414: public void setFormatOptions(Map formatOptions) {
415: this .formatOptions = formatOptions;
416: }
417:
418: /**
419: * DOCUMENT ME!
420: *
421: * @param height DOCUMENT ME!
422: */
423: public void setHeight(int height) {
424: this .mandatoryParams.height = height;
425: }
426:
427: public void setHeight(Integer height) {
428: this .mandatoryParams.height = height.intValue();
429: }
430:
431: /**
432: * DOCUMENT ME!
433: *
434: * @param layers DOCUMENT ME!
435: */
436: public void setLayers(MapLayerInfo[] layers) {
437: this .mandatoryParams.layers = layers;
438: }
439:
440: public void setLayers(List /*<MapLayerInfo>*/layers) {
441: this .mandatoryParams.layers = (MapLayerInfo[]) layers
442: .toArray(new MapLayerInfo[layers.size()]);
443: }
444:
445: /**
446: * DOCUMENT ME!
447: *
448: * @param styles List<org.geotools.styling.Style>
449: */
450: public void setStyles(List styles) {
451: this .mandatoryParams.styles = styles;
452: }
453:
454: /**
455: * Sets the url specified by the "SLD" parameter.
456: */
457: public void setSld(URL sld) {
458: this .optionalParams.sld = sld;
459: }
460:
461: /**
462: * Sets the string specified by the "SLD_BODY" parameter
463: */
464: public void setSldBody(String sldBody) {
465: this .optionalParams.sldBody = sldBody;
466: }
467:
468: /**
469: * Sets the flag to validate the "SLD" parameter or not.
470: * //TODO
471: */
472: public void setValidateSchema(Boolean validateSLD) {
473: this .optionalParams.validateSLD = validateSLD;
474: }
475:
476: /**
477: * Sets a list of filters, one for each layer
478: *
479: * @param filters A list of {@link Filter}.
480: * @deprecated use {@link #setFilter(List)}.
481: */
482: public void setFilters(List filters) {
483: setFilter(filters);
484: }
485:
486: /**
487: * Sets a list of filters, one for each layer
488: *
489: * @param filters A list of {@link Filter}.
490: */
491: public void setFilter(List filters) {
492: this .optionalParams.filters = filters;
493: }
494:
495: /**
496: * Sets a list of filters ( cql ), one for each layer.
497: *
498: * @param cqlFilters A list of {@link Filter}.
499: */
500: public void setCQLFilter(List cqlFilters) {
501: this .optionalParams.cqlFilters = cqlFilters;
502: }
503:
504: /**
505: * Sets a list of feature ids, one for each layer.
506: *
507: * @param featureIds A list of {@link String}.
508: */
509: public void setFeatureId(List featureIds) {
510: this .optionalParams.featureIds = featureIds;
511: }
512:
513: /**
514: * DOCUMENT ME!
515: *
516: * @param transparent DOCUMENT ME!
517: */
518: public void setTransparent(boolean transparent) {
519: this .optionalParams.transparent = transparent;
520: }
521:
522: public void setTransparent(Boolean transparent) {
523: this .optionalParams.transparent = (transparent != null) ? transparent
524: .booleanValue()
525: : false;
526: }
527:
528: public void setBuffer(int buffer) {
529: this .optionalParams.buffer = buffer;
530: }
531:
532: public void setPalette(InverseColorMapOp paletteInverter) {
533: this .optionalParams.paletteInverter = paletteInverter;
534: }
535:
536: public void setBuffer(Integer buffer) {
537: this .optionalParams.buffer = (buffer != null) ? buffer
538: .intValue() : 0;
539: }
540:
541: public void setTiled(boolean tiled) {
542: this .optionalParams.tiled = tiled;
543: }
544:
545: public void setTiled(Boolean tiled) {
546: this .optionalParams.tiled = (tiled != null) ? tiled
547: .booleanValue() : false;
548: }
549:
550: public void setTilesOrigin(Point2D origin) {
551: this .optionalParams.tilesOrigin = origin;
552: }
553:
554: /**
555: * DOCUMENT ME!
556: *
557: * @param width DOCUMENT ME!
558: */
559: public void setWidth(int width) {
560: this .mandatoryParams.width = width;
561: }
562:
563: public void setWidth(Integer width) {
564: this .mandatoryParams.width = width.intValue();
565: }
566:
567: /**
568: * @param score the KML/KMZ score value for image vs. vector response, from 0 to 100
569: * @deprecated use <code>getFormatOptions().put( "kmscore", new Integer( score ) );</code>
570: */
571: public void setKMScore(int score) {
572: getFormatOptions().put("kmscore", new Integer(score));
573: }
574:
575: /**
576: * @param on true: full attribution; false: no attribution
577: * @deprecated use <code>getFormatOptions().put( "kmattr", new Boolean( on ) );</code>
578: */
579: public void setKMattr(boolean on) {
580: getFormatOptions().put("kmattr", new Boolean(on));
581: }
582:
583: /**
584: * Sets the super overlay parameter on the request.
585: * @deprecated use <code>getFormatOptions().put( "superoverlay", new Boolean( superOverlay ) );</code>
586: */
587: public void setSuperOverlay(boolean super Overlay) {
588: getFormatOptions().put("superoverlay",
589: new Boolean(super Overlay));
590: }
591:
592: /**
593: * Sets the kml legend parameter of the request.
594: * @deprecated use <code>getFormatOptions().put( "legend", new Boolean( legend ) );</code>
595: */
596: public void setLegend(boolean legend) {
597: getFormatOptions().put("legend", new Boolean(legend));
598: }
599:
600: /**
601: * Sets the time request parameter.
602: *
603: */
604: public void setTime(List time) {
605: this .optionalParams.time = time;
606: }
607:
608: /**
609: * Sets the elevation request parameter.
610: */
611: public void setElevation(Integer elevation) {
612: this .optionalParams.elevation = elevation;
613: }
614:
615: /**
616: * Sets the feature version optional param
617: * @param featureVersion
618: */
619: public void setFeatureVersion(String featureVersion) {
620: this .optionalParams.featureVersion = featureVersion;
621: }
622:
623: public void setRemoteOwsType(String remoteOwsType) {
624: this .optionalParams.remoteOwsType = remoteOwsType;
625: }
626:
627: public void setRemoteOwsURL(URL remoteOwsURL) {
628: this .optionalParams.remoteOwsURL = remoteOwsURL;
629: }
630:
631: /**
632: * Sets the raw kvp parameters which were used to create the request.
633: */
634: public void setRawKvp(Map rawKvp) {
635: this .rawKvp = rawKvp;
636: }
637:
638: /**
639: * decodes a color of the form <code>#FFFFFF</code> into a
640: * <code>java.awt.Color</code> object
641: *
642: * @param hexColor DOCUMENT ME!
643: *
644: * @return DOCUMENT ME!
645: */
646: private static final Color decodeColor(String hexColor) {
647: return Color.decode(hexColor);
648: }
649:
650: /**
651: * DOCUMENT ME!
652: *
653: * @author Gabriel Roldan, Axios Engineering
654: * @version $Id: GetMapRequest.java 7639 2007-10-22 15:18:58Z aaime $
655: */
656: private class MandatoryParameters {
657: /** ordered list of requested layers */
658: MapLayerInfo[] layers;
659:
660: /**
661: * ordered list of requested layers' styles, in a one to one
662: * relationship with <code>layers</code>
663: */
664: List styles;
665:
666: /** DOCUMENT ME! */
667: Envelope bbox;
668:
669: /** DOCUMENT ME! */
670: int width;
671:
672: /** DOCUMENT ME! */
673: int height;
674:
675: /** DOCUMENT ME! */
676: String format;
677: }
678:
679: /**
680: * DOCUMENT ME!
681: *
682: * @author Gabriel Roldan, Axios Engineering
683: * @version $Id: GetMapRequest.java 7639 2007-10-22 15:18:58Z aaime $
684: */
685: private class OptionalParameters {
686: /**
687: * the map's background color requested, or the default (white) if not
688: * specified
689: */
690: Color bgColor = DEFAULT_BG;
691:
692: /** from SRS (1.1) or CRS (1.2) param */
693: CoordinateReferenceSystem crs;
694:
695: /** EPSG code for the SRS */
696: String srs;
697:
698: /** vendor extensions, allows to filter each layer with a user defined filter */
699: List filters;
700:
701: /** cql filters */
702: List cqlFilters;
703:
704: /** feature id filters */
705: List featureIds;
706:
707: /** DOCUMENT ME! */
708: String exceptions = SE_XML;
709:
710: /** DOCUMENT ME! */
711: boolean transparent = false;
712:
713: /**
714: * Tiling hint, according to the
715: * <a href="http://wiki.osgeo.org/index.php/WMS_Tiling_Client_Recommendation">WMS-C specification</a>
716: */
717: boolean tiled;
718:
719: /**
720: * Temporary hack since finding a good tiling origin would require us to compute
721: * the bbox on the fly
722: * TODO: remove this once we cache the real bbox of vector layers
723: */
724: public Point2D tilesOrigin;
725:
726: /** the rendering buffer, in pixels **/
727: int buffer;
728:
729: /** The paletteInverter used for rendering, if any */
730: InverseColorMapOp paletteInverter;
731:
732: /** time elevation parameter, a list since many pattern setup can be possible, see
733: * for example http://mapserver.gis.umn.edu/docs/howto/wms_time_support/#time-patterns */
734: List time;
735:
736: /** time elevation parameter */
737: Integer elevation;
738:
739: /**
740: * SLD parameter
741: */
742: URL sld;
743:
744: /**
745: * SLD_BODY parameter
746: */
747: String sldBody;
748:
749: /** flag to validate SLD parameter */
750: Boolean validateSLD = Boolean.FALSE;
751:
752: /** feature version (for versioned requests) */
753: String featureVersion;
754:
755: /** Remote OWS type */
756: String remoteOwsType;
757:
758: /** Remote OWS url */
759: URL remoteOwsURL;
760: }
761:
762: /**
763: * Standard override of toString()
764: *
765: * @return a String representation of this request.
766: */
767: public String toString() {
768: StringBuffer returnString = new StringBuffer("\nGetMap Request");
769: returnString.append("\n version: " + version);
770: returnString.append("\n output format: "
771: + mandatoryParams.format);
772: returnString.append("\n width height: "
773: + mandatoryParams.height + "," + mandatoryParams.width);
774: returnString.append("\n bbox: " + mandatoryParams.bbox);
775: returnString.append("\n layers: ");
776:
777: for (int i = 0; i < mandatoryParams.layers.length; i++) {
778: returnString.append(mandatoryParams.layers[i].getName());
779:
780: if (i < (mandatoryParams.layers.length - 1)) {
781: returnString.append(",");
782: }
783: }
784:
785: returnString.append("\n styles: ");
786:
787: for (Iterator it = mandatoryParams.styles.iterator(); it
788: .hasNext();) {
789: Style s = (Style) it.next();
790: returnString.append(s.getName());
791:
792: if (it.hasNext()) {
793: returnString.append(",");
794: }
795: }
796:
797: //returnString.append("\n inside: " + filter.toString());
798: return returnString.toString();
799: }
800: }
|