@@ -13,47 +13,50 @@ export default {
1313
1414 conic : true ,
1515
16+ // based on https://github.com/d3/d3-geo-projection, MIT-licensed
17+
1618 initializeConstants ( ) {
1719 if ( this . constants && vec2 . exactEquals ( this . parallels , this . constants . parallels ) ) {
1820 return ;
1921 }
2022
21- const p1 = degToRad ( this . parallels [ 0 ] ) ;
22- const p2 = degToRad ( this . parallels [ 1 ] ) ;
23- const sinp1 = Math . sin ( p1 ) ;
24- const cosp1 = Math . cos ( p1 ) ;
25- const cosp12 = cosp1 * cosp1 ;
26- const r = 0.5 ;
27- const n = 0.5 * ( sinp1 + Math . sin ( p2 ) ) ;
28- const c = cosp12 + 2 * n * sinp1 ;
29- const b = r / n * Math . sqrt ( c ) ;
30-
31- this . constants = { n, b, c, parallels : this . parallels } ;
23+ const sy0 = Math . sin ( degToRad ( this . parallels [ 0 ] ) ) ;
24+ const n = ( sy0 + Math . sin ( degToRad ( this . parallels [ 1 ] ) ) ) / 2 ;
25+ const c = 1 + sy0 * ( 2 * n - sy0 ) ;
26+ const r0 = Math . sqrt ( c ) / n ;
27+
28+ this . constants = { n, c, r0, parallels : this . parallels } ;
3229 } ,
30+
3331 project ( lng : number , lat : number ) {
3432 this . initializeConstants ( ) ;
3533
36- const { n, b, c} = this . constants ;
37- const theta = n * degToRad ( lng - this . center [ 0 ] ) ;
38- const a = 0.5 / n * Math . sqrt ( c - 2 * n * Math . sin ( degToRad ( lat ) ) ) ;
39- const x = a * Math . sin ( theta ) ;
40- const y = b - a * Math . cos ( theta ) ;
34+ const lambda = degToRad ( lng - this . center [ 0 ] ) ;
35+ const phi = degToRad ( lat ) ;
4136
42- return { x : 1 + 0.5 * x , y : 1 - 0.5 * y } ;
37+ const { n, c, r0} = this . constants ;
38+ const r = Math . sqrt ( c - 2 * n * Math . sin ( phi ) ) / n ;
39+ const x = r * Math . sin ( lambda * n ) ;
40+ const y = r * Math . cos ( lambda * n ) - r0 ;
41+ return { x, y} ;
4342 } ,
43+
4444 unproject ( x : number , y : number ) {
4545 this . initializeConstants ( ) ;
46+ const { n, c, r0} = this . constants ;
4647
47- const { n, b, c} = this . constants ;
48- const x_ = ( x - 1 ) * 2 ;
49- const y_ = ( y - 1 ) * - 2 ;
50- const y2 = - ( y_ - b ) ;
48+ const r0y = r0 + y ;
49+ let l = Math . atan2 ( x , Math . abs ( r0y ) ) * Math . sign ( r0y ) ;
50+ if ( r0y * n < 0 ) {
51+ l -= Math . PI * Math . sign ( x ) * Math . sign ( r0y ) ;
52+ }
5153 const dt = degToRad ( this . center [ 0 ] ) * n ;
52- const theta = wrap ( Math . atan2 ( x_ , y2 ) , - Math . PI - dt , Math . PI - dt ) ;
53- const lng = radToDeg ( theta / n ) + this . center [ 0 ] ;
54- const a = x_ / Math . sin ( theta ) ;
55- const s = clamp ( ( Math . pow ( a / 0.5 * n , 2 ) - c ) / ( - 2 * n ) , - 1 , 1 ) ;
56- const lat = clamp ( radToDeg ( Math . asin ( s ) ) , - MAX_MERCATOR_LATITUDE , MAX_MERCATOR_LATITUDE ) ;
54+ l = wrap ( l , - Math . PI - dt , Math . PI - dt ) ;
55+
56+ const lng = radToDeg ( l / n ) + this . center [ 0 ] ;
57+ const phi = Math . asin ( clamp ( ( c - ( x * x + r0y * r0y ) * n * n ) / ( 2 * n ) , - 1 , 1 ) ) ;
58+ const lat = clamp ( radToDeg ( phi ) , - MAX_MERCATOR_LATITUDE , MAX_MERCATOR_LATITUDE ) ;
59+
5760 return new LngLat ( lng , lat ) ;
5861 }
5962} ;
0 commit comments