/* * GeoTools java GIS tookit (c) The Centre for Computational Geography 2002 * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation version 2.1 */ package uk.ac.leeds.ccg.geotools; import java.io.*; import java.util.*; import uk.ac.leeds.ccg.shapefile.*; /** * An extension of the DataInputStream that handles * the input of GeoPrimitives. * This version extracts polygon maps from Arc/Info Generate files. * Later versions may deal with higher format files. * * $Log: ArcInfoReader.java,v $ * Revision 1.2 2002/02/22 18:36:38 loxnard * Updated JavaDoc comments and reformatted. * * * @author James Macgill * @version $Revision: 1.2 $ $Date: 2002/02/22 18:36:38 $ * @since before 0.5 */ public class ArcInfoReader extends BufferedReader { /** * switch */ boolean ignoreIDs = false; int sequentialID = 0; /** * Set up new GeoDataStream. * @param in Input stream to take data from. */ public ArcInfoReader(Reader in){ super(in); } /** * Sets the ignoreIDs option. * * many of the file types read by this class come with an ID code for each entry * you may under some circumstances want to ignore this and use a * sequential one instead, if so use this method and set flag to * true, note that by default, if you do not call this method the flag will be * set to false, i.e. ids will be read from file. * NB, incompeat, only affects some read methods, contact author if required for others. * * @param flag Boolean switch. Set to true to ignore IDs stored in files. */ public void setIgnoreIDs(boolean flag){ ignoreIDs = flag; } /** * Reads a GeoPolygon. * If the ignoreIDs flag is set to true, sequential IDs will be used. * @return The GeoPolygon read. * @throws IOException Thrown if there are any errors whilst reading the file. */ public final synchronized GeoPolygon readGeoPolygon() throws IOException { /** * The empty GeoPolygon */ GeoPolygon poly=null; /** * Polygon ID */ int id = 0; /** * The polygons Centroid */ float xcent = 0; float ycent = 0; /** * Temp storage for each point as loaded */ float x,y; /** * String to hold the 'END' of Polygon and File * Markers found in the Ungenerate file format */ String marker; /** * Holds one line of the Ungenerate file */ String line; //Read first line line = readLine(); marker = line.substring(0,3); if(marker.equals("END")) return null; //Finished i.e. end of file //Read polygon header try { id = Integer.parseInt(line.substring(4,10).trim()); if(id !=-99999){ //Closed Polygon sequentialID++; if(ignoreIDs) id = sequentialID; //System.out.println("ID was "+id); xcent = new Float(line.substring(11,28).trim()).floatValue(); ycent = new Float(line.substring(29,44).trim()).floatValue(); //poly = new GeoPolygon(id,xcent,ycent); } else{ id = -99999; xcent=0;ycent=0; //poly = new GeoPolygon(-99999,0,0); System.out.println("!Null Polygon!"); } double xtemp[],xpoints[]; double ytemp[],ypoints[]; xpoints = new double[500]; ypoints = new double[500]; int npoints = -1;//inc'd to 0 before first use... int limit = 500,grow = 20; while(true) { //Read co-ordinates line = readLine(); if(line.substring(0,3).trim().equals("END")) break;// //Above line made from ... //marker = line.substring(0,3).trim(); //if(marker.equals("END")) break; //End of polygon npoints++; if(npoints>=limit){//expand array to fit xtemp = xpoints; ytemp = ypoints; xpoints = new double[limit+grow]; ypoints = new double[limit+grow]; limit+=grow; System.arraycopy(xtemp,0,xpoints,0,npoints); System.arraycopy(ytemp,0,ypoints,0,npoints); } x = new Float(line.substring(4,18).trim()).floatValue(); y = new Float(line.substring(19,line.length()).trim()).floatValue(); xpoints[npoints]=x; ypoints[npoints]=y; } if(npoints 0){ col.put(new Integer(id),new Double(value)); } break; } } return col; } /** * Reads an attribute file of the form * id,value * nb. IDs <= 0 are skipped. * If this is a problem, a switch will be added. * @return GeoData containing all loaded values. * @throws IOException Thrown if there are any errors whilst reading the file. */ public final synchronized GeoData readGeoData() throws IOException{ //Hashtable t = new Table(); //Vector store = new Vector(); SimpleGeoData store = new SimpleGeoData(); StreamTokenizer st = new StreamTokenizer(this); st.eolIsSignificant(false); st.whitespaceChars(',',','); boolean done = false; while (!done) { int c = StreamTokenizer.TT_EOF; c = st.nextToken(); switch (c) { case StreamTokenizer.TT_EOF: done = true; break; case StreamTokenizer.TT_NUMBER: int id = (int)st.nval; c = st.nextToken(); if(c==StreamTokenizer.TT_NUMBER){ double value = (int)st.nval; store.setValue(id,value); } else{ String text = st.sval; store.setText(id,text); } break; } } return store; } /** * Reads a circle file of the form * id,x,y,r * nb. IDs <= 0 are skipped. * If this is a problem, a switch will be added. * @return The assembled CircleLayer. * @throws IOException Thrown if there are any errors whilst reading the file. */ public final synchronized CircleLayer readCircles() throws IOException{ //Hashtable t = new Table(); CircleLayer cl = new CircleLayer(); double x,y,r; int id; StreamTokenizer st = new StreamTokenizer(this); st.eolIsSignificant(false); st.whitespaceChars(',',','); boolean done = false; while (!done) { int c = StreamTokenizer.TT_EOF; c = st.nextToken(); switch (c) { case StreamTokenizer.TT_EOF: done = true; break; case StreamTokenizer.TT_NUMBER: id = (int)st.nval; st.nextToken(); x = (double)st.nval; st.nextToken(); y = (double)st.nval; st.nextToken(); r = (double)st.nval; if(id > 0){ cl.addGeoCircle(new GeoCircle(id,x,y,r)); } break; } } return cl; } /** * * Test function for specific application: should be removed. * @return Application-specific data. * @throws IOException Thrown if there are any errors whilst reading the file. * @deprecated Not needed. */ public final synchronized Table readZdes() throws IOException{ Table t = new Table(); double value; StreamTokenizer st = new StreamTokenizer(this); st.eolIsSignificant(false); st.whitespaceChars(',',','); boolean done = false; st.nextToken(); int zones = (int)st.nval; int j = 1; Hashtable col; while (!done) { j++; col = new Hashtable(); st.nextToken();//skip outer polygon... for(int i = 1;i 2){ poly = new GeoPolygon((int)header[0],(float)header[1],(float)header[2]); readingHeader = false; } } else { point[pair-1] = st.nval; pair = 3-pair; //alternates 1-2-1-2-1-2-1.... } break; } } return map; } }