fr.ign.datalift.RDFBuilder.java Source code

Java tutorial

Introduction

Here is the source code for fr.ign.datalift.RDFBuilder.java

Source

/*
 * Copyright / Copr. IGN 2013
 * Contributor(s) : Faycal Hamdi
 *
 * Contact: hamdi.faycal@gmail.com
 *
 * This software is governed by the CeCILL license under French law and
 * abiding by the rules of distribution of free software. You can use,
 * modify and/or redistribute the software under the terms of the CeCILL
 * license as circulated by CEA, CNRS and INRIA at the following URL
 * "http://www.cecill.info".
 *
 * As a counterpart to the access to the source code and rights to copy,
 * modify and redistribute granted by the license, users are provided only
 * with a limited warranty and the software's author, the holder of the
 * economic rights, and the successive licensors have only limited
 * liability.
 *
 * In this respect, the user's attention is drawn to the risks associated
 * with loading, using, modifying and/or developing or reproducing the
 * software by the user in light of its specific status of free software,
 * that may mean that it is complicated to manipulate, and that also
 * therefore means that it is reserved for developers and experienced
 * professionals having in-depth computer knowledge. Users are therefore
 * encouraged to load and test the software's suitability as regards their
 * requirements in conditions enabling the security of their systems and/or
 * data to be ensured and, more generally, to use and operate it in the
 * same conditions as regards security.
 *
 * The fact that you are presently reading this means that you have had
 * knowledge of the CeCILL license and that you accept its terms.
 */

package fr.ign.datalift;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.lang.WordUtils;
import org.openrdf.model.BNode;
import org.openrdf.model.Resource;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.vocabulary.RDF;
//import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFFormat;
import org.openrdf.rio.RDFHandlerException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.rio.RDFWriter;
import org.openrdf.rio.Rio;
import org.xml.sax.SAXException;

import com.vividsolutions.jts.io.ParseException;

import fr.ign.datalift.constants.GeoSPARQL;
import fr.ign.datalift.constants.Geometrie;
import fr.ign.datalift.constants.CRS;
import fr.ign.datalift.model.AbstractFeature;
import fr.ign.datalift.model.FeatureProperty;
import fr.ign.datalift.model.GeometryProperty;
import fr.ign.datalift.parser.Features_Parser;
import fr.ign.datalift.repository.SesameConnection;

public class RDFBuilder extends SesameConnection {

    protected ValueFactory vf;
    protected Statement geoStatement;
    private int count;
    private List<Statement> aboutGeometry;
    private Resource context;
    private String featureNS = "http://localhost:8080/test/";

    static Logger log = Logger.getLogger(RDFBuilder.class.getName());

    public RDFBuilder() throws RepositoryException {
        vf = super.getVf();
        super.connectSesameRepository();
    }

