/*******************************************************************************
* Copyright (c) 2014 Open Door Logistics (www.opendoorlogistics.com)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License 3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl.html
*
******************************************************************************/
package com.opendoorlogistics.core.scripts.formulae;
import java.util.ArrayList;
import com.opendoorlogistics.api.ExecutionReport;
import com.opendoorlogistics.api.geometry.ODLGeom;
import com.opendoorlogistics.api.tables.ODLColumnType;
import com.opendoorlogistics.api.tables.ODLTableReadOnly;
import com.opendoorlogistics.core.formulae.Function;
import com.opendoorlogistics.core.formulae.FunctionFactory;
import com.opendoorlogistics.core.formulae.FunctionParameters;
import com.opendoorlogistics.core.formulae.Functions;
import com.opendoorlogistics.core.formulae.definitions.FunctionDefinition;
import com.opendoorlogistics.core.formulae.definitions.FunctionDefinition.ArgumentType;
import com.opendoorlogistics.core.geometry.operations.GeomUnion;
import com.opendoorlogistics.core.scripts.execution.adapters.FunctionsBuilder;
import com.opendoorlogistics.core.scripts.execution.adapters.FunctionsBuilder.ProcessedLookupReferences;
import com.opendoorlogistics.core.scripts.execution.adapters.FunctionsBuilder.ToProcessLookupReferences;
import com.opendoorlogistics.core.scripts.execution.adapters.IndexedDatastores;
import com.opendoorlogistics.core.tables.ColumnValueProcessor;
/**
* Function lookupgeomunion does a lookup of objects in another table based on the key field and unions them
*
* @author Phil
*
*/
public class FmLookupGeomUnion extends FmAbstractLookup {
public static FunctionDefinition createDefinition(final IndexedDatastores<? extends ODLTableReadOnly> datastores, final int defaultDatastoreIndex, final ExecutionReport result) {
final String keyword = "lookupGeomUnion";
final FunctionDefinition dfn = new FunctionDefinition(keyword);
dfn.setDescription("Perform a geometry union of the polygon geometries in the foreign table.");
dfn.addArg("search_value", ArgumentType.GENERAL, "Value to search for in the other table.");
dfn.addArg("foreign_table", ArgumentType.TABLE_REFERENCE_CONSTANT, "Reference to the foreign table to search in.");
dfn.addArg("search_field", ArgumentType.STRING_CONSTANT, "Name of the foreign table's field to search for the value in.");
dfn.addArg("geometry_field_name", ArgumentType.STRING_CONSTANT, "Name of the geometry field in the foreign table.");
dfn.addArg("ESPG_SRID", ArgumentType.GENERAL, "Spatial Reference System Identifier (SRID) from the ESPG SRID database.");
// only build the factory if we have actual datastore to build against
if (datastores != null) {
dfn.setFactory(new FunctionFactory() {
@Override
public Function createFunction(Function... children) {
ToProcessLookupReferences toProcess = new ToProcessLookupReferences();
toProcess.tableReferenceFunction = children[1];
toProcess.fieldnameFunctions = new Function[] { children[2], children[3] };
ProcessedLookupReferences processed = FunctionsBuilder.processLookupReferenceNames(keyword, datastores, defaultDatastoreIndex, toProcess, result);
return new FmLookupGeomUnion(processed.datastoreIndx, processed.tableId, processed.columnIndices[0], processed.columnIndices[1], children[0], children[4]);
}
});
}
return dfn;
}
private final int otherTablePrimaryKeyColumn;
private FmLookupGeomUnion(int datastoreIndex, int otherTableId, int otherTablePrimaryKeyColumn, int otherTableReturnKeyColummn, Function foreignKeyValue, Function espgCode) {
super(datastoreIndex, otherTableId, otherTableReturnKeyColummn, foreignKeyValue, espgCode);
this.otherTablePrimaryKeyColumn = otherTablePrimaryKeyColumn;
}
@Override
public Object execute(FunctionParameters parameters) {
Object[] childExe = executeChildFormulae(parameters, true);
if (childExe == null) {
return Functions.EXECUTION_ERROR;
}
ODLTableReadOnly table = getForeignTable(parameters);
if (table == null) {
return null;
}
long[] list = table.find(otherTablePrimaryKeyColumn, childExe[0]);
int nr = list.length;
ArrayList<ODLGeom> geoms = new ArrayList<>(nr);
for (int i = 0; i < nr; i++) {
long id = list[i];
Object otherVal = table.getValueById(id, otherTableReturnKeyColummn);
if (otherVal != null) {
ODLGeom geom = (ODLGeom) ColumnValueProcessor.convertToMe(ODLColumnType.GEOM, otherVal);
if (geom == null) {
return Functions.EXECUTION_ERROR;
}
geoms.add(geom);
}
}
String espg = (String) ColumnValueProcessor.convertToMe(ODLColumnType.STRING, childExe[1]);
return new GeomUnion().union(geoms, espg);
}
}