com.esri.hadoop.hive.HiveGeometryOIHelper Maven / Gradle / Ivy
The newest version!
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.DeferredObject;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector.Category;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.Text;
import org.apache.log4j.Logger;
import com.esri.core.geometry.ogc.OGCGeometry;
import com.esri.core.geometry.ogc.OGCPoint;
public class HiveGeometryOIHelper {
static Logger LOG = Logger.getLogger(HiveGeometryOIHelper.class);
private PrimitiveObjectInspector oi;
private int argIndex;
private boolean isConstant;
OGCGeometry constantGeometry;
private HiveGeometryOIHelper(ObjectInspector oi, int argIndex) {
this.oi = (PrimitiveObjectInspector)oi;
this.argIndex = argIndex;
// constant geometries only need to be processed once and can
// be optimized in certain operations
isConstant = ObjectInspectorUtils.isConstantObjectInspector(oi);
}
public static HiveGeometryOIHelper create(ObjectInspector [] OIs, int argIndex) throws UDFArgumentException {
return create(OIs[argIndex], argIndex);
}
public static HiveGeometryOIHelper create(ObjectInspector oi, int argIndex) throws UDFArgumentException {
if (oi.getCategory() != Category.PRIMITIVE) {
throw new UDFArgumentException("Geometry argument must be a primitive type");
}
return new HiveGeometryOIHelper(oi, argIndex);
}
public static boolean canCreate(ObjectInspector oi) {
if (oi.getCategory() != Category.PRIMITIVE) {
return false;
}
return true;
}
/**
* Gets whether this geometry argument is constant.
*
* @return
*/
public boolean isConstant() {
return isConstant;
}
/**
* Returns the cached constant geometry object.
*
* @return cache geometry, or null if not constant
*/
public OGCGeometry getConstantGeometry() {
return constantGeometry;
}
/**
* Reads the corresponding geometry from the deferred object list
* or returns the cached geometry if argument is constant.
*
* @param args
* @return OGCPoint or null if not a point
* @see #getGeometry(DeferredObject[])
*/
public OGCPoint getPoint(DeferredObject[] args) {
OGCGeometry geometry = getGeometry(args);
if (geometry instanceof OGCPoint) {
return (OGCPoint)geometry;
} else {
return null;
}
}
/**
* Reads the corresponding geometry from the deferred object list
* or returns the cached geometry if argument is constant.
*
* @param args
* @return
*/
public OGCGeometry getGeometry(DeferredObject[] args) {
if (isConstant) {
if (constantGeometry == null) {
constantGeometry = getGeometry(args[argIndex]);
}
return constantGeometry;
} else {
// not constant, so we have to rebuild the geometry
// on every call
return getGeometry(args[argIndex]);
}
}
private OGCGeometry getGeometry(DeferredObject arg) {
Object writable;
try {
writable = oi.getPrimitiveWritableObject(arg.get());
} catch (HiveException e) {
LOG.error("Failed to get writable", e);
return null;
}
if (writable == null) {
return null;
}
switch (oi.getPrimitiveCategory()) {
case BINARY: return getGeometryFromBytes((BytesWritable)writable);
case STRING: return OGCGeometry.fromText(((Text)writable).toString());
default: return null;
}
}
private BytesWritable last = null;
// always assume bytes are reused until we determine they aren't
private boolean bytesReused = true;
private OGCGeometry getGeometryFromBytes(BytesWritable writable) {
if (bytesReused) {
if (last != null && last != writable) {
// this assumes that the source of these bytes will either always
// reuse the bytes or never reuse the bytes.
bytesReused = false;
}
last = writable;
}
return GeometryUtils.geometryFromEsriShape((BytesWritable)writable, bytesReused);
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("HiveGeometryHelper(");
builder.append("constant=" + isConstant + ";");
builder.append(")");
return builder.toString();
}
}