⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 miffile.java

📁 .mif .mid file read and write
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
     * Reads the header from the given MIF file stream tokenizer
     *
     * @param skipRead Skip the header, just to get to the data section
     * @param mif
     *
     * @throws IOException
     * @throws SchemaException Error reading header information
     */
    private void readMifHeader(boolean skipRead, MIFFileTokenizer mif)
        throws IOException, SchemaException {
        try {
            String tok;
            boolean hasMifText = false;
            AttributeDescriptor[] columns = null;

            while (mif.readLine()) {
                tok = mif.getToken().toLowerCase();

                // "data" might be a field name, in this case the type name would follow on the same line 
                if (tok.equals("data") && mif.getLine().equals("")) {
                    break;
                }

                if (skipRead) {
                    continue;
                }

                if (tok.equals(MIFDataStore.HCLAUSE_VERSION)) {
                    setHeaderClause(MIFDataStore.HCLAUSE_VERSION, mif.getLine());

                    continue;
                }

                if (tok.equals(MIFDataStore.HCLAUSE_CHARSET)) {
                    setHeaderClause(MIFDataStore.HCLAUSE_CHARSET,
                        mif.getToken(' ', false, true));

                    continue;
                }

                if (tok.equals(MIFDataStore.HCLAUSE_DELIMITER)) {
                    setHeaderClause(MIFDataStore.HCLAUSE_DELIMITER,
                        mif.getToken(' ', false, true));
                    chDelimiter = getHeaderClause(MIFDataStore.HCLAUSE_DELIMITER)
                                      .charAt(0);

                    continue;
                }

                if (tok.equals(MIFDataStore.HCLAUSE_UNIQUE)) {
                    setHeaderClause(MIFDataStore.HCLAUSE_UNIQUE, mif.getLine());

                    continue;
                }

                if (tok.equals(MIFDataStore.HCLAUSE_COORDSYS)) {
                    setHeaderClause(MIFDataStore.HCLAUSE_COORDSYS, mif.getLine());

                    continue;
                }

                if (tok.equals(MIFDataStore.HCLAUSE_INDEX)) {
                    setHeaderClause(MIFDataStore.HCLAUSE_INDEX, mif.getLine());

                    continue;
                }

                if (tok.equals(MIFDataStore.HCLAUSE_TRANSFORM)) {
                    useTransform = true;
                    multX = Float.parseFloat("0" + mif.getToken(','));
                    multY = Float.parseFloat("0" + mif.getToken(','));
                    sumX = Float.parseFloat("0" + mif.getToken(','));
                    sumY = Float.parseFloat("0" + mif.getToken(','));

                    if (multX == 0) {
                        multX = 1;
                    }

                    if (multY == 0) {
                        multY = 1;
                    }

                    continue;
                }

                if (tok.equals(CLAUSE_COLUMNS)) {
                    int cols;

                    try {
                        cols = Integer.parseInt(mif.getLine());
                    } catch (NumberFormatException nfexp) {
                        throw new IOException("bad number of colums: "
                            + mif.getLine());
                    }

                    // Columns <n> does not take into account the geometry column, so we increment
                    columns = new AttributeDescriptor[++cols];

                    String name;
                    String type;
                    Object defa;
                    Class typeClass;
                    int size;

                    for (int i = 1; i < cols; i++) {
                        if (!mif.readLine()) {
                            throw new IOException("Expected column definition");
                        }

                        name = mif.getToken();

                        if (fieldNameCase.equalsIgnoreCase("upper")) {
                            name = name.toUpperCase();
                        } else if (fieldNameCase.equalsIgnoreCase("lower")) {
                            name = name.toLowerCase();
                        }

                        type = mif.getToken('(').toLowerCase();
                        defa = null;
                        typeClass = null;
                        size = 4;

                        if (type.equals("float") || type.equals("decimal")) {
                            typeClass = Double.class;
                            size = 8;
                            defa = new Double(0.0);

                            // TODO: check precision?
                        } else if (type.startsWith("char")) {
                            typeClass = String.class;
                            size = Integer.parseInt(mif.getToken(')'));
                            defa = "";
                        } else if (type.equals("integer")
                                || type.equals("smallint")) {
                            typeClass = Integer.class;
                            defa = new Integer(0);

                            // TODO: apply a restriction for Smallint (value between -32768 and +32767)
                        } else if (type.equals("logical")) {
                            typeClass = Boolean.class;
                            size = 2; // ???
                            defa = new Boolean(false);
                        } else if (type.equals("date")) {
                            typeClass = Date.class; // MapInfo format: yyyymmdd
                            size = 4; // ???
                            defa = null; // Dates are "nillable" (like Strings can be empty)
                        } else {
                            LOGGER.fine("unknown type in mif/mid read " + type
                                + " storing as String");
                            typeClass = String.class;
                            size = 254;
                            defa = "";
                        }

                        
                        AttributeTypeBuilder b = new AttributeTypeBuilder();
                        b.setName(name);
                        b.setBinding(typeClass);
                        b.setNillable(defa == null);
                        b.setDefaultValue(defa);
                        
                        
                        // Apart from Geometry, MapInfo table fields cannot be null, so Nillable is always false and default value must always be provided!
                        columns[i] = b.buildDescriptor(name);
                    }
                }
            }

            // Builds schema if not in skip mode...
            if (!skipRead) {
                Class geomType = null;

                String geomClass = geometryClass.toLowerCase();

                if (geomClass.equals("untyped")) {
                    geomType = Geometry.class;
                } else if (geomClass.equals("typed")) {
                    toGeometryCollection = false;
                } else if (geomClass.equals("multi")) {
                    toGeometryCollection = true;
                } else if (geomClass.equals("point")) {
                    geomType = Point.class;
                } else if (geomClass.equals("text")) {
                    geomType = Point.class;
                    hasMifText = true;
                } else if (geomClass.equals("linestring")) {
                    geomType = LineString.class;
                } else if (geomClass.equals("multilinestring")) {
                    geomType = MultiLineString.class;
                    toGeometryCollection = true;
                } else if (geomClass.equals("polygon")) {
                    geomType = Polygon.class;
                } else if (geomClass.equals("multipolygon")) {
                    geomType = MultiPolygon.class;
                    toGeometryCollection = true;
                } else {
                    throw new SchemaException("Bad geometry type option: "
                        + geomClass);
                }

                // Determine geometry type from the first non-null geometry read from mif file
                if (geomType == null) {
                    Reader reader = new Reader(mif, null);
                    Geometry geom = null;

                    while (!reader.mifEOF) {
                        geom = reader.readGeometry();
                        hasMifText = (!reader.mifText.equals(""));

                        if (geom != null) {
                            geomType = geom.getClass();

                            if (toGeometryCollection) {
                                if (geomType.isAssignableFrom(Polygon.class)) {
                                    geomType = MultiPolygon.class;
                                } else if (geomType.isAssignableFrom(
                                            LineString.class)) {
                                    geomType = MultiLineString.class;
                                }
                            }

                            break;
                        }
                    }

                    reader.close();
                    reader = null;
                }

                if (geomType == null) {
                    throw new SchemaException(
                        "Unable to determine geometry type from mif file");
                }

                AttributeTypeBuilder b = new AttributeTypeBuilder();
                b.setName(geometryName);
                b.setBinding(geomType);
                b.setNillable(true);
                
                
                columns[0] = b.buildDescriptor(geometryName);

                try {
                    String typeName = mifFile.getName();
                    typeName = typeName.substring(0, typeName.indexOf("."));

                    SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
                    builder.setName(typeName);

                    builder.setNamespaceURI(namespace);

                    for (int i = 0; i < columns.length; i++)
                        builder.add(columns[i]);

                    if (hasMifText) {
                    	b = new AttributeTypeBuilder();
                    	b.setName("MIF_TEXT");
                    	b.setBinding(String.class);
                    	b.setNillable(true);
                    	
                        builder.add(b.buildDescriptor("MIF_TEXT"));
                    }

                    setSchema(builder.buildFeatureType());
                } catch (SchemaException schexp) {
                    throw new SchemaException(
                        "Exception creating feature type from MIF header: "
                        + schexp.toString());
                }
            }
        } catch (Exception e) {
            throw new IOException("IOException reading MIF header, line "
                + mif.getLineNumber() + ": " + e.getMessage());
        }
    }

    /**
     * Returns the MIF schema
     *
     * @return the current FeatureType associated with the MIF file
     */
    public SimpleFeatureType getSchema() {
        return featureType;
    }

    /**
     * Sets the schema (FeatureType) and creates value setters and IO object
     * buffer
     *
     * @param ft
     *
     * @throws SchemaException The given FeatureType is not compatible with
     *         MapInfo format
     */
    private void setSchema(SimpleFeatureType ft) throws SchemaException {
        featureType = ft;

        numAttribs = featureType.getAttributeCount();
        geomFieldIndex = -1;

        // Creates the input buffer for reading MID file
        featureDefaults = new Object[numAttribs];

        for (int i = 0; i < featureType.getAttributeCount(); i++) {
            AttributeDescriptor at = featureType.getAttribute(i);

            Class atc = at.getType().getBinding();

            if (Geometry.class.isAssignableFrom(atc)) {
                if (geomFieldIndex >= 0) {
                    throw new SchemaException(
                        "Feature Types with more than one geometric attribute are not supported.");
                }

                if (i > 0) {
                    throw new SchemaException(
                        "Geometry must be the first attribute in schema.");
                }

                geomFieldIndex = i; // = 0
            }
        }

        MIFValueSetter[] tmp = getValueSetters();

        for (int i = 0; i < featureType.getAttributeCount(); i++) {
            if (i != geomFieldIndex) {
                tmp[i].setString("");
                featureDefaults[i] = tmp[i].getValue();
            }
        }
    }

    /**
     * Gets the ValueSetters
     *
     * @return An array of valueSetters to be used for IO operations
     *
     * @throws SchemaException An attribute of an unsupported type was found.
     */
    private MIFValueSetter[] getValueSetters() throws SchemaException {
        MIFValueSetter[] fieldValueSetters = new MIFValueSetter[numAttribs];

        for (int i = 0; i < featureType.getAttributeCount(); i++) {
            AttributeDescriptor at = featureType.getAttribute(i);
            Class atc = at.getType().getBinding();

            if (i == geomFieldIndex) {
                fieldValueSetters[i] = null;
            } else if (atc == Integer.class) {
                fieldValueSetters[i] = new MIFValueSetter("0") {
                            protected void stringToValue()
                                throws Exception {
                                objValue = new Integer(strValue);
                            }
                        };
            } else if (atc == Double.class) {
                fieldValueSetters[i] = new MIFValueSetter("0") {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -