package uk.ac.leeds.ccg.geotools; import java.lang.*; import java.net.*; import uk.ac.leeds.ccg.sfsql.*; import uk.ac.leeds.ccg.simplefeature.*; import java.sql.*; import java.awt.Color; /** * A class to simplify the process of loading an ESRI(r) Shapefile. * It is effectivly a wrapper for the Shapefile class.

* This class will open the shapefile (both .shp and .dbf if avaiable) * after which calls to readLines,readPolygons and readData will extract * the necasary information out of the shapefile.

* The class also has a series of getTheme() methods that encapsulate the process * of building themes (complet with layer and shaders) as a v.easy way of setting up a theme * for inclusion in a viewer. * @author James Macgill, Center for computational Geography. * @author David Robison ArcM code and bug fixes */ public class SimpleFeatureReader extends java.lang.Object implements FeatureReader { private final static boolean DEBUG=true; private uk.ac.leeds.ccg.sfsql.DataSource source = null; private String url; /** * Creates and opens a new ShapefileReader * @param database url eg 'jdbc:odbc:map' */ public SimpleFeatureReader(String url){ this.url = url; try{ source = new uk.ac.leeds.ccg.sfsql.DataSource(url); } catch(Exception e){System.out.println(e);} } /** * Creates and opens a new ShapefileReader * If at all posible, this is the contstuctor that should be used. * @param base: url of file without extention e.g. 'name' not 'name.shp' * @param idCol An int giving the number of the colum to take the feature ids from. */ public SimpleFeatureReader(URL url){ this(url.toString()); } /** * gets the shape type for this shapefile. * * @return int The type of feature, constants defined in shapefile * match the values given, for example Shapefile.POLYGON; * */ public int getShapeType(){ return source.getGeometryType(); } /** * Reads the data in this shapefile and produces a theme for * use in a Viewer. * @return Theme a theme containig the features of the shapefile */ public Theme getTheme(){ Layer l = getLayer(); Theme t = new Theme(l); //t.setName(name); return t; } /** * Gets a theme based on the given shader and colName * as a bonus the method configures the shaders range * for you by reading the min and max values from the named column * @param shade a RampShader to shade this theme (includes HSV,sat and val shaders) * @param colName the name of the column to grab the data from */ public Theme getTheme(Shader shade,String colName){ Theme t = getTheme(); return t; } /** * convinience version of get theme (shade,colname) * provides a default satShader with the specified color * @param colName A string containing the name of the .dbf col to shade by * @param c A color to shade with. */ public Theme getTheme(String colName,Color c){ return getTheme(new satShader(c),colName); } /** * Reads the feature information from the shapefile * and produces a LineLayer for use in a Theme. * This will only work if the feature type is * line or polygon otherwise it will fail * @see getShapeType * @return LineLayer a LineLayer containing the lines from this shapefile. */ public LineLayer readLines(){ LineLayer map = new LineLayer(); GeoPolygon gp; return map; } public LineLayer readLinesM(){ LineLayer map = new LineLayer(); GeoPolygon gp; return map; } /** * Fills geodata objects with all of the data found in the shapefiles * .dbf file and indexes it by the shapefiles idColumn. * If during construction no ID collumn was given then it will be * guessed based on the feature type (not always successfull) * @return GeoData[] An array of SimpleGeoData's, one for each collum in the .dbf */ public GeoData[] readData(){ GeoData data[]=new SimpleGeoData[0]; return data; } private int[] getIds() throws SQLException{ return source.getIds(); } /** * Fills a geodata objects with the data found in the shapefiles * .dbf file from the specified collumg and indexes it by the shapefiles idColumn. * If during construction no ID collumn was given then it will be * guessed based on the feature type (not always successfull) * @param col An int representing the col to read the data from * @return GeoData A SimpleGeoData */ public GeoData readData(int col){ try{ return readData(col,getIds()); } catch(Exception e){System.err.println("ShapeFileReader error :"+e);} return null; } /** * Fills a geodata objects with the data found in the shapefiles * .dbf file from the specified collumg and indexes it by the shapefiles idColumn. * If during construction no ID collumn was given then it will be * guessed based on the feature type (not always successfull) * @param col An int representing the col to read the data from * @return GeoData A SimpleGeoData */ public GeoData readData(int col,int ids[]){ SimpleGeoData data = null; return data; } /** * Fills a geodata objects with the data found in the shapefiles * .dbf file from the specified collumg and indexes it by the shapefiles idColumn. * If during construction no ID collumn was given then it will be * guessed based on the feature type (not always successfull) * @param colName A String representing the col to read the data from * @return GeoData A SimpleGeoData */ public GeoData readData(String colName){ if(colName !=null) { } return null; } /** * Reads the feature information from the shapefile * and produces a PolygonLayer for use in a Theme. * This will only work if the feature type is * polygon otherwise it will fail. * * Modidied JM 10/May/2000 Polygons created without 0,0 centroid so that GeoPolygon will auto calculate this * @see getShapeType * @return LineLayer a LineLayer containing the lines from this shapefile. */ public PolygonLayer readGeometry()throws SQLException{ int[] ids = source.getIds(); PolygonLayer layer = new PolygonLayer(); //layer.setAnticlockwiseHoles(true); //holes apeare to be clockwise in sample data, blast. for(int i=0;i