All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.integratedmodelling.engine.geospace.datasources.VectorCoverageDataSource Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright (C) 2007, 2015:
 * 
 * - Ferdinando Villa  - integratedmodelling.org - any
 * other authors listed in @author annotations
 *
 * All rights reserved. This file is part of the k.LAB software suite, meant to enable
 * modular, collaborative, integrated development of interoperable data and model
 * components. For details, see http://integratedmodelling.org.
 * 
 * This program is free software; you can redistribute it and/or modify it under the terms
 * of the Affero General Public License Version 3 or any later version.
 *
 * This program 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 Affero General Public License for more details.
 * 
 * You should have received a copy of the Affero General Public License along with this
 * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite
 * 330, Boston, MA 02111-1307, USA. The license is also available at:
 * https://www.gnu.org/licenses/agpl.html
 *******************************************************************************/
package org.integratedmodelling.engine.geospace.datasources;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.geotools.feature.FeatureIterator;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.integratedmodelling.api.metadata.IMetadata;
import org.integratedmodelling.api.modelling.IDataSource;
import org.integratedmodelling.api.modelling.IExtent;
import org.integratedmodelling.api.modelling.IObserver;
import org.integratedmodelling.api.modelling.IScale;
import org.integratedmodelling.api.modelling.contextualization.IDirectInstantiator;
import org.integratedmodelling.api.modelling.contextualization.IStateContextualizer;
import org.integratedmodelling.api.modelling.runtime.IActiveObjectSource;
import org.integratedmodelling.api.modelling.scheduling.ITransition;
import org.integratedmodelling.api.monitoring.IMonitor;
import org.integratedmodelling.base.HashableObject;
import org.integratedmodelling.common.interfaces.IReifiableObject;
import org.integratedmodelling.common.metadata.Metadata;
import org.integratedmodelling.common.vocabulary.NS;
import org.integratedmodelling.engine.geospace.Geospace;
import org.integratedmodelling.engine.geospace.coverage.ICoverage;
import org.integratedmodelling.engine.geospace.coverage.vector.AbstractVectorCoverage;
import org.integratedmodelling.engine.geospace.extents.Grid;
import org.integratedmodelling.engine.geospace.extents.SpaceExtent;
import org.integratedmodelling.engine.geospace.literals.ShapeValue;
import org.integratedmodelling.engine.modelling.runtime.ObjectSourceSubjectInstantiator;
import org.integratedmodelling.engine.modelling.runtime.Scale;
import org.integratedmodelling.exceptions.KlabException;
import org.integratedmodelling.exceptions.KlabRuntimeException;
import org.integratedmodelling.exceptions.KlabUnsupportedOperationException;
import org.opengis.feature.simple.SimpleFeature;

import com.vividsolutions.jts.geom.Geometry;

/**
 * FIXME MONITORABLE!
 * 
 * @author Ferdinando
 */
