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

org.integratedmodelling.engine.geospace.gis.GISOperations 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.gis;

import java.awt.image.RenderedImage;
import java.util.Iterator;
import java.util.function.Function;

import javax.media.jai.iterator.RandomIter;
import javax.media.jai.iterator.RandomIterFactory;

import org.geotools.coverage.grid.GridCoverage2D;
import org.integratedmodelling.api.modelling.IActiveDirectObservation;
import org.integratedmodelling.api.modelling.IDirectObservation;
import org.integratedmodelling.api.modelling.IObservableSemantics;
import org.integratedmodelling.api.modelling.IScale;
import org.integratedmodelling.api.modelling.IScale.Index;
import org.integratedmodelling.api.modelling.IState;
import org.integratedmodelling.api.modelling.ISubject;
import org.integratedmodelling.api.monitoring.IMonitor;
import org.integratedmodelling.api.runtime.IContext;
import org.integratedmodelling.api.runtime.ISession;
import org.integratedmodelling.api.runtime.ITask;
import org.integratedmodelling.api.runtime.ITask.Status;
import org.integratedmodelling.common.configuration.KLAB;
import org.integratedmodelling.common.space.SpaceLocator;
import org.integratedmodelling.common.states.State;
import org.integratedmodelling.common.states.States;
import org.integratedmodelling.common.time.TimeLocator;
import org.integratedmodelling.common.vocabulary.NS;
import org.integratedmodelling.engine.geospace.coverage.raster.RasterCoverage;
import org.integratedmodelling.engine.geospace.extents.Grid;
import org.integratedmodelling.engine.geospace.extents.SpaceExtent;
import org.integratedmodelling.exceptions.KlabException;
import org.integratedmodelling.exceptions.KlabUnsupportedOperationException;
import org.integratedmodelling.exceptions.KlabValidationException;
import org.jgrasstools.gears.libs.monitor.IJGTProgressMonitor;

import es.unex.sextante.core.ITaskMonitor;
import es.unex.sextante.dataObjects.IRasterLayer;
import es.unex.sextante.geotools.GTRasterLayer;

public class GISOperations {

    public final static String  INFO_CLASS                 = "GIS_PROCESS";
    private static final double BASIN_IMPORTANCE_THRESHOLD = 0.05;
    private static final int    WATERSHEDS_TO_EXTRACT      = 1;

    public static class TaskMonitor implements IMonitor, ITaskMonitor, IJGTProgressMonitor {

        IMonitor       _monitor;
        private String _name;

        public TaskMonitor(IMonitor monitor) {
            _monitor = monitor;
        }
        @Override
        public boolean isCanceled() {
            return _monitor.getTask().getStatus() == Status.INTERRUPTED;
        }

        // JGT methods
        @Override
        public void beginTask(String name, int totalWork) {
            _name = name;
            // _monitor.defineProgressSteps(totalWork);
            // _monitor.info("beginning " + name, INFO_CLASS);
        }

        @Override
        public void message(String message) {
            // _monitor.info(message, INFO_CLASS);
        }

        @Override
        public void errorMessage(String message) {
            _monitor.error(message);
        }

        @Override
        public void done() {
            // _monitor.info("finished " + _name, INFO_CLASS);
        }

        @Override
        public void internalWorked(double work) {
            // TODO Auto-generated method stub

        }

        @Override
        public void setCanceled(boolean value) {
            if (value) {
                // _monitor.stop(null);
            }
        }

        @Override
        public void setTaskName(String name) {
            _name = name;
        }

        @Override
        public void subTask(String name) {
        }

        @Override
        public void worked(int work) {
            // _monitor.addProgress(work, "");
        }

        @Override
        public  T adapt(Class adaptee) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public void exceptionThrown(String message) {
            _monitor.error(message);
        }

        @Override
        public void onModuleExit() {
            // TODO Auto-generated method stub

        }

        @Override
        public void info(Object info, String infoClass) {
            // TODO Auto-generated method stub

        }

        @Override
        public void warn(Object o) {
            // TODO Auto-generated method stub

        }