    public void translateToRDF(ArrayList<AbstractFeature> featureList, String crs, ArrayList<String> asGmlList,
            URI context, String typeName, String vocabNS, boolean fileOut, String fileOutPath)
            throws RepositoryException, IOException, RDFParseException, RDFHandlerException, ParseException {

        this.context = context;
        //String cleanedFT = this.cleanUpString(typeName);
        String cleanedFT = typeName;
        this.featureNS = this.featureNamespace(context.toString(), cleanedFT);

        Statement statement;
        List<Statement> aboutAttributes = new ArrayList<Statement>();
        aboutGeometry = new ArrayList<Statement>();

        // create blank node for CRS
        /*BNode systcoord = vf.createBNode();
        if (crs != null) {
           statement = vf.createStatement(systcoord, RDFS.LABEL, vf.createLiteral(crs));
           aboutGeometry.add(statement);
        }*/

        if (crs != null)
            CRS.setCrsValue(crs);

        // serialize a featureCollection into RDF
        for (int i = 0; i < featureList.size(); i++) {
            count = i + 1;
            URI feature = vf.createURI(featureNS, cleanedFT + "_" + count);

            statement = vf.createStatement(feature, RDF.TYPE, vf.createURI(featureNS));
            aboutAttributes.add(statement);

            ArrayList<FeatureProperty> featureProperties = (ArrayList<FeatureProperty>) featureList.get(i)
                    .getProperties();

            for (int j = 0; j < featureProperties.size(); j++) {

                FeatureProperty fp = featureProperties.get(j);

                if (fp instanceof GeometryProperty) {

                    GeometryProperty gp = (GeometryProperty) fp;

                    String geoType = gp.getType();

                    //URI geomFeature = vf.createURI(featureNS, this.cleanUpString(geoType) + "_" + count);
                    URI geomFeature = vf.createURI(featureNS, geoType + "_" + count);

                    geoStatement = vf.createStatement(feature, Geometrie.GEOMETRIE, geomFeature);
                    aboutGeometry.add(geoStatement);

                    geoStatement = vf.createStatement(geomFeature, GeoSPARQL.ASWKT,
                            vf.createLiteral("<" + CRS.IGNFCRS + "> " + gp.getValue(), GeoSPARQL.WKTLITERAL));
                    aboutGeometry.add(geoStatement);

                    if (asGmlList != null) {
                        geoStatement = vf.createStatement(geomFeature, GeoSPARQL.ASGML,
                                vf.createLiteral(asGmlList.get(j)));
                        aboutGeometry.add(geoStatement);
                    }

                    if (geoType.equals("MultiPolygon")) {
                        this.serializeMultipolygon(gp, geomFeature, crs);
                    }

                    if (geoType.equals("MultiLineString")) {
                        this.serializeMultiLineString(gp, geomFeature, crs);
                    }

                    if (geoType.equals("MultiPoint")) {
                        this.serializeMultiPoint(gp, geomFeature, crs);
                    }

                    if (geoType.equals("Polygon")) {
                        this.serializePolygon(gp, geomFeature, crs);
                    }

                    if (geoType.equals("LineString")) {
                        this.serializeLineString(gp, geomFeature, crs, 0);
                    }

                    if (geoType.equals("LinearRing")) {
                        this.serializeLineString(gp, geomFeature, crs, 0);
                    }
                    if (geoType.equals("Point")) {
                        this.serializePoint(gp, geomFeature, crs, 0);
                    }

                } else {
                    if (fp.getType() != null) {
                        if (fp.getType().contains("int")) {
                            statement = vf.createStatement(feature, vf.createURI(vocabNS + fp.getName()),
                                    vf.createLiteral(fp.getIntValue()));
                            aboutAttributes.add(statement);
                        } else {
                            statement = vf.createStatement(feature, vf.createURI(vocabNS + fp.getName()),
                                    vf.createLiteral(fp.getDoubleValue()));
                            aboutAttributes.add(statement);
                        }
                    } else {
                        statement = vf.createStatement(feature, vf.createURI(vocabNS + fp.getName()),
                                vf.createLiteral(fp.getValue()));
                        aboutAttributes.add(statement);
                    }
                }
            }
        }
        if (!fileOut) {
            sesameRepository.getConnection().clear(this.context);
            sesameRepository.getConnection().add(aboutAttributes, this.context);
            sesameRepository.getConnection().add(aboutGeometry, this.context);
            sesameRepository.getConnection().commit();
            sesameRepository.getConnection().close();
        } else {
            FileOutputStream out = new FileOutputStream(fileOutPath);
            RDFWriter writer = Rio.createWriter(RDFFormat.TURTLE, out);
            try {
                writer.startRDF();
                for (Statement st : aboutAttributes) {
                    writer.handleStatement(st);
                }
                for (Statement st : aboutGeometry) {
                    writer.handleStatement(st);
                }
                writer.endRDF();
            } catch (RDFHandlerException e) {
                // oh no, do something!
            }
        }

    }

