The DataStore interface is general to all of the implemented DataStores. The Data access basic described how to use a DataStore, using a ShapefileDataStore as an example. The following document extends this to using a MIFDataStore created with a DataStoreFinder.
Some concepts about MapInfo data formats
The general concepts regarding how MapInfo stores "features" apply to both the native MapInfo format and the MapInfo Interchange Format (MIF), with the sole difference that MIF is a text import/export format, and has to be imported into the binary format before MapInfo can use it.
Features are stored in "tables". Each binary table is composed of different files (TAB header, attribute data, geometric data, indexes), while a "MIF table" is made of a .MIF file (Header data and geometry) and a .MID file (attribute data).
The following obsevations thus apply to MapInfo tables:
- A table can be "mappable" (i.e. can have one geometric field) or not.
- A mappable table has one and only one geometric field, which name is implicitly set to "obj".
- A mappable table must have a Geographic Reference System, which is used for storing all the geometries of that table.
- Geometries are untyped at the schema level. Different rows in the same table might have geometries of different types.
- Geometries can be NULL, i.e. the value for the obj column can be NULL.
- Geometry types at the instance level are: Point, Line (segment between two points), Polyline (LINESTRING), Region (POLYGON); also types which are not compatible with OGIS specs, like Rect, Roundrect, Arc, Text and Ellipse, are defined.
- Regions and polylines can be multiple (MULTIPOLYGON, MULTILINESTRING).
- Style information is saved along with each geometric object in a table.
Creating a MIFDataStore
You can create a MIFDataStore using a DataStoreFinder, which uses the interface for pluggable DataStores, allowing you to use different DataStores just by changing a few parameters. See DataStoreFinder Parameters for a list of available parameters for other DataStores.
The following code shows how to use the DataStoreFinder to create a MIFDataStore.
import java.util.HashMap; import java.util.Map; import org.geotools.data.DataStore; import org.geotools.data.DataStoreFinder; import org.geotools.data.FeatureSource; import org.geotools.data.Query; ... Map params = new HashMap(); // required parameters params.put("dbtype", "mif"); //must be "mif" params.put("path", "/path/to/mif/file/"); // Path to a single .mif file or to a directory containing mif files // Optional parameters params.put(MIFDataStore.PARAM_FIELDCASE, "upper"); params.put(MIFDataStore.PARAM_GEOMNAME, "the_geom"); params.put(MIFDataStore.PARAM_GEOMTYPE, "typed"); // params.put(MIFDataStore.PARAM_GEOMFACTORY, new GeometryFactory(new PrecisionModel(PrecisionModel.FLOATING_SINGLE), 26591)); params.put(MIFDataStore.PARAM_SRID, new Integer(26591)); params.put(MIFDataStore.HCLAUSE_COORDSYS, "Earth Projection 8, 87, \"m\", 9, 0, 0.9996, 1500000, 0 Bounds (-6746230.6469, -9998287.38389) (9746230.6469, 9998287.38389)"); DataStore mifDatastore = DataStoreFinder.getDataStore(params); FeatureReader fr = mifDatastore.getFeatureReader("mytable"); while (fr.hasNext()) { Feature feature = fr.next(); // do something with feature }
If the path parameter it is a mif file name, then the resulting DataStore will contain only one feature type corresponding to the mif file. The feature type name will be the same of the file name without path and extension.
If the path parameter is a directory, all the mif file headers contained in the directory will be read; the resulting datastore will contain one FeatureType for each .mif file. On such datastore a createSchema() call might be issued, resulting in the creation of an empty .mif / .mif file.
All other parameters are optional. The parameter names are defined using the MIFDataStore.PARAM_ (configuration parameters) and MIFDataStore.HCLAUSE_ (header clauses) variables. While the configuration parameters affect file reading and writing, the header parameters only affect the creation of new mif files, and are overridden by the clauses read from .mif headers.
The configuration parameters are:
PARAM_FIELDCASE |
field names tranformation:
|
PARAM_GEOMFACTORY |
GeometryFactory object to be used for creating geometries; better using PARAM_SRID; |
PARAM_SRID |
Integer SRID value for creating geometries; |
PARAM_GEOMNAME |
name of the geometry field (defaults to "the_geom") |
PARAM_GEOMTYPE |
geometry type handling:
|
The header clause parameters are:
HCLAUSE_VERSION |
MIF version (default "310") |
HCLAUSE_CHARSET |
Charset name (default "WindowsLatin1"); |
HCLAUSE_DELIMITER |
Delimiter char (default ","); |
HCLAUSE_UNIQUE |
Comma-separated list of field indexes (1..numFields) corresponding to unique values (i.e. street names for street segments) |
HCLAUSE_INDEX |
Comma-separated list of field indexes (1..numFields) indicating which fields are indexed in MapInfo |
HCLAUSE_COORDSYS |
MapInfo CoordSys clause |
HCLAUSE_TRANSFORM |
Comma-separated list of four multiplying factors and offsets for X and Y: multX, multY, sumX, sumY (for example "1000, 1000, 0, 0") |
At present, the MapInfo coordSys clause cannot be parsed into an EPSG SRID, so this binding had to be done by hand. In order to have the MIFDataStore interpret correctly the coordinates stored into a MIF file, the user should pass it a GeometryFactory object built using the right SRID value, or the SRID value itself.
When creating new MIF files, the user should pass a valid HCLAUSE_COORDSYS value so that importing the table in MapInfo will result in a correct interpretation of the coordinate values. The coordsys clause can be obtained by simply opening a .mif file with a text editor.
Until when it will be included in the official GeoTools release, you can get the MIFDAtaStore here: mif-2.2.x.jar
The source code is available on SVN trunk at http://svn.geotools.org/geotools/trunk/gt/plugin/mif/.