        @Override
        public void error(Object o) {
            // TODO Auto-generated method stub

        }

        @Override
        public void debug(Object o) {
            // TODO Auto-generated method stub

        }

        @Override
        public ITask getTask() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ISession getSession() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public void close() {
            // TODO Auto-generated method stub

        }

        @Override
        public void setDescriptionPrefix(String arg0) {
            // TODO Auto-generated method stub

        }

        @Override
        public void setDeterminate(boolean arg0) {
            // TODO Auto-generated method stub

        }

        @Override
        public void setProcessDescription(String arg0) {
            // TODO Auto-generated method stub

        }

        @Override
        public void setProgress(int arg0) {
            // TODO Auto-generated method stub

        }

        @Override
        public void setProgress(int arg0, int arg1) {
            // TODO Auto-generated method stub

        }

        @Override
        public void setProgressText(String arg0) {
            // TODO Auto-generated method stub

        }

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

        @Override
        public IContext getContext() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public void send(Object o) {
            // TODO Auto-generated method stub

        }
    }

    public static IRasterLayer stateToRaster(IState state) throws KlabException {

        GTRasterLayer ret = null;
        RasterCoverage coverage = new RasterCoverage(state);
        ret = new GTRasterLayer();
        ret.create(coverage.getCoverage());
        return ret;
    }

    /**
     * Turn a Thinklab state into a Geotools GridCoverage2D.
     * 
     * @param state
     * @return coverage
     * @throws KlabException
     */
    public static GridCoverage2D stateToCoverage(IState state) throws KlabException {
        RasterCoverage coverage = new RasterCoverage(state);
        return coverage.getCoverage();
    }

    /**
     * Turn a Thinklab state into a Geotools GridCoverage2D.
     * 
     * @param state
     * @return coverage
     * @throws KlabException
     */
    public static GridCoverage2D stateToCoverage(IState state, Iterable locators)
            throws KlabException {
        RasterCoverage coverage = new RasterCoverage(state, locators);
        return coverage.getCoverage();
    }
    
    /**
     * Aggregate a dynamic k.LAB state into a Geotools GridCoverage2D.
     * 
     * @param state
     * @return coverage
     * @throws KlabException
     */
    public static GridCoverage2D aggregateStateToCoverage(IState state)
            throws KlabException {
        
        if (!(state.getScale().isSpatiallyDistributed() && state.getScale().isSpatiallyDistributed())) {
            throw new KlabUnsupportedOperationException("wrong call: cannot aggregate a non-temporal spatial state with this call");
        }

        int tslices = (int)state.getScale().getTime().getMultiplicity() /* FIXME as usual */ - 3;
        double[] buffer = new double[(int)state.getScale().getSpace().getMultiplicity()];

        for (int i = 0; i < tslices; i++) {

            Index index = state.getScale().getIndex(TimeLocator.get(i), SpaceLocator.all());
            int so = 0;
            for (Iterator it = state.iterator(index); it.hasNext();) {

                Object vs = it.next();
                if (vs == null) {
                    vs = Double.NaN;
                }
                if (vs instanceof Number) {
                    if (Double.isNaN(((Number)vs).doubleValue()) || Double.isNaN(buffer[so])) {
                        buffer[so] = Double.NaN;
                    } else {
                        buffer[so] +=((Number)vs).doubleValue();
                    }
                }
                so++;
            }
        }
        
        /*
         * average unless this is an accumulating stock
         */
        if (!state.getObservable().getSemantics().is(KLAB.c(NS.CORE_EXTENSIVE_PHYSICAL_PROPERTY))) {
            for (int i = 0; i < buffer.length; i++) {
                buffer[i] /= tslices;
            }
        }
        
        return new RasterCoverage("aggregated", (Grid) state.getSpace().getGrid(), buffer).getCoverage();
        
    }

