package util.database;
import java.lang.Math;

public class ZIPCodeWorld {
	/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
	:::                                                                         :::
	:::  TITLE: Calculate Latitude and Longitude from Rate Center V&H in Java   :::
	:::                                                                         :::
	:::  This function calculates the latitude and longitude coordinates        :::
	:::  from Vertical and Horizontal (V&H) coordinates. V&H's are used to      :::
	:::  identify locations and hence relative distances between network        :::
	:::  elements and between rate centers listed in AreaCodeWorld(tm) Gold     :::
	:::  Edition in http://www.zipcodeworld.com.                                :::
	:::                                                                         :::
	:::  Function Input Parameters:                                             :::
	:::    V = Vertical value from 0 to 10000                                   :::
	:::    H = Horizontal value from 0 to 10000                                 :::
	:::                                                                         :::
	:::  Function Output Parameters:                                            :::
	:::    Lat = Latitude from Vertical value                                   :::
	:::    Long = Longitude from Horizontal value                               :::
	:::                                                                         :::
	:::  North American Area Code NPA NXX database with V&H values is           :::
	:::  available at http://www.zipcodeworld.com. This sample code is          :::
	:::  provided to database subscribers "AS IS" without warranty of any kind. :::
	:::                                                                         :::
	:::  Email: sales@zipcodeworld.com                                          :::
	:::                                                                         :::
	:::  URL:   http://www.zipcodeworld.com                                     :::
	:::                                                                         :::
	:::        ZIPCodeWorld.com (c) All Rights Reserved 2002-2006               :::
	:::                                                                         :::
	:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/

	/* constants contributed by vh2ll.c */
	public static void main(String args[]){
		/* VH2LatLong(500,500); */
	}


	static void VH2LatLong(double v,double  h)
	{

		double M_PI=3.14159265358979323846;
		double TRANSV = 6363.235;
		double TRANSH = 2250.7;

		double ROTC = 0.23179040;
		double ROTS = 0.97276575;

		double RADIUS = 12481.103;

		double EX = 0.40426992;
		double EY =0.68210848;
		double EZ =0.60933887;

		double WX = 0.65517646;
		double WY = 0.37733790;
		double WZ = 0.65449210;

		double PX =-0.555977821730048699;
		double PY =-0.345728488161089920;
		double PZ = 0.755883902605524030;

		double GX = 0.216507961908834992;
		double GY = -0.134633014879368199;

		double A = 0.151646645621077297;

		double Q = -0.294355056616412800;
		double Q2 = 0.0866448993556515751;


		int i=0, latdeg=0, latmin=0, londeg=0, lonmin=0, latsec=0, lonsec=0;
		double t1=0.0, t2=0.0, vhat=0.0, hhat=0.0, fx=0.0, fy=0.0;
		double e=0.0, w=0.0;
		double b=0.0, c=0.0, disc=0.0, z=0.0, x=0.0, y=0.0, delta=0.0, lat=0.0, lat2=0.0, lon=0.0;
		double earthlat=0.0, earthlon=0.0;
		final double bi[] = {
			1.00567724920722457,
			-0.00344230425560210245,
			0.000713971534527667990,
			-0.0000777240053499279217,
			0.00000673180367053244284,
			-0.000000742595338885741395,
			0.0000000905058919926194134
		};

		t1 = (v - TRANSV) / RADIUS;
		t2 = (h - TRANSH) / RADIUS;
		vhat = ROTC*t2 - ROTS*t1;
		hhat = ROTS*t2 + ROTC*t1;
		e = Math.cos(Math.sqrt(vhat*vhat + hhat*hhat));
		w = Math.cos(Math.sqrt(vhat*vhat + (hhat-0.4)*(hhat-0.4)));
		fx = EY*w - WY*e;
		fy = EX*w - WX*e;
		b = fx*GX + fy*GY;
		c = fx*fx + fy*fy - Q2;
		disc = b*b - A*c;
		if (disc==0.0) {
			z = b/A;
			x = (GX*z - fx)/Q;
			y = (fy - GY*z)/Q;
		} else {
			delta = Math.sqrt(disc);
			z = (b + delta)/A;
			x = (GX*z - fx)/Q;
			y = (fy - GY*z)/Q;
			if (vhat * (PX*x + PY*y + PZ*z) < 0) {
				z = (b - delta)/A;
				x = (GX*z - fx)/Q;
				y = (fy - GY*z)/Q;
			}
		}
		lat = Math.asin(z);

		lat2 = lat*lat;
		earthlat = 0.0;
		for (i=6; i>=0; i--) {
			earthlat = (earthlat + bi[i]) * ((i>0)? lat2: lat);
		}
		earthlat *= 180/M_PI;
		lon = Math.atan2(x, y) * 180/M_PI;
		earthlon = lon + 52;
		System.out.println( earthlat + "," + earthlon);
	}
}