Package org.catais.veriso.interlis

Source Code of org.catais.veriso.interlis.IliReader

package org.catais.veriso.interlis;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.catais.veriso.utils.GtUtils;
import org.catais.veriso.utils.IliUtils;
import org.catais.veriso.utils.Iox2wkt;
import org.catais.veriso.utils.PgUtils;
import org.catais.veriso.utils.SurfaceAreaBuilder;
import org.geotools.data.DataStore;
import org.geotools.data.DataUtilities;
import org.geotools.data.DefaultTransaction;
import org.geotools.data.FeatureSource;
import org.geotools.data.FeatureStore;
import org.geotools.data.Transaction;
import org.geotools.data.postgis.PostgisNGDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;

import ch.interlis.ili2c.Ili2cException;
import ch.interlis.ili2c.metamodel.AbstractClassDef;
import ch.interlis.ili2c.metamodel.AreaType;
import ch.interlis.ili2c.metamodel.AttributeDef;
import ch.interlis.ili2c.metamodel.CompositionType;
import ch.interlis.ili2c.metamodel.CoordType;
import ch.interlis.ili2c.metamodel.EnumerationType;
import ch.interlis.ili2c.metamodel.LocalAttribute;
import ch.interlis.ili2c.metamodel.NumericType;
import ch.interlis.ili2c.metamodel.PolylineType;
import ch.interlis.ili2c.metamodel.PrecisionDecimal;
import ch.interlis.ili2c.metamodel.RoleDef;
import ch.interlis.ili2c.metamodel.SurfaceType;
import ch.interlis.ili2c.metamodel.Type;
import ch.interlis.ili2c.metamodel.ViewableTransferElement;
import ch.interlis.iom.IomObject;
import ch.interlis.iom_j.itf.EnumCodeMapper;
import ch.interlis.iom_j.itf.ItfReader;
import ch.interlis.iox.EndBasketEvent;
import ch.interlis.iox.EndTransferEvent;
import ch.interlis.iox.IoxEvent;
import ch.interlis.iox.IoxException;
import ch.interlis.iox.IoxReader;
import ch.interlis.iox.ObjectEvent;
import ch.interlis.iox.StartBasketEvent;
import ch.interlis.iox_j.jts.Iox2jts;
import ch.interlis.iox_j.jts.Iox2jtsException;

import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;

public class IliReader {
    private static Logger logger = Logger.getLogger(IliReader.class);

    private ch.interlis.ili2c.metamodel.TransferDescription iliTd = null;
    private HashMap tag2class = null;
    private IoxReader ioxReader = null;
    private EnumCodeMapper enumCodeMapper = new EnumCodeMapper();
    private String modelName = null;

    private Boolean isAreaHelper = false;
    private Boolean isAreaMain = false;
    private String areaMainFeatureName = null;
    private Boolean isSurfaceHelper = false;
    private String surfaceMainFeatureName = null;
    private Boolean isSurfaceMain = false;
    private String geomName = null;
    private int tableNumber = 0;
    private String prefix = null;

    private HashMap params = null;

    private String dbhost = null;
    private String dbport = null;
    private String dbname = null;
    private String dbschema = null;
    private String dbuser = null;
    private String dbpwd = null;
    private String dbadmin = null;
    private String dbadminpwd = null;
    private String epsg = null;
    private String importModelName = null;
    private String importItfFile = null;

    private boolean enumerationText = false;
    private boolean renumberTid = false;

    private LinkedHashMap featureTypes = null;
    private String featureName = null;

    private ArrayList features = null;
    private ArrayList areaHelperFeatures = new ArrayList();
    private ArrayList surfaceMainFeatures = new ArrayList();

    private DataStore datastore = null;

    private Transaction t = null;

