def ellipticFi(phi, psi, m): if np.any(phi == 0): scalar = np.isscalar(phi) and np.isscalar(psi) and np.isscalar(m) phi, psi, m = np.broadcast_arrays(phi, psi, m) result = np.empty_like(phi, 'D') index = (phi == 0) result[index] = ellipticF(atan(sinh(abs(phi[index]))), 1 - m[index]) * sign(psi[index]) result[~index] = ellipticFi(phi[~index], psi[~index], m[~index]) return result.reshape(1)[0] if scalar else result r = abs(phi) i = abs(psi) sinhpsi2 = sinh(i)**2 cscphi2 = 1 / sin(r)**2 cotphi2 = 1 / tan(r)**2 b = -(cotphi2 + m * (sinhpsi2 * cscphi2) - 1 + m) c = (m - 1) * cotphi2 cotlambda2 = (-b + sqrt(b * b - 4 * c)) / 2 re = ellipticF(atan(1 / sqrt(cotlambda2)), m) * sign(phi) im = ellipticF(atan(sqrt(np.maximum(0, (cotlambda2 / cotphi2 - 1) / m))), 1 - m) * sign(psi) return re + 1j * im
def guyou(lam, phi): # [PAK] wrap into [-pi/2, pi/2] radians x, y = np.asarray(lam), np.asarray(phi) xn, x = divmod(x + 90, 180) yn, y = divmod(y + 90, 180) xn, lam = xn * 180, radians(x - 90) yn, phi = yn * 180, radians(y - 90) # Compute constant K cos_u = (sqrt2 - 1) / (sqrt2 + 1) sinsq_u = 1 - cos_u**2 K = ellipticF(pi / 2, sinsq_u) # [PAK] simplify expressions, using the fact that f = -1 # Note: exp(f log(x)) => 1/x, cos(f x) => cos(x), sin(f x) => -sin(x) r = 1 / (tan(pi / 4 + abs(phi) / 2) * sqrt(cos_u)) at = atan(r * (cos(lam) - 1j * sin(lam))) t = ellipticFi(at.real, at.imag, sinsq_u) x, y = (-t.imag, sign(phi + (phi == 0)) * (0.5 * K - t.real)) # [PAK] convert to degrees, and return to original tile return degrees(x) + xn, degrees(y) + yn
def guyou_invert(x, y): # [PAK] wrap into [-pi/2, pi/2] radians x, y = np.asarray(x), np.asarray(y) xn, x = divmod(x + 90, 180) yn, y = divmod(y + 90, 180) xn, x = xn * 180, radians(x - 90) yn, y = yn * 180, radians(y - 90) # compute constant K cos_u = (sqrt2 - 1) / (sqrt2 + 1) sinsq_u = 1 - cos_u**2 K = ellipticF(pi / 2, sinsq_u) # [PAK] simplify expressions, using the fact that f = -1 j = ellipticJi(K / 2 - y, -x, sinsq_u) tn = j[0] / j[1] # j[0], j[1] are complex # Note: -atan2(im(x)/re(x)) => angle(x) lam = -np.angle(tn) # Note: exp(0.5/f log(a re(x)^2 + a im(x)^2)) => 1/(sqrt(a) |x|) phi = 2 * atan(1 / sqrt(cos_u) / abs(tn)) - pi / 2 # [PAK] convert to degrees, and return to original tile return degrees(lam) + xn, degrees(phi) + yn