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.util.ArrayList;
019: import java.util.Collections;
020: import java.util.HashMap;
021: import java.util.HashSet;
022: import java.util.Iterator;
023: import java.util.List;
024: import java.util.Map;
025: import java.util.Set;
026: import java.util.TreeSet;
027:
028: import org.geotools.data.ows.Layer;
029: import org.geotools.data.ows.WMSCapabilities;
030: import org.geotools.referencing.CRS;
031: import org.opengis.metadata.Identifier;
032: import org.opengis.referencing.FactoryException;
033: import org.opengis.referencing.NoSuchAuthorityCodeException;
034: import org.opengis.referencing.crs.CoordinateReferenceSystem;
035: import org.opengis.referencing.operation.MathTransform;
036:
037: /**
038: * Provides miscellaneous utility methods for use with WMSs.
039: *
040: * @author Richard Gould
041: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/plugin/wms/src/main/java/org/geotools/data/wms/WMSUtils.java $
042: */
043: public class WMSUtils {
044: /**
045: * Utility method to return each layer that has a name. This method maintains no hierarchy at all.
046: *
047: * @return An array of Layers, each value has a it's name property set or an empty array if there are none. It will return null if there is no capabilities document
048: *
049: */
050: public static Layer[] getNamedLayers(WMSCapabilities capabilities) {
051:
052: if (capabilities == null) {
053: return null;
054: }
055:
056: List namedLayersList = new ArrayList();
057:
058: Layer[] layers = (Layer[]) capabilities.getLayerList().toArray(
059: new Layer[capabilities.getLayerList().size()]);
060:
061: for (int i = 0; i < layers.length; i++) {
062: if ((layers[i].getName() != null)
063: && (layers[i].getName().length() != 0)) {
064: namedLayersList.add(layers[i]);
065: }
066: }
067:
068: Layer[] namedLayers = new Layer[namedLayersList.size()];
069: for (int i = 0; i < namedLayersList.size(); i++) {
070: namedLayers[i] = (Layer) namedLayersList.get(i);
071: }
072:
073: return namedLayers;
074: }
075:
076: public static Set getQueryableLayers(WMSCapabilities capabilities) {
077: Set layers = new TreeSet();
078:
079: Layer[] namedLayers = getNamedLayers(capabilities);
080:
081: for (int i = 0; i < namedLayers.length; i++) {
082: Layer layer = namedLayers[i];
083:
084: if (layer.isQueryable()) {
085: layers.add(layer);
086: }
087: }
088:
089: return layers;
090: }
091:
092: public static Set getSRSs(WMSCapabilities capabilities) {
093: Set srss = new TreeSet();
094:
095: Layer[] layers = (Layer[]) capabilities.getLayerList().toArray(
096: new Layer[capabilities.getLayerList().size()]);
097:
098: for (int i = 0; i < layers.length; i++) {
099: if (layers[i].getSrs() != null) {
100: srss.addAll(layers[i].getSrs());
101: }
102: }
103:
104: return srss;
105: }
106:
107: /**
108: * Given a list of type Layer, return all EPSG codes that is supported
109: * by all of the layers. This is an intersection of each layer's SRS set.
110: *
111: * @param layers A List of type Layer
112: * @return a Set of type String, containin EPSG codes, or empty if none found
113: */
114: public static Set findCommonEPSGs(List layers) {
115: TreeSet set = new TreeSet();
116:
117: Layer first = (Layer) layers.get(0);
118:
119: set.addAll(first.getSrs());
120:
121: for (int i = 1; i < layers.size(); i++) {
122: Layer layer = (Layer) layers.get(i);
123: set.retainAll(layer.getSrs());
124: }
125:
126: return set;
127: }
128:
129: //Map<CoordinateReferenceSystem, TreeSet<String>>
130: private static Map crsCache;
131:
132: static {
133: crsCache = new HashMap();
134: }
135:
136: /**
137: * Given a CRS and a Set of type String consisting of EPSG CRS codes
138: * (such as "EPSG:4326"), it will check the transform that exists between
139: * each EPSG code's CRS and the given CRS. If this is the identity
140: * transform, meaning the CRS is equivalent to the EPSG code,
141: * the used EPSG code will be returned. The first valid EPSG code found
142: * is returned, so it is possibly that multiple valid codes exist.
143: *
144: * If no such identity transform can be found, null will be returned.
145: *
146: * If this method is succesful, the result is stored in a cache, which is
147: * called in subsequent calls.
148: *
149: * @param crs a CRS that is to be compared to each EPSG code in codes
150: * @param codes a Set of type String containing EPSG codes
151: * @return an EPSG code that correspondes to crs, or null if one can't be found
152: */
153: public static String matchEPSG(CoordinateReferenceSystem crs,
154: Set codes) {
155:
156: TreeSet previous = (TreeSet) crsCache.get(crs);
157: if (previous != null) {
158:
159: Iterator iter = previous.iterator();
160: while (iter.hasNext()) {
161: String code = (String) iter.next();
162:
163: if (codes.contains(code)) {
164: return code;
165: }
166: }
167: }
168:
169: Iterator iter = crs.getIdentifiers().iterator();
170: while (iter.hasNext()) {
171: Identifier ident = (Identifier) iter.next();
172: String epsgCode = ident.toString();
173: if (codes.contains(epsgCode)) {
174: if (crsCache.get(crs) == null) {
175: crsCache.put(crs, new TreeSet());
176: }
177: TreeSet set = (TreeSet) crsCache.get(crs);
178: set.add(epsgCode);
179:
180: return epsgCode;
181: }
182: }
183:
184: iter = null;
185:
186: iter = codes.iterator();
187: while (iter.hasNext()) {
188: String epsgCode = (String) iter.next();
189:
190: CoordinateReferenceSystem epsgCRS;
191: try {
192: epsgCRS = CRS.decode(epsgCode);
193: } catch (Exception e) {
194: // e.printStackTrace();
195: continue;
196: }
197:
198: MathTransform transform;
199: try {
200: transform = CRS.findMathTransform(crs, epsgCRS, true);
201: } catch (FactoryException e) {
202: // e.printStackTrace();
203: continue;
204: }
205:
206: if (transform.isIdentity()) {
207: if (crsCache.get(crs) == null) {
208: crsCache.put(crs, new TreeSet());
209: }
210: TreeSet set = (TreeSet) crsCache.get(crs);
211: set.add(epsgCode);
212:
213: return epsgCode;
214: }
215: }
216: return null;
217: }
218: }
|