package org.openlca.app.editors.lcia_methods;
import org.openlca.app.M;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.openlca.app.db.Database;
import org.openlca.app.editors.processes.kml.KmlUtil;
import org.openlca.core.database.LocationDao;
import org.openlca.core.database.ParameterDao;
import org.openlca.core.model.ImpactMethod;
import org.openlca.core.model.Parameter;
import org.openlca.core.model.descriptors.LocationDescriptor;
import org.openlca.geo.kml.KmlFeature;
import org.openlca.geo.parameter.ParameterCache;
import org.openlca.geo.parameter.ParameterCalculator;
import org.openlca.geo.parameter.ShapeFileFolder;
import org.python.google.common.base.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class EvaluateLocationsJob implements IRunnableWithProgress {
private Logger log = LoggerFactory.getLogger(getClass());
private ImpactMethod method;
private ShapeFileFolder shapeFileFolder;
private ParameterCache parameterCache;
private ParameterCalculator parameterCalculator;
private LocationDao locationDao;
private IProgressMonitor monitor;
private List<String> shapeFiles;
public EvaluateLocationsJob(ImpactMethod method) {
this.method = method;
}
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
this.monitor = monitor;
List<LocationDescriptor> locations = init();
beginTask(M.EvaluatingLocations, locations.size());
for (LocationDescriptor location : locations)
if (!isCanceled())
evaluate(location);
done();
}
private List<LocationDescriptor> init() {
beginTask(M.Initializing);
shapeFileFolder = new ShapeFileFolder(ShapeFileUtils.getFolder(method));
shapeFiles = shapeFileFolder.getShapeFiles();
if (shapeFiles.size() == 0)
return Collections.emptyList();
parameterCache = new ParameterCache(shapeFileFolder);
List<Parameter> parameters = getShapeFileParameters();
if (parameters.size() == 0)
return Collections.emptyList();
parameterCalculator = new ParameterCalculator(parameters,
shapeFileFolder);
locationDao = new LocationDao(Database.get());
return locationDao.getDescriptors();
}
private void evaluate(LocationDescriptor location) {
subTask(location.getName());
for (String shapeFile : ShapeFileUtils.getShapeFiles(method))
parameterCache.remove(location.getId(), shapeFile);
KmlFeature feature = getKmlFeature(location);
if (feature != null)
parameterCalculator.calculate(location.getId(), feature);
worked();
}
private List<Parameter> getShapeFileParameters() {
if (method == null)
return Collections.emptyList();
long methodId = method.getId();
String query = "select m.parameters from ImpactMethod m where " + "m.id = :methodId";
ParameterDao dao = new ParameterDao(Database.get());
List<Parameter> allParams = dao.getAll(query, Collections.singletonMap("methodId", methodId));
List<Parameter> shapeFileParams = new ArrayList<>();
for (Parameter param : allParams) {
if (param == null)
continue;
if (param.getExternalSource() == null)
continue;
if (!"SHAPE_FILE".equals(param.getSourceType()))
continue;
shapeFileParams.add(param);
}
return shapeFileParams;
}
private KmlFeature getKmlFeature(LocationDescriptor location) {
byte[] kmz = locationDao.getForId(location.getId()).getKmz();
if (kmz == null)
return null;
String kml = KmlUtil.toKml(kmz);
if (Strings.isNullOrEmpty(kml))
return null;
try {
KmlFeature feature = KmlFeature.parse(kml);
return feature;
} catch (Exception e) {
log.warn("Could not parse kml data for location " + location.getName());
}
return null;
}
private void beginTask(String name) {
beginTask(name, IProgressMonitor.UNKNOWN);
}
private void beginTask(String name, int totalWork) {
if (totalWork == 0)
return;
if (monitor != null)
monitor.beginTask(name, totalWork);
}
private void worked() {
if (monitor != null)
monitor.worked(1);
}
private void subTask(String name) {
if (monitor != null)
monitor.subTask(name);
}
private void done() {
if (monitor != null)
monitor.done();
}
private boolean isCanceled() {
if (monitor == null)
return false;
return monitor.isCanceled();
}
}