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 / DefaultCRSDefinition.java @ 867

History | View | Annotate | Download (12.7 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.CRS;
10
import org.geotools.referencing.wkt.Formatter;
11
import org.geotools.referencing.wkt.Symbols;
12
import org.gvsig.geotools.proj.catalog.datum.DefaultDatum;
13
import org.gvsig.geotools.proj.catalog.extent.DefaultExtent;
14
import org.gvsig.geotools.proj.catalog.extent.DefaultGeographicBoundingBox;
15
import org.gvsig.geotools.proj.catalog.extent.DefaultVerticalExtent;
16
import org.gvsig.geotools.proj.catalog.utils.GtUtils;
17
import org.gvsig.proj.catalog.CRSDefinition;
18
import org.gvsig.proj.catalog.CRSType;
19
import org.gvsig.proj.catalog.CoordinateSystemAxis;
20
import org.gvsig.proj.catalog.TextSerialization;
21
import org.gvsig.proj.catalog.TextSerialization.Format;
22
import org.gvsig.proj.catalog.TextSerialization.WKTConvention;
23
import org.gvsig.proj.catalog.TransformationDefinition;
24
import org.gvsig.proj.catalog.datum.Datum;
25
import org.gvsig.proj.catalog.exception.CoordinateReferenceSystemException;
26
import org.gvsig.proj.catalog.exception.UnsupportedCoordinateReferenceSystemException;
27
import org.gvsig.proj.catalog.extent.Extent;
28
import org.gvsig.proj.catalog.extent.GeographicBoundingBox;
29
import org.gvsig.proj.catalog.extent.VerticalExtent;
30
import org.opengis.metadata.Identifier;
31
import org.opengis.referencing.FactoryException;
32
import org.opengis.referencing.ReferenceIdentifier;
33
import org.opengis.referencing.crs.CompoundCRS;
34
import org.opengis.referencing.crs.CoordinateReferenceSystem;
35
import org.opengis.referencing.crs.GeneralDerivedCRS;
36
import org.opengis.referencing.crs.GeocentricCRS;
37
import org.opengis.referencing.crs.GeographicCRS;
38
import org.opengis.referencing.crs.ProjectedCRS;
39
import org.opengis.referencing.crs.SingleCRS;
40
import org.opengis.referencing.crs.TemporalCRS;
41
import org.opengis.referencing.crs.VerticalCRS;
42
import org.opengis.referencing.operation.Conversion;
43

    
44
public class DefaultCRSDefinition implements CRSDefinition {
45
        /**
46
         * Coordinate reference system in the original axis order
47
         */
48
        final private CoordinateReferenceSystem origCrs;
49
        /**
50
         * Coordinate reference system in the internal axis order (east-north)
51
         */
52
        final private CoordinateReferenceSystem internalCrs;
53
        final private String wkt;
54
        private CoordinateReferenceSystem epsgCrs = null;
55

    
56
        public DefaultCRSDefinition(CoordinateReferenceSystem crs) {
57
                this(crs, crs, null);
58
        }
59
        
60
        public DefaultCRSDefinition(CoordinateReferenceSystem crs, String wkt) {
61
                this(crs, crs, wkt);
62
        }
63
        
64
        public DefaultCRSDefinition(CoordinateReferenceSystem crs,  CoordinateReferenceSystem eastNorthCrs, String wkt) {
65
                this.origCrs = crs;
66
                this.wkt = wkt;
67
                this.internalCrs = eastNorthCrs;
68
        }
69

    
70
        /**
71
         * Gets the Geotools instance backing this definition, using the gvSIG internal
72
         * axis order (east-north).
73
         * definition
74
         * 
75
         * @return
76
         */
77
        public CoordinateReferenceSystem getInternalCRS() {
78
                return internalCrs;
79
        }
80
        
81
        /**
82
         * Gets the Geotools instance backing this definition, using the original,
83
         * unmodified axis order as defined by the defining authority or WKT string.
84
         * 
85
         * @return
86
         */
87
        public CoordinateReferenceSystem getOrigCRS() {
88
                return origCrs;
89
        }
90
        
91
        @Override
92
        public String getName() {
93
                if (origCrs.getName() != null) {
94
                        return origCrs.getName().getCode();
95
                }
96
                if (getIdentifier() != null) {
97
                        return getIdentifier();
98
                }
99
                StringBuilder name = new StringBuilder();
100
                if (origCrs.getCoordinateSystem().getName() != null) {
101
                        name.append(origCrs.getCoordinateSystem().getName());
102
                }
103
                if (getDatum().getName() != null) {
104
                        if (name.length()>0) {
105
                                name.append(" - ");
106
                        }
107
                        name.append(origCrs.getCoordinateSystem().getName());
108
                }
109
                if (name.length()>0) {
110
                        return name.toString();
111
                }
112
                return origCrs.getClass().getSimpleName();
113
        }
114

    
115
        @Override
116
        public String getIdentifier() {
117
                String id = GtUtils.getIdentifier(origCrs);
118
                if (id!=null) {
119
                        return id;
120
                }
121
                return null;
122
                /*return IdentifiedObjectUtils.getIdentifier(getEpsgCrs());*/
123
        }
124
        
125
        /**
126
         * Gets an EPSG code which can be considered equivalent to this CRS or
127
         * null if not found
128
         * @return
129
         */
130
        /*protected CoordinateReferenceSystem getEpsgCrs() {
131
                // FIXME: this method makes the class mutable
132
                if (epsgCrs==null) {
133
                        try {
134
                                String code = CRS.lookupIdentifier(Citations.EPSG, origCrs, true);
135
                                if (code!=null) {
136
                                        epsgCrs = CRS.decode("EPSG:"+code);
137
                                }
138
                        }
139
                        catch (FactoryException exc) {}
140
                }
141
                return epsgCrs;
142
        }*/
143

    
144
        @Override
145
        public Set<String> getIdentifiers() {
146
                HashSet<String> ids = new HashSet<String>();
147
                for (ReferenceIdentifier id: origCrs.getIdentifiers()) {
148
                        ids.add(id.toString());
149
                }
150
                /*
151
                if (!getAuthorityName().equals("EPSG") && getEpsgCrs() != null) {
152
                        for (ReferenceIdentifier id: getEpsgCrs().getIdentifiers()) {
153
                                ids.add(id.toString());
154
                        }
155
                }*/
156
                return ids;
157
        }
158

    
159
        @Override
160
        public String getAuthorityName() {
161
                return GtUtils.getIdentifier(origCrs.getName().getAuthority().getIdentifiers());
162
        }
163

    
164
        @Override
165
        public Extent getDomainOfValidity() {
166
                // FIXME: should we cache this?
167
                org.opengis.metadata.extent.Extent extent = origCrs.getDomainOfValidity();
168
                if (extent != null) {
169
                        String desc;
170
                        if (origCrs.getDomainOfValidity().getDescription() != null) {
171
                                desc = origCrs.getDomainOfValidity().getDescription().toString();
172
                        }
173
                        else {
174
                                desc = null;
175
                        }
176
                        ArrayList<GeographicBoundingBox> horizontalExtentList = new ArrayList<GeographicBoundingBox>();
177
                        for (org.opengis.metadata.extent.GeographicExtent horizExtent: origCrs.getDomainOfValidity().getGeographicElements()) {
178
                                if (horizExtent instanceof org.opengis.metadata.extent.GeographicBoundingBox) {
179
                                        DefaultGeographicBoundingBox bb = new DefaultGeographicBoundingBox(
180
                                                        ((org.opengis.metadata.extent.GeographicBoundingBox) horizExtent).getWestBoundLongitude(),
181
                                                        ((org.opengis.metadata.extent.GeographicBoundingBox) horizExtent).getEastBoundLongitude(),
182
                                                        ((org.opengis.metadata.extent.GeographicBoundingBox) horizExtent).getNorthBoundLatitude(),
183
                                                        ((org.opengis.metadata.extent.GeographicBoundingBox) horizExtent).getSouthBoundLatitude()); 
184
                                        horizontalExtentList.add(bb);
185
                                }                                
186
                        }
187
                        
188
                        ArrayList<VerticalExtent> vertExtentList = new ArrayList<VerticalExtent>();
189
                        for (org.opengis.metadata.extent.VerticalExtent verticalExtent: origCrs.getDomainOfValidity().getVerticalElements()) {
190
                                DefaultVerticalExtent ve = new DefaultVerticalExtent(
191
                                                new DefaultCRSDefinition(verticalExtent.getVerticalCRS()),
192
                                                verticalExtent.getMinimumValue(),
193
                                                verticalExtent.getMaximumValue()
194
                                                );
195
                                vertExtentList.add(ve);
196
                        }
197
                        return new DefaultExtent(desc, horizontalExtentList, vertExtentList);
198
                }
199
                return null;
200
        }
201

    
202
        @Override
203
        public String getDescription() {
204
                StringBuilder desc = new StringBuilder();
205
                if (origCrs.getScope() != null) {
206
                        desc.append("Scope: ").append(origCrs.getScope());
207
                }
208
                if (origCrs.getRemarks() != null) {
209
                        if (desc.length()>0) {
210
                                desc.append("\nRemarks: ");
211
                        }
212
                        else {
213
                                desc.append("Remarks: ");
214
                        }
215
                        desc.append(origCrs.getRemarks());
216
                }
217
                if (origCrs.getDomainOfValidity() != null &&
218
                                origCrs.getDomainOfValidity().getDescription() != null) {
219
                        if (desc.length()>0) {
220
                                desc.append("\nDomain: ");
221
                        }
222
                        else {
223
                                desc.append("Domain: ");
224
                        }
225
                        desc.append(origCrs.getDomainOfValidity().getDescription());
226
                }
227
                
228
                return desc.toString();
229
        }
230

    
231
        @Override
232
        public CRSType getType() {
233
                if (origCrs instanceof ProjectedCRS) {
234
                        return CRSType.ProjectedCRSType;
235
                }
236
                if (origCrs instanceof GeographicCRS) {
237
                        return CRSType.GeographicCRSType;
238
                }
239
                if (origCrs instanceof GeocentricCRS) {
240
                        return CRSType.GeocentricCRSType;
241
                }
242
                if (origCrs instanceof GeneralDerivedCRS) {
243
                        return CRSType.OtherDerivedCRSType;
244
                }
245
                if (origCrs instanceof CompoundCRS) {
246
                        return CRSType.CompoundCRSType;
247
                }
248
                if (origCrs instanceof VerticalCRS) {
249
                        return CRSType.VerticalCRSType;
250
                }
251
                if (origCrs instanceof TemporalCRS) {
252
                        return CRSType.TemporalCRSType;
253
                }
254
                return CRSType.OtherCRSType;
255
        }
256

    
257
        @Override
258
        public String toWKT() throws UnsupportedOperationException {
259
                if (wkt!=null) {
260
                        return wkt;
261
                }
262
                return export(Format.WKT1);
263
        }
264
        
265
        @Override
266
        public String toString() {
267
                return (getIdentifier()!=null)?(getIdentifier() + " - " + getName()):getName();
268
        }
269
        
270

    
271
        @Override
272
        public String export(Format format) throws UnsupportedOperationException {
273
                return export(format, null, 2);
274
        }
275

    
276
        @Override
277
        public String export(TextSerialization.Format format, WKTConvention convention, int indentation) throws UnsupportedOperationException {
278
                // FIXME: should we consider this.wkt if it is not null??
279
                if (format==Format.WKT1) {
280
                        Formatter formatter = new Formatter(Symbols.DEFAULT, indentation);
281
                        if (convention==null) {
282
                                formatter.append(this.origCrs);
283
                                return formatter.toString();
284
                        }
285
                        else if (convention==null || convention==WKTConvention.EPSG) {
286
                                formatter.setAuthority(Citations.EPSG);
287
                                if (!this.getAuthorityName().equals("EPSG")) {
288
                                        String id;
289
                                        try {
290
                                                id = CRS.lookupIdentifier(Citations.EPSG, this.origCrs, true);
291
                                                if (id!=null) {
292
                                                        if (!id.startsWith("EPSG:")) {
293
                                                                id = "EPSG:" + id;
294
                                                        }
295
                                                        CoordinateReferenceSystem crs = CRS.decode(id);
296
                                                        formatter.append(crs);
297
                                                        return formatter.toString();
298
                                                }
299
                                        } catch (FactoryException e) {
300
                                        }
301
                                }
302
                                formatter.append(this.origCrs);
303
                                return formatter.toString();
304
                        }
305
                        if (convention==WKTConvention.ESRI) {
306
                                // FIXME: should we consider this.wkt if it is not null??
307
                                formatter.setAuthority(Citations.ESRI);
308
                                formatter.append(this.origCrs);
309
                                return formatter.toString();
310
                        }
311
                        return toWKT();
312
                }
313
                throw new UnsupportedOperationException("Format not supported");
314
        }
315

    
316

    
317
        @Override
318
        public List<CRSDefinition> getComponents() {
319
                if (origCrs instanceof CompoundCRS) {
320
                        ArrayList<CRSDefinition> list = new ArrayList<CRSDefinition>();
321
                        for (CoordinateReferenceSystem component: ((CompoundCRS) origCrs).getCoordinateReferenceSystems()) {
322
                                list.add(new DefaultCRSDefinition(component));
323
                        }
324
                        return list;
325
                }
326
                return null;
327
        }
328

    
329
        @Override
330
        public int getAxisCount() {
331
                return origCrs.getCoordinateSystem().getDimension();
332
        }
333

    
334
        @Override
335
        public CoordinateSystemAxis getAxis(int dimension) throws IndexOutOfBoundsException {
336
                return new DefaultCoordinateSystemAxis(origCrs.getCoordinateSystem().getAxis(dimension));
337
        }
338

    
339
        @Override
340
        public CoordinateSystemAxis getAxisInternal(int dimension) throws IndexOutOfBoundsException {
341
                return new DefaultCoordinateSystemAxis(internalCrs.getCoordinateSystem().getAxis(dimension));
342
        }
343

    
344
        @Override
345
        public CRSDefinition getBaseCRS() {
346
                // FIXME: consider the axis order of the base CRS
347
                if (origCrs instanceof GeneralDerivedCRS) {
348
                        CoordinateReferenceSystem base = ((GeneralDerivedCRS)origCrs).getBaseCRS();
349
                        return new DefaultCRSDefinition(base);
350
                }
351
                return null;
352
        }
353

    
354
        @Override
355
        public TransformationDefinition getConversionFromBase() throws CoordinateReferenceSystemException {
356
                DefaultCRSDefinition baseDef = (DefaultCRSDefinition) getBaseCRS();
357
                if (baseDef!=null) {
358
                        CoordinateReferenceSystem base = baseDef.getInternalCRS();
359
                        Conversion conversion = ((GeneralDerivedCRS)origCrs).getConversionFromBase();
360
                        return new DefaultTransformationDefinition(conversion, baseDef, this);
361
                }
362
                return null;
363
        }
364

    
365
        @Override
366
        public Datum getDatum() {
367
                if (origCrs instanceof SingleCRS) {
368
                        SingleCRS singleCrs = (SingleCRS)origCrs;
369
                        return new DefaultDatum(singleCrs.getDatum());
370
                }
371
                else {
372
                        SingleCRS horizontalCrs = CRS.getHorizontalCRS(origCrs);
373
                        return new DefaultDatum(horizontalCrs.getDatum());
374
                }
375
        }
376
        
377
        @Override
378
        public Object clone() throws CloneNotSupportedException {
379
                return new DefaultCRSDefinition(this.origCrs, this.internalCrs, this.wkt);
380
        }
381
        
382
        @Override
383
        public boolean equals(Object obj) {
384
                if (obj instanceof DefaultCRSDefinition) {
385
                        return origCrs.equals(((DefaultCRSDefinition)obj).getOrigCRS());
386
                }
387
                if (obj instanceof CRSDefinition) {
388
                        return export(Format.WKT1, WKTConvention.EPSG, 0).equals(((CRSDefinition)obj).export(Format.WKT1, WKTConvention.EPSG, 0));
389
                }
390
                return false;
391
        }
392

    
393
        @Override
394
        public boolean equals(CRSDefinition definition, boolean ignoreAxis, boolean ignoreMetadata) {
395
                if (definition instanceof DefaultCRSDefinition) {
396
                        DefaultCRSDefinition def = (DefaultCRSDefinition) definition;
397
                        if (ignoreAxis) {
398
                                if (ignoreMetadata) {
399
                                        return CRS.equalsIgnoreMetadata(this.internalCrs, def.getInternalCRS());        
400
                                }
401
                                else {
402
                                        return this.internalCrs.equals(def.getInternalCRS());
403
                                }
404
                        }
405
                        else if (ignoreMetadata) {
406
                                return CRS.equalsIgnoreMetadata(this.origCrs, def.getOrigCRS());
407
                        }
408
                        else {
409
                                return CRS.equalsIgnoreMetadata(this.origCrs, def.getOrigCRS());
410
                        }
411
                }
412
                else {
413
                        return equals(definition);
414
                }
415
        }
416
        
417
    @Override
418
    public int hashCode() {
419
            return origCrs.hashCode();
420
    }
421
}