Package com.vividsolutions.jump.io
Class GMLReader
- java.lang.Object
-
- org.xml.sax.helpers.DefaultHandler
-
- com.vividsolutions.jump.io.GMLReader
-
- All Implemented Interfaces:
JUMPReader,TaskMonitorSupport,ContentHandler,DTDHandler,EntityResolver,ErrorHandler
- Direct Known Subclasses:
JMLReader
public class GMLReader extends DefaultHandler implements JUMPReader, TaskMonitorSupport
GMLReader is aJUMPReaderspecialized to read GML files.DataProperties for the JCSReader load(DataProperties) interface:
Parameter Meaning File or DefaultValue File name for the input .xml file InputTemplateFile Filename for the GMLInputTemplate .xml file CompressedFile File name (a .zip or .gz) with a .jml/.xml/.gml inside (specified by File) CompressedFileTemplate File name (.zip or .gz) with the input template in (specified by InputTemplateFile)
NOTE: If InputTemplateFile is unspecified, GMLReader will try to read one off the top of the input .xml file (the JCS format). This is the same as specifying the File and TemplateFile to be the same.
Typically, you would write:
gmlReader = new GMLReader(); gmlReader.load(DriverProperties); // has InputFile and InputTemplate
or:gmlReader.setInputTemplate( GMLInputTemplate); gmlReader.load( <Reader> , <stream name> );
Internal Details - This is based on a small finite state machine with these states:
STATE MEANING
0 Init
1 Waiting for Collection tag
2 Waiting for Feature tag
3 Getting jcs columns
4 Parsing geometry (goes back to state 3)
1000 Parsing Multi-geometry, recursion level =1
1001 Parsing Multi-geometry, recursion level =2
...
State Diagram
init
0 -----> 1 | | Collection start Tag | -->2----------------> FINISH \ | End Collection tag End Feature tag \ | \| 4<-------->3 Geometry start/end
For multi-geometries
On start Multi-geometry, increment state by 1 (or jump to 1000 if at state 4)
make sure recursivegeometry[state-1000] is null
<put any object into the recursivegeometry[state-1000] collection>
on end multi-geometry,
build geometry in recursivegeometry[state-1000], add it to recursivegeometry[state-1000-1]
state= state-1
For single geometries - they will be stuck into recursivegeometry[0], which is the same
as geometry
For multi geometries - they will also be stuck into recursivegeometry[0], which is the same
as geometry. But, for the first nested geometry, it will be stuck into recursivegeometry[1],
which will then be geometry
example of double GCs: START geometry -> move to state 4 START TAG: multi* -> move to state 1000, geometry = recursivegeometry[0] <POINT> -> added to geometry <POINT> -> added to geometry START TAG: multi* -> move to state 1001, geometry = recursivegeometry[1] <POINT> -> added to geometry <POINT> -> added to geometry END TAG: multi -> move to state 1000, build geometry in recursivegeometry[1], add to recursivegeometry[0], geometry = recursivegeometry[0] <POINT> -> added to geometry END TAG: multi -> <finished> move to state 4, build geometry in recursivegeometry[0] (thats the result) and put it in finalGeometry END geometry -> add to feature collection example of simple geometry: START geometry -> move to state 4 BEGIN polygon -> clear out inner ring accumulator BEGIN outerboundary BEGIN linearring END linearring -> put points in linearRing END outerboundary -> put linearRing in outerBoundary BEGIN innerboundary BEGIN linearring END linearring -> put points in linearRing END innerboundary -> add linearRing to innerBoundary list END polygon -> build polygon (put in geometry, which is recursivegeometry[0] END geometry => add to feature collection
Most of the work is done in the endTag method!
New additions: Jan 2005 by Dave Blasby allow srid to be parsed from the GML file For example: <gml:LineString srsName="EPSG:42102"> .... </gml:LineString> The SRID of the created geometry will be 42102. It accepts srsNames of the form "<letters>:<number>". ie. "EPSG:111" or "DAVE:222" or "BCGOV:333" etc... The Geometry's SRID will be the number. If you have a GEOMETRYCOLLECTION with more than one SRID specified the SRID of the result will be indeterminate (this isnt correct GML). Geometries without a srsName will get SRID 0. This functionality defaults to off for compatibility. To turn it on or off, call the acceptSRID(true|false) function. New Addition: Jan, 2005by Dave Blasby Added slightly better support for type=OBJECT. It sticks a String in. Before it would probably throw an error. Added support for multi-objects for example: <a> <b>...1...</b> <b>...2...</b> <b>...3...</b> </a> Old behavior would be to for column 'b' to have value "...3...". New behavior (only if you set b's type to 'OBJECT' and set the GMLReader to processMultiItems as lists) <a><b>...1...</b></a> --> b get the string "...1..." (as before) <a><b>...1...</b><b>...2...</b><b>...3...</b></a> --> 'b' is a list of String ['...1...','...2...','...3...']
-
-
Field Summary
Fields Modifier and Type Field Description booleanmultiItemsAsListstrue => for 'OBJECT' types, if you find more than 1 item, make a list and store all the results
-
Constructor Summary
Constructors Constructor Description GMLReader()Constructor - make a SAXParser and have this GMLReader be its ContentHandler and ErrorHandler.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description voidacceptSRID(boolean parseTheSRID)parse SRID information in geometry tagsprotected voidaddException(Exception e)protected voidaddParseException(String message, Exception cause)voidcharacters(char[] ch, int start, int length)SAX handler - store and accumulate tag bodiesvoidendDocument()SAX HANDLER - move to state 0voidendElement(String uri, String name, String qName)SAX handler - handle state information and transitions based on ending elements Most of the work of the parser is done here.voiderror(SAXParseException exception)voidfatalError(SAXParseException exception)Collection<Exception>getExceptions()TaskMonitorgetTaskMonitor()voidprocessMultiItems(boolean accept)Added slightly better support for type=OBJECT.FeatureCollectionread(DriverProperties dp)Main Entry - load in a GML fileFeatureCollectionread(InputStream is)Helper function - calls read(java.io.Reader r,String readerName) with the readerName "Unknown Stream".FeatureCollectionread(Object o, String readerName)Main function to read a GML file.voidsetDocumentLocator(Locator locator)voidsetInputTemplate(GMLInputTemplate template)Attach a GMLInputTemplate information class.voidsetTaskMonitor(TaskMonitor taskMonitor)voidstartDocument()SAX handler - move to state 1voidstartElement(String uri, String name, String qName, Attributes atts)SAX handler.voidwarning(SAXParseException exception)-
Methods inherited from class org.xml.sax.helpers.DefaultHandler
endPrefixMapping, ignorableWhitespace, notationDecl, processingInstruction, resolveEntity, skippedEntity, startPrefixMapping, unparsedEntityDecl
-
-
-
-
Method Detail
-
setDocumentLocator
public void setDocumentLocator(Locator locator)
- Specified by:
setDocumentLocatorin interfaceContentHandler- Overrides:
setDocumentLocatorin classDefaultHandler
-
acceptSRID
public void acceptSRID(boolean parseTheSRID)
parse SRID information in geometry tags- Parameters:
parseTheSRID- true = parse
-
processMultiItems
public void processMultiItems(boolean accept)
Added slightly better support for type=OBJECT. It sticks a String in. Before it would probably throw an error. Added support for multi-objects for example: ...1... ...2... ...3... Old behavior would be to for column 'b' to have value "...3...". New behavior (only if you set b's type to 'OBJECT' and set the GMLReader to processMultiItems as lists) ...1... --> b get the string "b" (as before) ...1......2......3... --> 'b' is a list of String ['...1...','...2...','...3...']
-
setInputTemplate
public void setInputTemplate(GMLInputTemplate template)
Attach a GMLInputTemplate information class.- Parameters:
template- The new inputTemplate value
-
characters
public void characters(char[] ch, int start, int length) throws SAXExceptionSAX handler - store and accumulate tag bodies- Specified by:
charactersin interfaceContentHandler- Overrides:
charactersin classDefaultHandler- Parameters:
ch- Description of the Parameterstart- Description of the Parameterlength- Description of the Parameter- Throws:
SAXException- Description of the Exception
-
read
public FeatureCollection read(DriverProperties dp) throws Exception
Main Entry - load in a GML file- Specified by:
readin interfaceJUMPReader- Parameters:
dp- Description of the Parameter- Returns:
- Description of the Return Value
- Throws:
IllegalParametersException- Description of the ExceptionException- Description of the Exception
-
read
public FeatureCollection read(InputStream is) throws Exception
Helper function - calls read(java.io.Reader r,String readerName) with the readerName "Unknown Stream". You should have already called setInputTempalate().- Parameters:
is- input stream to read the GML File from- Returns:
- Description of the Return Value
- Throws:
Exception- Description of the Exception
-
read
public FeatureCollection read(Object o, String readerName) throws Exception
Main function to read a GML file. You should have already called setInputTempalate(). NOTE: if proper xml charset support is needed this method should be called with an InputStream as source- Parameters:
o- reader/inputstream object to read the GML fromreaderName- what to call the reader for error reporting- Returns:
- Description of the Return Value
- Throws:
Exception- Description of the Exception
-
startDocument
public void startDocument()
SAX handler - move to state 1- Specified by:
startDocumentin interfaceContentHandler- Overrides:
startDocumentin classDefaultHandler
-
startElement
public void startElement(String uri, String name, String qName, Attributes atts) throws SAXException
SAX handler. Handle state and state transitions based on an element starting- Specified by:
startElementin interfaceContentHandler- Overrides:
startElementin classDefaultHandler- Parameters:
uri- Description of the Parametername- Description of the ParameterqName- Description of the Parameteratts- Description of the Parameter- Throws:
SAXException- Description of the Exception
-
endElement
public void endElement(String uri, String name, String qName) throws SAXException
SAX handler - handle state information and transitions based on ending elements Most of the work of the parser is done here.- Specified by:
endElementin interfaceContentHandler- Overrides:
endElementin classDefaultHandler- Parameters:
uri- Description of the Parametername- Description of the ParameterqName- Description of the Parameter- Throws:
SAXException- Description of the Exception
-
endDocument
public void endDocument()
SAX HANDLER - move to state 0- Specified by:
endDocumentin interfaceContentHandler- Overrides:
endDocumentin classDefaultHandler
-
warning
public void warning(SAXParseException exception) throws SAXException
- Specified by:
warningin interfaceErrorHandler- Overrides:
warningin classDefaultHandler- Throws:
SAXException
-
error
public void error(SAXParseException exception) throws SAXException
- Specified by:
errorin interfaceErrorHandler- Overrides:
errorin classDefaultHandler- Throws:
SAXException
-
fatalError
public void fatalError(SAXParseException exception) throws SAXException
- Specified by:
fatalErrorin interfaceErrorHandler- Overrides:
fatalErrorin classDefaultHandler- Throws:
SAXException
-
addException
protected void addException(Exception e)
-
getExceptions
public Collection<Exception> getExceptions()
- Specified by:
getExceptionsin interfaceJUMPReader- Returns:
- exceptions collected during the reading process.
-
setTaskMonitor
public void setTaskMonitor(TaskMonitor taskMonitor)
- Specified by:
setTaskMonitorin interfaceTaskMonitorSupport
-
getTaskMonitor
public TaskMonitor getTaskMonitor()
- Specified by:
getTaskMonitorin interfaceTaskMonitorSupport
-
-