    private String featureNamespace(String context, String featureTypeName) {
        String featureNS = context + "/" + featureTypeName + "/";
        return featureNS;
    }

    protected String cleanUpString(String str) {
        if (str.contains(":"))
            str = str.substring(str.lastIndexOf(':') + 1);
        return WordUtils.capitalizeFully(str, new char[] { ' ' }).replaceAll(" ", "").trim();
    }

    // serialize Geometry Features into RDF

    protected void serializeMultipolygon(GeometryProperty gp, Resource geomFeature, String crs) {
        geoStatement = vf.createStatement(geomFeature, RDF.TYPE, Geometrie.MULTIPOLYGON);
        aboutGeometry.add(geoStatement);
        this.setCrs(geomFeature, crs);
        int n = gp.getNumGeometries();
        for (int i = 0; i < n; i++) {
            BNode polygonMember = vf.createBNode();
            geoStatement = vf.createStatement(geomFeature, Geometrie.POLYGONMEMBER, polygonMember);
            aboutGeometry.add(geoStatement);
            this.serializePolygon(gp, polygonMember, crs);
        }
    }

    protected void serializeMultiLineString(GeometryProperty gp, Resource geomFeature, String crs) {
        geoStatement = vf.createStatement(geomFeature, RDF.TYPE, Geometrie.MULTILINESTRING);
        aboutGeometry.add(geoStatement);
        this.setCrs(geomFeature, crs);
        int n = gp.getNumGeometries();
        for (int i = 0; i < n; i++) {
            BNode lineStringMember = vf.createBNode();
            geoStatement = vf.createStatement(geomFeature, Geometrie.LINESTRINGMEMBER, lineStringMember);
            aboutGeometry.add(geoStatement);
            this.serializeLineString(gp, lineStringMember, crs, i);
        }
    }

    protected void serializeMultiPoint(GeometryProperty gp, Resource geomFeature, String crs) {
        geoStatement = vf.createStatement(geomFeature, RDF.TYPE, Geometrie.MULTIPOINT);
        aboutGeometry.add(geoStatement);
        this.setCrs(geomFeature, crs);
        int n = gp.getNumGeometries();
        for (int i = 0; i < n; i++) {
            BNode pointMember = vf.createBNode();
            geoStatement = vf.createStatement(geomFeature, Geometrie.POINTMEMBER, pointMember);
            aboutGeometry.add(geoStatement);
            this.serializePoint(gp, pointMember, crs, i);
        }
    }

    protected void serializePolygon(GeometryProperty gp, Resource geomFeature, String crs) {
        int indexPointList = 0;
        geoStatement = vf.createStatement(geomFeature, RDF.TYPE, Geometrie.POLYGON);
        aboutGeometry.add(geoStatement);
        this.setCrs(geomFeature, crs);
        BNode exterior = vf.createBNode();
        geoStatement = vf.createStatement(geomFeature, Geometrie.EXTERIOR, exterior);
        aboutGeometry.add(geoStatement);
        this.serializeLineString(gp, exterior, crs, indexPointList);
        int n = gp.getNumInteriorRing();
        for (int i = 0; i < n; i++) {
            indexPointList++;
            BNode interiorMember = vf.createBNode();
            geoStatement = vf.createStatement(geomFeature, Geometrie.INTERIOR, interiorMember);
            aboutGeometry.add(geoStatement);
            this.serializeLineString(gp, interiorMember, crs, indexPointList);
        }
    }

