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

org.integratedmodelling.engine.geospace.georss.GeoRSSCoverage Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright (C) 2014, 2015:
 * 
 * - Ioannis N. Athanasiadis  - 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.georss;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.integratedmodelling.api.modelling.IObserver;
import org.integratedmodelling.api.monitoring.IMonitor;
import org.integratedmodelling.api.monitoring.Messages;
import org.integratedmodelling.engine.geospace.GeotoolsVectorCoverage;
import org.integratedmodelling.engine.geospace.coverage.ICoverage;
import org.integratedmodelling.engine.geospace.coverage.raster.RasterCoverage;
import org.integratedmodelling.engine.geospace.extents.Area;
import org.integratedmodelling.engine.geospace.extents.Grid;
import org.integratedmodelling.engine.geospace.gis.FeatureRasterizer;
import org.integratedmodelling.engine.geospace.literals.ShapeValue;
import org.integratedmodelling.exceptions.KlabException;
import org.integratedmodelling.exceptions.KlabValidationException;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.TransformException;

import com.rometools.modules.georss.GeoRSSModule;
import com.rometools.modules.georss.GeoRSSUtils;
import com.rometools.rome.feed.synd.SyndEntry;
import com.rometools.rome.feed.synd.SyndFeed;
import com.rometools.rome.io.SyndFeedInput;
import com.rometools.rome.io.XmlReader;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;

/**
 * 
 * @author Ioannis N. Athanasiadis 
 * @since 2014
 */
public class GeoRSSCoverage implements ICoverage, Iterable, GeotoolsVectorCoverage {

    private String                                              layerName = "no name";
    private SyndFeed                                            feed;
    private URL                                                 url;
    List                                            shapes    = new ArrayList();
    Envelope                                                    env       = new Envelope();
    private CoordinateReferenceSystem                           crs;
    private FeatureCollection features;
    private ReferencedEnvelope                                  renv;
	private AttributeDescriptor attributeDescriptor;

    public FeatureCollection getFeatures() {
        return features;
    }

    public List getShapes() {
        return shapes;
    }

    public GeoRSSCoverage(URL url) throws KlabException {
        this.crs = DefaultGeographicCRS.WGS84;
        this.url = url;
        SyndFeedInput input = new SyndFeedInput();
        try {
            feed = input.build(new XmlReader(url));
        } catch (Exception e) {
            throw new KlabException("Can't read GeoRSS feed from url" + url);
        }

        String title = feed.getTitle();
        if (title != null && !title.isEmpty())
            layerName = title;

        // parse all entries and save them as ShapeValues
        List entries = feed.getEntries();

        DefaultFeatureCollection fc = new DefaultFeatureCollection();
        SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(createFeatureType());
        
         attributeDescriptor = featureBuilder.getFeatureType().getAttributeDescriptors().get(0);

        
        for (SyndEntry entry : entries) {
            GeoRSSModule geo = GeoRSSUtils.getGeoRSS(entry);

            if (geo != null) {
                ShapeValue s = ShapeValueFactory.create(geo.getGeometry(), getCoordinateReferenceSystem());
                shapes.add(s);
                env.expandToInclude(s.getEnvelope());
                featureBuilder.add(s.getGeometry());
                SimpleFeature feat = featureBuilder.buildFeature(null); // we could use
                                                                        // item id
                fc.add(feat);
            }
        }
        features = fc;
        renv = new ReferencedEnvelope(env, crs);
    }

    @Override
    public Iterator iterator() {
        return shapes.iterator();
    }

    @Override
    public String getSourceUrl() {
        return url.toString();
    }

    @Override
    public String getCoordinateReferenceSystemCode() throws KlabException {
        return crs.toString();
    }

    @Override
    public CoordinateReferenceSystem getCoordinateReferenceSystem() {
        return crs;
    }

    @Override
    public String getLayerName() {
        return layerName;
    }

    @Override
    public Object write(File f) throws KlabException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public ReferencedEnvelope getEnvelope() {
        return renv;
    }

    @Override
    public ICoverage requireMatch(Area arealExtent, IObserver observer, IMonitor monitor, boolean allowClassChange)
            throws KlabException {

        if (arealExtent instanceof Grid && allowClassChange) {
            Grid grid = (Grid) arealExtent;
            if (monitor != null) {
                monitor.info("rasterizing " + layerName + "...", null);
            }

            String valueId = null; // "Location", or whatever feature to select. for
                                   // presence data the
                                   // rastersizer wors wioth null (what else?);
            String valueDefault = "0";
            FeatureRasterizer rasterizer = new FeatureRasterizer(grid, -1f, features.getSchema()
                    .getDescriptor(valueId), monitor);

            FeatureIterator iterator = features.features();

            ReferencedEnvelope dataEnvelope = null;
            try {
                dataEnvelope = grid.getEnvelope().transform(crs, true);
            } catch (TransformException | FactoryException e) {
                throw new KlabException(e);
            }

            GridCoverage2D coverage = rasterizer.rasterize(getLayerName()
                    + "_rasterized", iterator, valueId, observer, valueDefault, dataEnvelope, false);

            if (monitor != null) {
                monitor.info("rasterizing " + layerName + "... done!", Messages.INFOCLASS_MODEL);
            }

            return new RasterCoverage(layerName + "_rasterized", coverage);

        }

        throw new KlabException("Cannot change GeoRSS coverage type via require Match");
    }

    @Override
    public Object getSubdivisionValue(int subdivisionOrder, Area extent) throws KlabValidationException {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * A simple feature type for Feed Items. In principle this could include all possible
     * types of information in a feed. For the moment, it simply contains a Location
     * 
     * @return
     */
    private SimpleFeatureType createFeatureType() {

        SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
        builder.setName("RSS Feed");
        builder.setCRS(crs); // <- Coordinate reference system

        // add attributes in order
        builder.add("Location", Geometry.class);
        // builder.length(15).add("Name", String.class); // <- 15 chars width for name
        // field

        // build the type
        final SimpleFeatureType LOCATION = builder.buildFeatureType();

        return LOCATION;
    }


	@Override
	public AttributeDescriptor getAttributeDescriptor(String valueId) throws KlabException {
		return attributeDescriptor;
	}

	@Override
	public FeatureIterator getFeatureIterator(ReferencedEnvelope envelope, String... attributes)
			throws KlabException {
		return features.features();
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy