org.geotools.data.ngi.NGIReader.java Source code

Java tutorial

Introduction

Here is the source code for org.geotools.data.ngi.NGIReader.java

Source

/*
 *    GeoTools - The Open Source Java GIS Toolkit
 *    http://geotools.org
 *
 *    (C) 2002-2012, Open Source Geospatial Foundation (OSGeo)
 *
 *    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;
 *    version 2.1 of the License.
 *
 *    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.
 */
package org.geotools.data.ngi;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.io.IOUtils;
import org.geotools.data.Query;
import org.geotools.factory.GeoTools;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.util.Converters;
import org.geotools.util.logging.Logging;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Polygon;

/**
 * NGI Reader
 * 
 * @author MapPlus, mapplus@gmail.com, http://onspatial.com
 * @since 2012-10-30
 * @see
 * 
 */
public class NGIReader extends AbstractNGIReader {
    protected static final Logger LOGGER = Logging.getLogger(NGIReader.class);

    CoordinateReferenceSystem crs;

    SimpleFeatureType schema;

    Query query = Query.ALL;

    Class<?> geomBinding;

    boolean hasNext = false;

    BufferedReader ngiReader = null;

    BufferedReader ndaReader = null;

    GeometryFactory gf = JTSFactoryFinder.getGeometryFactory(GeoTools.getDefaultHints());

    SimpleFeatureBuilder fb;

    int featureID = 0;

    public NGIReader(File ngiFile, File ndaFile, Charset charset) throws IOException {
        this.ngiReader = new BufferedReader(new InputStreamReader(new FileInputStream(ngiFile), charset));
        if (ndaFile.exists()) {
            this.ndaReader = new BufferedReader(new InputStreamReader(new FileInputStream(ndaFile), charset));
        }
    }

    public void close() {
        IOUtils.closeQuietly(ngiReader);
        IOUtils.closeQuietly(ndaReader);
    }

    public SimpleFeatureType getSchema() {
        return schema;
    }

    public void setQuery(Query query) {
        this.query = query == null ? Query.ALL : query;
    }

    public void setSchema(SimpleFeatureType schema) {
        this.schema = schema;
        this.crs = schema.getCoordinateReferenceSystem();
        this.geomBinding = schema.getGeometryDescriptor().getType().getBinding();
        this.fb = new SimpleFeatureBuilder(schema);
        this.featureID = 0;

        seekLayer(ngiReader, schema.getTypeName());
        hasNext = nextRecord(ngiReader);
        if (ndaReader != null) {
            seekLayer(ndaReader, schema.getTypeName());
            nextRecord(ndaReader);
        }
    }

    public boolean hasNext() {
        return hasNext;
    }

    public SimpleFeature next() {
        SimpleFeature feature = fb.buildFeature(schema.getTypeName() + "." + ++featureID);
        Geometry geometry = getNextGeometry(ngiReader);

        if (geometry != null) {
            geometry.setUserData(crs);
            feature.setDefaultGeometry(geometry);
        }

        hasNext = nextRecord(ngiReader);
        if (ndaReader != null) {
            try {
                String[] values = ndaReader.readLine().split(",");
                int addIndex = 0;
                for (int index = 0; index < schema.getAttributeCount(); index++) {
                    AttributeDescriptor desc = schema.getDescriptor(index);
                    if (desc instanceof GeometryDescriptor) {
                        continue;
                    }

                    Class<?> binding = desc.getType().getBinding();
                    if (binding.isAssignableFrom(String.class)) {
                        String value = (String) Converters.convert(values[addIndex++], binding);
                        if (value != null && !value.isEmpty()) {
                            value = value.trim();
                            value = value.substring(1, value.length() - 1);
                        }
                        feature.setAttribute(desc.getLocalName(), value);
                    } else {
                        Object value = Converters.convert(values[addIndex++], binding);
                        feature.setAttribute(desc.getLocalName(), value);
                    }
                }
            } catch (IOException e) {
                LOGGER.log(Level.WARNING, e.getMessage(), e);
            }

            nextRecord(ndaReader);
        }
        return feature;
    }

