Source Code Cross Referenced for Console.java in  » GIS » GeoTools-2.4.1 » org » geotools » referencing » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoTools 2.4.1 » org.geotools.referencing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2004-2006, GeoTools Project Managment Committee (PMC)
005:         *    (C) 2004, Institut de Recherche pour le Développement
006:         *   
007:         *    This library is free software; you can redistribute it and/or
008:         *    modify it under the terms of the GNU Lesser General Public
009:         *    License as published by the Free Software Foundation;
010:         *    version 2.1 of the License.
011:         *
012:         *    This library is distributed in the hope that it will be useful,
013:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015:         *    Lesser General Public License for more details.
016:         */
017:        package org.geotools.referencing;
018:
019:        // J2SE dependencies
020:        import java.io.FileReader;
021:        import java.io.IOException;
022:        import java.io.LineNumberReader;
023:        import java.text.DecimalFormat;
024:        import java.text.NumberFormat;
025:        import java.text.ParsePosition;
026:        import java.text.ParseException;
027:        import java.util.Arrays;
028:        import java.util.Locale;
029:        import java.util.StringTokenizer;
030:
031:        // OpenGIS dependencies
032:        import org.opengis.referencing.FactoryException;
033:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
034:        import org.opengis.referencing.operation.CoordinateOperationFactory;
035:        import org.opengis.referencing.operation.MathTransform;
036:        import org.opengis.referencing.operation.NoninvertibleTransformException;
037:        import org.opengis.referencing.operation.TransformException;
038:        import org.opengis.geometry.DirectPosition;
039:        import org.opengis.geometry.MismatchedDimensionException;
040:
041:        // Geotools dependencies
042:        import org.geotools.geometry.GeneralDirectPosition;
043:        import org.geotools.io.TableWriter;
044:        import org.geotools.measure.Measure;
045:        import org.geotools.referencing.crs.AbstractCRS;
046:        import org.geotools.referencing.wkt.AbstractConsole;
047:        import org.geotools.referencing.wkt.Parser;
048:        import org.geotools.referencing.wkt.Preprocessor;
049:        import org.geotools.resources.Arguments;
050:        import org.geotools.resources.i18n.Errors;
051:        import org.geotools.resources.i18n.ErrorKeys;
052:        import org.geotools.resources.i18n.Vocabulary;
053:        import org.geotools.resources.i18n.VocabularyKeys;
054:
055:        /**
056:         * A console for executing CRS operations from the command line.
057:         * Instructions are read from the {@linkplain System#in standard input stream}
058:         * and results are sent to the  {@linkplain System#out standard output stream}.
059:         * Instructions include:
060:         *
061:         * <table>
062:         *   <tr><td nowrap valign="top">{@code SET} <var>name</var> {@code =} <var>wkt</var></td><td>
063:         *   Set the specified <var>name</var> as a shortcut for the specified Well Know
064:         *   Text (<var>wkt</var>). This WKT can contains other shortcuts defined previously.</td></tr>
065:         *
066:         *   <tr><td nowrap valign="top">{@code transform = } <var>wkt</var></td><td>
067:         *   Set explicitly a {@linkplain MathTransform math transform} to use for
068:         *   coordinate transformations. This instruction is a more direct alternative to the usage of
069:         *   {@code source crs} and {@code target crs} instruction.</td></tr>
070:         *
071:         *   <tr><td nowrap valign="top">{@code source crs = } <var>wkt</var></td><td>
072:         *   Set the source {@linkplain CoordinateReferenceSystem coordinate reference
073:         *   system} to the specified object. This object can be specified as a Well Know Text
074:         *   (<var>wkt</var>) or as a shortcut previously set.</td></tr>
075:         *
076:         *   <tr><td nowrap valign="top">{@code target crs = } <var>wkt</var></td><td>
077:         *   Set the target {@linkplain CoordinateReferenceSystem coordinate reference
078:         *   system} to the specified object. This object can be specified as a Well Know Text
079:         *   (<var>wkt</var>) or as a shortcut previously set. Once both source and target
080:         *   CRS are specified a {@linkplain MathTransform math transform} from source to
081:         *   target CRS is automatically infered.</td></tr>
082:         *
083:         *   <tr><td nowrap valign="top">{@code source pt = } <var>coord</var></td><td>
084:         *   Transforms the specified coordinates from source CRS to target CRS
085:         *   and prints the result.</td></tr>
086:         *
087:         *   <tr><td nowrap valign="top">{@code target pt = } <var>coord</var></td><td>
088:         *   Inverse transforms the specified coordinates from target CRS to source CRS
089:         *   and prints the result.</td></tr>
090:         *
091:         *   <tr><td nowrap valign="top">{@code test tolerance = } <var>vector</var></td><td>
092:         *   Set the maximum difference between the transformed source point and the
093:         *   target point. Once this value is set, every occurence of the {@code target pt} instruction
094:         *   will trig this comparaison. If a greater difference is found, an exception is thrown or a
095:         *   message is printed to the error stream.</td></tr>
096:         *
097:         *   <tr><td nowrap valign="top">{@code print set}</td><td>
098:         *   Prints the set of shortcuts defined in previous calls to {@code SET} instruction.</td></tr>
099:         *
100:         *   <tr><td nowrap valign="top">{@code print crs}</td><td>
101:         *   Prints the source and target {@linkplain CoordinateReferenceSystem coordinate reference system}
102:         *   {@linkplain MathTransform math transform} and its inverse as Well Know Text (wkt).</td></tr>
103:         *
104:         *   <tr><td nowrap valign="top">{@code print pts}</td><td>
105:         *   Prints the source and target points, their transformed points, and the distance between
106:         *   them.</td></tr>
107:         *
108:         *   <tr><td nowrap valign="top">{@code exit}</td><td>
109:         *   Quit the console.</td></tr>
110:         * </table>
111:         *
112:         * @since 2.1
113:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/Console.java $
114:         * @version $Id: Console.java 25050 2007-04-06 00:41:49Z jgarnett $
115:         * @author Martin Desruisseaux
116:         */
117:        public class Console extends AbstractConsole {
118:            /**
119:             * The locale for number parser.
120:             */
121:            private final Locale locale = Locale.US;
122:
123:            /**
124:             * The number format to use for reading coordinate points.
125:             */
126:            private final NumberFormat numberFormat = NumberFormat
127:                    .getNumberInstance(locale);
128:
129:            /**
130:             * The number separator in vectors. Usually {@code ,}, but could
131:             * also be {@code ;} if the coma is already used as the decimal
132:             * separator.
133:             */
134:            private final String numberSeparator;
135:
136:            /**
137:             * The coordinate operation factory to use.
138:             */
139:            private final CoordinateOperationFactory factory = ReferencingFactoryFinder
140:                    .getCoordinateOperationFactory(null);
141:
142:            /**
143:             * The source and target CRS, or {@code null} if not yet determined.
144:             */
145:            private CoordinateReferenceSystem sourceCRS, targetCRS;
146:
147:            /**
148:             * Source and target coordinate points, or {@code null} if not yet determined.
149:             */
150:            private DirectPosition sourcePosition, targetPosition;
151:
152:            /**
153:             * The math transform, or {@code null} if not yet determined.
154:             */
155:            private MathTransform transform;
156:
157:            /**
158:             * The tolerance value. If non-null, the difference between the computed and the specified
159:             * target point will be compared against this tolerance threshold. If it is greater, a message
160:             * will be printed.
161:             */
162:            private double[] tolerance;
163:
164:            /**
165:             * The last error thats occured while processing an instruction.
166:             * Used in order to print the stack trace on request.
167:             */
168:            private transient Exception lastError;
169:
170:            /**
171:             * Creates a new console instance using {@linkplain System#in standard input stream},
172:             * {@linkplain System#out standard output stream}, {@linkplain System#err error output stream}
173:             * and the system default line separator.
174:             */
175:            public Console() {
176:                super (new Preprocessor(new Parser()));
177:                numberSeparator = getNumberSeparator(numberFormat);
178:            }
179:
180:            /**
181:             * Creates a new console instance using the specified input stream.
182:             *
183:             * @param in The input stream.
184:             */
185:            public Console(final LineNumberReader in) {
186:                super (new Preprocessor(new Parser()), in);
187:                numberSeparator = getNumberSeparator(numberFormat);
188:            }
189:
190:            /**
191:             * Returns the character to use as a number separator.
192:             * As a side effect, this method also adjust the minimum and maximum digits.
193:             */
194:            private static String getNumberSeparator(
195:                    final NumberFormat numberFormat) {
196:                numberFormat.setGroupingUsed(false);
197:                numberFormat.setMinimumFractionDigits(6);
198:                numberFormat.setMaximumFractionDigits(6);
199:                if (numberFormat instanceof  DecimalFormat) {
200:                    final char decimalSeparator = ((DecimalFormat) numberFormat)
201:                            .getDecimalFormatSymbols().getDecimalSeparator();
202:                    if (decimalSeparator == ',') {
203:                        return ";";
204:                    }
205:                }
206:                return ",";
207:            }
208:
209:            /**
210:             * Run the console from the command line. Before to process all instructions
211:             * from the {@linkplain System#in standard input stream}, this method first
212:             * process the following optional command-line arguments:
213:             * <P>
214:             * <TABLE CELLPADDING='0' CELLSPACING='0'>
215:             *   <TR><TD NOWRAP><CODE>-load</CODE> <VAR>&lt;filename&gt;</VAR></TD>
216:             *       <TD>&nbsp;Load a definition file before to run instructions from
217:             *           the standard input stream.</TD></TR>
218:             *   <TR><TD NOWRAP><CODE>-encoding</CODE> <VAR>&lt;code&gt;</VAR></TD>
219:             *       <TD>&nbsp;Set the character encoding.</TD></TR>
220:             *   <TR><TD NOWRAP><CODE>-locale</CODE> <VAR>&lt;language&gt;</VAR></TD>
221:             *       <TD>&nbsp;Set the language for the output (e.g. "fr" for French).</TD></TR>
222:             * </TABLE>
223:             *
224:             * @param args the command line arguments
225:             */
226:            public static void main(String[] args) {
227:                final Arguments arguments = new Arguments(args);
228:                final String load = arguments.getOptionalString("-load");
229:                final String file = arguments.getOptionalString("-file");
230:                args = arguments.getRemainingArguments(0);
231:                Locale.setDefault(arguments.locale);
232:                final LineNumberReader input;
233:                final Console console;
234:                /*
235:                 * The usual way to execute instructions from a file is to redirect the standard input
236:                 * stream using the standard DOS/Unix syntax (e.g. "< thefile.txt").  However, we also
237:                 * accept a "-file" argument for the same purpose. It is easier to debug. On DOS system,
238:                 * it also use the system default encoding instead of the command-line one.
239:                 */
240:                if (file == null) {
241:                    input = null;
242:                    console = new Console();
243:                } else
244:                    try {
245:                        input = new LineNumberReader(new FileReader(file));
246:                        console = new Console(input);
247:                        console.setPrompt(null);
248:                    } catch (IOException exception) {
249:                        System.err.println(exception.getLocalizedMessage());
250:                        return;
251:                    }
252:                /*
253:                 * Load predefined shorcuts. The file must be in the form "name = WKT". An example
254:                 * of such file is the property file used by the property-based authority factory.
255:                 */
256:                if (load != null)
257:                    try {
258:                        final LineNumberReader in = new LineNumberReader(
259:                                new FileReader(load));
260:                        try {
261:                            console.loadDefinitions(in);
262:                        } catch (ParseException exception) {
263:                            console.reportError(exception);
264:                            in.close();
265:                            return;
266:                        }
267:                        in.close();
268:                    } catch (IOException exception) {
269:                        console.reportError(exception);
270:                        return;
271:                    }
272:                /*
273:                 * Run all instructions and close the stream if it was a file one.
274:                 */
275:                console.run();
276:                if (input != null)
277:                    try {
278:                        input.close();
279:                    } catch (IOException exception) {
280:                        console.reportError(exception);
281:                    }
282:            }
283:
284:            /**
285:             * Execute the specified instruction.
286:             *
287:             * @param  instruction The instruction to execute.
288:             * @throws IOException if an I/O operation failed while writting to the
289:             *         {@linkplain #out output stream}.
290:             * @throws ParseException if a line can't be parsed.
291:             * @throws FactoryException If a transform can't be created.
292:             * @throws TransformException if a transform failed.
293:             */
294:            protected void execute(String instruction) throws IOException,
295:                    ParseException, FactoryException, TransformException {
296:                String value = null;
297:                int i = instruction.indexOf('=');
298:                if (i >= 0) {
299:                    value = instruction.substring(i + 1).trim();
300:                    instruction = instruction.substring(0, i).trim();
301:                }
302:                final StringTokenizer keywords = new StringTokenizer(
303:                        instruction);
304:                if (keywords.hasMoreTokens()) {
305:                    final String key0 = keywords.nextToken();
306:                    if (!keywords.hasMoreTokens()) {
307:                        // -------------------------------
308:                        //   exit
309:                        // -------------------------------
310:                        if (key0.equalsIgnoreCase("exit")) {
311:                            if (value != null) {
312:                                throw unexpectedArgument("exit");
313:                            }
314:                            stop();
315:                            return;
316:                        }
317:                        // -------------------------------
318:                        //   stacktrace
319:                        // -------------------------------
320:                        if (key0.equalsIgnoreCase("stacktrace")) {
321:                            if (value != null) {
322:                                throw unexpectedArgument("stacktrace");
323:                            }
324:                            if (lastError != null) {
325:                                lastError.printStackTrace(err);
326:                            }
327:                            return;
328:                        }
329:                        // -------------------------------
330:                        //   transform = <the transform>
331:                        // -------------------------------
332:                        if (key0.equalsIgnoreCase("transform")) {
333:                            transform = (MathTransform) parseObject(value,
334:                                    MathTransform.class);
335:                            sourceCRS = null;
336:                            targetCRS = null;
337:                            return;
338:                        }
339:                    } else {
340:                        final String key1 = keywords.nextToken();
341:                        if (!keywords.hasMoreTokens()) {
342:                            // -------------------------------
343:                            //   print definition|crs|points
344:                            // -------------------------------
345:                            if (key0.equalsIgnoreCase("print")) {
346:                                if (value != null) {
347:                                    throw unexpectedArgument("print");
348:                                }
349:                                if (key1.equalsIgnoreCase("set")) {
350:                                    printDefinitions();
351:                                    return;
352:                                }
353:                                if (key1.equalsIgnoreCase("crs")) {
354:                                    printCRS();
355:                                    return;
356:                                }
357:                                if (key1.equalsIgnoreCase("pts")) {
358:                                    printPts();
359:                                    return;
360:                                }
361:                            }
362:                            // -------------------------------
363:                            //   set <name> = <wkt>
364:                            // -------------------------------
365:                            if (key0.equalsIgnoreCase("set")) {
366:                                addDefinition(key1, value);
367:                                return;
368:                            }
369:                            // -------------------------------
370:                            //   test tolerance = <vector>
371:                            // -------------------------------
372:                            if (key0.equalsIgnoreCase("test")) {
373:                                if (key1.equalsIgnoreCase("tolerance")) {
374:                                    tolerance = parseVector(value);
375:                                    return;
376:                                }
377:                            }
378:                            // -------------------------------
379:                            //   source|target crs = <wkt>
380:                            // -------------------------------
381:                            if (key1.equalsIgnoreCase("crs")) {
382:                                if (key0.equalsIgnoreCase("source")) {
383:                                    sourceCRS = (CoordinateReferenceSystem) parseObject(
384:                                            value,
385:                                            CoordinateReferenceSystem.class);
386:                                    transform = null;
387:                                    return;
388:                                }
389:                                if (key0.equalsIgnoreCase("target")) {
390:                                    targetCRS = (CoordinateReferenceSystem) parseObject(
391:                                            value,
392:                                            CoordinateReferenceSystem.class);
393:                                    transform = null;
394:                                    return;
395:                                }
396:                            }
397:                            // -------------------------------
398:                            //   source|target pt = <coords>
399:                            // -------------------------------
400:                            if (key1.equalsIgnoreCase("pt")) {
401:                                if (key0.equalsIgnoreCase("source")) {
402:                                    sourcePosition = new GeneralDirectPosition(
403:                                            parseVector(value));
404:                                    return;
405:                                }
406:                                if (key0.equalsIgnoreCase("target")) {
407:                                    targetPosition = new GeneralDirectPosition(
408:                                            parseVector(value));
409:                                    if (tolerance != null
410:                                            && sourcePosition != null) {
411:                                        update();
412:                                        if (transform != null) {
413:                                            test();
414:                                        }
415:                                    }
416:                                    return;
417:                                }
418:                            }
419:                        }
420:                    }
421:                }
422:                throw new ParseException(Errors.format(
423:                        ErrorKeys.ILLEGAL_INSTRUCTION_$1, instruction), 0);
424:            }
425:
426:            /**
427:             * Executes the "{@code print crs}" instruction.
428:             */
429:            private void printCRS() throws FactoryException, IOException {
430:                final Locale locale = null;
431:                final Vocabulary resources = Vocabulary.getResources(locale);
432:                final TableWriter table = new TableWriter(out, " \u2502 ");
433:                table.setMultiLinesCells(true);
434:                char separator = '\u2500';
435:                if (sourceCRS != null || targetCRS != null) {
436:                    table.writeHorizontalSeparator();
437:                    table.write(resources.getString(VocabularyKeys.SOURCE_CRS));
438:                    table.nextColumn();
439:                    table.write(resources.getString(VocabularyKeys.TARGET_CRS));
440:                    table.nextLine();
441:                    table.writeHorizontalSeparator();
442:                    if (sourceCRS != null) {
443:                        table.write(parser.format(sourceCRS));
444:                    }
445:                    table.nextColumn();
446:                    if (targetCRS != null) {
447:                        table.write(parser.format(targetCRS));
448:                    }
449:                    table.nextLine();
450:                    separator = '\u2550';
451:                }
452:                /*
453:                 * Format the math transform and its inverse, if any.
454:                 */
455:                update();
456:                if (transform != null) {
457:                    table.nextLine(separator);
458:                    table.write(resources
459:                            .getString(VocabularyKeys.MATH_TRANSFORM));
460:                    table.nextColumn();
461:                    table.write(resources
462:                            .getString(VocabularyKeys.INVERSE_TRANSFORM));
463:                    table.nextLine();
464:                    table.writeHorizontalSeparator();
465:                    table.write(parser.format(transform));
466:                    table.nextColumn();
467:                    try {
468:                        table.write(parser.format(transform.inverse()));
469:                    } catch (NoninvertibleTransformException exception) {
470:                        table.write(exception.getLocalizedMessage());
471:                    }
472:                    table.nextLine();
473:                }
474:                table.writeHorizontalSeparator();
475:                table.flush();
476:            }
477:
478:            /**
479:             * Print the source and target point, and their transforms.
480:             *
481:             * @throws FactoryException if the transform can't be computed.
482:             * @throws TransformException if a transform failed.
483:             * @throws IOException if an error occured while writing to the output stream.
484:             */
485:            private void printPts() throws FactoryException,
486:                    TransformException, IOException {
487:                update();
488:                DirectPosition transformedSource = null;
489:                DirectPosition transformedTarget = null;
490:                String targetException = null;
491:                if (transform != null) {
492:                    if (sourcePosition != null) {
493:                        transformedSource = transform.transform(sourcePosition,
494:                                null);
495:                    }
496:                    if (targetPosition != null)
497:                        try {
498:                            transformedTarget = transform.inverse().transform(
499:                                    targetPosition, null);
500:                        } catch (NoninvertibleTransformException exception) {
501:                            targetException = exception.getLocalizedMessage();
502:                            if (sourcePosition != null) {
503:                                final GeneralDirectPosition p;
504:                                transformedTarget = p = new GeneralDirectPosition(
505:                                        sourcePosition.getDimension());
506:                                Arrays.fill(p.ordinates, Double.NaN);
507:                            }
508:                        }
509:                }
510:                final Locale locale = null;
511:                final Vocabulary resources = Vocabulary.getResources(locale);
512:                final TableWriter table = new TableWriter(out, 0);
513:                table.setMultiLinesCells(true);
514:                table.writeHorizontalSeparator();
515:                table.setAlignment(TableWriter.ALIGN_RIGHT);
516:                if (sourcePosition != null) {
517:                    table
518:                            .write(resources
519:                                    .getLabel(VocabularyKeys.SOURCE_POINT));
520:                    print(sourcePosition, table);
521:                    print(transformedSource, table);
522:                    table.nextLine();
523:                }
524:                if (targetPosition != null) {
525:                    table
526:                            .write(resources
527:                                    .getLabel(VocabularyKeys.TARGET_POINT));
528:                    print(transformedTarget, table);
529:                    print(targetPosition, table);
530:                    table.nextLine();
531:                }
532:                if (sourceCRS != null && targetCRS != null) {
533:                    table.write(resources.getLabel(VocabularyKeys.DISTANCE));
534:                    printDistance(sourceCRS, sourcePosition, transformedTarget,
535:                            table);
536:                    printDistance(targetCRS, targetPosition, transformedSource,
537:                            table);
538:                    table.nextLine();
539:                }
540:                table.writeHorizontalSeparator();
541:                table.flush();
542:                if (targetException != null) {
543:                    out.write(targetException);
544:                    out.write(lineSeparator);
545:                }
546:            }
547:
548:            /**
549:             * Print the specified point to the specified table.
550:             * This helper method is for use by {@link #printPts}.
551:             *
552:             * @param  point The point to print, or {@code null} if none.
553:             * @throws IOException if an error occured while writting to the output stream.
554:             */
555:            private void print(final DirectPosition point,
556:                    final TableWriter table) throws IOException {
557:                if (point != null) {
558:                    table.nextColumn();
559:                    table.write("  (");
560:                    final double[] coords = point.getCoordinates();
561:                    for (int i = 0; i < coords.length; i++) {
562:                        if (i != 0) {
563:                            table.write(", ");
564:                        }
565:                        table.nextColumn();
566:                        table.write(numberFormat.format(coords[i]));
567:                    }
568:                    table.write(')');
569:                }
570:            }
571:
572:            /**
573:             * Print the distance between two points using the specified CRS.
574:             */
575:            private void printDistance(final CoordinateReferenceSystem crs,
576:                    final DirectPosition position1,
577:                    final DirectPosition position2, final TableWriter table)
578:                    throws IOException {
579:                if (position1 == null) {
580:                    // Note: 'position2' is checked below, *after* blank columns insertion.
581:                    return;
582:                }
583:                for (int i = crs.getCoordinateSystem().getDimension(); --i >= 0;) {
584:                    table.nextColumn();
585:                }
586:                if (position2 != null) {
587:                    if (crs instanceof  AbstractCRS)
588:                        try {
589:                            final Measure distance;
590:                            distance = ((AbstractCRS) crs).distance(position1
591:                                    .getCoordinates(), position2
592:                                    .getCoordinates());
593:                            table.setAlignment(TableWriter.ALIGN_RIGHT);
594:                            table.write(numberFormat.format(distance
595:                                    .doubleValue()));
596:                            table.write("  ");
597:                            table.nextColumn();
598:                            table.write(String.valueOf(distance.getUnit()));
599:                            table.setAlignment(TableWriter.ALIGN_LEFT);
600:                            return;
601:                        } catch (UnsupportedOperationException ignore) {
602:                            /*
603:                             * Underlying CRS do not supports distance computation.
604:                             * Left the column blank.
605:                             */
606:                        }
607:                }
608:                table.nextColumn();
609:            }
610:
611:            ///////////////////////////////////////////////////////////
612:            ////////                                           ////////
613:            ////////        H E L P E R   M E T H O D S        ////////
614:            ////////                                           ////////
615:            ///////////////////////////////////////////////////////////
616:
617:            /**
618:             * Invoked automatically when the {@code target pt} instruction were executed and a
619:             * {@code test tolerance} were previously set. The default implementation compares
620:             * the transformed source point with the expected target point. If a mismatch greater than
621:             * the tolerance error is found, an exception is thrown. Subclasses may overrides this
622:             * method in order to performs more tests.
623:             *
624:             * @throws TransformException if the source point can't be transformed, or a mistmatch is found.
625:             * @throws MismatchedDimensionException if the transformed source point doesn't have the
626:             *         expected dimension.
627:             */
628:            protected void test() throws TransformException,
629:                    MismatchedDimensionException {
630:                final DirectPosition transformedSource = transform.transform(
631:                        sourcePosition, null);
632:                final int sourceDim = transformedSource.getDimension();
633:                final int targetDim = targetPosition.getDimension();
634:                if (sourceDim != targetDim) {
635:                    throw new MismatchedDimensionException(Errors.format(
636:                            ErrorKeys.MISMATCHED_DIMENSION_$2, new Integer(
637:                                    sourceDim), new Integer(targetDim)));
638:                }
639:                for (int i = 0; i < sourceDim; i++) {
640:                    // Use '!' for catching NaN.
641:                    if (!(Math.abs(transformedSource.getOrdinate(i)
642:                            - targetPosition.getOrdinate(i)) <= tolerance[Math
643:                            .min(i, tolerance.length - 1)])) {
644:                        throw new TransformException(Errors
645:                                .format(ErrorKeys.UNEXPECTED_TRANSFORM_RESULT));
646:                    }
647:                }
648:            }
649:
650:            /**
651:             * Check if the specified string start and end with the specified delimitors,
652:             * and returns the string without the delimitors.
653:             *
654:             * @param text  The string to check.
655:             * @param start The delimitor required at the string begining.
656:             * @param end   The delimitor required at the string end.
657:             */
658:            private static String removeDelimitors(String text,
659:                    final char start, final char end) {
660:                text = text.trim();
661:                final int endPos = text.length() - 1;
662:                if (endPos >= 1) {
663:                    if (text.charAt(0) == start && text.charAt(endPos) == end) {
664:                        text = text.substring(1, endPos).trim();
665:                    }
666:                }
667:                return text;
668:            }
669:
670:            /**
671:             * Parse a vector of values. Vectors are used for coordinate points.
672:             * Example:
673:             * <pre>
674:             * (46.69439222, 13.91405611, 41.21)
675:             * </pre>
676:             *
677:             * @param  text The vector to parse.
678:             * @return The vector as floating point numbers.
679:             * @throws ParseException if a number can't be parsed.
680:             */
681:            private double[] parseVector(String text) throws ParseException {
682:                text = removeDelimitors(text, '(', ')');
683:                final StringTokenizer st = new StringTokenizer(text,
684:                        numberSeparator);
685:                final double[] values = new double[st.countTokens()];
686:                for (int i = 0; i < values.length; i++) {
687:                    // Note: we need to convert the number to upper-case because
688:                    //       NumberParser seems to accepts "1E-10" but not "1e-10".
689:                    final String token = st.nextToken().trim().toUpperCase(
690:                            locale);
691:                    final ParsePosition position = new ParsePosition(0);
692:                    final Number result = numberFormat.parse(token, position);
693:                    if (position.getIndex() != token.length()) {
694:                        throw new ParseException(Errors.format(
695:                                ErrorKeys.UNPARSABLE_NUMBER_$1, token),
696:                                position.getErrorIndex());
697:                    }
698:                    values[i] = result.doubleValue();
699:                }
700:                return values;
701:            }
702:
703:            /**
704:             * Update the internal state after a change, before to apply transformation.
705:             * The most important change is to update the math transform, if needed.
706:             */
707:            private void update() throws FactoryException {
708:                if (transform == null && sourceCRS != null && targetCRS != null) {
709:                    transform = factory.createOperation(sourceCRS, targetCRS)
710:                            .getMathTransform();
711:                }
712:            }
713:
714:            /**
715:             * Constructs an exception saying that an argument was unexpected.
716:             *
717:             * @param  instruction The instruction name.
718:             * @return The exception to throws.
719:             */
720:            private static ParseException unexpectedArgument(
721:                    final String instruction) {
722:                return new ParseException(Errors.format(
723:                        ErrorKeys.UNEXPECTED_ARGUMENT_FOR_INSTRUCTION_$1,
724:                        instruction), 0);
725:            }
726:
727:            /**
728:             * {@inheritDoc}
729:             *
730:             * @param exception The exception to report.
731:             */
732:            protected void reportError(final Exception exception) {
733:                super.reportError(exception);
734:                lastError = exception;
735:            }
736:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.