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.responses.map.kml;
006:
007: import com.vividsolutions.jts.geom.Envelope;
008:
009: import net.opengis.ows.WGS84BoundingBoxType;
010:
011: import org.geotools.geometry.jts.ReferencedEnvelope;
012: import org.geotools.map.MapLayer;
013: import org.geotools.referencing.CRS;
014: import org.geotools.referencing.crs.DefaultGeocentricCRS;
015: import org.geotools.referencing.crs.DefaultGeographicCRS;
016: import org.geotools.xml.transform.TransformerBase;
017: import org.geotools.xml.transform.Translator;
018: import org.vfny.geoserver.util.Requests;
019: import org.vfny.geoserver.wms.WMSMapContext;
020: import org.vfny.geoserver.wms.WmsException;
021: import org.vfny.geoserver.wms.requests.GetMapRequest;
022: import org.xml.sax.ContentHandler;
023: import java.util.Map;
024:
025: /**
026: * Tranforms a feature colleciton to a kml "Document" element which contains a
027: * "Folder" element consisting of "GroundOverlay" elements.
028: * <p>
029: * Usage:
030: * <pre>
031: * <code>
032: * //have a reference to a map context and output stream
033: * WMSMapContext context = ...
034: * OutputStream output = ...;
035: *
036: * KMLRasterTransformer tx = new KMLRasterTransformer( context );
037: * for ( int i = 0; i < context.getLayerCount(); i++ ) {
038: * MapLayer mapLayer = mapConext.getMapLayer( i );
039: *
040: * //transform
041: * tx.transform( mapLayer, output );
042: * }
043: * </code>
044: * </pre>
045: * </p>
046: * <p>
047: * The inline parameter {@link #setInline(boolean)} controls wether the images
048: * for the request are refernces "inline" as local images, or remoteley as wms
049: * requests.
050: * </p>
051: *
052: * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
053: *
054: */
055: public class KMLRasterTransformer extends KMLTransformerBase {
056: /**
057: * The map context
058: */
059: final WMSMapContext mapContext;
060:
061: /**
062: * Flag controlling wether images are refernces inline or as remote wms calls.
063: */
064: boolean inline = false;
065:
066: public KMLRasterTransformer(WMSMapContext mapContext) {
067: this .mapContext = mapContext;
068:
069: setNamespaceDeclarationEnabled(false);
070: }
071:
072: public void setInline(boolean inline) {
073: this .inline = inline;
074: }
075:
076: public Translator createTranslator(ContentHandler handler) {
077: return new KMLRasterTranslator(handler);
078: }
079:
080: class KMLRasterTranslator extends KMLTranslatorSupport {
081: public KMLRasterTranslator(ContentHandler handler) {
082: super (handler);
083: }
084:
085: public void encode(Object o) throws IllegalArgumentException {
086: MapLayer mapLayer = (MapLayer) o;
087: int mapLayerOrder = mapContext.indexOf(mapLayer);
088:
089: if (isStandAlone()) {
090: start("kml");
091: }
092:
093: //start("Document");
094: //element("name", mapLayer.getTitle());
095:
096: //start the folder naming it 'layer_<mapLayerOrder>', this is
097: // necessary for a GroundOverlay
098: start("Folder");
099: element("name", "layer_" + mapLayerOrder);
100: element("description", mapLayer.getTitle());
101:
102: start("GroundOverlay");
103: //element( "name", feature.getID() );
104: element("name", mapLayer.getTitle());
105: element("drawOrder", Integer.toString(mapLayerOrder));
106:
107: //encode the icon
108: start("Icon");
109:
110: encodeHref(mapLayer);
111:
112: element("viewRefreshMode", "never");
113: element("viewBoundScale", "0.75");
114: end("Icon");
115:
116: //encde the bounding box
117: ReferencedEnvelope box = new ReferencedEnvelope(mapContext
118: .getAreaOfInterest());
119: boolean reprojectBBox = (box.getCoordinateReferenceSystem() != null)
120: && !CRS.equalsIgnoreMetadata(box
121: .getCoordinateReferenceSystem(),
122: DefaultGeographicCRS.WGS84);
123: if (reprojectBBox) {
124: try {
125: box = box.transform(DefaultGeographicCRS.WGS84,
126: true);
127: } catch (Exception e) {
128: throw new WmsException(
129: "Could not transform bbox to WGS84",
130: "ReprojectionError", e);
131: }
132: }
133: start("LatLonBox");
134: element("north", Double.toString(box.getMaxY()));
135: element("south", Double.toString(box.getMinY()));
136: element("east", Double.toString(box.getMaxX()));
137: element("west", Double.toString(box.getMinX()));
138: end("LatLonBox");
139:
140: end("GroundOverlay");
141:
142: end("Folder");
143:
144: //end("Document");
145: if (isStandAlone()) {
146: end("kml");
147: }
148: }
149:
150: protected void encodeHref(MapLayer mapLayer) {
151: if (inline) {
152: //inline means reference the image "inline" as in kmz
153: // use the mapLayerOrder
154: int mapLayerOrder = mapContext.indexOf(mapLayer);
155: element("href", "layer_" + mapLayerOrder + ".png");
156: } else {
157: //reference the image as a remote wms call
158: element("href", KMLUtils.getMapUrl(mapContext,
159: mapLayer, false));
160: }
161: }
162: }
163: }
|