    private Geometry getNextGeometry(BufferedReader reader) {
        try {
            String gtype = reader.readLine().toUpperCase().trim();
            if (gtype.startsWith("POINT")) {
                return gf.createPoint(parseCoordinate(reader.readLine()));
            } else if (gtype.startsWith("TEXT")) {
                return gf.createPoint(parseCoordinate(reader.readLine()));
            } else if (gtype.startsWith("LINE")) {
                int numofPoints = parseInteger(reader.readLine());
                Coordinate[] coordinates = new Coordinate[numofPoints];
                for (int index = 0; index < numofPoints; index++) {
                    coordinates[index] = parseCoordinate(reader.readLine());
                }
                return gf.createLineString(coordinates);
            } else if (gtype.startsWith("POLYGON")) {
                int numofRing = parseInteger(reader.readLine().replace("NUMPARTS", ""));
                LinearRing shell = null;
                LinearRing[] holes = numofRing > 1 ? new LinearRing[numofRing - 1] : null;
                for (int ringIndex = 0; ringIndex < numofRing; ringIndex++) {
                    int numofPoints = parseInteger(reader.readLine());
                    // =========================================================
                    // NGI ?? ?? ?? ? ???? .
                    Coordinate[] coordinates = new Coordinate[numofPoints + 1];
                    // =========================================================
                    for (int index = 0; index < numofPoints; index++) {
                        coordinates[index] = parseCoordinate(reader.readLine());
                    }
                    coordinates[numofPoints] = coordinates[0];

                    if (ringIndex == 0) {
                        shell = gf.createLinearRing(coordinates);
                    } else {
                        holes[ringIndex - 1] = gf.createLinearRing(coordinates);
                    }
                }

                return gf.createPolygon(shell, holes);
            } else if (gtype.startsWith("MULTIPOINT")) {
                int numofPoints = parseInteger(reader.readLine());
                Coordinate[] coordinates = new Coordinate[numofPoints];
                for (int index = 0; index < numofPoints; index++) {
                    coordinates[index] = parseCoordinate(reader.readLine());
                }
                return gf.createMultiPoint(coordinates);
            } else if (gtype.startsWith("MULTILINE")) {
                int numofParts = parseInteger(reader.readLine().replace("NUMPARTS", ""));
                LineString[] lineStrings = new LineString[numofParts];
                for (int partIndex = 0; partIndex < numofParts; partIndex++) {
                    int numofPoints = parseInteger(reader.readLine());
                    Coordinate[] coordinates = new Coordinate[numofPoints];
                    for (int index = 0; index < numofPoints; index++) {
                        coordinates[index] = parseCoordinate(reader.readLine());
                    }
                    lineStrings[partIndex] = gf.createLineString(coordinates);
                }
                return gf.createMultiLineString(lineStrings);
            } else if (gtype.startsWith("MULTIPOLY")) {
                int numofParts = parseInteger(reader.readLine().replace("NUMPARTS", ""));
                Polygon[] polygons = new Polygon[numofParts];
                for (int partIndex = 0; partIndex < numofParts; partIndex++) {
                    int numofRing = parseInteger(reader.readLine().replace("NUMPARTS", ""));
                    LinearRing shell = null;
                    LinearRing[] holes = numofRing > 1 ? new LinearRing[numofRing - 1] : null;
                    for (int ringIndex = 0; ringIndex < numofRing; ringIndex++) {
                        int numofPoints = parseInteger(reader.readLine());
                        // =========================================================
                        // NGI ?? ?? ?? ? ???? .
                        Coordinate[] coordinates = new Coordinate[numofPoints + 1];
                        // =========================================================
                        for (int index = 0; index < numofPoints; index++) {
                            coordinates[index] = parseCoordinate(reader.readLine());
                        }
                        coordinates[numofPoints] = coordinates[0];

                        if (ringIndex == 0) {
                            shell = gf.createLinearRing(coordinates);
                        } else {
                            holes[ringIndex - 1] = gf.createLinearRing(coordinates);
                        }
                    }
                    polygons[partIndex] = gf.createPolygon(shell, holes);
                }

                return gf.createMultiPolygon(polygons);
            }
        } catch (IOException e) {
            LOGGER.log(Level.FINER, e.getMessage(), e);
        }

        return null;
    }

    private boolean nextRecord(BufferedReader reader) {
        try {
            String line = reader.readLine();
            while (line != null) {
                if (line.toUpperCase().indexOf("$RECORD") != -1) {
                    return true;
                }

                if (line.toUpperCase().indexOf("<LAYER_END>") != -1) {
                    return false;
                }
                line = reader.readLine();
            }
        } catch (IOException e) {
            LOGGER.log(Level.FINER, e.getMessage(), e);
        }
        return false;
    }
}