    public IliReader(HashMap params) throws IOException, Ili2cException,
            ClassNotFoundException, SQLException, IllegalArgumentException,
            IoxException {
        logger.setLevel(Level.INFO);

        // get parameters
        this.params = params;
        readParams();

        // compile interlis model
        importModelName = IliUtils.getModelNameFromItf(importItfFile);
        iliTd = IliUtils.compileModel(importModelName);

        // TEMPORARY!!!!!!!!!!
        // delete database schema
        // deletePostgresSchemaAndTables();

        // create database schema
        createPostgresSchemaAndTables();

        // get all feature types
        featureTypes = GtUtils.getFeatureTypesFromItfTransferViewables(iliTd,
                epsg);

        tag2class = ch.interlis.iom_j.itf.ModelUtilities.getTagMap(iliTd);
    }

    public void read() throws IoxException, IOException {
        ioxReader = new ch.interlis.iom_j.itf.ItfReader(new java.io.File(
                importItfFile));
        ((ItfReader) ioxReader).setModel(iliTd);
        ((ItfReader) ioxReader).setRenumberTids(true);
        ((ItfReader) ioxReader).setReadEnumValAsItfCode(true);

        IoxEvent event = ioxReader.read();
        while (event != null) {
            if (event instanceof StartBasketEvent) {
                StartBasketEvent basket = (StartBasketEvent) event;
                logger.debug(basket.getType() + "(oid " + basket.getBid()
                        + ")...");

            } else if (event instanceof ObjectEvent) {
                IomObject iomObj = ((ObjectEvent) event).getIomObject();
                String tag = iomObj.getobjecttag();
                readObject(iomObj, tag);
                featureName = tag;
            } else if (event instanceof EndBasketEvent) {
                // do nothing
            } else if (event instanceof EndTransferEvent) {
                ioxReader.close();
                // write last table to postgis
                // this.writeToPostgis();
                datastore.dispose();
                break;
            }
            event = ioxReader.read();
        }
    }

