/*---------------- FILE HEADER ------------------------------------------
This class bases on the MapInfoDataSource class from the GeoTools project.
Geotools - OpenSource mapping toolkit
(C) 2002, Centre for Computational Geography
This file is part of deegree.
Copyright (C) 2001-2006 by:
EXSE, Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
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; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstr. 19
53115 Bonn
Germany
E-Mail: poth@lat-lon.de
Prof. Dr. Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: greve@giub.uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.io.mapinfoapi;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.StringTokenizer;
import org.deegree.datatypes.QualifiedName;
import org.deegree.datatypes.Types;
import org.deegree.framework.log.ILogger;
import org.deegree.framework.log.LoggerFactory;
import org.deegree.framework.util.CharsetUtils;
import org.deegree.framework.util.StringTools;
import org.deegree.model.feature.Feature;
import org.deegree.model.feature.FeatureCollection;
import org.deegree.model.feature.FeatureFactory;
import org.deegree.model.feature.FeatureProperty;
import org.deegree.model.feature.schema.FeatureType;
import org.deegree.model.feature.schema.PropertyType;
import org.deegree.model.filterencoding.Filter;
import org.deegree.model.spatialschema.JTSAdapter;
import org.deegree.ogcwebservices.wfs.operation.Query;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.geom.TopologyException;
/**
* @version $Revision: 1.21 $
* @author $author$
*/
public class MapInfoDataSource {
private static ILogger LOG = LoggerFactory.getLogger( MapInfoDataSource.class );
public static final String TYPE_NONE = "none";
public static final String TYPE_POINT = "point";
public static final String TYPE_LINE = "line";
public static final String TYPE_PLINE = "pline";
public static final String TYPE_REGION = "region";
public static final String TYPE_ARC = "arc";
public static final String TYPE_TEXT = "text";
public static final String TYPE_RECT = "rectangle";
public static final String TYPE_ROUNDRECT = "rounded rectangle";
public static final String TYPE_ELLIPSE = "ellipse";
public static final String CLAUSE_SYMBOL = "SYMBOL";
public static final String CLAUSE_PEN = "PEN";
public static final String CLAUSE_SMOOTH = "SMOOTH";
public static final String CLAUSE_CENTER = "CENTER";
public static final String CLAUSE_BRUSH = "BRUSH";
public static final String CLAUSE_VERSION = "Version";
public static final String CLAUSE_CHARSET = "Charset";
public static final String CLAUSE_DELIMETER = "DELIMITER";
public static final String CLAUSE_UNIQUE = "UNIQUE";
public static final String CLAUSE_INDEX = "INDEX";
public static final String CLAUSE_COLUMNS = "COLUMNS";
private ArrayList hColumnsNames;
private ArrayList hColumnsTypes;
private ArrayList hIndex;
private ArrayList hUnique;
/**
*
* @uml.property name="lineType"
* @uml.associationEnd multiplicity="(0 1)"
*/
private FeatureType lineType = null;
/**
*
* @uml.property name="pointType"
* @uml.associationEnd multiplicity="(0 1)"
*/
private FeatureType pointType = null;
/**
*
* @uml.property name="polygonType"
* @uml.associationEnd multiplicity="(0 1)"
*/
private FeatureType polygonType = null;
// Factory to use to build Geometries
private GeometryFactory geomFactory;
private String filename;
private String hCharset;
private String hDelimeter = "\t";
// Header information
private String hVersion;
// CoordsSys not supported
// Transform not supported
// Global variables (for the initial read)
private String line; // The current Line of the MIF file.
/**
* Creates a new MapInfoDataSource object.
*
* @param url
*
* @throws java.net.MalformedURLException
*/
public MapInfoDataSource(URL url) throws java.net.MalformedURLException {
try {
filename = java.net.URLDecoder.decode(url.getFile(), CharsetUtils.getSystemCharset() );
} catch (Exception e) {
throw new java.net.MalformedURLException(e.toString());
}
geomFactory = new GeometryFactory();
}
/**
* Reads the MIF and MID files and returns a ArrayList of the Features they
* contain
*
* @return a ArrayList of features?
*
* @throws Exception
* if file doesn't exist or is not readable etc
*/
protected ArrayList readMifMid() throws Exception {
if (filename == null) { throw new Exception(
"Invalid filename passed to readMifMid"); }
String mifFile = setExtension(filename, "MIF");
String midFile = setExtension(filename, "MID");
// Read files
try {
File mif = new File(mifFile);
if (!mif.exists()) {
mifFile = setExtension(filename, "mif");
mif = new File(mifFile);
if (!mif.exists()) {
mifFile = setExtension(filename.toLowerCase(), "mif");
mif = new File(mifFile);
if (!mif.exists()) {
mifFile = setExtension(filename.toUpperCase(), "MIF");
mif = new File(mifFile);
} // and at that I'm out of guesses
}
}
File mid = new File(midFile);
if (!mid.exists()) {
midFile = setExtension(filename, "mid");
mid = new File(midFile);
if (!mid.exists()) {
midFile = setExtension(filename.toLowerCase(), "mid");
mid = new File(midFile);
if (!mid.exists()) {
midFile = setExtension(filename.toUpperCase(), "MID");
mid = new File(midFile);
} // and at that I'm out of guesses
}
}
ArrayList features = readMifMid(new BufferedReader(new FileReader(
mif)), new BufferedReader(new FileReader(mid)));
return features;
} catch (FileNotFoundException fnfexp) {
throw new Exception(
"FileNotFoundException trying to read mif file : ", fnfexp);
}
}
/**
* @param filename
* @param ext
*
* @return
*/
private String setExtension(String filename, String ext) {
if (ext.indexOf(".") == -1) {
ext = "." + ext;
}
if (filename.lastIndexOf(".") == -1) { return filename + ext; }
return filename.substring(0, filename.lastIndexOf(".")) + ext;
}
/**
* This private method constructs the factories used to create the Feature,
* and Geometries as they are read It takes it's setup values from the value
* of the COLUMNS clause in the MIF file
*
* @throws Exception
*/
private void setUpFactories() throws Exception {
// Go through each column name, and set up an attribute for each one
ArrayList colAttribs = new ArrayList(hColumnsNames.size());
// Add attributes for each column
//Iterator it = hColumns.keySet().iterator();
for (int i = 0; i < hColumnsNames.size(); i++) {
String type = ((String) hColumnsTypes.get(i)).toLowerCase();
int typeClass = -999;
if (type.equals("float") || type.startsWith("decimal")) {
typeClass = Types.NUMERIC;
hColumnsTypes.set(i, "Double");
} else if (type.startsWith("char")) {
typeClass = Types.VARCHAR;
hColumnsTypes.set(i, "String");
} else if (type.equals("integer") || type.equals("smallint")) {
typeClass = Types.INTEGER;
hColumnsTypes.set(i, "Integer");
} else {
typeClass = Types.VARCHAR;
hColumnsTypes.set(i, "String");
}
PropertyType ftp = FeatureFactory.createSimplePropertyType(
new QualifiedName((String) hColumnsNames.get(i)), typeClass, true);
colAttribs.add(ftp);
}
PropertyType ftp = FeatureFactory.createSimplePropertyType(
new QualifiedName("GEOM"), Types.GEOMETRY, true);
// Add default Geometry attribute type
colAttribs.add(0, ftp);
// create point feature Type & factory
try {
PropertyType[] ftps = (PropertyType[]) colAttribs
.toArray(new PropertyType[colAttribs.size()]);
pointType = FeatureFactory.createFeatureType(filename.toString()
+ "_point", false, ftps);
} catch (Exception schexp) {
throw new Exception("SchemaException setting up point factory : ",
schexp);
}
// Set up Line factory
// Add default attribute type
ftp = FeatureFactory.createSimplePropertyType(new QualifiedName("GEOM"),
Types.GEOMETRY, true);
colAttribs.set(0, ftp);
// create line feature Type & factory
try {
PropertyType[] ftps = (PropertyType[]) colAttribs
.toArray(new PropertyType[colAttribs.size()]);
lineType = FeatureFactory.createFeatureType(filename.toString()
+ "_line", false, ftps);
} catch (Exception schexp) {
throw new Exception("SchemaException setting up line factory : ",
schexp);
}
// Set up Polygon factory
// Add default attribute type
ftp = FeatureFactory.createSimplePropertyType(new QualifiedName("GEOM"),
Types.GEOMETRY, true);
colAttribs.set(0, ftp);
// create polygon feature Type & factory
try {
PropertyType[] ftps = (PropertyType[]) colAttribs
.toArray(new PropertyType[colAttribs.size()]);
polygonType = FeatureFactory.createFeatureType(filename.toString()
+ "_poly", false, ftps);
} catch (Exception schexp) {
throw new Exception(
"SchemaException setting up polygon factory : ", schexp);
}
}
/**
* Reads an entire MID/MIF file. (Two files, actually, separately opened)
*
* @param mifReader
* An opened BufferedReader to the MIF file.
* @param midReader
* An opened BufferedReader to the MID file.
*
* @return @throws
* Exception
*/
private ArrayList readMifMid(BufferedReader mifReader,
BufferedReader midReader) throws Exception {
// Read the MIF header
readMifHeader(mifReader);
// Set up factories
setUpFactories();
ArrayList features = new ArrayList();
// Start by reading first line
try {
line = readMifLine(mifReader);
} catch (IOException ioexp) {
throw new Exception("No data at start of file", ioexp);
}
Feature feature;
// Read each object in the MIF file
while ((feature = readObject(mifReader, midReader)) != null) {
// Figure out which type of feature it is
// Add to relevent ArrayList
features.add(feature);
}
return features;
}
/**
* Reads the header from the given MIF file stream
*
* @param mifReader
*
* @throws Exception
*/
private void readMifHeader(BufferedReader mifReader) throws Exception {
try {
while ((readMifLine(mifReader) != null)
&& !line.trim().equalsIgnoreCase("DATA")) {
if (clause(line).equalsIgnoreCase(CLAUSE_VERSION)) {
// Read Version clause
hVersion = line.trim().substring(line.trim().indexOf(' '))
.trim();
LOG.logDebug("version [" + hVersion + "]");
}
if (clause(line).equalsIgnoreCase(CLAUSE_CHARSET)) {
// Read Charset clause
//hCharset = line.replace('\"','
// ').trim().substring(line.trim().indexOf(' ')).trim();
hCharset = remainder(line).replace('"', ' ').trim();
LOG.logDebug("Charset [" + hCharset + "]");
}
if (clause(line).equalsIgnoreCase(CLAUSE_DELIMETER)) {
// Read Delimeter clause
hDelimeter = line.replace('\"', ' ').trim().substring(
line.trim().indexOf(' ')).trim();
LOG.logDebug("delimiter [" + hDelimeter + "]");
}
if (clause(line).equalsIgnoreCase(CLAUSE_UNIQUE)) {
// Read Unique clause
StringTokenizer st = new StringTokenizer(line.trim()
.substring(line.trim().indexOf(' ')), ",");
hUnique = new ArrayList();
LOG.logDebug("Unique cols ");
while (st.hasMoreTokens()) {
String uniq = st.nextToken();
LOG.logDebug("\t" + uniq);
hUnique.add(uniq);
}
}
if (clause(line).equalsIgnoreCase(CLAUSE_INDEX)) {
// Read Index clause
StringTokenizer st = new StringTokenizer(line.trim()
.substring(line.trim().indexOf(' ')), ",");
hIndex = new ArrayList(st.countTokens());
LOG.logDebug("Indexes");
while (st.hasMoreTokens()) {
String index = st.nextToken();
LOG.logDebug("\t" + index);
hIndex.add(index);
}
}
if (clause(line).equalsIgnoreCase(CLAUSE_COLUMNS)) {
// Read Columns clause
int cols = 0;
try {
cols = Integer.parseInt(remainder(line));
} catch (NumberFormatException nfexp) {
LOG.logError( "bad number of colums ", nfexp );
}
// Read each of the columns
hColumnsNames = new ArrayList(cols);
hColumnsTypes = new ArrayList(cols);
for (int i = 0; i < cols; i++) {
line = readMifLine(mifReader);
//StringTokenizer st = new
// StringTokenizer(line.trim().substring(line.trim().indexOf('
// ')), " ");
String name = clause(line);
String value = remainder(line);
LOG.logDebug("column name " + name
+ " value " + value);
hColumnsNames.add(name);
hColumnsTypes.add(value);
}
}
}
} catch (IOException ioexp) {
throw new Exception("IOException reading MIF header : "
+ ioexp.getMessage());
}
}
/**
* A 'Clause' is stored as a single string at the start of a line. This rips
* the clause name out of the given line.
*
* @param line
*
* @return
*/
private String clause(String line) {
return clause(line, ' ');
}
/**
* @param line
* @param delimiter
*
* @return
*/
private String clause(String line, char delimiter) {
line = line.trim();
int index = line.indexOf(delimiter);
if (index == -1) {
return line;
}
return line.substring(0, index).trim();
}
/**
* returns the last word of the string
*
* @param line
*
* @return
*/
private String remainder(String line) {
return remainder(line, ' ');
}
/**
* @param line
* @param delimiter
*
* @return
*/
private String remainder(String line, char delimiter) {
line = line.trim();
int index = line.lastIndexOf(delimiter);
if (index == -1) {
return "";
}
return line.substring(index).trim();
}
/**
* Reads the next line in the reader, ignoring lines which are nothing but
* whitespace. Sets the global 'line' variable to the currently read line
*
* @param reader
*
* @return @throws
* IOException
* @throws Exception
*/
private String readMifLine(BufferedReader reader) throws IOException,
Exception {
do {
line = reader.readLine();
if (line == null) { return null; }
if (isShadingClause(line)) {
LOG.logDebug("going to process shading");
//processShading(line);
line = " ";
}
} while (line.trim().length() == 0);
line = line.trim();
//LOG.logDebug("returning line " + line);
return line;
}
/**
* Reads a single MIF Object (Point, Line, Region, etc.) as a Feature
*
* @param mifReader
* @param midReader
*
* @return @throws
* Exception
*/
private Feature readObject(BufferedReader mifReader,
BufferedReader midReader) throws Exception {
Feature feature = null;
//LOG.logDebug("line = " + line);
// examine The current line
if (line == null) { return null; }
int index = line.indexOf(' ');
if (index == -1) {
index = line.length();
}
if (line.substring(0, index).equalsIgnoreCase(TYPE_POINT)) {
// Read point data
feature = readPointObject(mifReader, midReader);
} else if (line.substring(0, index).equalsIgnoreCase(TYPE_LINE)) {
// Read line data
feature = readLineObject(mifReader, midReader);
} else if (line.substring(0, index).equalsIgnoreCase(TYPE_PLINE)) {
// Read pline data
feature = readPLineObject(mifReader, midReader);
} else if (line.substring(0, index).equalsIgnoreCase(TYPE_REGION)) {
// Read region data
feature = readRegionObject(mifReader, midReader);
} else {
LOG.logDebug(line + " unknown object in mif reader");
}
return feature;
}
/**
* Reads Point information from the MIF stream
*
* @param mifReader
* @param midReader
*
* @return @throws
* Exception
*/
private Feature readPointObject(BufferedReader mifReader,
BufferedReader midReader) throws Exception {
Feature feature = null;
StringTokenizer st = new StringTokenizer(line.substring(line
.indexOf(" ")), ",");
try {
double x = Double.parseDouble(st.nextToken());
double y = Double.parseDouble(st.nextToken());
// Construct Geomtry
Geometry pointGeom = geomFactory.createPoint(new Coordinate(x, y));
// Read next line
readMifLine(mifReader);
//Hashtable shading = readShading(mifReader);
// Shading is not included, as null feature attributes are not
// supported yet
ArrayList midValues = readMid(midReader);
// midValues.putAll(shading);
// Create Feature
feature = buildFeature(pointType, pointGeom, midValues);
LOG.logDebug("Built point feature : " + x + " " + y);
} catch (NumberFormatException nfexp) {
throw new Exception(
"Exception reading Point data from MIF file : ", nfexp);
} catch (IOException ioexp) {
throw new Exception("IOException reading point data : ", ioexp);
}
return feature;
}
/**
* Reads Line information from the MIF stream
*
* @param mifReader
* @param midReader
*
* @return @throws
* Exception
*/
private Feature readLineObject(BufferedReader mifReader,
BufferedReader midReader) throws Exception {
Feature feature = null;
StringTokenizer st = new StringTokenizer(line.substring(line
.indexOf(" ")), ",");
try {
double x1 = Double.parseDouble(st.nextToken());
double y1 = Double.parseDouble(st.nextToken());
double x2 = Double.parseDouble(st.nextToken());
double y2 = Double.parseDouble(st.nextToken());
// Construct Geomtry
Coordinate[] cPoints = new Coordinate[2];
cPoints[0] = new Coordinate(x1, y1);
cPoints[1] = new Coordinate(x2, y2);
Geometry lineGeom = geomFactory.createLineString(cPoints);
// Read next line
readMifLine(mifReader);
//Hashtable shading = readShading(mifReader);
// Shading is not included, as null feature attributes are not
// supported yet
ArrayList midValues = readMid(midReader);
// midValues.putAll(shading);
// Create Feature
feature = buildFeature(lineType, lineGeom, midValues);
LOG.logDebug("Built line feature : " + x1 + " " + y1
+ " - " + x2 + " " + y2);
} catch (NumberFormatException nfexp) {
throw new Exception("Exception reading Point data from MIF file : "
+ nfexp.getMessage());
} catch (IOException ioexp) {
throw new Exception("IOException reading point data : "
+ ioexp.getMessage());
}
return feature;
}
/**
* Reads Multi-Line (PLine) information from the MIF stream
*
* @param mifReader
* @param midReader
*
* @return @throws
* Exception
*/
private Feature readPLineObject(BufferedReader mifReader,
BufferedReader midReader) throws Exception {
Feature feature = null;
StringTokenizer st = new StringTokenizer(line.substring(line
.indexOf(" ")));
try {
int numsections = 1;
if (st.hasMoreTokens()
&& st.nextToken().trim().equalsIgnoreCase("MULTIPLE")) {
numsections = Integer.parseInt(st.nextToken());
}
// A ArrayList of coordinates
ArrayList coords = new ArrayList(numsections);
// Read each polygon
for (int i = 0; i < numsections; i++) {
// Read line (number of points
int numpoints = Integer.parseInt(readMifLine(mifReader));
// Read each point
for (int p = 0; p < numpoints; p++) {
StringTokenizer pst = new StringTokenizer(
readMifLine(mifReader));
double x = Double.parseDouble(pst.nextToken());
double y = Double.parseDouble(pst.nextToken());
coords.add(new Coordinate(x, y));
}
}
Geometry plineGeom = geomFactory
.createLineString((Coordinate[]) coords
.toArray(new Coordinate[coords.size()]));
// Read next line
readMifLine(mifReader);
//Hashtable shading = readShading(mifReader);
// Shading is not included, as null feature attributes are not
// supported yet
ArrayList midValues = readMid(midReader);
// midValues.putAll(shading);
// Create Feature
feature = buildFeature(lineType, plineGeom, midValues);
LOG.logDebug("Read polyline (" + coords.size() + ")");
} catch (NumberFormatException nfexp) {
throw new Exception("Exception reading Point data from MIF file : "
+ nfexp.getMessage());
} catch (IOException ioexp) {
throw new Exception("IOException reading point data : "
+ ioexp.getMessage());
}
return feature;
}
/**
* Reads Region (Polygon) information from the MIF stream
*
* @param mifReader
* @param midReader
*
* @return @throws
* Exception
*/
private Feature readRegionObject(BufferedReader mifReader,
BufferedReader midReader) throws Exception {
Feature feature = null;
StringTokenizer st = new StringTokenizer(line.substring(line
.indexOf(" ")));
try {
int numpolygons = Integer.parseInt(st.nextToken());
// A ArrayList of polygons
ArrayList polys = new ArrayList(numpolygons);
// Read each polygon
for (int i = 0; i < numpolygons; i++) {
// Read number of points
int numpoints = Integer.parseInt(readMifLine(mifReader));
ArrayList coords = new ArrayList(numpoints);
// Read each point
for (int p = 0; p < numpoints; p++) {
StringTokenizer pst = new StringTokenizer(
readMifLine(mifReader));
double x = Double.parseDouble(pst.nextToken());
double y = Double.parseDouble(pst.nextToken());
coords.add(new Coordinate(x, y));
}
// Create polygon from points
coords.add(new Coordinate(((Coordinate) coords.get(0)).x,
((Coordinate) coords.get(0)).y));
try {
Polygon pol = geomFactory.createPolygon(geomFactory
.createLinearRing((Coordinate[]) coords
.toArray(new Coordinate[coords.size()])),
null);
// Add to ArrayList
polys.add(pol);
} catch (TopologyException topexp) {
throw new Exception(
"TopologyException reading Region polygon : ",
topexp);
}
}
Geometry polyGeom = geomFactory
.createMultiPolygon((Polygon[]) polys
.toArray(new Polygon[polys.size()]));
// Read next line
readMifLine(mifReader);
//Hashtable shading = readShading(mifReader);
// Shading is not included, as null feature attributes are not
// supported yet
ArrayList midValues = readMid(midReader);
// midValues.putAll(shading);
// Create Feature
feature = buildFeature(polygonType, polyGeom, midValues);
LOG.logDebug("Read Region (" + polys.size() + ")");
} catch (NumberFormatException nfexp) {
throw new Exception(
"Exception reading Point data from MIF file : ", nfexp);
} catch (IOException ioexp) {
throw new Exception("IOException reading point data : ", ioexp);
}
return feature;
}
/**
* Builds a complete Feature object using the given FeatureType, with the
* Geometry geom, and the given attributes.
*
* @param featureType
* The FeatureType to use to constuct the Feature
* @param geom
* The Geometry to use as the default Geometry
* @param attribs
* The attibutes to use as the Feature's attributes (Attributes
* must be set up in the FeatureType)
*
* @return A fully-formed Feature
*
* @throws Exception
*/
private Feature buildFeature(FeatureType featureType, Geometry geom,
ArrayList attribs) throws Exception {
int numAttribs = featureType.getProperties().length;
// add geometry to the attributes
attribs.add(0, JTSAdapter.wrap(geom));
if (numAttribs != attribs.size()) { throw new Exception(
"wrong number of attributes passed to buildFeature.\n"
+ "expected " + numAttribs + " got " + attribs.size()); }
// Create Feature
FeatureProperty[] fp = new FeatureProperty[attribs.size()];
PropertyType[] ftp = featureType.getProperties();
for ( int i = 0; i < fp.length; i++ ) {
fp[i] = FeatureFactory.createFeatureProperty( ftp[i].getName(), attribs.get(i) );
}
try {
return FeatureFactory.createFeature("id", featureType, fp );
} catch (Exception ifexp) {
throw new Exception("Exception creating feature : ", ifexp);
}
}
/**
* Reads a single line of the given MID file stream, and returns a hashtable
* of the data in it, keyed byt he keys in the hColumns hash
*
* @param midReader
*
* @return @throws
* Exception
*/
private ArrayList readMid(BufferedReader midReader) throws Exception {
ArrayList midValues = new ArrayList();
if (midReader == null) { return new ArrayList(); }
// The delimeter is a single delimiting character
String midLine = "";
try {
midLine = midReader.readLine();
LOG.logDebug("Read MID " + midLine);
} catch (IOException ioexp) {
throw new Exception("IOException reading MID file");
}
// read MID tokens
int col = 0;
StringTokenizer quotes = new StringTokenizer(midLine, "\"");
while (quotes.hasMoreTokens()) {
StringTokenizer delimeters = new StringTokenizer(
quotes.nextToken(), hDelimeter + "\0");
// Read each delimited value into the ArrayList
while (delimeters.hasMoreTokens()) {
String token = delimeters.nextToken();
String type = (String) hColumnsTypes.get(col++);
addAttribute(type, token, midValues);
}
// Store the whole of the next bit (it's a quoted string)
if (quotes.hasMoreTokens()) {
String token = quotes.nextToken();
String type = (String) hColumnsTypes.get(col++);
addAttribute(type, token, midValues);
//LOG.logDebug("adding " + token);
}
}
return midValues;
}
/**
* @param type
* @param token
* @param midValues
*/
private void addAttribute(String type, String token, ArrayList midValues) {
if (type.equals("String")) {
midValues.add(token);
} else if (type.equals("Double")) {
try {
token = StringTools.validateString(token, ",");
midValues.add(new Double(token));
} catch (NumberFormatException nfe) {
LOG.logError( "Bad double " + token, nfe);
midValues.add(new Double(0.0));
}
} else if (type.equals("Integer")) {
try {
//token = StringExtend.validateString( token, "," );
midValues.add(new Integer(token));
} catch (NumberFormatException nfe) {
LOG.logError( "Bad integer " + token, nfe );
midValues.add(new Integer(0));
}
} else {
LOG.logDebug("Unknown type " + type);
}
}
/**
* Reads the shading information at the end of Object data
*
* @param line
*
* @throws Exception
*/
// private void processShading(String line) throws Exception {
// int color;
// int r;
// int g;
// int b;
//
// if (line == null) {
// return;
// }
//
// String shadeType = line.toLowerCase();
// String name = clause(shadeType, '(');
// String settings = remainder(shadeType, '(');
// StringTokenizer st = new StringTokenizer(settings, "(),");
// String[] values = new String[st.countTokens()];
//
// for (int i = 0; st.hasMoreTokens(); i++) {
// values[i] = st.nextToken();
// }
//
// if (name.equals("pen")) {
// try {
//
// stroke.setWidth(filterFactory.createLiteralExpression(new
// Integer(values[0])));
//
// int pattern = Integer.parseInt(values[1]);
//
// stroke.setDashArray(MifStyles.getPenPattern(new Integer(pattern)));
// color = Integer.parseInt(values[2]);
//
// String rgb = Integer.toHexString(color);
//
// stroke.setColor(filterFactory.createLiteralExpression(rgb));
// } catch (Exception nfe) {
// throw new Exception("Error setting up pen", nfe);
// }
//
// return;
// } else if (name.equals("brush")) {
// LOG.logDebug("setting new brush " + settings);
//
// int pattern = Integer.parseInt(values[0]);
// LOG.logDebug("pattern = " + pattern);
//
// Graphic dg = styleFactory.getDefaultGraphic();
// dg.addExternalGraphic(MifStyles.getBrushPattern(new Integer(pattern)));
// stroke.setGraphicFill(dg);
// color = Integer.parseInt(values[1]);
//
// String rgb = Integer.toHexString(color);
// LOG.logDebug("color " + color + " -> " + rgb);
// fill.setColor(filterFactory.createLiteralExpression(rgb)); // foreground
//
// if (values.length == 3) { // optional parameter
// color = Integer.parseInt(values[2]);
// rgb = Integer.toHexString(color);
// LOG.logDebug("color " + color + " -> " + rgb);
//
// fill.setBackgroundColor(filterFactory.createLiteralExpression(rgb)); //
// background
// } else {
// fill.setBackgroundColor((Expression) null);
// }
// } else if (name.equals("center")) {
// LOG.logDebug("setting center " + settings);
// } else if (name.equals("smooth")) {
// LOG.logDebug("setting smooth on");
// } else if (name.equals("symbol")) {
// LOG.logDebug("setting symbol " + settings);
//
// Mark symbol = null;
// ExternalGraphic eg = null;
//
// if (values.length == 3) { // version 3.0
//
// //symbol = symbols.get(new Integer(symNumb));
// } else if (values.length == 6) {}
// else if (values.length == 4) { // custom bitmap
// eg = styleFactory.createExternalGraphic("CustSymb/" +
// values[0],"image/unknown"); // hack!
//
// } else {
// LOGGER.info("unexpected symbol style " + name + settings);
// }
// } else if (name.equals("font")) {
// LOG.logDebug("setting font " + settings);
// } else {
// LOG.logDebug("unknown styling directive " + name + settings);
// }
//
// return;
// }
/**
* Test whether the given line contains a known shading clause keyword (PEN,
* STYLE, etc.)
*
* @param line
*
* @return
*/
private boolean isShadingClause(String line) {
line = line.toUpperCase();
boolean ret = ((line.indexOf(CLAUSE_PEN) != -1)
|| (line.indexOf(CLAUSE_SYMBOL) != -1)
|| (line.indexOf(CLAUSE_SMOOTH) != -1)
|| (line.indexOf(CLAUSE_CENTER) != -1) || line
.indexOf(CLAUSE_BRUSH) != -1);
return ret;
}
/**
* Loads features from the datasource into the passed collection, based on
* the passed filter. Note that all data sources must support this method at
* a minimum.
*
* @param collection
* The collection to put the features into.
* @param query
* contains info about request of which features to retrieve.
*
* @throws Exception
* For all data source errors.
*/
public void getFeatures(FeatureCollection collection, Query query)
throws Exception {
Filter filter = null;
if (query != null) {
filter = query.getFilter();
}
ArrayList features = readMifMid();
for (int i = 0; i < features.size(); i++) {
if ((filter == null) || filter.evaluate((Feature) features.get(i))) {
collection.add((Feature) features.get(i));
}
}
}
/**
* Retrieves the featureType that features extracted from this datasource
* will be created with.
* @tasks TODO: implement this method.
*/
public FeatureType getSchema() {
return null;
}
}/* ********************************************************************
Changes to this class. What the people have been up to:
$Log: MapInfoDataSource.java,v $
Revision 1.21 2006/11/27 09:07:52 poth
JNI integration of proj4 has been removed. The CRS functionality now will be done by native deegree code.
Revision 1.20 2006/10/17 20:31:19 poth
*** empty log message ***
Revision 1.19 2006/09/23 09:04:16 poth
reference to ISO-8859-1 substituted by UFT-8
Revision 1.18 2006/07/12 14:46:17 poth
comment footer added
********************************************************************** */