package mil.nga.giat.geowave.format.landsat8;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.io.FileUtils;
import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFinder;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vividsolutions.jts.geom.MultiPolygon;
public class WRS2GeometryStore
{
private final static Logger LOGGER = LoggerFactory.getLogger(WRS2GeometryStore.class);
protected static class WRS2Key
{
private final int path;
private final int row;
public WRS2Key(
final int path,
final int row ) {
this.path = path;
this.row = row;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = (prime * result) + path;
result = (prime * result) + row;
return result;
}
@Override
public boolean equals(
final Object obj ) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final WRS2Key other = (WRS2Key) obj;
if (path != other.path) {
return false;
}
if (row != other.row) {
return false;
}
return true;
}
}
private static final String WRS2_TYPE_NAME = "wrs2_asc_desc";
private static final String WRS2_SHAPE_URL = "https://landsat.usgs.gov/sites/default/files/documents/wrs2_asc_desc.zip";
private static final String WRS2_SHAPE_NAME = "wrs2_asc_desc.shp";
private static final String WRS2_SHAPE_ZIP = "wrs2_asc_desc.zip";
private static final String WRS2_SHAPE_DIRECTORY = "wrs2_asc_desc";
private final File wrs2Shape;
private final File wrs2Directory;
private final Map<WRS2Key, MultiPolygon> featureCache = new HashMap<WRS2Key, MultiPolygon>();
private SimpleFeatureType wrs2Type;
public WRS2GeometryStore(
final String workspaceDirectory )
throws MalformedURLException,
IOException {
wrs2Directory = new File(
workspaceDirectory,
WRS2_SHAPE_DIRECTORY);
wrs2Shape = new File(
wrs2Directory,
WRS2_SHAPE_NAME);
init();
}
public SimpleFeatureType getType() {
return wrs2Type;
}
private void init()
throws MalformedURLException,
IOException {
if (!wrs2Shape.exists()) {
if (!wrs2Directory.delete()) {
LOGGER.warn("Unable to delete '" + wrs2Directory.getAbsolutePath() + "'");
}
final File wsDir = wrs2Directory.getParentFile();
if (!wsDir.exists() && !wsDir.mkdirs()) {
LOGGER.warn("Unable to create directory '" + wsDir.getAbsolutePath() + "'");
}
// download and unzip the shapefile
final File targetFile = new File(
wsDir,
WRS2_SHAPE_ZIP);
if (targetFile.exists()) {
if (!targetFile.delete()) {
LOGGER.warn("Unable to delete file '" + targetFile.getAbsolutePath() + "'");
}
}
FileUtils.copyURLToFile(
new URL(
WRS2_SHAPE_URL),
targetFile);
final ZipFile zipFile = new ZipFile(
targetFile);
try {
final Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
while (entries.hasMoreElements()) {
final ZipArchiveEntry entry = entries.nextElement();
if (!entry.isDirectory()) {
FileUtils.copyInputStreamToFile(
zipFile.getInputStream(entry),
new File(
wsDir,
entry.getName()));
}
}
}
finally {
zipFile.close();
}
}
// read the shapefile and cache the features for quick lookup by path
// and row
try {
final Map<String, Object> map = new HashMap<String, Object>();
map.put(
"url",
wrs2Shape.toURI().toURL());
final DataStore dataStore = DataStoreFinder.getDataStore(map);
if (dataStore == null) {
LOGGER.error("Unable to get a datastore instance, getDataStore returned null");
return;
}
final SimpleFeatureSource source = dataStore.getFeatureSource(WRS2_TYPE_NAME);
final SimpleFeatureCollection featureCollection = source.getFeatures();
wrs2Type = featureCollection.getSchema();
final SimpleFeatureIterator iterator = featureCollection.features();
while (iterator.hasNext()) {
final SimpleFeature feature = iterator.next();
final Number path = (Number) feature.getAttribute("PATH");
final Number row = (Number) feature.getAttribute("ROW");
featureCache.put(
new WRS2Key(
path.intValue(),
row.intValue()),
(MultiPolygon) feature.getDefaultGeometry());
}
}
catch (final IOException e) {
LOGGER.error(
"Unable to read wrs2_asc_desc shapefile '" + wrs2Shape.getAbsolutePath() + "'",
e);
throw (e);
}
}
public MultiPolygon getGeometry(
final int path,
final int row ) {
return featureCache.get(new WRS2Key(
path,
row));
}
}