    private void readObject(IomObject iomObj, String featureName)
            throws IOException {
        String tag = iomObj.getobjecttag();

        if (!featureName.equalsIgnoreCase(this.featureName)) {
            logger.debug("neu: " + featureName);
            logger.debug("alt: " + this.featureName);

            if (features != null) {
                SimpleFeatureCollection fc = DataUtilities.collection(features);
                writeToPostgis();
            }
            features = new ArrayList();
        }

        // logger.debug("Feature: " + tag);
        SimpleFeatureType ft = (SimpleFeatureType) featureTypes.get(tag);
        if (ft != null) {
            SimpleFeatureBuilder featBuilder = new SimpleFeatureBuilder(ft);

            String tid = null;
            if (((ItfReader) ioxReader).isRenumberTids()) {
                tid = getTidOrRef(iomObj.getobjectoid());
            } else {
                tid = iomObj.getobjectoid();
            }
            featBuilder.set("tid", tid);

            Object tableObj = tag2class.get(iomObj.getobjecttag());
            if (tableObj instanceof AbstractClassDef) {
                AbstractClassDef tableDef = (AbstractClassDef) tag2class
                        .get(iomObj.getobjecttag());
                ArrayList attrs = ch.interlis.iom_j.itf.ModelUtilities
                        .getIli1AttrList(tableDef);

                Iterator attri = attrs.iterator();
                while (attri.hasNext()) {
                    ViewableTransferElement obj = (ViewableTransferElement) attri
                            .next();

                    if (obj.obj instanceof AttributeDef) {
                        AttributeDef attr = (AttributeDef) obj.obj;
                        Type type = attr.getDomainResolvingAliases();
                        String attrName = attr.getName();

                        // what is this good for?
                        if (type instanceof CompositionType) {
                            logger.debug("CompositionType");
                            int valuec = iomObj.getattrvaluecount(attrName);
                            for (int valuei = 0; valuei < valuec; valuei++) {
                                IomObject value = iomObj.getattrobj(attrName,
                                        valuei);
                                if (value != null) {
                                    // do nothing...
                                }
                            }
                        } else if (type instanceof PolylineType) {
                            IomObject value = iomObj.getattrobj(attrName, 0);
                            if (value != null) {
                                featBuilder.set(attrName.toLowerCase(),
                                        Iox2wkt.polyline2jts(value, 0));
                            } else {
                                featBuilder.set(attrName.toLowerCase(), null);
                            }
                        } else if (type instanceof SurfaceType) {
                            isSurfaceMain = true;
                            geomName = attrName.toLowerCase();
                        } else if (type instanceof AreaType) {
                            isAreaMain = true;
                            IomObject value = iomObj.getattrobj(attrName, 0);
                            try {
                                Point point = new GeometryFactory()
                                        .createPoint(Iox2jts.coord2JTS(value));
                                // point.setSRID( Integer.parseInt(this.epsg) );
                                featBuilder.set(attrName.toLowerCase()
                                        + "_point", point);
                                geomName = attrName.toLowerCase();
                            } catch (Iox2jtsException e) {
                                e.printStackTrace();
                                logger.warn(e.getMessage());
                            }
                        } else if (type instanceof CoordType) {
                            IomObject value = iomObj.getattrobj(attrName, 0);
                            if (value != null) {
                                if (!value.getobjecttag().equals("COORD")) {
                                    logger.warn("object tag <> COORD");
                                } else {
                                    try {
                                        Point point = new GeometryFactory()
                                                .createPoint(Iox2jts
                                                        .coord2JTS(value));
                                        featBuilder.set(attrName.toLowerCase(),
                                                point);
                                    } catch (Iox2jtsException e) {
                                        e.printStackTrace();
                                        logger.warn(e.getMessage());
                                    }
                                }
                            }
                        } else if (type instanceof NumericType) {
                            String value = iomObj.getattrvalue(attrName);
                            if (value != null) {
                                featBuilder.set(attrName.toLowerCase(),
                                        Double.valueOf(value));
                            } else {
                                featBuilder.set(attrName.toLowerCase(), null);
                            }
                        } else if (type instanceof EnumerationType) {
                            String value = iomObj.getattrvalue(attrName);
                            if (value != null) {
                                featBuilder.set(attrName.toLowerCase(),
                                        Integer.valueOf(value));
                                if (true == true) {
                                    featBuilder.set(attrName.toLowerCase()
                                            + "_txt", enumCodeMapper
                                            .mapItfCode2XtfCode(
                                                    (EnumerationType) type,
                                                    value));
                                }
                            } else {
                                featBuilder.set(attrName.toLowerCase(), null);
                                if (true) {
                                    featBuilder.set(attrName.toLowerCase()
                                            + "_txt", null);
                                }
                            }
                        } else {
                            String value = iomObj.getattrvalue(attrName);
                            if (value != null) {
                                featBuilder.set(attrName.toLowerCase(), value);
                            } else {
                                featBuilder.set(attrName.toLowerCase(), null);
                            }
                        }
                    }
                    if (obj.obj instanceof RoleDef) {
                        RoleDef role = (RoleDef) obj.obj;
                        String roleName = role.getName();

                        IomObject structvalue = iomObj.getattrobj(roleName, 0);
                        String refoid = "";
                        if (structvalue != null) {
                            if (((ItfReader) ioxReader).isRenumberTids()) {
                                refoid = getTidOrRef(structvalue
                                        .getobjectrefoid());
                            } else {
                                refoid = structvalue.getobjectrefoid();
                            }
                        }
                        featBuilder.set(roleName.toLowerCase(),
                                refoid.toString());
                    }
                }
            } else if (tableObj instanceof LocalAttribute) {
                LocalAttribute localAttr = (LocalAttribute) tag2class
                        .get(iomObj.getobjecttag());
                Type type = localAttr.getDomainResolvingAliases();

                if (type instanceof SurfaceType) {
                    isSurfaceHelper = true;
                    geomName = localAttr.getName().toLowerCase();

                    String fkName = ch.interlis.iom_j.itf.ModelUtilities
                            .getHelperTableMainTableRef(localAttr);
                    IomObject structvalue = iomObj.getattrobj(fkName, 0);
                    String refoid = null;
                    if (((ItfReader) ioxReader).isRenumberTids()) {
                        refoid = getTidOrRef(structvalue.getobjectrefoid());
                    } else {
                        refoid = structvalue.getobjectrefoid();
                    }
                    featBuilder.set("_itf_ref", refoid);

                    IomObject value = iomObj.getattrobj(
                            ch.interlis.iom_j.itf.ModelUtilities
                                    .getHelperTableGeomAttrName(localAttr), 0);
                    if (value != null) {
                        PrecisionDecimal maxOverlaps = ((SurfaceType) type)
                                .getMaxOverlap();
                        if (maxOverlaps == null) {
                            featBuilder.set(localAttr.getName().toLowerCase(),
                                    Iox2wkt.polyline2jts(value, 0.02));
                        } else {
                            // featBuilder.set(localAttr.getName().toLowerCase(),
                            // Iox2wkt.polyline2jts( value,
                            // maxOverlaps.doubleValue() ) );
                            featBuilder.set(localAttr.getName().toLowerCase(),
                                    Iox2wkt.polyline2jts(value, 0.001));
                        }
                    }
                } else if (type instanceof AreaType) {
                    isAreaHelper = true;
                    geomName = localAttr.getName().toLowerCase();

                    String fkName = ch.interlis.iom_j.itf.ModelUtilities
                            .getHelperTableMainTableRef(localAttr);
                    IomObject structvalue = iomObj.getattrobj(fkName, 0);

                    featBuilder.set("_itf_ref", null);

                    IomObject value = iomObj.getattrobj(
                            ch.interlis.iom_j.itf.ModelUtilities
                                    .getHelperTableGeomAttrName(localAttr), 0);
                    if (value != null) {
                        PrecisionDecimal maxOverlaps = ((AreaType) type)
                                .getMaxOverlap();
                        if (maxOverlaps == null) {
                            featBuilder.set(localAttr.getName().toLowerCase(),
                                    Iox2wkt.polyline2jts(value, 0.02));
                        } else {
                            // featBuilder.set(localAttr.getName().toLowerCase(),
                            // Iox2wkt.polyline2jts(value,
                            // maxOverlaps.doubleValue()));
                            featBuilder.set(localAttr.getName().toLowerCase(),
                                    Iox2wkt.polyline2jts(value, 0.001));
                        }
                    }
                }
            }

            SimpleFeature feature = featBuilder.buildFeature(null);
            logger.debug(feature.toString());
            features.add(feature);
        }
    }

