Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I wrote ST_Project following the same syntax as hive esri spatial function, but the result is the not exactly the same #175

Closed
fragrantic opened this issue May 15, 2018 · 1 comment

Comments

@fragrantic
Copy link

import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.hive.serde2.io.DoubleWritable;
import com.esri.core.geometry.ogc.OGCGeometry;
import com.esri.core.geometry.ogc.OGCPoint;
import com.esri.hadoop.hive.GeometryUtils;
import com.esri.core.geometry.Point;

public class ST_Project extends UDF {
final DoubleWritable resultDouble = new DoubleWritable();

static double EARTH_RADIUS = 6378137.0;

static double degToRad(double deg) {
return (deg * Math.PI) / 180.0;
}

static double radToDeg(double rad) {
return (rad * 180.0) / Math.PI;
}

static double x;
static double y;

public static BytesWritable evaluate(BytesWritable geom, double distance, double bearing) {

if (geom == null) {
	return null;
}

try {

double angular = distance / EARTH_RADIUS;
double bearingRad = degToRad(bearing);
OGCGeometry Geometry = GeometryUtils.geometryFromEsriShape(geom);
OGCPoint pt1 = (OGCPoint)Geometry;		
double latRad = degToRad(((OGCPoint) pt1).X());
double lonRad = degToRad(((OGCPoint) pt1).Y());
double a = Math.sin((latRad));
double b = Math.cos((angular));
double c = Math.cos((latRad));
double d = Math.sin((angular));
double e = Math.cos((bearingRad));

double lat = Math.asin(((a * b) + (c * d * e)));

double f = Math.sin((bearingRad));
double h = Math.sin((lat));
double i = (f * d * c);
double j = (b - (a * h));

double lon = lonRad + Math.atan2(i, j);

x = radToDeg(lon);
y = radToDeg(lat);

DoubleWritable x1 = new DoubleWritable(x);
DoubleWritable y1 = new DoubleWritable(y);

Point stPt = new Point(y1.get(),x1.get());

BytesWritable ret = GeometryUtils.geometryToEsriShapeBytesWritable(OGCGeometry.createFromEsriGeometry(stPt, null));


return ret;
} catch (Exception e) {
    return null;} } }
@randallwhitman
Copy link
Contributor

The code posted in the description on 2018/05/15 appears to have calculations for a sphere, which is a fast approximation, but not entirely accurate, for an oblate spheroid such as the Earth.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants