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 | 828 | cmartinez | 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 | 853 | cmartinez | 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 | 867 | cmartinez | import org.gvsig.geotools.proj.catalog.utils.GtUtils; |
17 | 828 | cmartinez | 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 | 831 | cmartinez | import org.gvsig.proj.catalog.exception.CoordinateReferenceSystemException; |
26 | import org.gvsig.proj.catalog.exception.UnsupportedCoordinateReferenceSystemException; |
||
27 | 853 | cmartinez | import org.gvsig.proj.catalog.extent.Extent; |
28 | import org.gvsig.proj.catalog.extent.GeographicBoundingBox; |
||
29 | import org.gvsig.proj.catalog.extent.VerticalExtent; |
||
30 | 828 | cmartinez | 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 | 853 | cmartinez | /**
|
46 | * Coordinate reference system in the original axis order
|
||
47 | */
|
||
48 | 831 | cmartinez | final private CoordinateReferenceSystem origCrs; |
49 | 853 | cmartinez | /**
|
50 | * Coordinate reference system in the internal axis order (east-north)
|
||
51 | */
|
||
52 | final private CoordinateReferenceSystem internalCrs; |
||
53 | 831 | cmartinez | final private String wkt; |
54 | 828 | cmartinez | private CoordinateReferenceSystem epsgCrs = null; |
55 | |||
56 | 853 | cmartinez | public DefaultCRSDefinition(CoordinateReferenceSystem crs) {
|
57 | this(crs, crs, null); |
||
58 | 828 | cmartinez | } |
59 | |||
60 | 853 | cmartinez | public DefaultCRSDefinition(CoordinateReferenceSystem crs, String wkt) { |
61 | this(crs, crs, wkt);
|
||
62 | } |
||
63 | |||
64 | public DefaultCRSDefinition(CoordinateReferenceSystem crs, CoordinateReferenceSystem eastNorthCrs, String wkt) { |
||
65 | 828 | cmartinez | this.origCrs = crs;
|
66 | 853 | cmartinez | this.wkt = wkt;
|
67 | this.internalCrs = eastNorthCrs;
|
||
68 | 828 | cmartinez | } |
69 | |||
70 | 853 | cmartinez | /**
|
71 | * Gets the Geotools instance backing this definition, using the gvSIG internal
|
||
72 | * axis order (east-north).
|
||
73 | * definition
|
||
74 | *
|
||
75 | * @return
|
||
76 | */
|
||
77 | 828 | cmartinez | public CoordinateReferenceSystem getInternalCRS() {
|
78 | 853 | cmartinez | 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 | 828 | cmartinez | return origCrs;
|
89 | } |
||
90 | |||
91 | @Override
|
||
92 | public String getName() { |
||
93 | 839 | cmartinez | if (origCrs.getName() != null) { |
94 | 853 | cmartinez | return origCrs.getName().getCode();
|
95 | 839 | cmartinez | } |
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 | 828 | cmartinez | } |
114 | |||
115 | @Override
|
||
116 | public String getIdentifier() { |
||
117 | 867 | cmartinez | String id = GtUtils.getIdentifier(origCrs);
|
118 | 828 | cmartinez | if (id!=null) { |
119 | return id;
|
||
120 | } |
||
121 | 853 | cmartinez | return null; |
122 | /*return IdentifiedObjectUtils.getIdentifier(getEpsgCrs());*/
|
||
123 | 828 | cmartinez | } |
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 | 853 | cmartinez | /*protected CoordinateReferenceSystem getEpsgCrs() {
|
131 | // FIXME: this method makes the class mutable
|
||
132 | 828 | cmartinez | 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 | 853 | cmartinez | }*/
|
143 | 828 | cmartinez | |
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 | 853 | cmartinez | /*
|
151 | 828 | cmartinez | if (!getAuthorityName().equals("EPSG") && getEpsgCrs() != null) {
|
152 | for (ReferenceIdentifier id: getEpsgCrs().getIdentifiers()) {
|
||
153 | ids.add(id.toString());
|
||
154 | }
|
||
155 | 853 | cmartinez | }*/
|
156 | 828 | cmartinez | return ids;
|
157 | } |
||
158 | |||
159 | @Override
|
||
160 | public String getAuthorityName() { |
||
161 | 867 | cmartinez | return GtUtils.getIdentifier(origCrs.getName().getAuthority().getIdentifiers());
|
162 | 828 | cmartinez | } |
163 | |||
164 | @Override
|
||
165 | public Extent getDomainOfValidity() {
|
||
166 | 853 | cmartinez | // 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 | 828 | cmartinez | return null; |
200 | } |
||
201 | |||
202 | @Override
|
||
203 | public String getDescription() { |
||
204 | 853 | cmartinez | 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 | 828 | cmartinez | } |
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 | 867 | cmartinez | return export(Format.WKT1); |
263 | 828 | cmartinez | } |
264 | |||
265 | 853 | cmartinez | @Override
|
266 | public String toString() { |
||
267 | return (getIdentifier()!=null)?(getIdentifier() + " - " + getName()):getName(); |
||
268 | } |
||
269 | |||
270 | 828 | cmartinez | |
271 | @Override
|
||
272 | 867 | cmartinez | public String export(Format format) throws UnsupportedOperationException { |
273 | return export(format, null, 2); |
||
274 | 828 | cmartinez | } |
275 | |||
276 | @Override
|
||
277 | 867 | cmartinez | public String export(TextSerialization.Format format, WKTConvention convention, int indentation) throws UnsupportedOperationException { |
278 | 839 | cmartinez | // FIXME: should we consider this.wkt if it is not null??
|
279 | 828 | cmartinez | if (format==Format.WKT1) { |
280 | 839 | cmartinez | 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 | 828 | cmartinez | 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 | 853 | cmartinez | return new DefaultCoordinateSystemAxis(internalCrs.getCoordinateSystem().getAxis(dimension)); |
342 | 828 | cmartinez | } |
343 | |||
344 | @Override
|
||
345 | public CRSDefinition getBaseCRS() {
|
||
346 | 853 | cmartinez | // FIXME: consider the axis order of the base CRS
|
347 | 828 | cmartinez | if (origCrs instanceof GeneralDerivedCRS) { |
348 | CoordinateReferenceSystem base = ((GeneralDerivedCRS)origCrs).getBaseCRS(); |
||
349 | return new DefaultCRSDefinition(base); |
||
350 | } |
||
351 | return null; |
||
352 | } |
||
353 | |||
354 | @Override
|
||
355 | 831 | cmartinez | public TransformationDefinition getConversionFromBase() throws CoordinateReferenceSystemException { |
356 | DefaultCRSDefinition baseDef = (DefaultCRSDefinition) getBaseCRS(); |
||
357 | if (baseDef!=null) { |
||
358 | CoordinateReferenceSystem base = baseDef.getInternalCRS(); |
||
359 | 828 | cmartinez | Conversion conversion = ((GeneralDerivedCRS)origCrs).getConversionFromBase(); |
360 | 831 | cmartinez | return new DefaultTransformationDefinition(conversion, baseDef, this); |
361 | 828 | cmartinez | } |
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 | 853 | cmartinez | return new DefaultCRSDefinition(this.origCrs, this.internalCrs, this.wkt); |
380 | 828 | cmartinez | } |
381 | 839 | cmartinez | |
382 | @Override
|
||
383 | public boolean equals(Object obj) { |
||
384 | if (obj instanceof DefaultCRSDefinition) { |
||
385 | 853 | cmartinez | return origCrs.equals(((DefaultCRSDefinition)obj).getOrigCRS());
|
386 | 839 | cmartinez | } |
387 | if (obj instanceof CRSDefinition) { |
||
388 | 867 | cmartinez | return export(Format.WKT1, WKTConvention.EPSG, 0).equals(((CRSDefinition)obj).export(Format.WKT1, WKTConvention.EPSG, 0)); |
389 | 839 | cmartinez | } |
390 | return false; |
||
391 | } |
||
392 | 828 | cmartinez | |
393 | @Override
|
||
394 | public boolean equals(CRSDefinition definition, boolean ignoreAxis, boolean ignoreMetadata) { |
||
395 | 853 | cmartinez | 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 | 828 | cmartinez | } |
416 | 867 | cmartinez | |
417 | @Override
|
||
418 | public int hashCode() { |
||
419 | return origCrs.hashCode();
|
||
420 | } |
||
421 | 828 | cmartinez | } |