/* This program is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) 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
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package org.opentripplanner.analyst.batch;
import java.io.File;
import lombok.Setter;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.Query;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.referencing.CRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
public class ShapefilePopulation extends BasicPopulation {
private static final Logger LOG = LoggerFactory.getLogger(ShapefilePopulation.class);
@Setter String labelAttribute;
@Setter String inputAttribute;
@Override
public void createIndividuals() {
String filename = this.sourceFilename;
LOG.debug("Loading population from shapefile {}", filename);
LOG.debug("Feature attributes: input data in {}, labeled with {}", inputAttribute, labelAttribute);
try {
File file = new File(filename);
if ( ! file.exists())
throw new RuntimeException("Shapefile does not exist.");
FileDataStore store = FileDataStoreFinder.getDataStore(file);
SimpleFeatureSource featureSource = store.getFeatureSource();
CoordinateReferenceSystem sourceCRS = featureSource.getInfo().getCRS();
CoordinateReferenceSystem WGS84 = CRS.decode("EPSG:4326", true);
Query query = new Query();
query.setCoordinateSystem(sourceCRS);
query.setCoordinateSystemReproject(WGS84);
SimpleFeatureCollection featureCollection = featureSource.getFeatures(query);
SimpleFeatureIterator it = featureCollection.features();
int i = 0;
while (it.hasNext()) {
SimpleFeature feature = it.next();
Geometry geom = (Geometry) feature.getDefaultGeometry();
Point point = null;
if (geom instanceof Point) {
point = (Point) geom;
} else if (geom instanceof Polygon) {
point = ((Polygon) geom).getCentroid();
} else if (geom instanceof MultiPolygon) {
point = ((MultiPolygon) geom).getCentroid();
} else {
throw new RuntimeException("Shapefile must contain either points or polygons.");
}
String label;
if (labelAttribute == null) {
label = Integer.toString(i);
} else {
label = feature.getAttribute(labelAttribute).toString();
}
double input = 0.0;
if (inputAttribute != null) {
Number n = (Number) feature.getAttribute(inputAttribute);
input = n.doubleValue();
}
Individual individual = new Individual(label, point.getX(), point.getY(), input);
this.addIndividual(individual);
i += 1;
}
LOG.debug("loaded {} features", i);
it.close();
} catch (Exception ex) {
LOG.error("Error loading population from shapefile: {}", ex.getMessage());
throw new RuntimeException(ex);
}
LOG.debug("Done loading shapefile.");
}
}