org.integratedmodelling.engine.geospace.georss.GeoRSSCoverage Maven / Gradle / Ivy
/*******************************************************************************
* 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 void write(File f) throws KlabException {
// TODO Auto-generated method stub
}
@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 - 2025 Weber Informatics LLC | Privacy Policy