/******************************************
* XML2Shape.java
* Uses the NVS shapefile library to read
* the specified XML file and translate
* it into an ESRI shapefile
*
*****************************************/
import java.io.*;
import com.nvs.shapefile.*;
import java.util.zip.*;
import java.io.*;
import java.util.*;
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.output.*;
import org.apache.xerces.parsers.*;
public class XML2Shape
{
private static String strXMLFile;
private static String strShapefile;
public static void main(String args[])
{
if(args.length < 2)
{
System.out.println("Usage: XML2Shape <xml_file> <shape_file>");
return;
}
strXMLFile = args[0];
strShapefile = args[1];
new XML2Shape();
}
public XML2Shape()
{
Shapefile shp = new Shapefile();
try
{
TableDescription tableDesc = null;
BoundingBox box = null;
SAXBuilder builder = new SAXBuilder(true);
Document doc = builder.build(new FileInputStream(strXMLFile));
Element elShapefile = doc.getRootElement();
Element elBox = elShapefile.getChild("bounding-box");
if(elBox != null)
{
box = processBox(elBox);
shp.setBoundingBox(box);
}
Element elTable = elShapefile.getChild("table");
if(elTable != null)
{
tableDesc = processTable(elTable);
shp.setTableDescription(tableDesc);
}
if(elShapefile.getAttributeValue("type").equals("points"))
{
shp.setType(Shapefile.SHAPETYPE_POINT);
}
else if(elShapefile.getAttributeValue("type").equals("lines"))
{
shp.setType(Shapefile.SHAPETYPE_POLYLINE);
}
else if(elShapefile.getAttributeValue("type").equals("polygons"))
{
shp.setType(Shapefile.SHAPETYPE_POLYGON);
}
else if(elShapefile.getAttributeValue("type").equals("mixed"))
{
// Need to implement this eventually
return;
}
// Shape Objects
Iterator itrShapeObjects = elShapefile.getChildren("shape").iterator();
while(itrShapeObjects.hasNext())
{
Element elShape = (Element)itrShapeObjects.next();
if(elShape.getAttributeValue("type").equals("point"))
{
if(shp.getType() != Shapefile.SHAPETYPE_POINT)
{
// Throw some exception
}
shp.addShapeObject(processPointShape(elShape));
}
else if(elShape.getAttributeValue("type").equals("line"))
{
if(shp.getType() != Shapefile.SHAPETYPE_POLYLINE)
{
// Throw some exception
}
System.out.println("adding shapeobject - line");
shp.addShapeObject(processLineShape(elShape));
}
else if(elShape.getAttributeValue("type").equals("polygon"))
{
if(shp.getType() != Shapefile.SHAPETYPE_POLYGON)
{
// Throw some exception
}
System.out.println("adding shapeobject - polygon");
shp.addShapeObject(processPolygonShape(elShape));
}
}
ByteArrayOutputStream bosMain = new ByteArrayOutputStream();
ByteArrayOutputStream bosIndex = new ByteArrayOutputStream();
ByteArrayOutputStream bosRecords = new ByteArrayOutputStream();
shp.write(bosMain, bosIndex, bosRecords);
ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(strShapefile + ".zip"));
zip.setMethod(ZipOutputStream.DEFLATED);
zip.setLevel(Deflater.BEST_COMPRESSION);
byte[] buffer = new byte[1024];
int length;
ByteArrayInputStream bisMain = new ByteArrayInputStream(bosMain.toByteArray());
ByteArrayInputStream bisIndex = new ByteArrayInputStream(bosIndex.toByteArray());
ByteArrayInputStream bisRecords = new ByteArrayInputStream(bosRecords.toByteArray());
ZipEntry entryMain = new ZipEntry(strShapefile + ".shp");
zip.putNextEntry(entryMain);
while ((length = bisMain.read(buffer)) >= 0)
{
zip.write(buffer, 0, length);
}
zip.closeEntry();
ZipEntry entryIndex = new ZipEntry(strShapefile + ".shx");
zip.putNextEntry(entryIndex);
while ((length = bisIndex.read(buffer)) >= 0)
{
zip.write(buffer, 0, length);
}
zip.closeEntry();
ZipEntry entryRecords = new ZipEntry(strShapefile + ".dbf");
zip.putNextEntry(entryRecords);
while ((length = bisRecords.read(buffer)) >= 0)
{
zip.write(buffer, 0, length);
}
zip.closeEntry();
zip.close();
}
catch(JDOMException e)
{
e.printStackTrace();
}
catch(InvalidFieldNameException e)
{
e.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}
private ShapeObject processPointShape(Element elPointShape)
{
ShapeObject shpObj = new ShapeObject(ShapeObject.POINT);
Element elPoint = elPointShape.getChild("point");
Point pt = new Point(Double.parseDouble(elPoint.getAttributeValue("x")), Double.parseDouble(elPoint.getAttributeValue("y")));
shpObj.addPoint(pt);
Record rec = new Record();
Iterator itrFields = elPointShape.getChildren("field").iterator();
while(itrFields.hasNext())
{
Element elField = (Element)itrFields.next();
RecordField recField = new RecordField();
recField.setName(elField.getAttributeValue("name"));
recField.setValue(elField.getAttributeValue("value"));
rec.addField(recField);
}
shpObj.setRecord(rec);
return shpObj;
}
private ShapeObject processLineShape(Element elLineShape)
{
ShapeObject shpObj = new ShapeObject(ShapeObject.POLYLINE);
Iterator itrPoints = elLineShape.getChildren("point").iterator();
while(itrPoints.hasNext())
{
Element elPoint = (Element)itrPoints.next();
Point pt = new Point(Double.parseDouble(elPoint.getAttributeValue("x")), Double.parseDouble(elPoint.getAttributeValue("y")));
System.out.println("Adding point - " + elPoint.getAttributeValue("x") + " " + elPoint.getAttributeValue("y"));
shpObj.addPoint(pt);
}
Record rec = new Record();
Iterator itrFields = elLineShape.getChildren("field").iterator();
while(itrFields.hasNext())
{
Element elField = (Element)itrFields.next();
RecordField recField = new RecordField();
recField.setName(elField.getAttributeValue("name"));
recField.setValue(elField.getAttributeValue("value"));
System.out.println("Adding record " + elField.getAttributeValue("name") + " " + elField.getAttributeValue("value"));
rec.addField(recField);
}
shpObj.setRecord(rec);
return shpObj;
}
private ShapeObject processPolygonShape(Element elLineShape)
{
ShapeObject shpObj = new ShapeObject(ShapeObject.POLYGON);
Iterator itrPoints = elLineShape.getChildren("point").iterator();
while(itrPoints.hasNext())
{
Element elPoint = (Element)itrPoints.next();
Point pt = new Point(Double.parseDouble(elPoint.getAttributeValue("x")), Double.parseDouble(elPoint.getAttributeValue("y")));
System.out.println("Adding point - " + elPoint.getAttributeValue("x") + " " + elPoint.getAttributeValue("y"));
shpObj.addPoint(pt);
}
Record rec = new Record();
Iterator itrFields = elLineShape.getChildren("field").iterator();
while(itrFields.hasNext())
{
Element elField = (Element)itrFields.next();
RecordField recField = new RecordField();
recField.setName(elField.getAttributeValue("name"));
recField.setValue(elField.getAttributeValue("value"));
System.out.println("Adding record " + elField.getAttributeValue("name") + " " + elField.getAttributeValue("value"));
rec.addField(recField);
}
shpObj.setRecord(rec);
return shpObj;
}
private TableDescription processTable(Element elTD)
{
TableDescription tableDesc = new TableDescription();
Iterator itrTD = elTD.getChildren("entry").iterator();
while(itrTD.hasNext())
{
int iType = Shapefile.FIELDTYPE_CHARACTER;
Element elEntry = (Element)itrTD.next();
String strDatatype = elEntry.getAttributeValue("datatype");
if(strDatatype.equals("string"))
{
iType = Shapefile.FIELDTYPE_CHARACTER;
}
tableDesc.addTableDescriptor(new TableDescriptor(elEntry.getAttributeValue("name"), iType));
}
return tableDesc;
}
private BoundingBox processBox(Element elBox)
{
BoundingBox box = new BoundingBox();
if(elBox.getAttributeValue("xmin") != null)
box.setXMin(Double.parseDouble(elBox.getAttributeValue("xmin")));
if(elBox.getAttributeValue("xmax") != null)
box.setXMax(Double.parseDouble(elBox.getAttributeValue("xmax")));
if(elBox.getAttributeValue("ymin") != null)
box.setYMin(Double.parseDouble(elBox.getAttributeValue("ymin")));
if(elBox.getAttributeValue("ymax") != null)
box.setYMax(Double.parseDouble(elBox.getAttributeValue("ymax")));
return box;
}
}