    protected void serializeLineString(GeometryProperty gp, Resource geomFeature, String crs, int indexPointList) {
        if (gp.getIsRing(indexPointList)) {
            geoStatement = vf.createStatement(geomFeature, RDF.TYPE, Geometrie.LINEARRING);
            aboutGeometry.add(geoStatement);
            this.setCrs(geomFeature, crs);
        } else {
            // carry out the Line case (when numPoints = 2)
            if (gp.getNumPoint(indexPointList) == 2) {
                geoStatement = vf.createStatement(geomFeature, RDF.TYPE, Geometrie.LINE);
                aboutGeometry.add(geoStatement);
                this.setCrs(geomFeature, crs);
            } else {
                geoStatement = vf.createStatement(geomFeature, RDF.TYPE, Geometrie.LINESTRING);
                aboutGeometry.add(geoStatement);
                this.setCrs(geomFeature, crs);
            }
        }
        ////// Add  the line Case

        BNode points = vf.createBNode();
        geoStatement = vf.createStatement(geomFeature, Geometrie.POINTS, points);
        aboutGeometry.add(geoStatement);
        this.serializePointsList(gp, points, crs, indexPointList);
    }

    protected void serializePointsList(GeometryProperty gp, Resource geomFeature, String crs, int indexPointList) {
        int n = gp.getNumPoint(indexPointList);
        int indexPoint = getCurrentIndexPoint(gp, indexPointList);
        boolean ring = gp.getIsRing(indexPointList);
        Resource firstPoint = null;
        // In the case of LinearRing the first point and the last point is the same
        if (ring)
            n = n - 1;
        for (int i = 0; i < n; i++) {
            geoStatement = vf.createStatement(geomFeature, RDF.TYPE, Geometrie.POINTSLIST);
            aboutGeometry.add(geoStatement);
            this.setCrs(geomFeature, crs);
            BNode first = vf.createBNode();
            if (!ring) {
                geoStatement = vf.createStatement(geomFeature, RDF.FIRST, first);
            } else {
                geoStatement = vf.createStatement(geomFeature, Geometrie.FIRSTANDLAST, first);
                firstPoint = geomFeature;
                ring = false;
            }
            aboutGeometry.add(geoStatement);
            this.setCrs(geomFeature, crs);
            this.serializePoint(gp, first, crs, i + indexPoint);
            if (i == n - 1) {
                if (gp.getIsRing(indexPointList)) {
                    geoStatement = vf.createStatement(geomFeature, RDF.REST, firstPoint);
                } else {
                    geoStatement = vf.createStatement(geomFeature, RDF.REST, RDF.NIL);
                }
                aboutGeometry.add(geoStatement);
            } else {
                BNode rest = vf.createBNode();
                geoStatement = vf.createStatement(geomFeature, RDF.REST, rest);
                aboutGeometry.add(geoStatement);
                geomFeature = rest;
            }
        }
    }

    protected void serializePoint(GeometryProperty gp, Resource geomFeature, String crs, int indexPoint) {
        Double[] point = gp.getPoint(indexPoint);
        geoStatement = vf.createStatement(geomFeature, RDF.TYPE, Geometrie.POINT);
        aboutGeometry.add(geoStatement);
        this.setCrs(geomFeature, crs);
        geoStatement = vf.createStatement(geomFeature, Geometrie.COORDX, vf.createLiteral(point[0]));
        aboutGeometry.add(geoStatement);
        geoStatement = vf.createStatement(geomFeature, Geometrie.COORDY, vf.createLiteral(point[1]));
        aboutGeometry.add(geoStatement);

    }

    protected int getCurrentIndexPoint(GeometryProperty gp, int currentIndexPoint) {
        int indexPoint = 0;
        for (int i = 0; i < currentIndexPoint; i++) {
            indexPoint = indexPoint + gp.getNumPoint(i);
        }
        return indexPoint;
    }

    protected void setCrs(Resource geomFeature, String crs) {
        if (crs != null) {
            geoStatement = vf.createStatement(geomFeature, Geometrie.SYSTCOORD, CRS.IGNFCRS);
            aboutGeometry.add(geoStatement);
        }
    }

