@@ -271,16 +271,16 @@ def transform(self, ll):
271
271
cos_latitude = np .cos (latitude )
272
272
273
273
alpha = np .arccos (cos_latitude * np .cos (half_long ))
274
- # Mask this array, or we'll get divide-by-zero errors
274
+ # Mask this array or we'll get divide-by-zero errors
275
275
alpha = ma .masked_where (alpha == 0.0 , alpha )
276
+ # The numerators also need to be masked so that masked
277
+ # division will be invoked.
276
278
# We want unnormalized sinc. numpy.sinc gives us normalized
277
279
sinc_alpha = ma .sin (alpha ) / alpha
278
280
279
- x = (cos_latitude * np .sin (half_long )) / sinc_alpha
280
- y = (np .sin (latitude ) / sinc_alpha )
281
- x .set_fill_value (0.0 )
282
- y .set_fill_value (0.0 )
283
- return np .concatenate ((x .filled (), y .filled ()), 1 )
281
+ x = (cos_latitude * ma .sin (half_long )) / sinc_alpha
282
+ y = (ma .sin (latitude ) / sinc_alpha )
283
+ return np .concatenate ((x .filled (0 ), y .filled (0 )), 1 )
284
284
transform .__doc__ = Transform .transform .__doc__
285
285
286
286
transform_non_affine = transform
@@ -436,23 +436,35 @@ def __init__(self, resolution):
436
436
def transform (self , ll ):
437
437
def d (theta ):
438
438
delta = - (theta + np .sin (theta ) - pi_sin_l ) / (1 + np .cos (theta ))
439
- return delta , abs (delta ) > 0.001
439
+ return delta , np . abs (delta ) > 0.001
440
440
441
- longitude = ll [:, 0 :1 ]
442
- latitude = ll [:, 1 :2 ]
441
+ longitude = ll [:, 0 ]
442
+ latitude = ll [:, 1 ]
443
+
444
+ clat = np .pi / 2 - np .abs (latitude )
445
+ ihigh = clat < 0.087 # within 5 degrees of the poles
446
+ ilow = ~ ihigh
447
+ aux = np .empty (latitude .shape , dtype = np .float )
443
448
444
- pi_sin_l = np .pi * np .sin (latitude )
445
- theta = 2.0 * latitude
446
- delta , large_delta = d (theta )
447
- while np .any (large_delta ):
448
- theta += np .where (large_delta , delta , 0 )
449
+ if ilow .any (): # Newton-Raphson iteration
450
+ pi_sin_l = np .pi * np .sin (latitude [ilow ])
451
+ theta = 2.0 * latitude [ilow ]
449
452
delta , large_delta = d (theta )
450
- aux = theta / 2
453
+ while np .any (large_delta ):
454
+ theta [large_delta ] += delta [large_delta ]
455
+ delta , large_delta = d (theta )
456
+ aux [ilow ] = theta / 2
451
457
452
- x = (2.0 * np .sqrt (2.0 ) * longitude * np .cos (aux )) / np .pi
453
- y = (np .sqrt (2.0 ) * np .sin (aux ))
458
+ if ihigh .any (): # Taylor series-based approx. solution
459
+ e = clat [ihigh ]
460
+ d = 0.5 * (3 * np .pi * e ** 2 ) ** (1.0 / 3 )
461
+ aux [ihigh ] = (np .pi / 2 - d ) * np .sign (latitude [ihigh ])
454
462
455
- return np .concatenate ((x , y ), 1 )
463
+ xy = np .empty (ll .shape , dtype = np .float )
464
+ xy [:,0 ] = (2.0 * np .sqrt (2.0 ) / np .pi ) * longitude * np .cos (aux )
465
+ xy [:,1 ] = np .sqrt (2.0 ) * np .sin (aux )
466
+
467
+ return xy
456
468
transform .__doc__ = Transform .transform .__doc__
457
469
458
470
transform_non_affine = transform
0 commit comments