/** * MIFMIDReader.java * * Created on December 15, 2001, 11:32 PM **/ package uk.ac.leeds.ccg.mif; import java.net.*; import java.io.*; import uk.ac.leeds.ccg.geotools.*; import java.util.*; /** * As part of the geotool package, MIFMIDReader could read * mapinfo interchange files (MIF,MID) as geotools objects. * construct a MIFMIDFile class object in which the geographical information are stored. * it is quite simple to use the class. only three public method can be called in it. * Two of them are construct methods used to create a MIFMIDReader object * by using a File object or a URL object respectively. * Another one is getMIFMIDFile() which is the only method can called in this class * it will return an MIFMIDFile object. * * if the read method of some object type in mif file have not been developped * in the current version of the class, it will throw MIFObjectTypeException * @see MIFObjectTypeException * @see MIFMIDFile * @author Jianhui Jin * @version 1.0 **/ public class MIFMIDReader extends java.lang.Object { private URL mifUrl=null; // file url private File mifFileName=null;// file name private BufferedReader reader=null; private int DATATYPE=0;// storing the data type ids for the mif file private MultiLayer multiLayer;// combine all the possible layer together since mif contain all possible geographical objects.points lines polygons private PointLayer pointLayer=new PointLayer(); // point layer for point objects private LineLayer lineLayer=new LineLayer();// line layer for line,pline objects private PolygonLayer polyLayer=new PolygonLayer();// polygons layer for region,rect objects //private Hashtable table1=new Hashtable(); private String delimiter = null;// delimiter for database private int colNumber=0;// column number of database private String[] colName;// column name of the current geodata private byte[] colType;// two possible '0' for double and '1' for string for the type of column in database private SimpleGeoData[] geoData; // contain all the attribut data private SimpleGeoData[] pointGeoData;// contain attribute data for point layer private SimpleGeoData[] lineGeoData;// contain attribute data for line layer private SimpleGeoData[] polyGeoData;// contain attribute data for polygon layer private int id=0,polyId=0,lineId=0,pointId=0,noneId=0;// count the number of geographical objects private String fileLine=null;// the line in mif file currently has been readed in the reader. only read once throught out all the method, continues read thought out the file private String midFileLine=null;// the line in mid file currently has been readed in the reader. only read once throught out all the method, continues read thought out the file private BufferedReader midReader;// bufferedReader object for mid file private Object[][] midData;// mid file data in array private Vector objectDbaseIndex= new Vector(1,1);// index of geotools geographical objects' id and mif geographical objects' id private Vector layerVector = new Vector(1,1);// index of geotools geographical objects' id starting from 0 and each layer name string private MIFMIDFile mifmidFile; // MIFMIDFile object contain all the information read private int objectNumber=0;// mif geographical objects number private String shadingString=new String();// storing the currectly read shadingStrings private Hashtable shadingStringsTable=new Hashtable(); // keep all shading Strings, late convert to shadingStr. private String[] shadingStr;// finally storing all shadingString private int shadingNumber=0;// count the shadingStrings in the mif file private String[] mifFileHeader; // mif file header from top to "Data" or "data" line /** Creates new MIFMIDReader by using URL as file source * if the read method of some object type in mif file have not been developped * in the current version of the class, it will throw MIFObjectTypeException */ public MIFMIDReader(URL url) throws MIFObjectTypeException, FileNotFoundException, IOException { String urlFile=url.toString(); if(urlFile.endsWith("d")) url= new URL(urlFile.substring(0,urlFile.length()-1)+"f"); else if(urlFile.endsWith("D")) url= new URL(urlFile.substring(0,urlFile.length()-1)+"F"); this.mifUrl=url; // assign url to the parameter read() need read(); // read all data setMIFMIDFile(); // assign data to MIFMIDFile object } /** Creates new MIFMIDReader by using URL as file source * if the read method of some object type in mif file have not been developped * in the current version of the class, it will throw MIFObjectTypeException */ public MIFMIDReader(File fName) throws MIFObjectTypeException, FileNotFoundException, IOException { String fn=fName.toString(); if(fn.endsWith("d")) fName= new File(fn.substring(0,fn.length()-1)+"f"); else if(fn.endsWith("D")) fName= new File(fn.substring(0,fn.length()-1)+"F"); this.mifFileName=fName;// assign fName to the parameter read() need read();// read all data setMIFMIDFile();// assign data to MIFMIDFile object } // create and set the MIFMIDFile Object private void setMIFMIDFile(){ multiLayer=new MultiLayer(); // construct multiLayer; if(pointId>0) multiLayer.addLayer(pointLayer);// if point object number greater than 0, add it to multiLayer if(lineId>0) multiLayer.addLayer(lineLayer);//if line object number greater than 0, add it to multiLayer if(polyId>0) multiLayer.addLayer(polyLayer);//if polygon object number greater than 0, add it to multiLayer mifmidFile=new MIFMIDFile(); // construct MIFMIDFile object // the below code basicly assign all the data to mifmidfile object calling related methods mifmidFile.setMIFFileHeader(mifFileHeader); mifmidFile.setLineGeoData(lineGeoData); mifmidFile.setLineLayerAndLineCount(lineId,lineLayer); mifmidFile.setMultiGeoData(geoData); mifmidFile.setMultiLayerAndTotalCount(id,multiLayer); mifmidFile.setPointGeoData(pointGeoData); mifmidFile.setPointLayerAndPointCount(pointId,pointLayer); mifmidFile.setPolygonGeoData(polyGeoData); mifmidFile.setPolygonLayerAndPolygonCount(polyId,polyLayer); // convert Vector layerVector to String[] one by one and get rid of "none" object int id=0; Object[] temp=layerVector.toArray(); Vector newlayerVector=new Vector(1,1); for(int i=0;i1) assignShadingStrings(); // construct a string storing all shading strings for one object } while((fileLine=reader.readLine())!=null); midReader(); assignShadingStrings();//construct possible last one,since the loop stop. } // read mif file header part private void headerReader() throws IOException{ Vector headerString= new Vector();// contain the file header line strings and will be convected // into the String[] late in the method while(!(fileLine=reader.readLine()).substring(0,4).equalsIgnoreCase("Data")) { headerString.add(fileLine);// vector add each fileline StringTokenizer st=new StringTokenizer(fileLine); String fileItem=st.nextToken();// get the start string // get delimiter from header for reading atribute data in mid file if (fileItem.equalsIgnoreCase("delimiter")) { String s= st.nextToken(); delimiter=s.substring(1,s.length()-1); } // get column number ,name and type // the code will convert types of char,logical and date to string // types of interger smallint,decilmal,float to Double since the requirement of geodat class // since there are only two possibe datta type can be stored in the GeoData object, mid file data have to convert into those two types. if (fileItem.equalsIgnoreCase("columns")) { colNumber= Integer.valueOf(st.nextToken()).intValue(); // total how many columns in mid file colType=new byte[colNumber]; // for keeping the converted data types for each columns colName=new String[colNumber]; // columns' names for(int i=0;i