/*******************************************************************************
* 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 gnu.trove.list.array.TLongArrayList;
import gnu.trove.map.hash.TLongObjectHashMap;
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.FunctionParameters;
import com.opendoorlogistics.core.formulae.Functions;
import com.opendoorlogistics.core.geometry.operations.GeomWeightedCentroid;
import com.opendoorlogistics.core.tables.ColumnValueProcessor;
import com.opendoorlogistics.core.utils.Pair;
public class FmGroupWeightedCentroid extends FmAbstractGroupAggregate {
public FmGroupWeightedCentroid(TLongObjectHashMap<TLongArrayList> groupRowIdToSourceRowIds, int srcDsIndex, int srcTableId, Function geometryField, Function weightField, Function espgCode) {
super(groupRowIdToSourceRowIds, srcDsIndex, srcTableId, geometryField,weightField,espgCode);
}
@Override
public Object execute(FunctionParameters parameters) {
if(!checkGroupedByTableExists(parameters)){
return Functions.EXECUTION_ERROR;
}
TLongArrayList srcRowIds = getSourceRows(parameters);
if (srcRowIds == null || srcRowIds.size()==0) {
return null;
}
// get source table
ODLTableReadOnly srcTable = getSourceTable(parameters);
if(srcTable==null){
return Functions.EXECUTION_ERROR;
}
// execute the child formulae against all rows in this source table, getting geoms and weights
int nbSrcRows = srcRowIds.size();
ArrayList<Pair<ODLGeom, Double>> geoms = new ArrayList<>(nbSrcRows);
for (int i = 0; i < nbSrcRows; i++) {
long srcRowId = srcRowIds.get(i);
if (srcTable.containsRowId(srcRowId)==false) {
return Functions.EXECUTION_ERROR;
}
// get geometry
Object geomVal = executeFunctionOnSourceTable(parameters, srcRowId, child(0));
if (geomVal == Functions.EXECUTION_ERROR) {
return Functions.EXECUTION_ERROR;
}
ODLGeom geom = (ODLGeom) ColumnValueProcessor.convertToMe(ODLColumnType.GEOM, geomVal);
if (geom == null) {
return null;
}
// get weight
Object weightVal = executeFunctionOnSourceTable(parameters, srcRowId, child(1));
if (weightVal == Functions.EXECUTION_ERROR) {
return Functions.EXECUTION_ERROR;
}
Double d=1.0;
if(weightVal!=null){
d = (Double)ColumnValueProcessor.convertToMe(ODLColumnType.DOUBLE, weightVal);
if(d==null){
return null;
}
}
geoms.add(new Pair<ODLGeom, Double>(geom, d));
}
// get espg code
Object epsgVal = child(2).execute(parameters);
if(epsgVal == Functions.EXECUTION_ERROR){
return Functions.EXECUTION_ERROR;
}
// allow EPSG to be null, we then do weighted centroid in lat-long coords
String epsg = (String) ColumnValueProcessor.convertToMe(ODLColumnType.STRING, epsgVal);
return new GeomWeightedCentroid().calculate(geoms, epsg);
}
@Override
public Function deepCopy() {
throw new UnsupportedOperationException();
}
}