package com.esri.hadoop.hive;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.apache.log4j.Logger;
import com.esri.core.geometry.OperatorContains;
import com.esri.core.geometry.OperatorSimpleRelation;
import com.esri.core.geometry.Geometry.GeometryAccelerationDegree;
import com.esri.core.geometry.ogc.OGCGeometry;
/**
* Abstract class that all simple relational tests (contains, touches, ...) extend from
*
*/
public abstract class ST_GeometryRelational extends GenericUDF {
private static Logger LOG = Logger.getLogger(ST_GeometryRelational.class);
private static final int NUM_ARGS = 2;
private static final int GEOM_1 = 0;
private static final int GEOM_2 = 1;
private transient HiveGeometryOIHelper geomHelper1;
private transient HiveGeometryOIHelper geomHelper2;
private transient OperatorSimpleRelation opSimpleRelation;
private transient boolean firstRun = true;
private transient boolean geom1IsAccelerated = false;
/**
* Operators that extend this should return an instance of
* <code>OperatorSimpleRelation</code>
*
* @return operator for simple relationship tests
*/
protected abstract OperatorSimpleRelation getRelationOperator();
@Override
public ObjectInspector initialize(ObjectInspector[] OIs)
throws UDFArgumentException {
opSimpleRelation = getRelationOperator();
if (OIs.length != NUM_ARGS) {
throw new UDFArgumentException("The " + opSimpleRelation.getType().toString().toLowerCase() + " relationship operator takes exactly two arguments");
}
geomHelper1 = HiveGeometryOIHelper.create(OIs[GEOM_1], GEOM_1);
geomHelper2 = HiveGeometryOIHelper.create(OIs[GEOM_2], GEOM_2);
if (LOG.isDebugEnabled()) {
LOG.debug("OI[0]=" + geomHelper1);
LOG.debug("OI[1]=" + geomHelper2);
}
firstRun = true;
geom1IsAccelerated = false;
return PrimitiveObjectInspectorFactory.javaBooleanObjectInspector;
}
@Override
public Object evaluate(DeferredObject[] args) throws HiveException {
OGCGeometry geom1 = geomHelper1.getGeometry(args);
OGCGeometry geom2 = geomHelper2.getGeometry(args);
if (geom1 == null || geom2 == null) {
return false;
}
if (firstRun && geomHelper1.isConstant()) {
// accelerate geometry 1 for quick relation operations since it is constant
geom1IsAccelerated = opSimpleRelation.accelerateGeometry(geom1.getEsriGeometry(),
geom1.getEsriSpatialReference(), GeometryAccelerationDegree.enumMedium);
}
firstRun = false;
return opSimpleRelation.execute(geom1.getEsriGeometry(), geom2.getEsriGeometry(), geom1.getEsriSpatialReference(), null);
}
@Override
public void close() {
if (geom1IsAccelerated && geomHelper1 != null && geomHelper1.getConstantGeometry() != null) {
OperatorContains.deaccelerateGeometry(geomHelper1.getConstantGeometry().getEsriGeometry());
}
}
}