    private void writeToPostgis() throws IOException {
        logger.debug("writeToPostgis (Geknorze.....)");
        logger.debug("featureName:: " + featureName);
        if (isAreaHelper == true) {
            areaHelperFeatures.addAll(features);

            isAreaHelper = false;
        } else if (isAreaMain == true) {
            if (areaHelperFeatures == null) {
                SimpleFeatureCollection collection = DataUtilities
                        .collection(features);
                writeToPostgis(collection, featureName);
            } else {
                if (areaHelperFeatures.size() == 0) {
                    SimpleFeatureCollection collection = DataUtilities
                            .collection(features);
                    writeToPostgis(collection, featureName);
                } else {
                    SimpleFeatureCollection areaHelperCollection = DataUtilities
                            .collection(areaHelperFeatures);
                    SimpleFeatureCollection collection = DataUtilities
                            .collection(features);
                    logger.debug("build area");
                    SimpleFeatureCollection areaCollection = SurfaceAreaBuilder
                            .buildArea(collection, areaHelperCollection);
                    logger.debug("done");

                    writeToPostgis(areaCollection, featureName);
                    areaHelperFeatures.clear();
                }
            }

            isAreaHelper = false;
            isAreaMain = false;
        } else if (isSurfaceMain == true) {

            logger.debug("isSurfaceMain = true");

            // Problem bei zwei aufeinanderfolgenden Surface-Tabellen.
            // Falls die erste KEINE Geometrie hat (keine Helper-Tabelle),
            // wird sie nicht in die DB geschrieben.
            // Wurde sie geschrieben, sollte die Anzahl = 0 sein.
            // Falls ungleich 0 -> in die DB schreiben.

            try {
                SimpleFeatureCollection surfaceMainCollection = DataUtilities
                        .collection(surfaceMainFeatures);

                logger.debug("surfaceMainFeatureName: "
                        + surfaceMainFeatureName);
                logger.debug("featureName: " + featureName);

                writeToPostgis(surfaceMainCollection, surfaceMainFeatureName);
                surfaceMainFeatures.clear();

            } catch (NullPointerException e) {
                System.err.println("surfaceMainCollection keine features");
                logger.warn("no features in surfaceMainCollection");
            }
            surfaceMainFeatures.addAll(features);

            surfaceMainFeatureName = featureName;
            isSurfaceMain = false;
        } else if (isSurfaceHelper == true) {

            logger.debug("isSurfaceHelper = true");

            SimpleFeatureCollection surfaceMainCollection = DataUtilities
                    .collection(surfaceMainFeatures);
            SimpleFeatureCollection collection = DataUtilities
                    .collection(features);
            logger.debug("build surface");
            SimpleFeatureCollection coll = SurfaceAreaBuilder.buildSurface(
                    surfaceMainCollection, collection);
            logger.debug("done");

            writeToPostgis(coll, surfaceMainFeatureName);
            surfaceMainFeatures.clear();

            isSurfaceHelper = false;
            isSurfaceMain = false;
        } else {
            logger.debug("writeToPostgis: " + featureName);
            SimpleFeatureCollection collection = DataUtilities
                    .collection(features);
            writeToPostgis(collection, featureName);

            // Falls keine Geometrie zur Surface Main Table
            // wird isSurfaceHelper nie true, somit
            // gibts die surfaceMainCollection immer noch und
            // sie muss noch in die DB geschrieben werden.

            // 2014-06-01: Ich blicke zwar momentan nicht mehr
            // durch in dem Geheue. Aber so funktionierts wieder
            // (war auskommentiert).

            if (surfaceMainFeatures != null) {
                if (surfaceMainFeatures.size() > 0) {
                    logger.debug("writeToPostgis (letzte Surface Tabelle ohne Geometrie): "
                            + surfaceMainFeatureName);
                    SimpleFeatureCollection surfaceMainCollection = DataUtilities
                            .collection(surfaceMainFeatures);
                    this.writeToPostgis(surfaceMainCollection,
                            surfaceMainFeatureName);
                    surfaceMainFeatures.clear();
                }
            }
        }
        features.clear();
    }

