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 / GtCRSCatalogManager.java @ 824

History | View | Annotate | Download (14.9 KB)

1
package org.gvsig.geotools.proj.catalog;
2

    
3
import java.io.File;
4
import java.sql.Connection;
5
import java.sql.PreparedStatement;
6
import java.sql.ResultSet;
7
import java.sql.SQLException;
8
import java.text.ParseException;
9
import java.util.ArrayList;
10
import java.util.Arrays;
11
import java.util.Collections;
12
import java.util.HashMap;
13
import java.util.List;
14
import java.util.Map;
15
import java.util.Set;
16

    
17
import javax.sql.DataSource;
18

    
19
import org.geotools.factory.FactoryFinder;
20
import org.geotools.factory.FactoryNotFoundException;
21
import org.geotools.referencing.CRS;
22
import org.geotools.referencing.ReferencingFactoryFinder;
23
import org.geotools.referencing.factory.BufferedAuthorityFactory;
24
import org.geotools.referencing.factory.epsg.HsqlEpsgDatabase;
25
import org.geotools.referencing.factory.epsg.ThreadedEpsgFactory;
26
import org.geotools.resources.i18n.ErrorKeys;
27
import org.geotools.resources.i18n.Errors;
28
import org.gvsig.proj.catalog.CRSCatalogManager;
29
import org.gvsig.proj.catalog.CRSDefinition;
30
import org.gvsig.proj.catalog.TextSerialization;
31
import org.gvsig.proj.catalog.TextSerialization.Format;
32
import org.gvsig.proj.catalog.TransformationDefinition;
33
import org.gvsig.proj.catalog.exception.CoordinateReferenceSystemException;
34
import org.gvsig.proj.catalog.exception.UnsupportedCoordinateReferenceSystemException;
35
import org.gvsig.proj.catalog.exception.UnsupportedTransformationException;
36
import org.opengis.referencing.FactoryException;
37
import org.opengis.referencing.NoSuchAuthorityCodeException;
38
import org.opengis.referencing.crs.CRSAuthorityFactory;
39
import org.opengis.referencing.crs.CRSFactory;
40
import org.opengis.referencing.crs.CompoundCRS;
41
import org.opengis.referencing.crs.CoordinateReferenceSystem;
42
import org.opengis.referencing.crs.GeocentricCRS;
43
import org.opengis.referencing.crs.GeographicCRS;
44
import org.opengis.referencing.cs.CartesianCS;
45
import org.opengis.referencing.cs.CoordinateSystem;
46
import org.opengis.referencing.cs.EllipsoidalCS;
47
import org.opengis.referencing.cs.SphericalCS;
48
import org.opengis.referencing.cs.VerticalCS;
49
import org.opengis.referencing.datum.EngineeringDatum;
50
import org.opengis.referencing.datum.GeodeticDatum;
51
import org.opengis.referencing.datum.VerticalDatum;
52
import org.opengis.referencing.operation.Conversion;
53
import org.opengis.referencing.operation.CoordinateOperation;
54
import org.opengis.referencing.operation.CoordinateOperationFactory;
55
import org.opengis.referencing.operation.MathTransform;
56
import org.opengis.referencing.operation.Projection;
57

    
58
public class GtCRSCatalogManager implements CRSCatalogManager {
59
        private static final String EPSG_DB_SUBFOLDER = "epsg";        
60
        private static final List<TextSerialization.Format> SUPPORTED_FORMATS = Arrays.asList(TextSerialization.Format.WKT1);
61
        private static final List<String> supportedAuthorities = Collections.unmodifiableList(Arrays.asList("EPSG", "ESRI", "USER"));
62

    
63
        public GtCRSCatalogManager() {
64
                
65
        }
66

    
67
        @Override
68
        public List<String> getAuthorityNames() {
69
                return supportedAuthorities;
70
                //return new ArrayList<String>(CRS.getSupportedAuthorities(true));
71
        }
72
        
73
        protected String toCode(String authorityName, String relCode) {
74
                return authorityName + ":" + relCode;
75
        }
76

    
77
        @Override
78
        public List<String> getCodes() {
79
                ArrayList<String> codes = new ArrayList<String>();
80
                Set<String> authorities = CRS.getSupportedAuthorities(true);
81
                for (String auth: authorities) {
82
                        CRSAuthorityFactory factory = ReferencingFactoryFinder.getCRSAuthorityFactory(auth, null);
83
                        try {
84
                                for (String code: factory.getAuthorityCodes(CoordinateReferenceSystem.class)) {
85
                                        codes.add(toCode(auth, code));
86
                                }
87
                        } catch (FactoryException | FactoryNotFoundException e) {
88
                                // TODO Auto-generated catch block
89
                                e.printStackTrace();
90
                        }
91
                }
92
                return codes;
93
        }
94

    
95
        @Override
96
        public List<String> getCodes(String authorityName) {
97
                // FIXME handle other authorities
98
                ArrayList<String> codes = new ArrayList<String>();
99

    
100
                if ("EPSG".equals(authorityName)) {
101
                        try {
102
                                CRSAuthorityFactory factory = ReferencingFactoryFinder.getCRSAuthorityFactory(authorityName, null);
103
                                for (String code: factory.getAuthorityCodes(CoordinateReferenceSystem.class)) {
104
                                        codes.add(toCode(authorityName, code));
105
                                }
106

    
107
                        } catch (FactoryException | FactoryNotFoundException e) {
108
                                // TODO Auto-generated catch block
109
                                e.printStackTrace();
110
                        }
111
                }
112
                return codes;
113
        }
114

    
115
        @Override
116
        public List<String> search(String searchString) {
117
                // FIXME handle other authorities
118
                return searchEpsg(searchString);
119
        }
120

    
121
        @Override
122
        public List<String> search(String authority, String searchString) {
123
                // FIXME handle other authorities
124
                if (authority.equals("EPSG")) {
125
                        return searchEpsg(searchString);
126
                }
127
                return Collections.emptyList();
128
        }
129
        
130
        protected List<String> searchEpsg(String searchString) {
131
                // FIXME handle other authorities
132
                CRSAuthorityFactory factory = ReferencingFactoryFinder.getCRSAuthorityFactory("EPSG", null);
133
                if (factory instanceof ThreadedEpsgFactory) {
134
                        ThreadedEpsgFactory epsgFactory = (ThreadedEpsgFactory) factory;
135
                        try {
136
                                DataSource ds = epsgFactory.getDataSource();
137
                                Connection c = ds.getConnection();
138
                                return searchEpsg(searchString, c);
139
                        } catch (SQLException e) {
140
                                // TODO Auto-generated catch block
141
                                e.printStackTrace();
142
                        }
143
                }
144
                return Collections.EMPTY_LIST;
145
        }
146
        
147
    public synchronized List<String> searchEpsg(String searchString, Connection conn) throws SQLException
148
    {
149
            ArrayList<String> codes = new ArrayList<String>();
150
            
151
            if (searchString.startsWith("EPSG:")) {
152
                    searchString = searchString.substring(5);
153
            }
154
            searchString = "%" + searchString.toLowerCase() + "%";
155
        try {
156
            // FIXME: JOIN query with area of use. Maybe also with  COORD_SYS_CODE to search for coord sys name
157
            final PreparedStatement stmt;
158
            stmt = conn.prepareStatement("SELECT COORD_REF_SYS_CODE,"
159
                  +       " COORD_REF_SYS_NAME,"
160
                  +       " AREA_OF_USE_CODE,"
161
                  +       " CRS_SCOPE,"
162
                  +       " REMARKS,"
163
                  +       " COORD_REF_SYS_KIND,"
164
                  +       " COORD_SYS_CODE,"       // Null for CompoundCRS
165
                  +       " DATUM_CODE,"           // Null for ProjectedCRS
166
                  +       " SOURCE_GEOGCRS_CODE,"  // For ProjectedCRS
167
                  +       " PROJECTION_CONV_CODE," // For ProjectedCRS
168
                  +       " CMPD_HORIZCRS_CODE,"   // For CompoundCRS only
169
                  +       " CMPD_VERTCRS_CODE"     // For CompoundCRS only
170
                  + " FROM epsg_coordinatereferencesystem"
171
                  + " WHERE COORD_REF_SYS_CODE LIKE ? OR LCASE(COORD_REF_SYS_NAME) LIKE ?"
172
                  + " OR LCASE(REMARKS) LIKE ?"
173
                  + " OR LCASE(CRS_SCOPE) LIKE ?");
174
            stmt.setString(1, searchString);
175
            stmt.setString(2, searchString);
176
            stmt.setString(3, searchString);
177
            stmt.setString(4, searchString);
178
            ResultSet result = stmt.executeQuery();
179
            while (result.next()) {
180
                final String epsg    = result.getString(1);//getString(result, 1, code);
181
                final String name    = result.getString(2);//getString(result, 2, code);
182
                final String area    = result.getString(3);
183
                final String scope   = result.getString(4);
184
                final String remarks = result.getString(5);
185

    
186
                final String csCode  = result.getString(7);
187
                final String dmCode    = result.getString( 8); // geographic
188
                final String geoCode = result.getString(9);
189
                final String opCode  = result.getString(10);
190
                // vertical:
191
                final String code1 = result.getString(11);
192
                final String code2 = result.getString(12);
193
                codes.add(epsg);
194
            }
195
            result.close();
196
        } catch (SQLException exception) {
197
            throw exception;
198
        }
199
        conn.close();
200
        System.out.println(codes.size());
201
        return codes;
202
    }
203

    
204
        @Override
205
        public CRSDefinition getCRSDefinition(String code) throws UnsupportedCoordinateReferenceSystemException {
206
                CoordinateReferenceSystem crs;
207
                try {
208
                        crs = CRS.decode(code);
209
                } catch (NoSuchAuthorityCodeException e) {
210
                        throw new UnsupportedCoordinateReferenceSystemException(code, e);
211
                } catch (FactoryException e) {
212
                        throw new UnsupportedCoordinateReferenceSystemException(code, e);
213
                }
214
                return new DefaultCRS(crs);
215
        }
216
        
217
        public CRSDefinition getCRSDefinition(CoordinateReferenceSystem crs) throws UnsupportedCoordinateReferenceSystemException {
218
                return new DefaultCRS(crs);
219
        }
220

    
221

    
222
        @Override
223
        public CRSDefinition getCompoundCRS(CRSDefinition... crsList) throws UnsupportedCoordinateReferenceSystemException {
224
                DefaultCRS[] defs = (DefaultCRS[]) crsList;
225
                ArrayList<CoordinateReferenceSystem> components = new ArrayList<CoordinateReferenceSystem>();
226
                for (CRSDefinition def: defs) {
227
                        if (def instanceof DefaultCRS) {
228
                                components.add(((DefaultCRS)def).getInternalCRS());        
229
                        }
230
                        else {
231
                                def = new DefaultCRS(def.toWKT());
232
                        }
233
                }
234
            CRSFactory crsFactory = ReferencingFactoryFinder.getCRSFactory(null);
235
                CoordinateReferenceSystem compoundCRS;
236
                try {
237
                    Map<String, String> properties = new HashMap<String, String>();
238
                    crsFactory.createCompoundCRS(properties, components.toArray(new CoordinateReferenceSystem[components.size()]));
239
                        compoundCRS = crsFactory.createCompoundCRS(properties, components.toArray(new CoordinateReferenceSystem[components.size()]));;
240
                        return new DefaultCRS(compoundCRS);
241
                } catch (FactoryException e) {
242
                        throw new UnsupportedCoordinateReferenceSystemException(e);
243
                }
244
        }
245
        
246
        @Override
247
        public CRSDefinition parseCRSDefinition(String def) throws UnsupportedCoordinateReferenceSystemException {
248
                CoordinateReferenceSystem crs;
249
                try {
250
                        crs = CRS.parseWKT(def);
251
                } catch (NoSuchAuthorityCodeException e) {
252
                        throw new UnsupportedCoordinateReferenceSystemException(def, e);
253
                } catch (FactoryException e) {
254
                        throw new UnsupportedCoordinateReferenceSystemException(def, e);
255
                }
256
                return new DefaultCRS(crs);
257
        }
258
        
259

    
260
        @Override
261
        public CRSDefinition parseCRSDefinition(String def, Format format)
262
                        throws UnsupportedCoordinateReferenceSystemException {
263
                if (SUPPORTED_FORMATS.contains(format)) {
264
                        parseCRSDefinition(def);
265
                }
266
                throw new UnsupportedOperationException("Format not supported");
267
        }
268
        
269

    
270
        @Override
271
        public DefaultTransformation parseTransformationDefinition(String def) throws ParseException {
272
                return new DefaultTransformation(def);
273
        }
274

    
275
        @Override
276
        public DefaultTransformation parseTransformationDefinition(String def, Format format)
277
                        throws UnsupportedCoordinateReferenceSystemException, ParseException {
278
                if (SUPPORTED_FORMATS.contains(format)) {
279
                        return new DefaultTransformation(def);
280
                }
281
                throw new UnsupportedOperationException("Format not supported");
282
        }
283

    
284
        @Override
285
        public TransformationDefinition getTransformationDefinition(String code) {
286
                // TODO Auto-generated method stub
287
                return null;
288
        }
289
        
290
        public TransformationDefinition getTransformationDefinition(CoordinateOperation operation, boolean inverse) {
291
                // TODO Auto-generated method stub
292
                return null;
293
        }
294

    
295
        @Override
296
        public String registerCoordinateReferenceSystem(String wktDefinition, String description) {
297
                // TODO Auto-generated method stub
298
                return null;
299
        }
300

    
301
        @Override
302
        public String registerTransformation(String wktDefinition, String description) {
303
                // TODO Auto-generated method stub
304
                return null;
305
        }
306

    
307
        @Override
308
        public String registerCoordinateTransformationPVT(String sourceCRS, String targetCRS, String description,
309
                        float xTraslation, float yTraslation, float zTraslation, float xRotation, float yRotation, float zRotation,
310
                        float scaleDifference) {
311
                // TODO Auto-generated method stub
312
                return null;
313
        }
314

    
315
        @Override
316
        public String registerCoordinateTransformationCFR(String sourceCRS, String targetCRS, String description,
317
                        float xTraslation, float yTraslation, float zTraslation, float xRotation, float yRotation, float zRotation,
318
                        float scaleDifference) {
319
                // TODO Auto-generated method stub
320
                return null;
321
        }
322

    
323
        @Override
324
        public String registerCoordinateTransformation(String sourceCRS, String targetCRS, String description,
325
                        File ntv2Grid) {
326
                // TODO Auto-generated method stub
327
                return null;
328
        }
329

    
330
        @Override
331
        public List<TransformationDefinition> getCoordinateTransformations(CRSDefinition source, CRSDefinition target) throws CoordinateReferenceSystemException {
332
                ArrayList<TransformationDefinition> transforms = new ArrayList<TransformationDefinition>();
333
                try {
334
                        CoordinateReferenceSystem sourceCRS = ((DefaultCRS)source).getInternalCRS();
335
                        CoordinateReferenceSystem targetCRS = ((DefaultCRS)target).getInternalCRS();
336
                CoordinateOperationFactory operationFactory = CRS.getCoordinateOperationFactory(false);
337
                Set<CoordinateOperation> ops = operationFactory.findOperations(sourceCRS, targetCRS);
338
                for (CoordinateOperation op: ops) {
339
                        DefaultTransformation def = new DefaultTransformation(op);
340
                        transforms.add(def);
341
                }
342
                } catch (FactoryException | ClassCastException e) {
343
                        throw new UnsupportedTransformationException(e);
344
                }
345
                return transforms;
346
        }
347

    
348
        @Override
349
        public List<TransformationDefinition> getCoordinateTransformations(String source, String target) throws UnsupportedTransformationException {
350
                ArrayList<TransformationDefinition> transforms = new ArrayList<TransformationDefinition>();
351
                try {
352
                        CoordinateReferenceSystem sourceCRS = CRS.decode(source);
353
                        CoordinateReferenceSystem targetCRS = CRS.decode(target);
354
                CoordinateOperationFactory operationFactory = CRS.getCoordinateOperationFactory(false);
355
                Set<CoordinateOperation> ops = operationFactory.findOperations(sourceCRS, targetCRS);
356
                for (CoordinateOperation op: ops) {
357
                        DefaultTransformation def = new DefaultTransformation(op);
358
                        transforms.add(def);
359
                }
360
                } catch (FactoryException e) {
361
                        throw new UnsupportedTransformationException(e);
362
                }
363
                return transforms;
364
        }
365

    
366
        /**
367
         * Sets the path to the folder to be used by the library to load the CRS and
368
         * transformation definitions. The specified path must contain one or more subfolders,
369
         * containg the CRS and transformation database in the appropriate format:
370
         * <ul><li>for EPSG database: a "epsg" subfolder must exist, which contains a HSQL database
371
         * called "EPSG". The structure of this database must be the same used by Geotools,
372
         * which is essentially based in the EPSG data model.</li>
373
         * </ul>
374
         * 
375
         * This method only has effect when it is called before any other method in the manager
376
         * (before instantiating any CRS, transformation, etc). 
377
         * 
378
         * @param path The path to the folder containing the system CRS and transformation
379
         * definitions
380
         */
381
        @Override
382
        public void setSystemDataPath(File path) {
383
                System.setProperty(HsqlEpsgDatabase.DIRECTORY_KEY, path.getAbsolutePath() + "/" + EPSG_DB_SUBFOLDER);
384
        }
385

    
386
        @Override
387
        public void setUserDataPath(File path) {
388
                // TODO Auto-generated method stub
389
                
390
        }
391

    
392
        @Override
393
        public List<TextSerialization.Format> getSupportedFormats() {
394
                // TODO Auto-generated method stub
395
                return SUPPORTED_FORMATS;
396
        }
397

    
398
}