001: /*
002: * uDig - User Friendly Desktop Internet GIS client
003: * http://udig.refractions.net
004: * (C) 2004, Refractions Research Inc.
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;
009: * version 2.1 of the License.
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: */
017: package net.refractions.udig.render.internal.wms.basic;
018:
019: import java.io.IOException;
020: import java.util.HashMap;
021: import java.util.HashSet;
022: import java.util.Iterator;
023: import java.util.Map;
024: import java.util.Set;
025:
026: import net.refractions.udig.project.render.IRenderContext;
027: import net.refractions.udig.project.render.IRenderMetrics;
028: import net.refractions.udig.project.render.IRenderMetricsFactory;
029:
030: import org.geotools.data.ows.Layer;
031: import org.geotools.data.wms.WebMapServer;
032: import org.geotools.referencing.CRS;
033: import org.opengis.referencing.FactoryException;
034: import org.opengis.referencing.NoSuchAuthorityCodeException;
035: import org.opengis.referencing.crs.CoordinateReferenceSystem;
036: import org.opengis.referencing.operation.MathTransform;
037:
038: /**
039: * Creates Metrics for the BasicWMSRenderer
040: *
041: * @author Richard Gould
042: */
043: public class BasicWMSMetricsFactory2 implements IRenderMetricsFactory {
044:
045: Map<String, CoordinateReferenceSystem> crsCache = new HashMap<String, CoordinateReferenceSystem>();
046: Map<Pair, MathTransform> transformCache = new HashMap<Pair, MathTransform>();
047: Map<Layer, Set<CoordinateReferenceSystem>> legalCRSCache = new HashMap<Layer, Set<CoordinateReferenceSystem>>();
048:
049: public boolean canRender(IRenderContext toolkit) {
050: if (!toolkit.getLayer().hasResource(WebMapServer.class)) {
051: return false; // not a wms
052: }
053: CoordinateReferenceSystem crs = toolkit.getViewportModel()
054: .getCRS();
055: if (crs == null) {
056: return true; // we will assume our default
057: }
058: org.geotools.data.ows.Layer layer;
059: try {
060: layer = toolkit.getLayer().getResource(
061: org.geotools.data.ows.Layer.class, null);
062: } catch (IOException e) {
063: return false;
064: }
065:
066: Set<CoordinateReferenceSystem> crss = legalCRSCache.get(layer);
067: if (crss != null && crss.contains(crs))
068: return true;
069: if (searchForCRSMatch(crs, layer)) {
070: if (crss == null) {
071: crss = new HashSet<CoordinateReferenceSystem>();
072: legalCRSCache.put(layer, crss);
073: }
074: crss.add(crs);
075:
076: return true;
077: }
078: return false;
079: }
080:
081: private boolean searchForCRSMatch(CoordinateReferenceSystem crs,
082: org.geotools.data.ows.Layer layer) {
083: Set srs = layer.getSrs();
084: for (Iterator i = srs.iterator(); i.hasNext();) {
085: try {
086: String epsgCode = (String) i.next();
087: CoordinateReferenceSystem rs = getCRS(epsgCode);
088:
089: if (rs.equals(crs)) {
090: return true;
091: }
092:
093: MathTransform transform = getMathTransform(crs, rs);
094:
095: if (transform != null) {
096: return true;
097: }
098: } catch (Throwable t) {
099: // could not create a object representation of this code
100: }
101: }
102: return false; // we cannot handle crs
103: }
104:
105: private synchronized MathTransform getMathTransform(
106: CoordinateReferenceSystem from, CoordinateReferenceSystem to)
107: throws FactoryException {
108: Pair pair = new Pair(from, to);
109: MathTransform result = this .transformCache.get(pair);
110: if (result == null) {
111: result = CRS.findMathTransform(from, to, true);
112: transformCache.put(pair, result);
113: }
114: return result;
115: }
116:
117: private synchronized CoordinateReferenceSystem getCRS(
118: String epsgCode) throws NoSuchAuthorityCodeException {
119: CoordinateReferenceSystem result = crsCache.get(epsgCode);
120: if (result == null) {
121: result = CRS.decode(epsgCode);
122: crsCache.put(epsgCode, result);
123: }
124: return result;
125: }
126:
127: /**
128: * @see net.refractions.udig.project.render.RenderMetricsFactory#createMetrics(net.refractions.udig.project.render.RenderContext)
129: */
130: public IRenderMetrics createMetrics(IRenderContext context) {
131: return new BasicWMSMetrics2(context, this );
132: }
133:
134: /**
135: * @see net.refractions.udig.project.render.RenderMetrics#getRendererType()
136: */
137: public Class getRendererType() {
138: return BasicWMSRenderer2.class;
139: }
140:
141: private class Pair {
142: final CoordinateReferenceSystem from, to;
143:
144: public Pair(CoordinateReferenceSystem from,
145: CoordinateReferenceSystem to) {
146: this .from = from;
147: this .to = to;
148: }
149:
150: @Override
151: public int hashCode() {
152: final int PRIME = 31;
153: int result = 1;
154: result = PRIME * result
155: + ((from == null) ? 0 : from.hashCode());
156: result = PRIME * result
157: + ((to == null) ? 0 : to.hashCode());
158: return result;
159: }
160:
161: @Override
162: public boolean equals(Object obj) {
163: if (this == obj)
164: return true;
165: if (obj == null)
166: return false;
167: if (getClass() != obj.getClass())
168: return false;
169: final Pair other = (Pair) obj;
170: if (from == null) {
171: if (other.from != null)
172: return false;
173: } else if (!from.equals(other.from))
174: return false;
175: if (to == null) {
176: if (other.to != null)
177: return false;
178: } else if (!to.equals(other.to))
179: return false;
180: return true;
181: }
182: }
183: }
|