    private void writeToPostgis(SimpleFeatureCollection collection,
            String featureName) throws IOException {

        Map params = new HashMap();
        params.put("dbtype", "postgis");
        params.put("host", this.dbhost);
        params.put("port", this.dbport);
        params.put("database", this.dbname);
        params.put("schema", this.dbschema);
        params.put("user", this.dbadmin);
        params.put("passwd", this.dbadminpwd);
        params.put(PostgisNGDataStoreFactory.VALIDATECONN, true);
        params.put(PostgisNGDataStoreFactory.MAX_OPEN_PREPARED_STATEMENTS, 50);
        params.put(PostgisNGDataStoreFactory.LOOSEBBOX, true);
        params.put(PostgisNGDataStoreFactory.PREPARED_STATEMENTS, true);

        if (datastore == null) {
            datastore = new PostgisNGDataStoreFactory().createDataStore(params);
        }

        String tableName = (featureName.substring(featureName.indexOf(".") + 1))
                .replace(".", "_").toLowerCase();

        FeatureSource<SimpleFeatureType, SimpleFeature> source = datastore
                .getFeatureSource(tableName);
        FeatureStore<SimpleFeatureType, SimpleFeature> store = (FeatureStore<SimpleFeatureType, SimpleFeature>) source;

        store.setTransaction(t);

        logger.info("Add features: " + featureName);
        store.addFeatures(collection);
    }

