#include <math.h>
float theta, phi;
float r = chf("radius");
if(chi("reverse")) {
theta = asin(@P.z/r);
phi = atan2(@P.y,@P.x);
float lat = degrees(theta);
float lon = degrees(phi);
@P.x = lon;
@P.z = lat*-1;
@P.y = 0;
} else {
float lat1 = vector(getbbox_max(0)).z;
float lat2 = vector(getbbox_min(0)).z;
float lon1 = vector(getbbox_min(0)).x;
float lon2 = vector(getbbox_max(0)).x;
theta = PI/2 - radians(@P.z*-1);
phi = radians(@P.x);
float dLat = lat2 * PI / 180 - lat1 * PI / 180;
float dLon = lon1 * PI / 180 - lon1 * PI / 180;
float a = sin(dLat/2) * sin(dLat/2) + cos(lat1
* PI / 180) * cos(lat2 * PI / 180)
* sin(dLon/2) * sin(dLon/2);
float c = 2 * atan2(sqrt(a), sqrt(1-a))*r;
@d = r*c;
float x = (r+@P.y*c) * sin(theta) * cos(phi);
float y = (r+@P.y*c) * sin(theta) * sin(phi);
float z = (r+@P.y*c) * cos(theta);
v@P = set(x,y,z);
}
//def gps_to_ecef_custom(lat, lon, alt):
//WGS84 to ECEF
#include <math.h>
float rad_lat = (@P.z) * (PI / 180.0);
float rad_lon = @P.x * (PI / 180.0);
float a = 6378.1370;
float finv = 298.257223563;
float f = 1 / finv;
float e2 = 1 - (1 - f) * (1 - f);
float v = a / sqrt(1 - e2 * sin(rad_lat) * sin(rad_lat));
@P.x = (v + @P.y) * cos(rad_lat) * cos(rad_lon);
@P.z = (v + @P.y) * cos(rad_lat) * sin(rad_lon) *-1;
@P.y = (v * (1 - e2) + @P.y) * sin(rad_lat) *-1;
//Equal Earth Projection
//https://en.wikipedia.org/wiki/Equal_Earth_projection
float A1 = 1.340264;
float A2 = -0.081106;
float A3 = 0.000893;
float A4 = 0.003796;
float M = sqrt(3) / 2.0;
float paramLatSq, paramLatPow6, paramLat;
paramLat = asin(M * sin(radians(@P.z)));
paramLatSq = paramLat * paramLat;
paramLatPow6 = paramLatSq * paramLatSq * paramLatSq;
@P.x = radians(@P.x) * cos(paramLat)
/ (M * (A1 + 3 * A2 * paramLatSq + paramLatPow6 * (7 * A3 + 9 * A4 * paramLatSq)));
@P.z = paramLat * (A1 + A2 * paramLatSq + paramLatPow6 * (A3 + A4 * paramLatSq));
//Gall Peters
//https://en.wikipedia.org/wiki/Gall%E2%80%93Peters_projection
#include <math.h>
float R = 6378.1370;
vector pos = @P;
@P.x = R*PI*@P.x*cos(radians(45))/180;
@P.z = R*sin(radians(@P.z)) / cos(radians(45));
//@P.x = R*PI*pos.x / 180 * sqrt(2);
//@P.z = R * sqrt(2) * sin(radians(pos.z));
//@P.x = R*pos.x;
//@P.y = 2*R*sin(pos.z);
//https://desktop.arcgis.com/de/arcmap/latest/map/projections/craster-parabolic.htm
float XM = 0.97720502380583984317;
float RXM = 1.02332670794648848847;
float YM = 3.06998012383946546542;
float RYM = 0.32573500793527994772;
float THIRD = 0.333333333333333333;
float lpphi = radians(@P.z);
float lplam = radians(@P.x);
lpphi *= THIRD;
@P.x = XM * lplam * (2. * cos((lpphi + lpphi)) - 1.);
@P.z = YM * sin(lpphi);
@P *= chf("radius");
//https://www.youtube.com/watch?v=D3tdW9l1690
//https://en.wikipedia.org/wiki/Euler_spiral
//INIT START
float projectionLatitude = radians(ch("eulerLat0"));
float projectionLatitude1 = radians(ch("eulerLat1"));
float projectionLatitude2 = radians(ch("eulerLat2"));
@del = 0.5 * (projectionLatitude2 - projectionLatitude1);
float sig = 0.5 * (projectionLatitude2 + projectionLatitude1);
@n = sin(sig) * sin((@del)) / @del;
@del *= 0.5;
@rho_c = @del / (tan(@del) * tan(sig)) + sig;
@rho_0 = @rho_c - projectionLatitude;
//INIT END
float lplam = radians(@P.x);
float lpphi = radians(@P.z*-1);
float rho = @rho_c - lpphi;
@P.x = rho * sin(lplam*=@n+radians(chf("radius")));
@P.z = @rho_0 - rho * cos(lplam);
float XM = 0.97720502380583984317;
float RXM = 1.02332670794648848847;
float YM = 3.06998012383946546542;
float RYM = 0.32573500793527994772;
float THIRD = 0.333333333333333333;
float lpphi = radians(@P.z*-1);
float lplam = radians(@P.x);
lpphi *= THIRD;
@P.x = XM * lplam * (2.0 * cos(lpphi + lpphi) - 1.0)*1.0;
@P.z = YM * sin(lpphi)*1.0;
#include <math.h>
float scaleFactor = chf("scaleFactor");
float phi = radians(@P.z*-1);
float lam = radians(@P.x);
float maxLatitude = radians(85);
float minLatitude = radians(-85);
float e = 2.71828;
float tsfn(float phi; float sinphi; float e;)
{
sinphi *= e;
return (tan(.5 * ((PI/2) - phi))
/ pow((1. - sinphi) / (1. + sinphi), .5 * e));
}
float __sinphi__ = sin(radians(phi));
if (chi("spherical")) {
@P.x = scaleFactor * lam;
if (phi > maxLatitude) {
phi = maxLatitude;
} else if (phi < minLatitude) {
phi = minLatitude;
}
@P.z = scaleFactor * log(tan((PI/4) + 0.5 * phi));
} else {
@P.x = scaleFactor * lam;
@P.z = -scaleFactor * log( tsfn(phi, __sinphi__, e) );
}
#include <math.h>
//Eckert V https://proj.org/operations/projections/eck5.html
float XF = 0.44101277172455148219;
float RXF = 2.26750802723822639137;
float YF = 0.88202554344910296438;
float RYF = 1.13375401361911319568;
float lplam = radians(@P.x);
float lpphi = (radians(@P.z*-1));
@P.x = XF * (1. + cos(lpphi)) * lplam;
@P.z = YF * lpphi;
#include <math.h>
float w = 0.25;
float m = 1;
float rm;
if ((m = abs(m)) <= 0.) {
printf("ERROR");
} else {
m = 1.;
}
rm = 1.0 / m;
m /= w;
float cosphi, d;
float lpphi = radians(@P.z*-1);
float lplam = radians(@P.x);
d = sqrt(2. / (1. + (cosphi = cos(lpphi)) * cos(lplam *= w)));
//cosphi = cos(lpphi) * cos(lplam *= w);
@P.x = m * d * cosphi * sin(lplam) ;
@P.z = rm * d * sin(lpphi);
//https://en.wikipedia.org/wiki/Winkel_tripel_projection
float lplam = radians(@P.x);
float lpphi = radians(@P.z);
float c = 0.5 * lplam;
float d = acos(cos(lpphi) * cos(c));
if (d != 0) {
@P.x = 2. * d * cos(lpphi) * sin(c) * (@P.z = 1. / sin(d));
@P.z *= d * sin(lpphi);
} else {
@P.x = @P.z = 0.0;
}
@P.x = (@P.x + lplam * 0.636619772367581343) * 0.5;
@P.z = (@P.z + lpphi) * 0.5;
#include <math.h>
float phi1 = acos(2./PI);
float cosphi1 = 2./PI;
int MAX_ITER = 10;
float LOOP_TOL = 1e-7;
float TWO_D_PI = 0.636619772367581343;
float k, V;
int i;
float lpphi = radians(@P.z);
float lplam = radians(@P.x);
@P.z = lpphi * TWO_D_PI;
k = PI * sin(lpphi);
lpphi *= 1.8;
for (i = MAX_ITER; i > 0; --i) {
lpphi -= V = (lpphi + sin(lpphi) - k) / (1. + cos(lpphi));
if (abs(V) < LOOP_TOL)
break;
}
@P.x = 0.5 * lplam * (cos(lpphi) + cosphi1);
@P.z = (PI/4) * (sin(lpphi) + @P.z);
float phi1 = radians(50. + 28. / 60.);
float cosphi1 = cos(phi1);
float lplam = radians(@P.x);
float lpphi = radians(@P.z);
@P.x = .5 * lplam * (cosphi1 + cos(lpphi));
@P.z = lpphi;
float theta, ct, D;
float lpphi = radians(@P.z);
float lplam = radians(@P.x);
theta = asin(@P.z = 0.90630778703664996 * sin(lpphi));
@P.x = 2.66723 * (ct = cos(theta)) * sin(lplam /= 3.);
@P.z *= 1.24104 * (D = 1 / (sqrt(0.5 * (1 + ct * cos(lplam)))));
@P.x *= D;
//VanDerGrintenProjection
//https://en.wikipedia.org/wiki/Van_der_Grinten_projection
#include <math.h>
float TOL = 1.e-10;
float THIRD = .33333333333333333333;
float TWO_THRD = .66666666666666666666;
float C2_27 = .07407407407407407407;
float PI4_3 = 4.18879020478639098458;
float PISQ = 9.86960440108935861869;
float TPISQ = 19.73920880217871723738;
float HPISQ = 4.93480220054467930934;
float lplam = radians(@P.x);
float lpphi = radians(@P.z);
float al, al2, g, g2, p2;
p2 = abs(lpphi / (PI/2));
if ((p2 - TOL) > 1.) printf("ERROR #F");
if (p2 > 1.)
p2 = 1.;
if (abs(lpphi) <= TOL) {
@P.x = lplam;
@P.z = 0.;
} else if (abs(lplam) <= TOL || abs(p2 - 1.) < TOL) {
@P.x = 0.;
@P.z = PI * tan(.5 * asin(p2));
if (lpphi < 0.) @P.z = -@P.z;
} else {
al = .5 * abs(PI / lplam - lplam / PI);
al2 = al * al;
g = sqrt(1. - p2 * p2);
g = g / (p2 + g - 1.);
g2 = g * g;
p2 = g * (2. / p2 - 1.);
p2 = p2 * p2;
@P.x = g - p2; g = p2 + al2;
@P.x = PI * (al * @P.x + sqrt(al2 * @P.x * @P.x - g * (g2 - p2))) / g;
if (lplam < 0.) @P.x = -@P.x;
@P.z = abs(@P.x / PI);
@P.z = 1. - @P.z * (@P.z + 2. * al);
if (@P.z < -TOL) printf("ERROR #F");
if (@P.z < 0.)
@P.z = 0.;
else
@P.z = sqrt(@P.z) * (lpphi < 0. ? -PI : PI);
}
//URMFPSProjection
// * With the default parameter n, this is identical to Wagner I.
float C_x = 0.8773826753;
float C_y = 1.139753528477;
float n = 0.8660254037844386467637231707;// wag1
//float C_y = chf("radius");
float lplam = radians(@P.x);
float lpphi = radians(@P.z);
lpphi = asin(n * sin(lpphi));
@P.x = C_x * lplam * cos(lpphi);
@P.z = C_y * lpphi;
float projectionLatitude = radians(45);
float projectionLatitude1 = radians(chf("lat_1_35"));
float projectionLatitude2 = radians(chf("lat_2_60"));
float EPS = 1e-10;
float rho_c, rho_0, n;
// FIXME this will throw an exception with lat1 = lat2, which is the default.
float del = 0.5 * (projectionLatitude2 - projectionLatitude1);
float sig = 0.5 * (projectionLatitude2 + projectionLatitude1);
if (abs(del) < EPS || abs(sig) < EPS) {
//throw new ProjectionException("-42");
}
n = sin(sig);
float cs = cos(del);
rho_c = n / cs + cs / n;
rho_0 = sqrt((rho_c - 2 * sin(projectionLatitude)) / n);
float lpphi = radians(@P.z*-1);
float lplam = radians(@P.x);
float rho = rho_c - lpphi;
@P.x = rho * sin(lplam *= n);
@P.z = rho_0 - rho * cos(lplam)*-1;