Source Code Cross Referenced for KMLReflector.java in  » GIS » GeoServer » org » vfny » geoserver » wms » servlets » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoServer » org.vfny.geoserver.wms.servlets 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.servlets;
006:
007:        import com.vividsolutions.jts.geom.Envelope;
008:
009:        import org.geoserver.ows.util.KvpUtils;
010:        import org.geoserver.ows.util.RequestUtils;
011:        import org.geoserver.platform.GeoServerExtensions;
012:        import org.geotools.styling.Style;
013:        import org.springframework.context.ApplicationContext;
014:        import org.springframework.web.context.support.WebApplicationContextUtils;
015:        import org.vfny.geoserver.Response;
016:        import org.vfny.geoserver.ServiceException;
017:        import org.vfny.geoserver.config.WMSConfig;
018:        import org.vfny.geoserver.global.GeoServer;
019:        import org.vfny.geoserver.global.MapLayerInfo;
020:        import org.vfny.geoserver.global.WMS;
021:        import org.vfny.geoserver.util.requests.readers.KvpRequestReader;
022:        import org.vfny.geoserver.util.requests.readers.XmlRequestReader;
023:        import org.vfny.geoserver.wms.requests.GetKMLReflectKvpReader;
024:        import org.vfny.geoserver.wms.requests.GetMapRequest;
025:        import org.vfny.geoserver.wms.responses.GetMapResponse;
026:        import org.vfny.geoserver.wms.responses.map.kml.KMLMapProducerFactory;
027:        import java.io.BufferedOutputStream;
028:        import java.io.IOException;
029:        import java.util.ArrayList;
030:        import java.util.Enumeration;
031:        import java.util.HashMap;
032:        import java.util.List;
033:        import java.util.Map;
034:        import java.util.logging.Logger;
035:        import javax.servlet.ServletConfig;
036:        import javax.servlet.ServletException;
037:        import javax.servlet.http.HttpServletRequest;
038:        import javax.servlet.http.HttpServletResponse;
039:
040:        /**
041:         * This class takes in a simple WMS request, presumably from Google Earth, and
042:         * produces a completed WMS request that outputs KML/KMZ. To map a request to
043:         * this, simple pass a "layers=myLayer" parameter to "wms/kml_reflect":
044:         * <b>http://localhost:8080/geoserver/wms/kml_reflect?layers=states<b>
045:         * No extra information, such as styles or EPSG code need to be passed.
046:         * A request to kml_reflect will return a network link for each layer
047:         * passed in. Each network layer makes a full WMS request with these
048:         * default values:
049:         * - smart KMZ output (vector or raster output)
050:         * - KMScore value of 30
051:         * - Image size of 1024x1024
052:         * - Full attribution on vector features
053:         * - WMS version 1.0.0
054:         * - Transparent
055:         *
056:         *
057:         * @author Brent Owens
058:         * 
059:         * @deprecated use {@link org.vfny.geoserver.wms.responses.map.kml.KMLReflector}.
060:         *
061:         */
062:        public class KMLReflector extends WMService {
063:            private static Logger LOGGER = org.geotools.util.logging.Logging
064:                    .getLogger("org.vfny.geoserver.wms.servlets");
065:            final String KML_MIME_TYPE = "application/vnd.google-earth.kml+xml";
066:            final String KMZ_MIME_TYPE = "application/vnd.google-earth.kmz+xml";
067:
068:            // Values for the prepared WMS request. Later move these to web.xml server config
069:            final int KMSCORE = 50;
070:            final int REFRESH = 1;
071:            final boolean KMATTR = true;
072:            final boolean TRANSPARENT = true;
073:            final int WIDTH = 1024;
074:            final int HEIGHT = 1024;
075:            final String VERSION = "1.0.0";
076:            final String SRS = "EPSG:4326";
077:            final String DEFAULT_BBOX = "-180,-90,180,90";
078:
079:            public KMLReflector() {
080:                super ("kml_reflect", null);
081:            }
082:
083:            public void init(ServletConfig config) throws ServletException {
084:                super .init(config);
085:                setWMS((WMS) config.getServletContext().getAttribute(
086:                        WMS.WEB_CONTAINER_KEY));
087:            }
088:
089:            protected Response getResponseHandler() {
090:                ApplicationContext context = WebApplicationContextUtils
091:                        .getWebApplicationContext(getServletContext());
092:
093:                //return new GetMapResponse(config);
094:                return new GetMapResponse(getWMS(), context);
095:            }
096:
097:            protected KvpRequestReader getKvpReader(Map params) {
098:                return new GetKMLReflectKvpReader(params, this );
099:            }
100:
101:            protected XmlRequestReader getXmlRequestReader() {
102:                /**
103:                 * @todo Implement this org.vfny.geoserver.servlets.AbstractService
104:                 *       abstract method
105:                 */
106:                throw new java.lang.UnsupportedOperationException(
107:                        "Method getXmlRequestReader() not yet implemented.");
108:            }
109:
110:            /**
111:             * This will create a <folder> with <networklinks>, one network link
112:             * for each layer.
113:             * The only mandatory parameter is "layers" with the layer names.
114:             * Styles is optional, and so are all other parameters such as:
115:             * KMScore
116:             * KMAttr
117:             * Version
118:             * Width
119:             * Height
120:             * SRS
121:             *
122:             * The result is written to the buffered output stream.
123:             */
124:            public void doGet(HttpServletRequest request,
125:                    HttpServletResponse response) throws ServletException,
126:                    IOException {
127:                //set to KML mime type, so GEarth opens automatically
128:                response.setContentType(KMLMapProducerFactory.MIME_TYPE);
129:
130:                // the output stream we will write to
131:                BufferedOutputStream out = new BufferedOutputStream(response
132:                        .getOutputStream());
133:
134:                Map requestParams = new HashMap();
135:                String paramName;
136:                String paramValue;
137:
138:                // gather the parameters
139:                for (Enumeration pnames = request.getParameterNames(); pnames
140:                        .hasMoreElements();) {
141:                    paramName = (String) pnames.nextElement();
142:                    paramValue = request.getParameter(paramName);
143:                    requestParams.put(paramName.toUpperCase(), paramValue);
144:                }
145:
146:                // Some settings for network links don't pass in a bounding box, so we will
147:                // supply one in that case that covers the whole world (pray your data isn't big and
148:                // the KMScore value isn't large)
149:                if (!requestParams.containsKey("BBOX")) {
150:                    requestParams.put("BBOX", DEFAULT_BBOX);
151:                }
152:
153:                KvpRequestReader requestReader = getKvpReader(requestParams);
154:
155:                GetMapRequest serviceRequest;
156:
157:                try {
158:                    serviceRequest = (GetMapRequest) requestReader
159:                            .getRequest(request);
160:                } catch (ServiceException e) {
161:                    e.printStackTrace();
162:
163:                    return;
164:                }
165:
166:                final MapLayerInfo[] layers = serviceRequest.getLayers();
167:                LOGGER.info("KML NetworkLink sharing " + layers.length
168:                        + " layer(s) created.");
169:
170:                Style[] styles = null;
171:
172:                if ((serviceRequest.getStyles() != null)
173:                        && !serviceRequest.getStyles().isEmpty()) {
174:                    styles = (Style[]) serviceRequest.getStyles().toArray(
175:                            new Style[] {});
176:                }
177:
178:                // fill in our default values for the request if the user didn't pass the value in
179:                if (!requestParams.containsKey("TRANSPARENT")) {
180:                    serviceRequest.setTransparent(TRANSPARENT);
181:                }
182:
183:                if (!requestParams.containsKey("KMATTR")) {
184:                    serviceRequest.setKMattr(KMATTR);
185:                }
186:
187:                if (!requestParams.containsKey("KMSCORE")) {
188:                    serviceRequest.setKMScore(KMSCORE);
189:                }
190:
191:                if (!requestParams.containsKey("WIDTH")) {
192:                    serviceRequest.setWidth(WIDTH);
193:                }
194:
195:                if (!requestParams.containsKey("HEIGHT")) {
196:                    serviceRequest.setHeight(HEIGHT);
197:                }
198:
199:                if (!requestParams.containsKey("VERSION")) {
200:                    serviceRequest.setVersion(VERSION);
201:                }
202:
203:                List filters = null;
204:                String filterKey = null;
205:                if (requestParams.containsKey("FILTER")) {
206:                    String filter = (String) requestParams.get("FILTER");
207:                    filters = KvpUtils.readFlat(filter,
208:                            KvpUtils.OUTER_DELIMETER);
209:                    filterKey = "filter";
210:                } else if (requestParams.containsKey("CQL_FILTER")) {
211:                    String filter = (String) requestParams.get("CQL_FILTER");
212:                    filters = KvpUtils.readFlat(filter, KvpUtils.CQL_DELIMITER);
213:                    filterKey = "cql_filter";
214:                } else if (requestParams.containsKey("FEATUREID")) {
215:                    //JD: featureid semantics slightly different then other types of 
216:                    // filters
217:                    String filter = (String) requestParams.get("FEATUREID");
218:                    filters = new ArrayList();
219:                    for (int i = 0; i < layers.length; i++) {
220:                        filters.add(filter);
221:                    }
222:                    filterKey = "featureid";
223:                }
224:
225:                if (filters != null && filters.size() != layers.length) {
226:                    throw (IOException) new IOException()
227:                            .initCause(new ServiceException(layers.length
228:                                    + " layers specified, but "
229:                                    + filters.size() + " filters"));
230:                }
231:
232:                //set the content disposition
233:                StringBuffer filename = new StringBuffer();
234:                for (int i = 0; i < layers.length; i++) {
235:                    String name = layers[i].getName();
236:
237:                    //strip off prefix
238:                    int j = name.indexOf(':');
239:                    if (j > -1) {
240:                        name = name.substring(j + 1);
241:                    }
242:
243:                    filename.append(name + "_");
244:                }
245:                filename.setLength(filename.length() - 1);
246:
247:                response.setHeader("Content-Disposition",
248:                        "attachment; filename=" + filename.toString() + ".kml");
249:
250:                // we use the mandatory SRS value of 4326 (lat/lon)
251:                serviceRequest.setFormat(KML_MIME_TYPE); // output mime type of KML
252:
253:                StringBuffer sb = new StringBuffer();
254:                sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
255:                sb.append("<kml xmlns=\"http://earth.google.com/kml/2.0\">\n");
256:
257:                sb.append("<Folder>\n");
258:
259:                String proxifiedBaseUrl = RequestUtils.baseURL(request);
260:                GeoServer gs = (GeoServer) GeoServerExtensions.extensions(
261:                        GeoServer.class).get(0);
262:                proxifiedBaseUrl = RequestUtils.proxifiedBaseURL(
263:                        proxifiedBaseUrl, gs.getProxyBaseUrl());
264:
265:                Envelope layerbbox = null;
266:
267:                // make a network link for every layer
268:                for (int i = 0; i < layers.length; i++) {
269:                    //if (layers[i].getType() == MapLayerInfo.TYPE_VECTOR) {
270:                    String style = "&styles="
271:                            + layers[i].getDefaultStyle().getName();
272:
273:                    if ((styles != null) && (styles.length >= (i + 1))) { // if the user specified styles
274:                        style = "&styles=" + styles[i].getName(); // use them, else we use the default style
275:                    }
276:
277:                    String filter = (String) (filters != null ? filters.get(i)
278:                            : null);
279:                    if (filter != null) {
280:                        filter = "&" + filterKey + "=" + filter;
281:                    } else {
282:                        filter = "";
283:                    }
284:
285:                    //Envelope le = (layers[i].getFeature() == null ? layers[i].getBoundingBox() : layers[i].getFeature().getLatLongBoundingBox());
286:                    Envelope le = layers[i].getLatLongBoundingBox();
287:                    if (layerbbox == null) {
288:                        layerbbox = new Envelope(le);
289:                    } else {
290:                        layerbbox.expandToInclude(le);
291:                    }
292:
293:                    if (serviceRequest.getSuperOverlay()) {
294:                        Envelope bbox = serviceRequest.getBbox();
295:
296:                        sb.append("<NetworkLink>\n");
297:                        sb.append("<name>" + layers[0].getName() + "</name>\n");
298:                        sb.append("<Region>");
299:                        sb.append("<LatLonAltBox>");
300:                        sb.append("<north>" + bbox.getMaxY() + "</north>");
301:                        sb.append("<south>" + bbox.getMinY() + "</south>");
302:                        sb.append("<east>" + bbox.getMaxX() + "</east>");
303:                        sb.append("<west>" + bbox.getMinX() + "</west>");
304:                        sb.append("</LatLonAltBox>");
305:                        sb.append("<Lod>");
306:                        sb.append("<minLodPixels>256</minLodPixels>");
307:                        sb.append("<maxLodPixels>-1</maxLodPixels>");
308:                        sb.append("</Lod>");
309:                        sb.append("</Region>");
310:
311:                        sb.append("<Link>\n");
312:                        sb
313:                                .append("<href><![CDATA["
314:                                        + proxifiedBaseUrl
315:                                        + "/wms?service=WMS&request=GetMap&format=application/vnd.google-earth.kml+XML"
316:                                        + "&width="
317:                                        + WIDTH
318:                                        + "&height="
319:                                        + HEIGHT
320:                                        + "&srs="
321:                                        + SRS
322:                                        + "&layers="
323:                                        + layers[i].getName()
324:                                        + style
325:                                        + "&bbox="
326:                                        + (String) requestParams.get("BBOX")
327:                                        + filter
328:                                        + "&legend="
329:                                        + String.valueOf(serviceRequest
330:                                                .getLegend())
331:                                        + "&superoverlay=true]]></href>\n");
332:                        sb
333:                                .append("<viewRefreshMode>onRegion</viewRefreshMode>\n");
334:
335:                        sb.append("</Link>\n");
336:                        sb.append("</NetworkLink>\n");
337:                    } else {
338:
339:                        sb.append("<NetworkLink>\n");
340:                        sb.append(getLookAt(le));
341:                        sb.append("<name>" + layers[i].getName() + "</name>\n");
342:                        sb.append("<open>1</open>\n");
343:                        sb.append("<visibility>1</visibility>\n");
344:                        sb.append("<Url>\n");
345:                        sb
346:                                .append("<href><![CDATA["
347:                                        + proxifiedBaseUrl
348:                                        + "/wms?service=WMS&request=GetMap&format=application/vnd.google-earth.kmz+XML"
349:                                        + "&width="
350:                                        + WIDTH
351:                                        + "&height="
352:                                        + HEIGHT
353:                                        + "&srs="
354:                                        + SRS
355:                                        + "&layers="
356:                                        + layers[i].getName()
357:                                        + style
358:                                        + filter // optional
359:                                        + "&KMScore="
360:                                        + serviceRequest.getKMScore()
361:                                        + "&KMAttr="
362:                                        + String.valueOf(serviceRequest
363:                                                .getKMattr())
364:                                        + "&legend="
365:                                        + String.valueOf(serviceRequest
366:                                                .getLegend()) + "]]></href>\n");
367:                        sb
368:                                .append("<viewRefreshMode>onStop</viewRefreshMode>\n");
369:                        sb.append("<viewRefreshTime>" + REFRESH
370:                                + "</viewRefreshTime>\n");
371:                        sb.append("</Url>\n");
372:                        sb.append("</NetworkLink>\n");
373:                    }
374:                }
375:
376:                sb.append(getLookAt(layerbbox));
377:
378:                sb.append("</Folder>\n");
379:
380:                sb.append("</kml>\n");
381:
382:                byte[] kml_b = sb.toString().getBytes();
383:                out.write(kml_b);
384:                out.flush();
385:            }
386:
387:            private String getLookAt(Envelope e) {
388:                double lon1 = e.getMinX();
389:                double lat1 = e.getMinY();
390:                double lon2 = e.getMaxX();
391:                double lat2 = e.getMaxY();
392:
393:                double R_EARTH = 6.371 * 1000000; // meters
394:                double VIEWER_WIDTH = 22 * Math.PI / 180; // The field of view of the google maps camera, in radians
395:                double[] p1 = getRect(lon1, lat1, R_EARTH);
396:                double[] p2 = getRect(lon2, lat2, R_EARTH);
397:                double[] midpoint = new double[] { (p1[0] + p2[0]) / 2,
398:                        (p1[1] + p2[1]) / 2, (p1[2] + p2[2]) / 2 };
399:
400:                midpoint = getGeographic(midpoint[0], midpoint[1], midpoint[2]);
401:
402:                // averaging the longitudes; using the rectangular coordinates makes the calculated center tend toward the corner that's closer to the equator. 
403:                midpoint[0] = ((lon1 + lon2) / 2);
404:
405:                double distance = distance(p1, p2);
406:
407:                double height = distance / (2 * Math.tan(VIEWER_WIDTH));
408:
409:                LOGGER.fine("lat1: " + lat1 + "; lon1: " + lon1);
410:                LOGGER.fine("lat2: " + lat2 + "; lon2: " + lon2);
411:                LOGGER.fine("latmid: " + midpoint[1] + "; lonmid: "
412:                        + midpoint[0]);
413:
414:                return "<LookAt id=\"geoserver\">"
415:                        + "  <longitude>"
416:                        + ((lon1 + lon2) / 2)
417:                        + "</longitude>      <!-- kml:angle180 -->"
418:                        + "  <latitude>"
419:                        + midpoint[1]
420:                        + "</latitude>        <!-- kml:angle90 -->"
421:                        + "  <altitude>0</altitude>       <!-- double --> "
422:                        + "  <range>"
423:                        + distance
424:                        + "</range>              <!-- double -->"
425:                        + "  <tilt>0</tilt>               <!-- float -->"
426:                        + "  <heading>0</heading>         <!-- float -->"
427:                        + "  <altitudeMode>clampToGround</altitudeMode> "
428:                        + "  <!--kml:altitudeModeEnum:clampToGround, relativeToGround, absolute -->"
429:                        + "</LookAt>";
430:            }
431:
432:            private double[] getRect(double lat, double lon, double radius) {
433:                double theta = (90 - lat) * Math.PI / 180;
434:                double phi = (90 - lon) * Math.PI / 180;
435:
436:                double x = radius * Math.sin(phi) * Math.cos(theta);
437:                double y = radius * Math.sin(phi) * Math.sin(theta);
438:                double z = radius * Math.cos(phi);
439:                return new double[] { x, y, z };
440:            }
441:
442:            private double[] getGeographic(double x, double y, double z) {
443:                double theta, phi, radius;
444:                radius = distance(new double[] { x, y, z }, new double[] { 0,
445:                        0, 0 });
446:                theta = Math.atan2(Math.sqrt(x * x + y * y), z);
447:                phi = Math.atan2(y, x);
448:
449:                double lat = 90 - (theta * 180 / Math.PI);
450:                double lon = 90 - (phi * 180 / Math.PI);
451:
452:                return new double[] { (lon > 180 ? lon - 360 : lon), lat,
453:                        radius };
454:            }
455:
456:            private double distance(double[] p1, double[] p2) {
457:                double dx = p1[0] - p2[0];
458:                double dy = p1[1] - p2[1];
459:                double dz = p1[2] - p2[2];
460:                return Math.sqrt(dx * dx + dy * dy + dz * dz);
461:            }
462:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.