Statistics
| Revision:

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
}