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