    /**
     * @param args
     * @throws ParserConfigurationException 
     * @throws SAXException 
     * @throws IOException 
     * @throws RepositoryException 
     * @throws ParseException 
     * @throws RDFHandlerException 
     * @throws RDFParseException 
     */
    public static void main(String[] args) throws IOException, SAXException, ParserConfigurationException,
            RepositoryException, RDFParseException, RDFHandlerException, ParseException {
        // TODO Auto-generated method stub

        RDFBuilder builder = new RDFBuilder();
        URI context = builder.getVf().createURI("http://data.ign.fr/id/geofla");

        // Convert Region
        String shpPathRegion = ".//input/DonneesGeoflaWGS84/region.shp";
        Features_Parser parserRegion = new Features_Parser();
        //parserRegion.parseSHP(shpPathRegion, true, "EPSG:4326");
        parserRegion.parseSHP(shpPathRegion, false, "");
        String nameRegion = "region";
        //String crsRegion = parserRegion.crs;
        String crsRegion = "EPSG:4326";
        builder.translateToRDF(parserRegion.readFeatureCollection(), crsRegion, parserRegion.asGmlList, context,
                nameRegion, "http://data.ig.fr/ontology/geofla/", true, ".//output/regions.ttl");

        // Convert Departement
        String shpPathDepartement = ".//input/DonneesGeoflaWGS84/departement.shp";
        Features_Parser parserDepartement = new Features_Parser();
        //parserDepartement.parseSHP(shpPathDepartement, true, "EPSG:4326");
        parserDepartement.parseSHP(shpPathDepartement, false, "");
        String nameDepartement = "departement";
        //String crsDepartement = parserDepartement.crs;
        String crsDepartement = "EPSG:4326";
        builder.translateToRDF(parserDepartement.readFeatureCollection(), crsDepartement,
                parserDepartement.asGmlList, context, nameDepartement, "http://data.ig.fr/ontology/geofla/", true,
                ".//output/departements.ttl");

        // Convert Commune
        String shpPathCommune = ".//input/DonneesGeoflaWGS84/commune.shp";
        Features_Parser parserCommune = new Features_Parser();
        //parserCommune.parseSHP(shpPathCommune, true, "EPSG:4326");
        parserCommune.parseSHP(shpPathCommune, false, "");
        String nameCommune = "commune";
        //String crsCommune = parserCommune.crs;
        String crsCommune = "EPSG:4326";
        builder.translateToRDF(parserCommune.readFeatureCollection(), crsCommune, parserCommune.asGmlList, context,
                nameCommune, "http://data.ig.fr/ontology/geofla/", true, ".//output/communes.ttl");

        // Convert Canton
        String shpPathCanton = ".//input/DonneesGeoflaWGS84/canton.shp";
        Features_Parser parserCanton = new Features_Parser();
        //parserCanton.parseSHP(shpPathCanton, true, "EPSG:4326");
        parserCanton.parseSHP(shpPathCanton, false, "");
        String nameCanton = "canton";
        //String crsCanton = parserCanton.crs;
        String crsCanton = "EPSG:4326";
        builder.translateToRDF(parserCanton.readFeatureCollection(), crsCanton, parserCanton.asGmlList, context,
                nameCanton, "http://data.ig.fr/ontology/geofla/", true, ".//output/cantons.ttl");

        // Convert Arrondissement
        String shpPathArrondissement = ".//input/DonneesGeoflaWGS84/arrondissement.shp";
        Features_Parser parserArrondissement = new Features_Parser();
        //parserArrondissement.parseSHP(shpPathArrondissement, true, "EPSG:4326");
        parserArrondissement.parseSHP(shpPathArrondissement, false, "");
        String name = "arrondissement";
        //String crsArrondissement = parserArrondissement.crs;
        String crsArrondissement = "EPSG:4326";
        builder.translateToRDF(parserArrondissement.readFeatureCollection(), crsArrondissement,
                parserArrondissement.asGmlList, context, name, "http://data.ig.fr/ontology/geofla/", true,
                ".//output/arrondissements.ttl");
    }

}