org.integratedmodelling.engine.geospace.coverage.vector.VectorCoverage 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.coverage.vector;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.geotools.data.DataStore;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.feature.FeatureIterator;
import org.integratedmodelling.common.beans.ObservationData;
import org.integratedmodelling.common.configuration.KLAB;
import org.integratedmodelling.engine.geospace.Geospace;
import org.integratedmodelling.engine.geospace.coverage.CoverageFactory;
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.referencing.crs.CoordinateReferenceSystem;
import com.vividsolutions.jts.geom.Geometry;
public class VectorCoverage extends AbstractVectorCoverage {
DataStore store = null;
public VectorCoverage(URL url, String layerName, String valueField, String filter)
throws KlabException {
super(url, layerName, valueField, filter, null);
}
/**
* Use this to create features by adding direct observations:
*
* VectorCoverage coverage = new VectorCoverage("observations");
* for (ISubject s : ....) {
* coverage.add(s);
* }
* coverage.write(new File("observations.shp"));
*
*
* @param layername
*/
public VectorCoverage(String layername) {
}
/**
* Utility function: reads a file (shapefile only for now) into a list of maps where each map
* describes a feature. The "the_geom" field will be the ShapeValue corresponding to the
* geometry, and everything else is attributes with their original type.
*
* @param file
* @return features
*/
public static List readFeatures(File file) throws KlabException {
ArrayList ret = new ArrayList<>();
VectorCoverage coverage = CoverageFactory.readVector(file, "", null, null);
String[] attributes = coverage.getAttributeNames();
// TODO for another time
Double simplify = null;
CoordinateReferenceSystem crs = coverage.getCoordinateReferenceSystem();
if (crs == null) {
/*
* TODO this really needs a monitor
*/
KLAB.warn("cannot establish projection for source " + file + ": assuming EPSG:4326");
crs = Geospace.get().getDefaultCRS();
}
FeatureIterator fi = null;
try {
fi = coverage.getFeatureIterator(null, attributes);
int feature_index = 0;
while (fi.hasNext()) {
feature_index++;
SimpleFeature f = fi.next();
Geometry geometry = (Geometry) f.getDefaultGeometry();
ShapeValue shape = new ShapeValue(geometry, crs);
/*
* simplify if so requested, using values in original units.
*/
if (simplify != null)
shape.simplify(simplify);
ObservationData fields = new ObservationData();
/*
* TODO may also want to pass a projection and only transform if requested
* TODO passing WKT instead of WKB because we will normally want to display this.
*/
fields.setGeometryWKB(shape.transform(Geospace.get().getDefaultCRS()).toString());
fields.setName(f.getID().toString());
for (int i = 0; i < attributes.length; i++) {
/*
* skip the monster geometry. FIXME this should use the
* "endorsed" name from the schema, although it's always
* the_geom for now.
*/
if (!attributes[i].equals("the_geom")) {
Object attv = f.getAttribute(attributes[i]);
if (attv != null) {
fields.getAttributes().put(attributes[i], f.getAttribute(attributes[i]));
}
}
}
ret.add(fields);
}
} finally {
if (fi != null) {
fi.close();
}
}
return ret;
}
@Override
protected DataStore getDataStore() throws KlabException {
if (store == null) {
try {
store = new ShapefileDataStore(new URL(sourceUrl));
} catch (MalformedURLException e) {
throw new KlabValidationException(e);
}
}
return store;
}
@Override
protected void setDataStore(DataStore store) {
this.store = store;
}
}