001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2004-2006, Geotools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.data.wms;
017:
018: import java.io.IOException;
019: import java.net.URL;
020:
021: import org.geotools.data.ows.AbstractOpenWebService;
022: import org.geotools.data.ows.GetCapabilitiesRequest;
023: import org.geotools.data.ows.GetCapabilitiesResponse;
024: import org.geotools.data.ows.Layer;
025: import org.geotools.data.ows.OperationType;
026: import org.geotools.data.ows.Specification;
027: import org.geotools.data.ows.WMSCapabilities;
028: import org.geotools.data.wms.request.DescribeLayerRequest;
029: import org.geotools.data.wms.request.GetFeatureInfoRequest;
030: import org.geotools.data.wms.request.GetLegendGraphicRequest;
031: import org.geotools.data.wms.request.GetMapRequest;
032: import org.geotools.data.wms.request.GetStylesRequest;
033: import org.geotools.data.wms.request.PutStylesRequest;
034: import org.geotools.data.wms.response.DescribeLayerResponse;
035: import org.geotools.data.wms.response.GetFeatureInfoResponse;
036: import org.geotools.data.wms.response.GetLegendGraphicResponse;
037: import org.geotools.data.wms.response.GetMapResponse;
038: import org.geotools.data.wms.response.GetStylesResponse;
039: import org.geotools.data.wms.response.PutStylesResponse;
040: import org.geotools.geometry.GeneralEnvelope;
041: import org.geotools.ows.ServiceException;
042: import org.opengis.referencing.crs.CoordinateReferenceSystem;
043:
044: /**
045: * WebMapServer is a class representing a WMS. It is used to access the
046: * Capabilities document and perform requests. It supports multiple versions
047: * and will perform version negotiation automatically and use the highest
048: * known version that the server can communicate.
049: *
050: * If restriction of versions to be used is desired, this class should be
051: * subclassed and it's setupSpecifications() method over-ridden. It should
052: * add which version/specifications are to be used to the specs array. See
053: * the current implementation for an example.
054: *
055: * Example usage:
056: * <code><pre>
057: * WebMapServer wms = new WebMapServer("http://some.example.com/wms");
058: * WMSCapabilities capabilities = wms.getCapabilities();
059: * GetMapRequest request = wms.getMapRequest();
060: *
061: * ... //configure request
062: *
063: * GetMapResponse response = (GetMapResponse) wms.issueRequest(request);
064: *
065: * ... //extract image from the response
066: * </pre></code>
067: *
068: * @author Richard Gould, Refractions Research
069: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/plugin/wms/src/main/java/org/geotools/data/wms/WebMapServer.java $
070: */
071: public class WebMapServer extends AbstractOpenWebService {
072:
073: /**
074: * Creates a new WebMapServer instance and attempts to retrieve the
075: * Capabilities document specified by serverURL.
076: *
077: * @param serverURL a URL that points to the capabilities document of a server
078: * @throws IOException if there is an error communicating with the server
079: * @throws ServiceException if the server responds with an error
080: */
081: public WebMapServer(final URL serverURL) throws IOException,
082: ServiceException {
083: super (serverURL);
084: }
085:
086: /**
087: * Sets up the specifications/versions that this server is capable of
088: * communicating with.
089: */
090: protected void setupSpecifications() {
091: specs = new Specification[4];
092: specs[0] = new WMS1_0_0();
093: specs[1] = new WMS1_1_0();
094: specs[2] = new WMS1_1_1();
095: specs[3] = new WMS1_3_0();
096: }
097:
098: public GetCapabilitiesResponse issueRequest(
099: GetCapabilitiesRequest request) throws IOException,
100: ServiceException {
101: return (GetCapabilitiesResponse) internalIssueRequest(request);
102: }
103:
104: public GetMapResponse issueRequest(GetMapRequest request)
105: throws IOException, ServiceException {
106: return (GetMapResponse) internalIssueRequest(request);
107: }
108:
109: public GetFeatureInfoResponse issueRequest(
110: GetFeatureInfoRequest request) throws IOException,
111: ServiceException {
112: return (GetFeatureInfoResponse) internalIssueRequest(request);
113: }
114:
115: public DescribeLayerResponse issueRequest(
116: DescribeLayerRequest request) throws IOException,
117: ServiceException {
118: return (DescribeLayerResponse) internalIssueRequest(request);
119: }
120:
121: public GetLegendGraphicResponse issueRequest(
122: GetLegendGraphicRequest request) throws IOException,
123: ServiceException {
124: return (GetLegendGraphicResponse) internalIssueRequest(request);
125: }
126:
127: public GetStylesResponse issueRequest(GetStylesRequest request)
128: throws IOException, ServiceException {
129: return (GetStylesResponse) internalIssueRequest(request);
130: }
131:
132: public PutStylesResponse issueRequest(PutStylesRequest request)
133: throws IOException, ServiceException {
134: return (PutStylesResponse) internalIssueRequest(request);
135: }
136:
137: /**
138: * Get the getCapabilities document. If there was an error parsing it
139: * during creation, it will return null (and it should have thrown an
140: * exception during creation).
141: *
142: * @return a WMSCapabilities object, representing the Capabilities of the server
143: */
144: public WMSCapabilities getCapabilities() {
145: return (WMSCapabilities) capabilities;
146: }
147:
148: private WMSSpecification getSpecification() {
149: return (WMSSpecification) specification;
150: }
151:
152: private URL findURL(OperationType operation) {
153: if (operation.getGet() != null) {
154: return operation.getGet();
155: }
156: return serverURL;
157: }
158:
159: /**
160: * Creates a GetMapRequest that can be configured and then passed to
161: * issueRequest().
162: *
163: * @return a configureable GetMapRequest object
164: */
165: public GetMapRequest createGetMapRequest() {
166: URL onlineResource = findURL(getCapabilities().getRequest()
167: .getGetMap());
168:
169: return (GetMapRequest) getSpecification().createGetMapRequest(
170: onlineResource);
171: }
172:
173: /**
174: * Creates a GetFeatureInfoRequest that can be configured and then passed to
175: * issueRequest().
176: *
177: * @param getMapRequest a previous configured GetMapRequest
178: * @return a GetFeatureInfoRequest
179: * @throws UnsupportedOperationException if the server does not support GetFeatureInfo
180: */
181: public GetFeatureInfoRequest createGetFeatureInfoRequest(
182: GetMapRequest getMapRequest) {
183: if (getCapabilities().getRequest().getGetFeatureInfo() == null) {
184: throw new UnsupportedOperationException(
185: "This Web Map Server does not support GetFeatureInfo requests");
186: }
187:
188: URL onlineResource = findURL(getCapabilities().getRequest()
189: .getGetFeatureInfo());
190:
191: GetFeatureInfoRequest request = getSpecification()
192: .createGetFeatureInfoRequest(onlineResource,
193: getMapRequest);
194:
195: return request;
196: }
197:
198: public DescribeLayerRequest createDescribeLayerRequest()
199: throws UnsupportedOperationException {
200: if (getCapabilities().getRequest().getDescribeLayer() == null) {
201: throw new UnsupportedOperationException(
202: "Server does not specify a DescribeLayer operation. Cannot be performed");
203: }
204:
205: URL onlineResource = getCapabilities().getRequest()
206: .getDescribeLayer().getGet();
207: if (onlineResource == null) {
208: onlineResource = serverURL;
209: }
210:
211: DescribeLayerRequest request = getSpecification()
212: .createDescribeLayerRequest(onlineResource);
213:
214: return request;
215: }
216:
217: public GetLegendGraphicRequest createGetLegendGraphicRequest()
218: throws UnsupportedOperationException {
219: if (getCapabilities().getRequest().getGetLegendGraphic() == null) {
220: throw new UnsupportedOperationException(
221: "Server does not specify a GetLegendGraphic operation. Cannot be performed");
222: }
223:
224: URL onlineResource = getCapabilities().getRequest()
225: .getGetLegendGraphic().getGet();
226: if (onlineResource == null) {
227: onlineResource = serverURL;
228: }
229:
230: GetLegendGraphicRequest request = getSpecification()
231: .createGetLegendGraphicRequest(onlineResource);
232:
233: return request;
234: }
235:
236: public GetStylesRequest createGetStylesRequest()
237: throws UnsupportedOperationException {
238: if (getCapabilities().getRequest().getGetStyles() == null) {
239: throw new UnsupportedOperationException(
240: "Server does not specify a GetStyles operation. Cannot be performed");
241: }
242:
243: URL onlineResource = getCapabilities().getRequest()
244: .getGetStyles().getGet();
245: if (onlineResource == null) {
246: onlineResource = serverURL;
247: }
248:
249: GetStylesRequest request = getSpecification()
250: .createGetStylesRequest(onlineResource);
251:
252: return request;
253: }
254:
255: public PutStylesRequest createPutStylesRequest()
256: throws UnsupportedOperationException {
257: if (getCapabilities().getRequest().getPutStyles() == null) {
258: throw new UnsupportedOperationException(
259: "Server does not specify a PutStyles operation. Cannot be performed");
260: }
261:
262: URL onlineResource = getCapabilities().getRequest()
263: .getPutStyles().getGet();
264: if (onlineResource == null) {
265: onlineResource = serverURL;
266: }
267:
268: PutStylesRequest request = getSpecification()
269: .createPutStylesRequest(onlineResource);
270: return request;
271: }
272:
273: /**
274: * Given a layer and a coordinate reference system, will locate an envelope
275: * for that layer in that CRS. If the layer is declared to support that CRS,
276: * but no envelope can be found, it will try to calculate an appropriate
277: * bounding box.
278: *
279: * If null is returned, no valid bounding box could be found and one couldn't
280: * be transformed from another.
281: *
282: * @param layer
283: * @param crs
284: * @return an Envelope containing a valid bounding box, or null if none are found
285: */
286: public GeneralEnvelope getEnvelope(Layer layer,
287: CoordinateReferenceSystem crs) {
288: return layer.getEnvelope(crs);
289: }
290: }
|