    private String getTidOrRef(String oriTid) {
        if (this.prefix != null) {
            if (this.prefix.length() > 0) {
                int tidc = oriTid.length();
                for (int i = 0; i < (8 - tidc); i++) {
                    oriTid = "0" + oriTid;
                }
            }
        }
        if (this.prefix == null) {
            prefix = "";
        }
        return this.prefix + oriTid;
    }

    public void startTransaction() {
        logger.debug("Starting Transaction...");
        t = new DefaultTransaction();
    }

    public void commitTransaction() throws IOException {
        logger.info("Committing Transaction...");
        try {
            t.commit();
        } catch (IOException e) {
            logger.error("Cannot commit transaction");
            logger.error(e.getMessage());
            t.rollback();
        } finally {
            t.close();
        }
        logger.info("Transaction committed.");
    }

    private void deletePostgresSchemaAndTables() throws ClassNotFoundException,
            SQLException {
        logger.info("Start deleting schema and tables...");

        String sql = "DROP SCHEMA IF EXISTS " + dbschema + " CASCADE;";

        Class.forName("org.postgresql.Driver");
        Connection conn = DriverManager.getConnection("jdbc:postgresql://"
                + dbhost + "/" + dbname, dbadmin, dbadminpwd);

        Statement s = null;
        s = conn.createStatement();
        int m = 0;
        m = s.executeUpdate(sql);

        s.close();
        conn.close();

        logger.info("Schema and tables deleted.");
    }

    private void createPostgresSchemaAndTables() throws ClassNotFoundException,
            SQLException, IOException {
        logger.info("Start creating schema and tables...");

        String sql = PgUtils.getSqlCreateStatements(iliTd, dbschema, dbadmin,
                dbuser, epsg);

        Class.forName("org.postgresql.Driver");
        Connection conn = DriverManager.getConnection("jdbc:postgresql://"
                + dbhost + "/" + dbname, dbadmin, dbadminpwd);

        Statement s = null;
        s = conn.createStatement();
        int m = 0;
        m = s.executeUpdate(sql);

        s.close();
        conn.close();

        logger.info("Schema and tables created.");
    }

    public void setEpsg(String epsg) {
        this.epsg = epsg;
    }

    private void readParams() {
        dbhost = (String) params.get("dbhost");
        if (dbhost == null) {
            throw new IllegalArgumentException("'dbhost' not set.");
        }

        dbport = (String) params.get("dbport");
        if (dbport == null) {
            throw new IllegalArgumentException("'dbport' not set.");
        }

        dbname = (String) params.get("dbname");
        if (dbname == null) {
            throw new IllegalArgumentException("'dbname' not set.");
        }

        dbschema = (String) params.get("dbschema");
        if (dbschema == null) {
            throw new IllegalArgumentException("'dbschema' not set.");
        }

        dbuser = (String) params.get("dbuser");
        if (dbuser == null) {
            throw new IllegalArgumentException("'dbuser' not set.");
        }

        dbpwd = (String) params.get("dbpwd");
        if (dbpwd == null) {
            throw new IllegalArgumentException("'dbpwd' not set.");
        }

        dbadmin = (String) params.get("dbadmin");
        if (dbadmin == null) {
            throw new IllegalArgumentException("'dbadmin' not set.");
        }

        dbadminpwd = (String) params.get("dbadminpwd");
        if (dbadminpwd == null) {
            throw new IllegalArgumentException("'dbadminpwd' not set.");
        }

        importModelName = (String) params.get("importModelName");
        if (importModelName == null) {
            throw new IllegalArgumentException("'importModelName' not set.");
        }

        importItfFile = (String) params.get("importItfFile");
        if (importItfFile == null) {
            throw new IllegalArgumentException("'importItfFile' not set.");
        }

        enumerationText = (Boolean) params.get("enumerationText");

        renumberTid = (Boolean) params.get("renumberTid");

        epsg = (String) params.get("epsg");
        if (epsg == null) {
            epsg = "21781";
        }
    }

}
TOP

Related Classes of org.catais.veriso.interlis.IliReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.