    public static IState rasterToState(IRasterLayer layer, IObservableSemantics observable, ISubject context)
            throws KlabException {

        GTRasterLayer l = (GTRasterLayer) layer;
        SpaceExtent ext = (SpaceExtent) context.getScale().getSpace();

        if (ext.getGrid() == null) {
            throw new KlabValidationException("cannot return a raster layer from a non-grid extent");
        }

        Grid grid = ext.getGrid();
        double[] data = new double[grid.getCellCount()];

        for (int i = 0; i < grid.getCellCount(); i++) {
            int[] xy = grid.getXYOffsets(i);
            data[i] = l.getCellValueAsDouble(xy[0], xy[1]);
        }

        // FIXME see what to do with dynamic state - depends on semantics
        return new State(data, observable, context, false, false);
    }

    public static int countNodata(GridCoverage2D layer, IDirectObservation context) throws KlabException {

        SpaceExtent ext = (SpaceExtent) context.getScale().getSpace();
        if (ext.getGrid() == null) {
            throw new KlabValidationException("cannot return a raster layer from a non-grid extent");
        }

        Grid grid = ext.getGrid();
        RenderedImage image = layer.getRenderedImage();
        RandomIter itera = RandomIterFactory.create(image, null);

        int nodata = 0;
        for (int i = 0; i < grid.getCellCount(); i++) {
            int[] xy = grid.getXYOffsets(i);
            double d = itera.getSampleDouble(xy[0], xy[1], 0);
            if (Double.isNaN(d)) {
            	nodata ++;
            }
        }

        return nodata;
    }
    
    /**
     * Get a static state built from the passed layer.
     * 
     * @param layer
     * @param observable
     * @param context
     * @param label
     * @return state
     * @throws KlabException
     */
    public static IState coverageToState(GridCoverage2D layer, IObservableSemantics observable, IActiveDirectObservation context, String label)
            throws KlabException {
    	return coverageToState(layer, observable, context, label, null);
    }
    
    /**
     * Get a static state built from the passed layer. Do not add to a context.
     * 
     * @param layer
     * @param observable
     * @param context
     * @param label
     * @return state
     * @throws KlabException
     */
    public static IState coverageToState(GridCoverage2D layer, IObservableSemantics observable, IContext context, String label, Function transformation )
            throws KlabException {

        SpaceExtent ext = (SpaceExtent) context.getSubject().getScale().getSpace();
        if (ext.getGrid() == null) {
            throw new KlabValidationException("cannot return a raster layer from a non-grid extent");
        }

        Grid grid = ext.getGrid();
        RenderedImage image = layer.getRenderedImage();
        RandomIter itera = RandomIterFactory.create(image, null);

        IState ret = States.createStatic(observable, context.getSubject().getScale(), context);
        
        for (int i = 0; i < grid.getCellCount(); i++) {
            int[] xy = grid.getXYOffsets(i);
            double value = itera.getSampleDouble(xy[0], xy[1], 0);
            States.set(ret, transformation == null ? value : transformation.apply(value), i);
        }

        ret.getMetadata().put(NS.DISPLAY_LABEL_PROPERTY, label);

        return ret;
    }
    
    /**
     * Get a static state built from the passed layer.
     * 
     * @param layer
     * @param observable
     * @param context
     * @param label
     * @return state
     * @throws KlabException
     */
    public static IState coverageToState(GridCoverage2D layer, IObservableSemantics observable, IActiveDirectObservation context, String label, Function transformation )
            throws KlabException {

        SpaceExtent ext = (SpaceExtent) context.getScale().getSpace();
        if (ext.getGrid() == null) {
            throw new KlabValidationException("cannot return a raster layer from a non-grid extent");
        }

        Grid grid = ext.getGrid();
        RenderedImage image = layer.getRenderedImage();
        RandomIter itera = RandomIterFactory.create(image, null);

        IState ret = context.getStaticState(observable);
        
        for (int i = 0; i < grid.getCellCount(); i++) {
            int[] xy = grid.getXYOffsets(i);
            double value = itera.getSampleDouble(xy[0], xy[1], 0);
            States.set(ret, transformation == null ? value : transformation.apply(value), i);
        }

        ret.getMetadata().put(NS.DISPLAY_LABEL_PROPERTY, label);

        return ret;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy