Source Code Cross Referenced for GMLReader.java in  » GIS » openjump » com » vividsolutions » jump » io » 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 » openjump » com.vividsolutions.jump.io 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
0003:         * for visualizing and manipulating spatial features with geometry and attributes.
0004:         *
0005:         * Copyright (C) 2003 Vivid Solutions
0006:         *
0007:         * This program is free software; you can redistribute it and/or
0008:         * modify it under the terms of the GNU General Public License
0009:         * as published by the Free Software Foundation; either version 2
0010:         * of the License, or (at your option) any later version.
0011:         *
0012:         * This program is distributed in the hope that it will be useful,
0013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0015:         * GNU General Public License for more details.
0016:         *
0017:         * You should have received a copy of the GNU General Public License
0018:         * along with this program; if not, write to the Free Software
0019:         * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
0020:         *
0021:         * For more information, contact:
0022:         *
0023:         * Vivid Solutions
0024:         * Suite #1A
0025:         * 2328 Government Street
0026:         * Victoria BC  V8T 5G5
0027:         * Canada
0028:         *
0029:         * (250)385-6040
0030:         * www.vividsolutions.com
0031:         */
0032:        package com.vividsolutions.jump.io;
0033:
0034:        import com.vividsolutions.jts.geom.*;
0035:
0036:        import com.vividsolutions.jump.feature.*;
0037:
0038:        import org.xml.sax.*;
0039:        import org.xml.sax.helpers.DefaultHandler;
0040:
0041:        import java.io.*;
0042:
0043:        import java.util.List;
0044:        import java.util.ArrayList;
0045:        import java.util.StringTokenizer;
0046:
0047:        /**
0048:         *  GMLReader is a {@link JUMPReader} specialized to read GML files.
0049:         *
0050:         *  <p>
0051:         *     DataProperties for the JCSReader load(DataProperties) interface:
0052:         *  </p>
0053:         *  <p>
0054:         *  <table border='1' cellspacing='0' cellpadding='4'>
0055:         *    <tr>
0056:         *      <th>Parameter</th>
0057:         *      <th>Meaning</th>
0058:         *    </tr>
0059:         *    <tr>
0060:         *      <td>
0061:         *        File or DefaultValue
0062:         *      </td>
0063:         *
0064:         *      <td>
0065:         *        File name for the input .xml file
0066:         *      </td>
0067:         *    </tr>
0068:         *
0069:         *    <tr>
0070:         *      <td>
0071:         *        InputTemplateFile
0072:         *      </td>
0073:         *      <td>
0074:         *        Filename for the GMLInputTemplate .xml file
0075:         *      </td>
0076:         *    </tr>
0077:         *
0078:         *    <tr>
0079:         *      <td>CompressedFile</td>
0080:         *      <td>
0081:         *        File name (a .zip or .gz) with a .jml/.xml/.gml inside
0082:         *        (specified by File)
0083:         *      </td>
0084:         *    </tr>
0085:         *
0086:         *    <tr>
0087:         *      <td>
0088:         *        CompressedFileTemplate</td><td>File name (.zip or .gz)
0089:         *        with the input template in (specified by InputTemplateFile)
0090:         *      </td>
0091:         *    </tr>
0092:         *  </table>
0093:         * </p>
0094:         *
0095:         *  <br>
0096:         *  NOTE: If InputTemplateFile is unspecified, GMLReader will try to read one
0097:         *  off the top of the input .xml file (the JCS format). This is the same as
0098:         *  specifying the File and TemplateFile to be the same. <br>
0099:         *  <br>
0100:         *
0101:         *  Typically, you would write:<br>
0102:         *
0103:         *  <pre>
0104:         *     gmlReader = new GMLReader();
0105:         *     gmlReader.load( DriverProperties) ; // has InputFile and InputTemplate
0106:         *  </pre>
0107:         *  or:
0108:         *  <pre>
0109:         *     gmlReader.setInputTemplate( GMLInputTemplate);
0110:         *     gmlReader.load( <Reader> , <stream name> );
0111:         *  </pre>
0112:         *  <br>
0113:         *  <br>
0114:         *  Internal Details - This is based on a small finite state machine with these
0115:         *  states: <br>
0116:         *  <br>
0117:         *  STATE MEANING <br>
0118:         *  0 Init <br>
0119:         *  1 Waiting for Collection tag <br>
0120:         *  2 Waiting for Feature tag <br>
0121:         *  3 Getting jcs columns <br>
0122:         *  4 Parsing geometry (goes back to state 3) <br>
0123:         *  1000 Parsing Multi-geometry, recursion level =1 <br>
0124:         *  1001 Parsing Multi-geometry, recursion level =2 <br>
0125:         *  ... <br>
0126:         *  <br>
0127:         *  <br>
0128:         *  State Diagram <br>
0129:         *  <br>
0130:         *  init <br>
0131:         *  <PRE>
0132:         *        0  ----->  1
0133:         *                   |
0134:         *                   | Collection start Tag
0135:         *                   |
0136:         *                -->2---------------->     FINISH
0137:         *                \  |   End Collection tag
0138:         * End Feature tag \ |
0139:         *                  \|
0140:         *        4<-------->3
0141:         *           Geometry start/end
0142:         *</PRE>
0143:         *  <br>
0144:         *  For multi-geometries <br>
0145:         *  On start Multi-geometry, increment state by 1 (or jump to 1000 if at state
0146:         *  4) <br>
0147:         *  make sure recursivegeometry[state-1000] is null <br>
0148:         *  <put any object into the recursivegeometry[state-1000] collection>
0149:         *
0150:         *  <br>
0151:         *  <br>
0152:         *  on end multi-geometry, <br>
0153:         *  build geometry in recursivegeometry[state-1000], add it to
0154:         *  recursivegeometry[state-1000-1] <br>
0155:         *  state= state-1 <br>
0156:         *  <br>
0157:         *  For single geometries - they will be stuck into recursivegeometry[0], which
0158:         *  is the same <br>
0159:         *  as geometry <br>
0160:         *  <br>
0161:         *  For multi geometries - they will also be stuck into recursivegeometry[0],
0162:         *  which is the same <br>
0163:         *  as geometry. But, for the first nested geometry, it will be stuck into
0164:         *  recursivegeometry[1], <br>
0165:         *  which will then be geometry <br>
0166:         *  <pre>
0167:         *  example of double GCs:
0168:         *  START geometry     ->move to state 4
0169:         *  START TAG: multi*  -> move to state 1000, geometry = recursivegeometry[0]
0170:         *  <POINT>
0171:         *
0172:         *  -> added to geometry <POINT>
0173:         *
0174:         *  -> added to geometry START TAG: multi* -> move to state 1001, geometry =
0175:         *  recursivegeometry[1] <POINT>
0176:         *
0177:         *  -> added to geometry <POINT>
0178:         *
0179:         *  -> added to geometry END TAG: multi -> move to state 1000, build geometry in
0180:         *  recursivegeometry[1], add to recursivegeometry[0], geometry =
0181:         *  recursivegeometry[0] <POINT>
0182:         *
0183:         *  -> added to geometry END TAG: multi -> <finished> move to state 4, build
0184:         *  geometry in recursivegeometry[0] (thats the result) and put it in
0185:         *  finalGeometry END geometry -> add to feature collection example of simple
0186:         *  geometry: START geometry ->move to state 4 BEGIN polygon ->clear out inner
0187:         *  ring accumulator BEGIN outerboundary BEGIN linearring END linearring -> put
0188:         *  points in linearRing END outerboundary -> put linearRing in outerBoundary
0189:         *  BEGIN innerboundary BEGIN linearring END linearring -> put points in
0190:         *  linearRing END innerboundary -> add linearRing to innerBoundary list END
0191:         *  polygon -> build polygon (put in geometry, which is recursivegeometry[0] END
0192:         *  geometry => add to feature collection
0193:         *  </pre>
0194:         *
0195:         *  Most of the work is done in the endTag method!
0196:         *  <br>
0197:         * <br>
0198:         * New additions: Jan 2005 by Dave Blasby
0199:         *  allow srid to be parsed from the GML file
0200:         *   For example:
0201:         *      <gml:LineString srsName="EPSG:42102">
0202:         *        ....
0203:         *      </gml:LineString>
0204:         *   The SRID of the created geometry will be 42102.
0205:         *    It accepts srsNames of the form "<letters>:<number>".
0206:         *      ie. "EPSG:111" or "DAVE:222" or "BCGOV:333" etc...
0207:         *    The Geometry's SRID will be the number.
0208:         *    If you have a GEOMETRYCOLLECTION with more than one SRID specified
0209:         *    the SRID of the result will be indeterminate (this isnt correct GML).
0210:         *
0211:         *    Geometries without a srsName will get SRID 0.
0212:         *
0213:         *    This functionality defaults to off for compatibility.
0214:         *    To turn it on or off, call the acceptSRID(true|false) function.
0215:         *
0216:         *   New Addition: Jan, 2005by Dave Blasby
0217:         *    Added slightly better support for type=OBJECT.  It sticks a String in.  Before it would probably throw an error.
0218:         *    Added support for multi-objects for example:
0219:         *       <a>
0220:         *            <b>...1...</b>
0221:         *            <b>...2...</b>
0222:         *            <b>...3...</b>
0223:         *       </a>
0224:         *     Old behavior would be to for column 'b' to have value "...3...".
0225:         *     New behavior (only if you set b's  type to 'OBJECT' and set the GMLReader to processMultiItems as lists)
0226:         *     <a><b>...1...</b></a>  -->  b get the string "...1..." (as before)
0227:         *     <a><b>...1...</b><b>...2...</b><b>...3...</b></a> --> 'b' is a list of String ['...1...','...2...','...3...']
0228:         *
0229:         */
0230:        public class GMLReader extends DefaultHandler implements  JUMPReader {
0231:            static int STATE_GET_COLUMNS = 3;
0232:
0233:            /**
0234:             *  STATE   MEANING <br>
0235:             *  0      Init <br>
0236:             *  1      Waiting for Collection tag <br>
0237:             *  2      Waiting for Feature tag <br>
0238:             *  3      Getting jcs columns <br>
0239:             *  4      Parsing geometry (goes back to state 3) <br>
0240:             *  1000   Parsing Multi-geometry, recursion level =1 <br>
0241:             *  1001   Parsing Multi-geometry, recursion level =2 <br>
0242:             */
0243:            static int STATE_INIT = 0;
0244:            static int STATE_PARSE_GEOM_NESTED = 1000;
0245:            static int STATE_PARSE_GEOM_SIMPLE = 4;
0246:            static int STATE_WAIT_COLLECTION_TAG = 1;
0247:            static int STATE_WAIT_FEATURE_TAG = 2;
0248:            GMLInputTemplate GMLinput = null;
0249:            int STATE = STATE_INIT; //list of points
0250:            Point apoint;
0251:            Feature currentFeature;
0252:            int currentGeometryNumb = 1;
0253:            FeatureCollection fc;
0254:            FeatureSchema fcmd; // list of geometries
0255:            Geometry finalGeometry; //list of geometrycollections - list of list of geometry
0256:            ArrayList geometry;
0257:            GeometryFactory geometryFactory = new GeometryFactory(); //this might get replaced if there's an SRID change
0258:            ArrayList innerBoundaries = new ArrayList();
0259:            Attributes lastStartTag_atts;
0260:            String lastStartTag_name;
0261:            String lastStartTag_qName; //accumulate values inside a tag
0262:
0263:            // info about the last start tag encountered
0264:            String lastStartTag_uri;
0265:            LineString lineString;
0266:            LinearRing linearRing; // a LR
0267:            LinearRing outerBoundary; //list of LinearRing
0268:            ArrayList pointList = new ArrayList(); // list of accumulated points (Coordinate)
0269:            Polygon polygon; // polygon
0270:
0271:            // higherlevel geomery object
0272:            ArrayList recursivegeometry = new ArrayList();
0273:
0274:            // low-level geometry objects
0275:            Coordinate singleCoordinate = new Coordinate();
0276:            String streamName; //result geometry  -
0277:            StringBuffer tagBody;
0278:            XMLReader xr; //see above
0279:
0280:            int SRID = 0; // srid to give the created geometries
0281:            public boolean parseSRID = false; //true = put SRID for srsName="EPSG:42102"
0282:            /**
0283:             * true => for 'OBJECT' types, if you find more than 1 item, make a list and store all the results
0284:             */
0285:            public boolean multiItemsAsLists = false;
0286:
0287:            /**
0288:             *  Constructor - make a SAXParser and have this GMLReader be its
0289:             *  ContentHandler and ErrorHandler.
0290:             */
0291:            public GMLReader() {
0292:                super ();
0293:                xr = new org.apache.xerces.parsers.SAXParser();
0294:                xr.setContentHandler(this );
0295:                xr.setErrorHandler(this );
0296:            }
0297:
0298:            /**
0299:             * parse SRID information in geometry tags
0300:             * @param parseTheSRID true = parse
0301:             */
0302:            public void acceptSRID(boolean parseTheSRID) {
0303:                parseSRID = parseTheSRID;
0304:            }
0305:
0306:            /**
0307:             *    Added slightly better support for type=OBJECT.  It sticks a String in.  Before it would probably throw an error.
0308:             *    Added support for multi-objects for example:
0309:             *       <a>
0310:             *            <b>...1...</b>
0311:             *            <b>...2...</b>
0312:             *            <b>...3...</b>
0313:             *       </a>
0314:             *     Old behavior would be to for column 'b' to have value "...3...".
0315:             *     New behavior (only if you set b's  type to 'OBJECT' and set the GMLReader to processMultiItems as lists)
0316:             *     <a><b>...1...</b></a>  -->  b get the string "b" (as before)
0317:             *     <a><b>...1...</b><b>...2...</b><b>...3...</b></a> --> 'b' is a list of String ['...1...','...2...','...3...']
0318:             */
0319:            public void processMultiItems(boolean accept) {
0320:                multiItemsAsLists = accept;
0321:            }
0322:
0323:            /**
0324:             *  Attach a GMLInputTemplate information class.
0325:             *
0326:             *@param  template  The new inputTemplate value
0327:             */
0328:            public void setInputTemplate(GMLInputTemplate template) {
0329:                GMLinput = template;
0330:            }
0331:
0332:            /**
0333:             *  SAX handler - store and accumulate tag bodies
0334:             *
0335:             *@param  ch                Description of the Parameter
0336:             *@param  start             Description of the Parameter
0337:             *@param  length            Description of the Parameter
0338:             *@exception  SAXException  Description of the Exception
0339:             */
0340:            public void characters(char[] ch, int start, int length)
0341:                    throws SAXException {
0342:                try {
0343:                    tagBody.append(ch, start, length);
0344:                } catch (Exception e) {
0345:                    throw new SAXException(e.getMessage());
0346:                }
0347:            }
0348:
0349:            /**
0350:             *  SAX HANDLER - move to state 0
0351:             */
0352:            public void endDocument() {
0353:                //System.out.println("End document");
0354:                STATE = STATE_INIT;
0355:            }
0356:
0357:            /**
0358:             *  SAX handler - handle state information and transitions based on ending
0359:             *  elements Most of the work of the parser is done here.
0360:             *
0361:             *@param  uri               Description of the Parameter
0362:             *@param  name              Description of the Parameter
0363:             *@param  qName             Description of the Parameter
0364:             *@exception  SAXException  Description of the Exception
0365:             */
0366:            public void endElement(String uri, String name, String qName)
0367:                    throws SAXException {
0368:                try {
0369:                    int index;
0370:
0371:                    // System.out.println("End element: " + qName);
0372:                    if (STATE == STATE_INIT) {
0373:                        tagBody = new StringBuffer();
0374:
0375:                        return; //something wrong
0376:                    }
0377:
0378:                    if (STATE > STATE_GET_COLUMNS) {
0379:                        if (isMultiGeometryTag(qName)) {
0380:                            if (STATE == STATE_PARSE_GEOM_NESTED) {
0381:                                STATE = STATE_PARSE_GEOM_SIMPLE; //finished - no action.  geometry is correct
0382:                            } else {
0383:                                //build the geometry that was in that collection
0384:                                Geometry g;
0385:
0386:                                g = geometryFactory.buildGeometry(geometry);
0387:                                geometry = (ArrayList) recursivegeometry
0388:                                        .get(STATE - STATE_PARSE_GEOM_NESTED
0389:                                                - 1);
0390:                                geometry.add(g);
0391:                                recursivegeometry.remove(STATE
0392:                                        - STATE_PARSE_GEOM_NESTED);
0393:                                g = null;
0394:
0395:                                STATE--;
0396:                            }
0397:                        }
0398:
0399:                        if (GMLinput.isGeometryElement(qName)) {
0400:                            tagBody = new StringBuffer();
0401:                            STATE = STATE_GET_COLUMNS;
0402:
0403:                            finalGeometry = geometryFactory
0404:                                    .buildGeometry(geometry);
0405:
0406:                            //System.out.println("end geom: "+finalGeometry.toString() );
0407:                            currentFeature.setGeometry(finalGeometry);
0408:                            currentGeometryNumb++;
0409:
0410:                            return;
0411:                        }
0412:
0413:                        //these correspond to <coord><X>0.0</X><Y>0.0</Y></coord>
0414:                        if ((qName.compareToIgnoreCase("X") == 0)
0415:                                || (qName.compareToIgnoreCase("gml:X") == 0)) {
0416:                            singleCoordinate.x = (new Double(tagBody.toString()))
0417:                                    .doubleValue();
0418:                        } else if ((qName.compareToIgnoreCase("Y") == 0)
0419:                                || (qName.compareToIgnoreCase("gml:y") == 0)) {
0420:                            singleCoordinate.y = (new Double(tagBody.toString()))
0421:                                    .doubleValue();
0422:                        } else if ((qName.compareToIgnoreCase("Z") == 0)
0423:                                || (qName.compareToIgnoreCase("gml:z") == 0)) {
0424:                            singleCoordinate.z = (new Double(tagBody.toString()))
0425:                                    .doubleValue();
0426:                        } else if ((qName.compareToIgnoreCase("COORD") == 0)
0427:                                || (qName.compareToIgnoreCase("gml:coord") == 0)) {
0428:                            pointList.add(new Coordinate(singleCoordinate)); //remember it
0429:                        }
0430:                        // this corresponds to <gml:coordinates>1195156.78946687,382069.533723461</gml:coordinates>
0431:                        else if ((qName.compareToIgnoreCase("COORDINATES") == 0)
0432:                                || (qName
0433:                                        .compareToIgnoreCase("gml:coordinates") == 0)) {
0434:                            //tagBody has a wack-load of points in it - we need
0435:                            // to parse them into the pointList list.
0436:                            // assume that the x,y,z coordinate are "," separated, and the points are " " separated
0437:                            parsePoints(tagBody.toString(), geometryFactory);
0438:                        } else if ((qName.compareToIgnoreCase("linearring") == 0)
0439:                                || (qName.compareToIgnoreCase("gml:linearring") == 0)) {
0440:                            Coordinate[] c = new Coordinate[0];
0441:
0442:                            c = (Coordinate[]) pointList.toArray(c);
0443:
0444:                            //c= (Coordinate[])l;
0445:                            linearRing = geometryFactory.createLinearRing(c);
0446:                        } else if ((qName
0447:                                .compareToIgnoreCase("outerBoundaryIs") == 0)
0448:                                || (qName
0449:                                        .compareToIgnoreCase("gml:outerBoundaryIs") == 0)) {
0450:                            outerBoundary = linearRing;
0451:                        } else if ((qName
0452:                                .compareToIgnoreCase("innerBoundaryIs") == 0)
0453:                                || (qName
0454:                                        .compareToIgnoreCase("gml:innerBoundaryIs") == 0)) {
0455:                            innerBoundaries.add(linearRing);
0456:                        } else if ((qName.compareToIgnoreCase("polygon") == 0)
0457:                                || (qName.compareToIgnoreCase("gml:polygon") == 0)) {
0458:                            //LinearRing[] lrs = new LinearRing[1];
0459:                            LinearRing[] lrs = new LinearRing[0];
0460:
0461:                            lrs = (LinearRing[]) innerBoundaries.toArray(lrs);
0462:                            polygon = geometryFactory.createPolygon(
0463:                                    outerBoundary, lrs);
0464:                            geometry.add(polygon);
0465:                        } else if ((qName.compareToIgnoreCase("linestring") == 0)
0466:                                || (qName.compareToIgnoreCase("gml:linestring") == 0)) {
0467:                            Coordinate[] c = new Coordinate[0];
0468:
0469:                            c = (Coordinate[]) pointList.toArray(c);
0470:
0471:                            lineString = geometryFactory.createLineString(c);
0472:                            geometry.add(lineString);
0473:                        } else if ((qName.compareToIgnoreCase("point") == 0)
0474:                                || (qName.compareToIgnoreCase("gml:point") == 0)) {
0475:                            apoint = geometryFactory
0476:                                    .createPoint((Coordinate) pointList.get(0));
0477:                            geometry.add(apoint);
0478:                        }
0479:                    } else if (STATE == STATE_GET_COLUMNS) {
0480:                        if (qName.compareToIgnoreCase(GMLinput.featureTag) == 0) {
0481:                            tagBody = new StringBuffer();
0482:                            STATE = STATE_WAIT_FEATURE_TAG;
0483:
0484:                            //System.out.println("end feature");
0485:                            //create a feature and put it inside the featurecollection
0486:                            if (currentFeature.getGeometry() == null) {
0487:                                Geometry g = currentFeature.getGeometry();
0488:
0489:                                if (g != null) {
0490:                                    System.out.println(g.toString());
0491:                                }
0492:
0493:                                throw new ParseException(
0494:                                        "no geometry specified in feature");
0495:                            }
0496:
0497:                            fc.add(currentFeature);
0498:                            currentFeature = null;
0499:
0500:                            return;
0501:                        } else {
0502:                            //check to see if this was a tag we want to store as a column
0503:                            //DB: added 2nd check for GML like <a><b></b></a>
0504:                            //     the "b" tag is the "lastStartTag_qName" for "</b>" and "</a>" we only need to
0505:                            //     process it once.
0506:                            try {
0507:                                if (((index = GMLinput.match(
0508:                                        lastStartTag_qName, lastStartTag_atts)) > -1)
0509:                                        && (lastStartTag_qName
0510:                                                .equalsIgnoreCase(qName))) {
0511:                                    // System.out.println("value of " + GMLinput.columnName(index)+" : " +  GMLinput.getColumnValue(index,tagBody, lastStartTag_atts) );
0512:
0513:                                    // if the column already has a value and multiItems support is turned on
0514:                                    //..and its type ==object
0515:                                    if ((multiItemsAsLists)
0516:                                            && (currentFeature
0517:                                                    .getAttribute(GMLinput
0518:                                                            .columnName(index)) != null)
0519:                                            && (((ColumnDescription) (GMLinput.columnDefinitions
0520:                                                    .get(index))).type == AttributeType.OBJECT)) {
0521:                                        Object oldValue = currentFeature
0522:                                                .getAttribute(GMLinput
0523:                                                        .columnName(index));
0524:                                        if (oldValue instanceof  List) {
0525:                                            //already a list there - just stuff another thing in!
0526:                                            ((List) oldValue).add(GMLinput
0527:                                                    .getColumnValue(index,
0528:                                                            tagBody.toString(),
0529:                                                            lastStartTag_atts));
0530:                                        } else {
0531:                                            //no list currently there - make a list and replace
0532:                                            List l = new ArrayList();
0533:                                            l.add(oldValue);
0534:                                            l.add(GMLinput.getColumnValue(
0535:                                                    index, tagBody.toString(),
0536:                                                    lastStartTag_atts)); // new value
0537:                                            currentFeature.setAttribute(
0538:                                                    GMLinput.columnName(index),
0539:                                                    l);
0540:                                        }
0541:                                    } else // handle normally
0542:                                    {
0543:                                        currentFeature.setAttribute(GMLinput
0544:                                                .columnName(index), GMLinput
0545:                                                .getColumnValue(index, tagBody
0546:                                                        .toString(),
0547:                                                        lastStartTag_atts));
0548:                                    }
0549:                                }
0550:                            } catch (Exception e) {
0551:                                //dont actually do anything with the parse problem - just ignore it,
0552:                                // we cannot send it back because the function its overiding doesnt allow
0553:                                e.printStackTrace();
0554:                            }
0555:
0556:                            tagBody = new StringBuffer();
0557:                        }
0558:                    } else if (STATE == STATE_WAIT_FEATURE_TAG) {
0559:                        if (qName.compareToIgnoreCase(GMLinput.collectionTag) == 0) {
0560:                            STATE = STATE_INIT; //finish
0561:
0562:                            //System.out.println("DONE!");
0563:                            tagBody = new StringBuffer();
0564:
0565:                            return;
0566:                        }
0567:                    } else if (STATE == STATE_WAIT_COLLECTION_TAG) {
0568:                        tagBody = new StringBuffer();
0569:
0570:                        return; //still look for start collection tag
0571:                    }
0572:                } catch (Exception e) {
0573:                    throw new SAXException(e.getMessage());
0574:                }
0575:            }
0576:
0577:            public void error(SAXParseException exception) throws SAXException {
0578:                throw exception;
0579:            }
0580:
0581:            public void fatalError(SAXParseException exception)
0582:                    throws SAXException {
0583:                throw exception;
0584:            }
0585:
0586:            /**
0587:             *  Main Entry - load in a GML file
0588:             *
0589:             *@param  dp                              Description of the Parameter
0590:             *@return                                 Description of the Return Value
0591:             *@exception  IllegalParametersException  Description of the Exception
0592:             *@exception  Exception                   Description of the Exception
0593:             */
0594:            public FeatureCollection read(DriverProperties dp)
0595:                    throws IllegalParametersException, Exception {
0596:                FeatureCollection fc;
0597:                GMLInputTemplate gmlTemplate;
0598:                String inputFname;
0599:                boolean isCompressed;
0600:                boolean isCompressed_template;
0601:
0602:                isCompressed_template = (dp
0603:                        .getProperty("CompressedFileTemplate") != null);
0604:
0605:                isCompressed = (dp.getProperty("CompressedFile") != null);
0606:
0607:                inputFname = dp.getProperty("File");
0608:
0609:                if (inputFname == null) {
0610:                    inputFname = dp.getProperty("DefaultValue");
0611:                }
0612:
0613:                if (inputFname == null) {
0614:                    throw new IllegalParametersException(
0615:                            "call to GMLReader.read() has DataProperties w/o a InputFile specified");
0616:                }
0617:
0618:                if (dp.getProperty("TemplateFile") == null) {
0619:                    // load from .gml file
0620:                    if (isCompressed) {
0621:                        InputStream in = CompressedFile.openFile(inputFname, dp
0622:                                .getProperty("CompressedFile"));
0623:                        gmlTemplate = inputTemplateFromFile(in);
0624:                        in.close();
0625:                    } else {
0626:                        gmlTemplate = inputTemplateFromFile(inputFname);
0627:                    }
0628:                } else {
0629:                    //template file specified
0630:                    if (isCompressed_template) {
0631:                        InputStream in = CompressedFile.openFile(dp
0632:                                .getProperty("TemplateFile"), dp
0633:                                .getProperty("CompressedFileTemplate"));
0634:                        gmlTemplate = inputTemplateFromFile(in);
0635:                        in.close();
0636:                    } else {
0637:                        if (isCompressed) //special case if the .gml file is compressed, and a template file is specified
0638:                        {
0639:                            if (dp.getProperty("CompressedFile").equals(
0640:                                    dp.getProperty("TemplateFile"))) //the template file is the compressed file
0641:                            {
0642:                                InputStream in = CompressedFile.openFile(
0643:                                        inputFname, dp
0644:                                                .getProperty("CompressedFile"));
0645:                                gmlTemplate = inputTemplateFromFile(in);
0646:                                in.close();
0647:                            } else {
0648:                                gmlTemplate = inputTemplateFromFile(dp
0649:                                        .getProperty("TemplateFile"));
0650:                            }
0651:                        } else {
0652:                            //normal load
0653:                            gmlTemplate = inputTemplateFromFile(dp
0654:                                    .getProperty("TemplateFile"));
0655:                        }
0656:                    }
0657:                }
0658:
0659:                java.io.Reader r;
0660:
0661:                this .setInputTemplate(gmlTemplate);
0662:
0663:                if (isCompressed) {
0664:                    r = new BufferedReader(new InputStreamReader(CompressedFile
0665:                            .openFile(inputFname, dp
0666:                                    .getProperty("CompressedFile"))));
0667:                } else {
0668:                    r = new BufferedReader(new FileReader(inputFname));
0669:                }
0670:
0671:                fc = read(r, inputFname);
0672:                r.close();
0673:
0674:                return fc;
0675:            }
0676:
0677:            /**
0678:             *  Helper function - calls read(java.io.Reader r,String readerName) with the
0679:             *  readerName "Unknown Stream". You should have already called
0680:             *  setInputTempalate().
0681:             *
0682:             *@param  r              reader to read the GML File from
0683:             *@return                Description of the Return Value
0684:             *@exception  Exception  Description of the Exception
0685:             */
0686:            public FeatureCollection read(java.io.Reader r) throws Exception {
0687:                return read(r, "Unknown Stream");
0688:            }
0689:
0690:            /**
0691:             *  Main function to read a GML file. You should have already called
0692:             *  setInputTempalate().
0693:             *
0694:             *@param  r              reader to read the GML File from
0695:             *@param  readerName     what to call the reader for error reporting
0696:             *@return                Description of the Return Value
0697:             *@exception  Exception  Description of the Exception
0698:             */
0699:            public FeatureCollection read(java.io.Reader r, String readerName)
0700:                    throws Exception {
0701:                LineNumberReader myReader = new LineNumberReader(r);
0702:
0703:                if (GMLinput == null) {
0704:                    throw new ParseException(
0705:                            "you must set the GMLinput template first!");
0706:                }
0707:
0708:                streamName = readerName;
0709:
0710:                fcmd = GMLinput.toFeatureSchema();
0711:                fc = new FeatureDataset(fcmd);
0712:
0713:                try {
0714:                    xr.parse(new InputSource(myReader));
0715:                } catch (SAXParseException e) {
0716:                    throw new ParseException(e.getMessage()
0717:                            + "  Last Opened Tag: " + lastStartTag_qName
0718:                            + ".  Reader reports last line read as "
0719:                            + myReader.getLineNumber(), streamName + " - "
0720:                            + e.getPublicId() + " (" + e.getSystemId() + ") ",
0721:                            e.getLineNumber(), e.getColumnNumber());
0722:                } catch (SAXException e) {
0723:                    throw new ParseException(e.getMessage()
0724:                            + "  Last Opened Tag: " + lastStartTag_qName,
0725:                            streamName, myReader.getLineNumber(), 0);
0726:                }
0727:
0728:                return fc;
0729:            }
0730:
0731:            ////////////////////////////////////////////////////////////////////
0732:            // Event handlers.
0733:            ////////////////////////////////////////////////////////////////////
0734:
0735:            /**
0736:             *  SAX handler - move to state 1
0737:             */
0738:            public void startDocument() {
0739:                //System.out.println("Start document");
0740:                tagBody = new StringBuffer();
0741:                STATE = STATE_WAIT_COLLECTION_TAG;
0742:            }
0743:
0744:            /**
0745:             *  SAX handler. Handle state and state transitions based on an element
0746:             *  starting
0747:             *
0748:             *@param  uri               Description of the Parameter
0749:             *@param  name              Description of the Parameter
0750:             *@param  qName             Description of the Parameter
0751:             *@param  atts              Description of the Parameter
0752:             *@exception  SAXException  Description of the Exception
0753:             */
0754:            public void startElement(String uri, String name, String qName,
0755:                    Attributes atts) throws SAXException {
0756:                try {
0757:                    //System.out.println("Start element: " + qName);
0758:                    tagBody = new StringBuffer();
0759:                    lastStartTag_uri = uri;
0760:                    lastStartTag_name = name;
0761:                    lastStartTag_qName = qName;
0762:                    lastStartTag_atts = atts;
0763:
0764:                    if (STATE == STATE_INIT) {
0765:                        return; //something wrong
0766:                    }
0767:
0768:                    if ((STATE == STATE_WAIT_COLLECTION_TAG)
0769:                            && (qName
0770:                                    .compareToIgnoreCase(GMLinput.collectionTag) == 0)) {
0771:                        //found the collection tag
0772:                        // System.out.println("found collection");
0773:                        STATE = STATE_WAIT_FEATURE_TAG;
0774:
0775:                        return;
0776:                    }
0777:
0778:                    if ((STATE == STATE_WAIT_FEATURE_TAG)
0779:                            && (qName.compareToIgnoreCase(GMLinput.featureTag) == 0)) {
0780:                        //found the feature tag
0781:                        //System.out.println("found feature");
0782:                        currentFeature = new BasicFeature(fcmd);
0783:                        STATE = STATE_GET_COLUMNS;
0784:                        SRID = 0;// default SRID (reset for each feature, but should be constant for a featurecollection)
0785:                        if (geometryFactory.getSRID() != SRID)
0786:                            geometryFactory = new GeometryFactory(
0787:                                    new PrecisionModel(), SRID);
0788:
0789:                        return;
0790:                    }
0791:
0792:                    if ((STATE == STATE_GET_COLUMNS)
0793:                            && GMLinput.isGeometryElement(qName)) {
0794:                        //found the geom tag
0795:                        // System.out.println("found geom #"+currentGeometryNumb );
0796:                        recursivegeometry = new ArrayList();
0797:                        geometry = new ArrayList();
0798:                        recursivegeometry.add(geometry);
0799:
0800:                        // recursivegeometry[0] = geometry
0801:                        finalGeometry = null;
0802:                        STATE = STATE_PARSE_GEOM_SIMPLE;
0803:
0804:                        return;
0805:                    }
0806:
0807:                    if (parseSRID && (STATE >= STATE_PARSE_GEOM_SIMPLE)
0808:                            && isGeometryTag(qName)) {
0809:                        //System.out.println("src="+atts.getValue("srsName"));
0810:                        //System.out.println("srid="+ parseSRID(atts.getValue("srsName")));
0811:
0812:                        int newSRID = parseSRID(atts.getValue("srsName"));
0813:                        //NOTE: if parseSRID it usually means that there was an error parsing
0814:                        //      but, it could actually be specified as 'EPGS:0'.  Thats not
0815:                        //      a problem because we've already defaulted to srid 0.
0816:                        if (newSRID != 0) {
0817:                            SRID = newSRID;
0818:                            if (geometryFactory.getSRID() != SRID)
0819:                                geometryFactory = new GeometryFactory(
0820:                                        new PrecisionModel(), SRID);
0821:                        }
0822:                    }
0823:
0824:                    if ((STATE >= STATE_PARSE_GEOM_SIMPLE)
0825:                            && ((qName.compareToIgnoreCase("coord") == 0) || (qName
0826:                                    .compareToIgnoreCase("gml:coord") == 0))) {
0827:                        singleCoordinate.x = Double.NaN;
0828:                        singleCoordinate.y = Double.NaN;
0829:                        singleCoordinate.z = Double.NaN;
0830:                    }
0831:
0832:                    if ((STATE >= STATE_PARSE_GEOM_SIMPLE)
0833:                            && (!((qName.compareToIgnoreCase("X") == 0)
0834:                                    || (qName.compareToIgnoreCase("gml:x") == 0)
0835:                                    || (qName.compareToIgnoreCase("y") == 0)
0836:                                    || (qName.compareToIgnoreCase("gml:y") == 0)
0837:                                    || (qName.compareToIgnoreCase("z") == 0)
0838:                                    || (qName.compareToIgnoreCase("gml:z") == 0)
0839:                                    || (qName.compareToIgnoreCase("coord") == 0) || (qName
0840:                                    .compareToIgnoreCase("gml:coord") == 0)))) {
0841:                        pointList.clear(); //clear out any accumulated points
0842:                    }
0843:
0844:                    if ((STATE >= STATE_PARSE_GEOM_SIMPLE)
0845:                            && ((qName.compareToIgnoreCase("polygon") == 0) || (qName
0846:                                    .compareToIgnoreCase("gml:polygon") == 0))) {
0847:                        innerBoundaries.clear(); //polygon just started - clear out the last one
0848:                    }
0849:
0850:                    if ((STATE > STATE_GET_COLUMNS)
0851:                            && (isMultiGeometryTag(qName))) {
0852:                        //in state 4 or a 1000 state and found a start GC (or Multi-geom) event
0853:                        if (STATE == STATE_PARSE_GEOM_SIMPLE) {
0854:                            // geometry already = recursivegeometry[0]
0855:                            STATE = STATE_PARSE_GEOM_NESTED;
0856:                        } else {
0857:                            STATE++;
0858:                            geometry = new ArrayList();
0859:                            recursivegeometry.add(geometry);
0860:                        }
0861:                    }
0862:                } catch (Exception e) {
0863:                    throw new SAXException(e.getMessage());
0864:                }
0865:            }
0866:
0867:            ////////////////////////////////////////////////////////////////////
0868:            // Error handlers.
0869:            ////////////////////////////////////////////////////////////////////
0870:            public void warning(SAXParseException exception)
0871:                    throws SAXException {
0872:                throw exception;
0873:            }
0874:
0875:            /**
0876:             *  returns true if the the string represents a  geometry type
0877:             *  ie. "gml:linestring" or "linestring"
0878:             *
0879:             *@param  s  Description of the Parameter
0880:             *@return    true if this is a geometry tag
0881:             */
0882:            private boolean isGeometryTag(String s) {
0883:                //remove the "gml:" if its there
0884:                if ((s.length() > 5)
0885:                        && (s.substring(0, 4).compareToIgnoreCase("gml:") == 0)) {
0886:                    s = s.substring(4);
0887:                }
0888:
0889:                if ((s.compareToIgnoreCase("multigeometry") == 0)
0890:                        || (s.compareToIgnoreCase("multipoint") == 0)
0891:                        || (s.compareToIgnoreCase("multilinestring") == 0)
0892:                        || (s.compareToIgnoreCase("multipolygon") == 0)
0893:                        || (s.compareToIgnoreCase("polygon") == 0)
0894:                        || (s.compareToIgnoreCase("linestring") == 0)
0895:                        || (s.compareToIgnoreCase("point") == 0)
0896:                        || (s.compareToIgnoreCase("geometrycollection") == 0)) {
0897:                    return true;
0898:                }
0899:
0900:                return false;
0901:            }
0902:
0903:            /**
0904:             *  returns true if the the string represents a multi* geometry type
0905:             *
0906:             *@param  s  Description of the Parameter
0907:             *@return    The multiGeometryTag value
0908:             */
0909:            private boolean isMultiGeometryTag(String s) {
0910:                //remove the "gml:" if its there
0911:                if ((s.length() > 5)
0912:                        && (s.substring(0, 4).compareToIgnoreCase("gml:") == 0)) {
0913:                    s = s.substring(4);
0914:                }
0915:
0916:                if ((s.compareToIgnoreCase("multigeometry") == 0)
0917:                        || (s.compareToIgnoreCase("multipoint") == 0)
0918:                        || (s.compareToIgnoreCase("multilinestring") == 0)
0919:                        || (s.compareToIgnoreCase("multipolygon") == 0)) {
0920:                    return true;
0921:                }
0922:
0923:                return false;
0924:            }
0925:
0926:            private GMLInputTemplate inputTemplateFromFile(InputStream in)
0927:                    throws ParseException, FileNotFoundException, IOException {
0928:                GMLInputTemplate result;
0929:                java.io.Reader r = new BufferedReader(new InputStreamReader(in));
0930:                result = inputTemplate(r);
0931:                r.close();
0932:
0933:                return result;
0934:            }
0935:
0936:            private GMLInputTemplate inputTemplateFromFile(String filename)
0937:                    throws ParseException, FileNotFoundException, IOException {
0938:                GMLInputTemplate result;
0939:                java.io.Reader r = new BufferedReader(new FileReader(filename));
0940:                result = inputTemplate(r);
0941:                r.close();
0942:
0943:                return result;
0944:            }
0945:
0946:            /**
0947:             *  Parse a bunch of points - stick them in pointList. Handles 2d and 3d.
0948:             *
0949:             *@param  ptString         string containing a bunch of coordinates
0950:             *@param  geometryFactory  JTS point/coordinate factory
0951:             */
0952:            private void parsePoints(String ptString,
0953:                    GeometryFactory geometryFactory) {
0954:                String aPoint;
0955:                StringTokenizer stokenizerPoint;
0956:                Coordinate coord = new Coordinate();
0957:                int dim;
0958:                String numb;
0959:                StringBuffer sb;
0960:                int t;
0961:                char ch;
0962:
0963:                //remove \n and \r and replace with spaces
0964:                sb = new StringBuffer(ptString);
0965:
0966:                for (t = 0; t < sb.length(); t++) {
0967:                    ch = sb.charAt(t);
0968:
0969:                    if ((ch == '\n') || (ch == '\r')) {
0970:                        sb.setCharAt(t, ' ');
0971:                    }
0972:                }
0973:
0974:                StringTokenizer stokenizer = new StringTokenizer(
0975:                        new String(sb), " ", false);
0976:
0977:                while (stokenizer.hasMoreElements()) {
0978:                    //have a point in memory - handle the single point
0979:                    aPoint = stokenizer.nextToken();
0980:                    stokenizerPoint = new StringTokenizer(aPoint, ",", false);
0981:                    coord.x = coord.y = coord.z = Double.NaN;
0982:                    dim = 0;
0983:
0984:                    while (stokenizerPoint.hasMoreElements()) {
0985:                        numb = stokenizerPoint.nextToken();
0986:
0987:                        if (dim == 0) {
0988:                            coord.x = Double.parseDouble(numb);
0989:                        } else if (dim == 1) {
0990:                            coord.y = Double.parseDouble(numb);
0991:                        } else if (dim == 2) {
0992:                            coord.z = Double.parseDouble(numb);
0993:                        }
0994:
0995:                        dim++;
0996:                    }
0997:                    if ((coord.x != coord.x) || (coord.y != coord.y)) //one (x,y) is NaN
0998:                    {
0999:                        throw new IllegalArgumentException(
1000:                                "GML error - coordinate list isnt valid GML. Watch your spaces and commas!");
1001:                    }
1002:                    pointList.add(coord); //remember it
1003:                    coord = new Coordinate();
1004:                    stokenizerPoint = null;
1005:                }
1006:            }
1007:
1008:            private GMLInputTemplate inputTemplate(java.io.Reader r)
1009:                    throws IOException, ParseException {
1010:                GMLInputTemplate gmlTemplate = new GMLInputTemplate();
1011:                gmlTemplate.load(r);
1012:                r.close();
1013:
1014:                if (!(gmlTemplate.loaded)) {
1015:                    throw new ParseException(
1016:                            "Failed to load GML input template");
1017:                }
1018:
1019:                return gmlTemplate;
1020:            }
1021:
1022:            /**
1023:             *  parses the given srs text and returns the SRID
1024:             * @param srsName srsName of the type "EPSG:<number>"
1025:             * @return srid or 0 if there is a problem
1026:             */
1027:            private int parseSRID(String srsName) {
1028:                try {
1029:                    int semicolonLoc = srsName.lastIndexOf(':');
1030:                    if (semicolonLoc == -1)
1031:                        return 0;
1032:                    srsName = srsName.substring(semicolonLoc + 1).trim();
1033:                    return Integer.parseInt(srsName);
1034:                } catch (Exception e) {
1035:                    return 0;
1036:                }
1037:            }
1038:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.