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 |
} |