/*******************************************************************************
* 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 com.opendoorlogistics.api.ExecutionReport;
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.GeomWeightedCentroid;
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;
public class FmLookupWeightedCentroid extends FmAbstractLookup {
public static FunctionDefinition createDefinition(final IndexedDatastores<? extends ODLTableReadOnly> datastores, final int defaultDatastoreIndex,final boolean isWeighted, final ExecutionReport result) {
final String keyword = "lookup" + (isWeighted? "Weighted" : "") + "Centroid";
final FunctionDefinition dfn = new FunctionDefinition(keyword);
dfn.setDescription("Get the weighted centroid of the geometries in the foreign table.");
dfn.addArg("search_value", ArgumentType.GENERAL, "Key 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.");
if(isWeighted){
dfn.addArg("weight_field_name", ArgumentType.STRING_CONSTANT, "Weight of the geometry value in the foreign table.");
}
dfn.addArg("EPSG_SRID", ArgumentType.GENERAL, "Spatial Reference System Identifier (SRID) from the EPSG SRID database. If EPSG code is null, centroid is calculated using lat-long coordinates.");
// 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];
if(isWeighted){
toProcess.fieldnameFunctions = new Function[] { children[2], children[3] , children[4]};
ProcessedLookupReferences processed = FunctionsBuilder.processLookupReferenceNames(keyword, datastores, defaultDatastoreIndex, toProcess, result);
return new FmLookupWeightedCentroid(processed.datastoreIndx, processed.tableId, processed.columnIndices[0], processed.columnIndices[1],processed.columnIndices[2], children[0], children[5]);
}
else{
toProcess.fieldnameFunctions = new Function[] { children[2], children[3]};
ProcessedLookupReferences processed = FunctionsBuilder.processLookupReferenceNames(keyword, datastores, defaultDatastoreIndex, toProcess, result);
return new FmLookupWeightedCentroid(processed.datastoreIndx, processed.tableId, processed.columnIndices[0], processed.columnIndices[1],-1, children[0], children[4]);
}
}
});
}
return dfn;
}
private final int otherTablePrimaryKeyColumn;
private final int otherTableWeightColumn;
private FmLookupWeightedCentroid(int datastoreIndex, int otherTableId, int otherTablePrimaryKeyColumn, int otherTableGeomColumn,int otherTableWeightColumn, Function foreignKeyValue, Function epsgCode) {
super(datastoreIndex, otherTableId, otherTableGeomColumn, foreignKeyValue, epsgCode);
this.otherTablePrimaryKeyColumn = otherTablePrimaryKeyColumn;
this.otherTableWeightColumn = otherTableWeightColumn;
}
@Override
public Object execute(FunctionParameters parameters) {
Object[] childExe = executeChildFormulae(parameters, false);
if (childExe == null) {
return Functions.EXECUTION_ERROR;
}
ODLTableReadOnly table = getForeignTable(parameters);
if (table == null) {
return null;
}
long[] list = table.find(otherTablePrimaryKeyColumn, childExe[0]);
String epsg = (String) ColumnValueProcessor.convertToMe(ODLColumnType.STRING, childExe[1]);
return new GeomWeightedCentroid().calculate(table, list, otherTableReturnKeyColummn, otherTableWeightColumn, epsg);
}
}