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()); } } }