public abstract class VectorCoverageDataSource extends HashableObject implements IDataSource,
        IActiveObjectSource {

    protected ICoverage coverage          = null;
    IMetadata           metadata          = new Metadata();
    IMonitor            _monitor;
    protected String    _id;
    // if not passed as an init parameter, this will stay null and we use defaults that
    // depend on the projection.
    Boolean             invertCoordinates = null;
    protected int       _errors           = 0;

    class ShapeObject implements IReifiableObject {

        SimpleFeature _feature;
        ShapeValue    _shape;
        IScale        _scale;

        public ShapeObject(SimpleFeature feature) {
            _feature = feature;
            _shape = new ShapeValue((Geometry) _feature.getDefaultGeometry(), coverage
                    .getCoordinateReferenceSystem());
        }

        @Override
        public IScale getScale(IScale parent) {

            if (_scale == null) {

                SpaceExtent pspace = (SpaceExtent) parent.getSpace();
                try {
                    _shape = _shape.transform(pspace.getShape().getCRS());
                    _shape = pspace.getShape().intersection(_shape);
                    SpaceExtent space = new SpaceExtent(_shape);
                    _scale = new Scale(new IExtent[] { space });
                } catch (KlabException e) {
                    throw new KlabRuntimeException(e);
                }
            }

            return _scale;
        }

        @Override
        public Object getAttributeValue(String attribute, IObserver observer) {

            Object ret = _feature.getAttribute(attribute);
            if (ret == null) {
                ret = _feature.getAttribute(attribute.toLowerCase());
            }
            if (ret == null) {
                return null;
            }
            if (observer != null && NS.isNumericTransformation(observer)) {
                ret = Double.parseDouble(ret.toString());
            }

            return ret;
        }

        @Override
        public String getId() {
            return _feature.getID();
        }

    }

    /**
     * This must ensure that coverage contains a valid vector coverage.
     * 
     * @throws KlabException
     */
    protected abstract void initialize() throws KlabException;

    @Override
    public IStateContextualizer getContextualizer(IScale context, IObserver observer, IMonitor monitor)
            throws KlabException {

        initialize();

        SpaceExtent space = context.getSpace() instanceof SpaceExtent ? (SpaceExtent) (context.getSpace())
                : null;

        if (space != null && space.getGrid() != null) {

            ICoverage cov = coverage.requireMatch(space.getGrid(), observer, monitor, true);
            RegularRasterGridDataSource ds = new RegularRasterGridDataSource(cov, space.getGrid()) {

                IMetadata _metadata = new Metadata();

                @Override
                protected ICoverage readData() throws KlabException {
                    return this.coverage;
                }

                @Override
                protected Grid getFinalExtent(IScale context) throws KlabException {
                    return this.finalExtent;
                }

                @Override
                public IMetadata getMetadata() {
                    return _metadata;
                }

                @Override
                public boolean isAvailable() {
                    return true;
                }
            };

            return ds.getContextualizer(context, observer, monitor);

        } else {

            /*
             * TODO accessor for vectors - may need to do the monster conversion if the
             * context's shapes are different
             */
            throw new KlabUnsupportedOperationException("vector accessors not there yet, please be patient");
        }
    }

    @Override
    public IMetadata getMetadata() {
        return metadata;
    }

    @Override
    public IScale getCoverage() {

        Scale ret = new Scale();

        try {
            initialize();
        } catch (KlabException e) {
            if (_monitor != null && _errors == 0) {
                _monitor.error("vector data source " + _id + " is inaccessible");
                _errors++;
            }
            return ret;
        }

        if (coverage == null) {
            if (_monitor != null && _errors == 0) {
                _monitor.error("vector data source " + _id + " is inaccessible");
                _errors++;
            }
            throw new KlabRuntimeException("cannot read vector data source");
        }

        try {
            ShapeValue shape = new ShapeValue(coverage.getEnvelope());
            shape = shape.transform(Geospace.get().getDefaultCRS());
            shape = shape.expandIfPoint(0.001);
            ret.mergeExtent(new SpaceExtent(shape), true);
        } catch (KlabException e) {
            if (_monitor != null && _errors == 0) {
                _monitor.error("vector data source " + _id + " is inaccessible");
                _errors++;
            }
            throw new KlabRuntimeException(e);
        }

        return ret;
    }
    
    @Override
	public IDirectInstantiator getInstantiator() {

		return new ObjectSourceSubjectInstantiator() {

			@Override
			protected Collection getObjects(IScale scale, ITransition transition) {
				return VectorCoverageDataSource.this.getObjects(scale, transition);
			}
			
		};
	}

	@Override
	public boolean isAvailable() {
		// TODO Auto-generated method stub
		return false;
	}

	public List getObjects(IScale scale, ITransition transition) {

    	/*
    	 * for now I guess
    	 */
    	if (transition != ITransition.INITIALIZATION) {
    		return null;
    	}
    	
        IExtent space = scale.getSpace();
        if (!(space instanceof SpaceExtent)) {
            throw new KlabRuntimeException("cannot extract objects from a vector coverage in a non-spatial context");
        }

        ReferencedEnvelope env = ((SpaceExtent) space).getEnvelope();
        if (invertCoordinates != null && invertCoordinates) {
            env = new ReferencedEnvelope(env.getMinY(), env.getMaxY(), env.getMinX(), env.getMaxX(), env
                    .getCoordinateReferenceSystem());
        }
        ArrayList ret = new ArrayList();

        FeatureIterator fit = null;
        try {
            initialize();
            fit = ((AbstractVectorCoverage) coverage).getFeatureIterator(env);
            while (fit.hasNext()) {
                ret.add(new ShapeObject(fit.next()));
            }

        } catch (KlabException e) {
            throw new KlabRuntimeException(e);
        } finally {
            if (fit != null) {
                fit.close();
            }
        }

        return ret;
    }

    /**
     * Extract the first shape as a shape value.
     * 
     * @return first shape
     * @throws KlabException
     */
    public ShapeValue extractFirst() throws KlabException {

        FeatureIterator fit = null;
        SimpleFeature feature = null;
        try {
            initialize();
            fit = ((AbstractVectorCoverage) coverage).getFeatureIterator(null);
            if (fit.hasNext()) {
                feature = fit.next();
            }
        } finally {
            if (fit != null) {
                fit.close();
            }
        }

        return new ShapeValue((Geometry) feature.getDefaultGeometry(), coverage
                .getCoordinateReferenceSystem());
    }

    @Override
    public IStateContextualizer getContextualizer(String attribute, IObserver observer, IScale context, IMonitor monitor)
            throws KlabException {

        /*
         * if observer is presence, return rasterizing accessor with no attribute
         */

        /*
         * else must find attribute with compatible observer and rasterize it, with
         * mediation if necessary.
         */
        // TODO Auto-generated method stub
        return null;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy