root / org.gvsig.geotools.proj / trunk / org.gvsig.geotools.proj / org.gvsig.geotools.proj.catalog.impl / src / main / java / org / gvsig / geotools / proj / catalog / DefaultTransformationDefinition.java @ 867
History | View | Annotate | Download (11 KB)
1 |
package org.gvsig.geotools.proj.catalog; |
---|---|
2 |
|
3 |
import java.util.ArrayList; |
4 |
import java.util.HashSet; |
5 |
import java.util.List; |
6 |
import java.util.Set; |
7 |
|
8 |
import org.geotools.metadata.iso.citation.Citations; |
9 |
import org.geotools.referencing.operation.transform.ConcatenatedTransform; |
10 |
import org.geotools.referencing.wkt.Formatter; |
11 |
import org.geotools.referencing.wkt.Symbols; |
12 |
import org.gvsig.geotools.proj.catalog.extent.DefaultExtent; |
13 |
import org.gvsig.geotools.proj.catalog.extent.DefaultGeographicBoundingBox; |
14 |
import org.gvsig.geotools.proj.catalog.extent.DefaultVerticalExtent; |
15 |
import org.gvsig.geotools.proj.catalog.utils.GtUtils; |
16 |
import org.gvsig.proj.catalog.CRSDefinition; |
17 |
import org.gvsig.proj.catalog.TextSerialization.Format; |
18 |
import org.gvsig.proj.catalog.TextSerialization.WKTConvention; |
19 |
import org.gvsig.proj.catalog.TransformationDefinition; |
20 |
import org.gvsig.proj.catalog.exception.CoordinateReferenceSystemException; |
21 |
import org.gvsig.proj.catalog.exception.NoninvertibleTransformException; |
22 |
import org.gvsig.proj.catalog.exception.TransformationException; |
23 |
import org.gvsig.proj.catalog.exception.UnsupportedFormatException; |
24 |
import org.gvsig.proj.catalog.exception.UnsupportedTransformationException; |
25 |
import org.gvsig.proj.catalog.extent.Extent; |
26 |
import org.gvsig.proj.catalog.extent.GeographicBoundingBox; |
27 |
import org.gvsig.proj.catalog.extent.VerticalExtent; |
28 |
import org.opengis.referencing.ReferenceIdentifier; |
29 |
import org.opengis.referencing.operation.ConcatenatedOperation; |
30 |
import org.opengis.referencing.operation.CoordinateOperation; |
31 |
import org.opengis.referencing.operation.MathTransform; |
32 |
import org.opengis.referencing.operation.PassThroughOperation; |
33 |
import org.opengis.referencing.operation.Projection; |
34 |
import org.opengis.referencing.operation.SingleOperation; |
35 |
import org.opengis.referencing.operation.Transformation; |
36 |
|
37 |
public class DefaultTransformationDefinition implements TransformationDefinition { |
38 |
final private CoordinateOperation operation; |
39 |
final private MathTransform mathTransform; |
40 |
final private DefaultCRSDefinition source; |
41 |
final private DefaultCRSDefinition target; |
42 |
// FIXME: do we need the inverse concept in the definition??
|
43 |
final private boolean inverse; |
44 |
|
45 |
/**
|
46 |
* Creates a DefaultTransformationDefinition object
|
47 |
*
|
48 |
* @param operation
|
49 |
* @param source
|
50 |
* @param target
|
51 |
* @throws UnsupportedTransformationException
|
52 |
*/
|
53 |
public DefaultTransformationDefinition(CoordinateOperation operation,
|
54 |
DefaultCRSDefinition source, DefaultCRSDefinition target) |
55 |
throws UnsupportedTransformationException {
|
56 |
if (source.getInternalCRS().equals(operation.getSourceCRS())
|
57 |
&& target.getInternalCRS().equals(operation.getTargetCRS())) { |
58 |
this.inverse = false; |
59 |
} |
60 |
else if (source.getInternalCRS().equals(operation.getTargetCRS()) |
61 |
&& target.getInternalCRS().equals(operation.getSourceCRS())) { |
62 |
this.inverse = true; |
63 |
} |
64 |
else {
|
65 |
throw new UnsupportedTransformationException( |
66 |
"The provided source and target do not match any of the sources and targets of the provided operation");
|
67 |
} |
68 |
if (inverse) {
|
69 |
try {
|
70 |
this.mathTransform = operation.getMathTransform().inverse();
|
71 |
} catch (org.opengis.referencing.operation.NoninvertibleTransformException e) {
|
72 |
throw new UnsupportedTransformationException(e); |
73 |
} |
74 |
} |
75 |
else {
|
76 |
this.mathTransform = operation.getMathTransform();
|
77 |
} |
78 |
this.operation = operation;
|
79 |
this.source = source;
|
80 |
this.target = target;
|
81 |
} |
82 |
|
83 |
/**
|
84 |
* Creates a DefaultTransformationDefinition object
|
85 |
*
|
86 |
* @param mathTransform
|
87 |
* @param source
|
88 |
* @param target
|
89 |
* @throws UnsupportedTransformationException
|
90 |
*/
|
91 |
public DefaultTransformationDefinition(MathTransform mathTransform,
|
92 |
DefaultCRSDefinition source, DefaultCRSDefinition target) throws CoordinateReferenceSystemException {
|
93 |
this.mathTransform = mathTransform;
|
94 |
this.inverse = false; |
95 |
this.operation = null; |
96 |
this.source = source;
|
97 |
this.target = target;
|
98 |
} |
99 |
|
100 |
public CoordinateOperation getInternalOperation() {
|
101 |
return operation;
|
102 |
} |
103 |
|
104 |
@Override
|
105 |
public DefaultCRSDefinition getSourceDefinition() {
|
106 |
return source;
|
107 |
} |
108 |
|
109 |
@Override
|
110 |
public DefaultCRSDefinition getTargetDefinition() {
|
111 |
return target;
|
112 |
} |
113 |
|
114 |
@Override
|
115 |
public String getName() { |
116 |
if (operation != null) { |
117 |
return nameFromOperation(operation);
|
118 |
} |
119 |
return nameFromMathTransform();
|
120 |
} |
121 |
|
122 |
protected String nameFromMathTransform() { |
123 |
StringBuilder meaningfulName = new StringBuilder(); |
124 |
appendSourceTargetToName(meaningfulName); |
125 |
meaningfulName.append(" using ");
|
126 |
meaningfulName.append(mathTransform.getClass().getSimpleName()); |
127 |
return meaningfulName.toString();
|
128 |
} |
129 |
|
130 |
protected void appendSourceTargetToName(StringBuilder builder) { |
131 |
builder.append(source.getName()); |
132 |
builder.append(" to ");
|
133 |
builder.append(target.getName()); |
134 |
} |
135 |
|
136 |
protected String nameFromOperation(CoordinateOperation op) { |
137 |
if (op instanceof ConcatenatedOperation) { |
138 |
StringBuilder meaningfulName = new StringBuilder(); |
139 |
List<SingleOperation> opList = ((ConcatenatedOperation) op).getOperations();
|
140 |
for (SingleOperation singleOp: opList) {
|
141 |
if (singleOp instanceof Transformation) { |
142 |
String id = GtUtils.getIdentifier(singleOp);
|
143 |
if (id!=null) { |
144 |
meaningfulName.append(id).append("-based concat operation").append(" - "); |
145 |
} |
146 |
if (singleOp.getName() != null) { |
147 |
meaningfulName.append(singleOp.getName()); |
148 |
} |
149 |
} |
150 |
} |
151 |
if (op.getName() != null) { |
152 |
if (meaningfulName.length()==0) { |
153 |
meaningfulName.append("Concat operation");
|
154 |
} |
155 |
} |
156 |
if (meaningfulName.length()>0) { |
157 |
return meaningfulName.toString();
|
158 |
} |
159 |
} |
160 |
else if (op instanceof PassThroughOperation) { |
161 |
return nameFromOperation(((PassThroughOperation)op).getOperation());
|
162 |
} |
163 |
if (op.getName() !=null) { |
164 |
return op.getName().toString().replace("\u21e8", "=>"); |
165 |
} |
166 |
return nameFromMathTransform();
|
167 |
} |
168 |
|
169 |
@Override
|
170 |
public String getIdentifier() { |
171 |
if (operation==null) { |
172 |
return null; |
173 |
} |
174 |
return GtUtils.getIdentifier(operation);
|
175 |
} |
176 |
|
177 |
@Override
|
178 |
public Set<String> getIdentifiers() { |
179 |
HashSet<String> ids = new HashSet<String>(); |
180 |
for (ReferenceIdentifier id: operation.getIdentifiers()) {
|
181 |
ids.add(id.toString()); |
182 |
} |
183 |
return ids;
|
184 |
} |
185 |
|
186 |
@Override
|
187 |
public String getAuthorityName() { |
188 |
if (operation==null || |
189 |
operation.getName()==null ||
|
190 |
operation.getName().getAuthority()==null) {
|
191 |
return null; |
192 |
} |
193 |
return GtUtils.getIdentifier(operation.getName().getAuthority().getIdentifiers());
|
194 |
} |
195 |
|
196 |
@Override
|
197 |
public String getOperationVersion() { |
198 |
if (operation==null) { |
199 |
return null; |
200 |
} |
201 |
return operation.getOperationVersion();
|
202 |
} |
203 |
|
204 |
@Override
|
205 |
public Extent getDomainOfValidity() {
|
206 |
org.opengis.metadata.extent.Extent extent = operation.getDomainOfValidity(); |
207 |
if (extent != null) { |
208 |
String desc;
|
209 |
if (operation.getDomainOfValidity().getDescription() != null) { |
210 |
desc = operation.getDomainOfValidity().getDescription().toString(); |
211 |
} |
212 |
else {
|
213 |
desc = null;
|
214 |
} |
215 |
ArrayList<GeographicBoundingBox> horizontalExtentList = new ArrayList<GeographicBoundingBox>(); |
216 |
for (org.opengis.metadata.extent.GeographicExtent horizExtent: operation.getDomainOfValidity().getGeographicElements()) {
|
217 |
if (horizExtent instanceof org.opengis.metadata.extent.GeographicBoundingBox) { |
218 |
DefaultGeographicBoundingBox bb = new DefaultGeographicBoundingBox(
|
219 |
((org.opengis.metadata.extent.GeographicBoundingBox) horizExtent).getWestBoundLongitude(), |
220 |
((org.opengis.metadata.extent.GeographicBoundingBox) horizExtent).getEastBoundLongitude(), |
221 |
((org.opengis.metadata.extent.GeographicBoundingBox) horizExtent).getNorthBoundLatitude(), |
222 |
((org.opengis.metadata.extent.GeographicBoundingBox) horizExtent).getSouthBoundLatitude()); |
223 |
horizontalExtentList.add(bb); |
224 |
} |
225 |
} |
226 |
|
227 |
ArrayList<VerticalExtent> vertExtentList = new ArrayList<VerticalExtent>(); |
228 |
for (org.opengis.metadata.extent.VerticalExtent verticalExtent: operation.getDomainOfValidity().getVerticalElements()) {
|
229 |
DefaultVerticalExtent ve = new DefaultVerticalExtent(
|
230 |
new DefaultCRSDefinition(verticalExtent.getVerticalCRS()),
|
231 |
verticalExtent.getMinimumValue(), |
232 |
verticalExtent.getMaximumValue() |
233 |
); |
234 |
vertExtentList.add(ve); |
235 |
} |
236 |
return new DefaultExtent(desc, horizontalExtentList, vertExtentList); |
237 |
} |
238 |
return null; |
239 |
} |
240 |
|
241 |
@Override
|
242 |
public String getDescription() { |
243 |
if (operation==null) { |
244 |
return null; |
245 |
} |
246 |
StringBuilder desc = new StringBuilder(); |
247 |
CoordinateOperation op = GtUtils.getDefiningOperation(operation); |
248 |
if (op!=null) { |
249 |
fillDescription(op, desc); |
250 |
if (desc.length()>0) { |
251 |
return desc.toString();
|
252 |
} |
253 |
} |
254 |
fillDescription(operation, desc); |
255 |
return desc.toString();
|
256 |
} |
257 |
|
258 |
protected StringBuilder fillDescription(CoordinateOperation op, StringBuilder desc) { |
259 |
if (op.getName() != null) { |
260 |
desc.append("Summary: Concatenated operation");
|
261 |
String id = GtUtils.getIdentifier(op);
|
262 |
if (id!=null) { |
263 |
desc.append(" based on ").append(id).append(","); |
264 |
} |
265 |
desc.append(" transforming ");
|
266 |
desc.append(op.getName().toString().replace("\u21e8", "=>")).append("\n"); |
267 |
} |
268 |
if (op.getScope() != null) { |
269 |
desc.append("Scope: ").append(op.getScope());
|
270 |
} |
271 |
if (op.getRemarks() != null) { |
272 |
if (desc.length()>0) { |
273 |
desc.append("\nRemarks: ");
|
274 |
} |
275 |
else {
|
276 |
desc.append("Remarks: ");
|
277 |
} |
278 |
desc.append(op.getRemarks()); |
279 |
} |
280 |
if (op.getDomainOfValidity() != null && |
281 |
op.getDomainOfValidity().getDescription() != null) {
|
282 |
if (desc.length()>0) { |
283 |
desc.append("\nDomain: ");
|
284 |
} |
285 |
else {
|
286 |
desc.append("Domain: ");
|
287 |
} |
288 |
desc.append(op.getDomainOfValidity().getDescription()); |
289 |
} |
290 |
return desc;
|
291 |
} |
292 |
|
293 |
@Override
|
294 |
public TransformationDefinition getInverseDefinition()
|
295 |
throws NoninvertibleTransformException, UnsupportedTransformationException { |
296 |
if (this.operation==null) { |
297 |
try {
|
298 |
return new DefaultTransformationDefinition(mathTransform.inverse(), target, source); |
299 |
} catch (CoordinateReferenceSystemException
|
300 |
| org.opengis.referencing.operation.NoninvertibleTransformException e) { |
301 |
throw new NoninvertibleTransformException(e); |
302 |
} |
303 |
} |
304 |
return new DefaultTransformationDefinition(this.operation, target, source); |
305 |
} |
306 |
|
307 |
@Override
|
308 |
public String toWKT() throws UnsupportedOperationException { |
309 |
return mathTransform.toWKT();
|
310 |
} |
311 |
|
312 |
@Override
|
313 |
public String export(Format format) throws UnsupportedFormatException { |
314 |
if (format==Format.WKT1) { |
315 |
return toWKT();
|
316 |
} |
317 |
throw new UnsupportedFormatException(format); |
318 |
} |
319 |
|
320 |
@Override
|
321 |
public String export(Format format, WKTConvention convention, int indentation) throws UnsupportedFormatException { |
322 |
if (format==Format.WKT1) { |
323 |
Formatter formatter = new Formatter(Symbols.DEFAULT, indentation); |
324 |
if (convention==WKTConvention.EPSG) {
|
325 |
formatter.setAuthority(Citations.EPSG); |
326 |
} |
327 |
else if (convention==WKTConvention.ESRI) { |
328 |
formatter.setAuthority(Citations.ESRI); |
329 |
} |
330 |
formatter.append(mathTransform); |
331 |
return formatter.toString();
|
332 |
} |
333 |
throw new UnsupportedFormatException(format); |
334 |
} |
335 |
|
336 |
public MathTransform getMathTransform() {
|
337 |
return mathTransform;
|
338 |
} |
339 |
|
340 |
@Override
|
341 |
public String toString() { |
342 |
return getName();
|
343 |
} |
344 |
|
345 |
@Override
|
346 |
public boolean equals(Object obj) { |
347 |
// TODO Auto-generated method stub
|
348 |
return super.equals(obj); |
349 |
} |
350 |
|
351 |
} |