package org.openlca.geo.parameter;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.geotools.data.DataStore;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.io.Files;
import com.google.gson.Gson;
/**
* A folder where shapefiles are stored.
*/
public class ShapeFileFolder {
private Logger log = LoggerFactory.getLogger(getClass());
public final File folder;
public ShapeFileFolder(File folder) {
log.trace("init shapefile repository @ {}", folder);
this.folder = folder;
if (!folder.exists())
folder.mkdirs();
}
/**
* Get the names (without file extension) of all shapefiles in this
* repository.
*/
public List<String> getShapeFiles() {
List<String> names = new ArrayList<>();
for (File file : folder.listFiles()) {
if (!ShapeFileUtils.hasValidExtension(file))
continue;
String name = ShapeFileUtils.getName(file);
if (!names.contains(name))
names.add(name);
}
return names;
}
/**
* Imports the given shape-file and the associated files into the folder.
*/
public String importFile(File shapeFile) {
String shapeFileName = ShapeFileUtils.getName(shapeFile);
try {
List<File> importFiles = ShapeFileUtils.getAllFiles(shapeFile);
for (File importFile : importFiles) {
File file = new File(folder, importFile.getName());
Files.copy(importFile, file);
}
// initialize the parameter file
getParameters(shapeFileName);
return shapeFileName;
} catch (Exception e) {
log.error("failed to import shapefile " + shapeFile, e);
return shapeFileName;
}
}
public DataStore openDataStore(String shapeFile) {
try {
File file = new File(folder, shapeFile + ".shp");
log.trace("open shape-file {}", file);
return new ShapefileDataStore(file.toURI().toURL());
} catch (Exception e) {
log.error("Failed to open shape-file", e);
return null;
}
}
public List<ShapeFileParameter> getParameters(String shapeFile) {
File paramFile = new File(folder, shapeFile + ".gisolca");
if (paramFile.exists())
return readParameterFile(paramFile);
else {
log.trace("create parameter file {}", paramFile);
DataStore store = openDataStore(shapeFile);
List<ShapeFileParameter> params = readParameters(store);
writeParameterFile(shapeFile, params);
store.dispose();
return params;
}
}
private List<ShapeFileParameter> readParameterFile(File paramFile) {
log.trace("read parameter file {}", paramFile);
try (FileInputStream is = new FileInputStream(paramFile);
InputStreamReader reader = new InputStreamReader(is, "utf-8");
BufferedReader buffer = new BufferedReader(reader)) {
Gson gson = new Gson();
ShapeFileParameter[] params = gson.fromJson(buffer,
ShapeFileParameter[].class);
return Arrays.asList(params);
} catch (Exception e) {
log.error("failed to read paramater file " + paramFile, e);
return Collections.emptyList();
}
}
private void writeParameterFile(String shapeFile,
List<ShapeFileParameter> parameters) {
File paramFile = new File(folder, shapeFile + ".gisolca");
try (FileOutputStream os = new FileOutputStream(paramFile);
OutputStreamWriter writer = new OutputStreamWriter(os, "utf-8");
BufferedWriter buffer = new BufferedWriter(writer)) {
Gson gson = new Gson();
gson.toJson(parameters, buffer);
} catch (Exception e) {
log.error("failed to write paramater file " + shapeFile, e);
}
}
private List<ShapeFileParameter> readParameters(DataStore dataStore) {
if (dataStore == null)
return Collections.emptyList();
try {
Map<String, ShapeFileParameter> params = new HashMap<>();
String typeName = dataStore.getTypeNames()[0];
SimpleFeatureCollection source = dataStore.getFeatureSource(
typeName).getFeatures();
SimpleFeatureIterator it = source.features();
while (it.hasNext()) {
SimpleFeature feature = it.next();
readParameters(params, feature);
}
it.close();
List<ShapeFileParameter> list = new ArrayList<>();
list.addAll(params.values());
return list;
} catch (Exception e) {
log.error("failed to get parameters from shape file", e);
return Collections.emptyList();
}
}
private static void readParameters(Map<String, ShapeFileParameter> params,
SimpleFeature feature) {
for (Property property : feature.getProperties()) {
if (!(property.getValue() instanceof Number))
continue;
if (property.getName() == null)
continue;
String name = property.getName().toString();
double value = ((Number) property.getValue()).doubleValue();
ShapeFileParameter param = params.get(name);
if (param == null) {
param = new ShapeFileParameter();
param.name = name;
param.max = value;
param.min = value;
params.put(name, param);
} else {
param.max = Math.max(param.max, value);
param.min = Math.min(param.min, value);
}
}
}
}