@plotdb/chart 0.0.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/CHANGELOG.md +34 -1
  2. package/README.md +3 -3
  3. package/{dist/data → data}/index.js +0 -0
  4. package/{dist/chart.css → index.css} +0 -0
  5. package/{dist/chart.js → index.js} +3 -1
  6. package/{dist/chart.min.css → index.min.css} +0 -0
  7. package/index.min.js +1 -0
  8. package/package.json +1 -89
  9. package/{dist/utils → utils}/axis.js +6 -0
  10. package/utils/axis.min.js +1 -0
  11. package/{dist/utils → utils}/config.js +0 -0
  12. package/utils/config.min.js +1 -0
  13. package/{dist/utils → utils}/data.js +0 -0
  14. package/utils/data.min.js +1 -0
  15. package/{dist/utils → utils}/format.js +0 -0
  16. package/utils/format.min.js +1 -0
  17. package/{dist/utils → utils}/legend.css +0 -0
  18. package/{dist/utils → utils}/legend.js +0 -0
  19. package/{dist/utils → utils}/legend.min.css +0 -0
  20. package/utils/legend.min.js +1 -0
  21. package/{dist/utils → utils}/tint.js +0 -0
  22. package/utils/tint.min.js +1 -0
  23. package/{dist/utils → utils}/tip.js +0 -0
  24. package/utils/tip.min.js +1 -0
  25. package/build +0 -39
  26. package/dist/chart.min.js +0 -1
  27. package/dist/utils/axis.min.js +0 -1
  28. package/dist/utils/config.min.js +0 -1
  29. package/dist/utils/data.min.js +0 -1
  30. package/dist/utils/format.min.js +0 -1
  31. package/dist/utils/legend.min.js +0 -1
  32. package/dist/utils/tint.min.js +0 -1
  33. package/dist/utils/tip.min.js +0 -1
  34. package/doc/charts.md +0 -58
  35. package/doc/config.md +0 -44
  36. package/doc/draft/chart.md +0 -146
  37. package/doc/draft/data.md +0 -8
  38. package/doc/draft/definition.md +0 -0
  39. package/doc/draft/events.md +0 -0
  40. package/doc/draft/filter.md +0 -0
  41. package/doc/draft/lifecycle.md +0 -89
  42. package/doc/spec.md +0 -89
  43. package/doc/todo.md +0 -27
  44. package/doc/utils/tip.md +0 -84
  45. package/src/chart.ls +0 -323
  46. package/src/chart.styl +0 -6
  47. package/src/data/en-US/category +0 -20
  48. package/src/data/en-US/fruit +0 -39
  49. package/src/data/en-US/movie +0 -125
  50. package/src/data/en-US/name +0 -58
  51. package/src/data/index.ls +0 -34
  52. package/src/data/zh-TW/category +0 -20
  53. package/src/data/zh-TW/fruits +0 -38
  54. package/src/data/zh-TW/movie +0 -125
  55. package/src/data/zh-TW/names +0 -105
  56. package/src/utils/axis.ls +0 -229
  57. package/src/utils/config.ls +0 -11
  58. package/src/utils/data.ls +0 -104
  59. package/src/utils/format.ls +0 -30
  60. package/src/utils/legend.ls +0 -134
  61. package/src/utils/legend.styl +0 -37
  62. package/src/utils/tint.ls +0 -66
  63. package/src/utils/tip.ls +0 -97
  64. package/web/src/pug/base.pug +0 -20
  65. package/web/src/pug/block/axis/0.0.1/index.ls +0 -38
  66. package/web/src/pug/block/axis/0.0.1/index.pug +0 -1
  67. package/web/src/pug/block/axis-bubble/0.0.1/index.ls +0 -141
  68. package/web/src/pug/block/axis-bubble/0.0.1/index.pug +0 -1
  69. package/web/src/pug/block/bar/0.0.1/index.ls +0 -274
  70. package/web/src/pug/block/bar/0.0.1/index.pug +0 -35
  71. package/web/src/pug/block/bar-list/0.0.1/index.ls +0 -85
  72. package/web/src/pug/block/bar-list/0.0.1/index.pug +0 -30
  73. package/web/src/pug/block/bar-race/0.0.1/index.ls +0 -83
  74. package/web/src/pug/block/bar-race/0.0.1/index.pug +0 -21
  75. package/web/src/pug/block/base/0.0.1/index.ls +0 -67
  76. package/web/src/pug/block/base/0.0.1/index.pug +0 -5
  77. package/web/src/pug/block/blank/0.0.1/index.ls +0 -25
  78. package/web/src/pug/block/blank/0.0.1/index.pug +0 -1
  79. package/web/src/pug/block/bubble/0.0.1/index.ls +0 -220
  80. package/web/src/pug/block/bubble/0.0.1/index.pug +0 -28
  81. package/web/src/pug/block/curve-bar/0.0.1/index.ls +0 -89
  82. package/web/src/pug/block/curve-bar/0.0.1/index.pug +0 -16
  83. package/web/src/pug/block/curve-bar/0.0.1/sample.js +0 -338
  84. package/web/src/pug/block/dumbbell/0.0.1/index.ls +0 -90
  85. package/web/src/pug/block/dumbbell/0.0.1/index.pug +0 -1
  86. package/web/src/pug/block/empty/0.0.1/index.ls +0 -27
  87. package/web/src/pug/block/empty/0.0.1/index.pug +0 -2
  88. package/web/src/pug/block/gauge/0.0.1/index.ls +0 -100
  89. package/web/src/pug/block/gauge/0.0.1/index.pug +0 -31
  90. package/web/src/pug/block/gauge/0.0.1/sample.js +0 -338
  91. package/web/src/pug/block/line/0.0.1/index.ls +0 -302
  92. package/web/src/pug/block/line/0.0.1/index.pug +0 -33
  93. package/web/src/pug/block/number/0.0.1/index.ls +0 -69
  94. package/web/src/pug/block/number/0.0.1/index.pug +0 -20
  95. package/web/src/pug/block/percent-list/0.0.1/index.ls +0 -167
  96. package/web/src/pug/block/percent-list/0.0.1/index.pug +0 -34
  97. package/web/src/pug/block/pie/0.0.1/index.ls +0 -125
  98. package/web/src/pug/block/pie/0.0.1/index.pug +0 -19
  99. package/web/src/pug/block/pie/0.0.1/sample.js +0 -338
  100. package/web/src/pug/block/pie-bubble/0.0.1/index.ls +0 -185
  101. package/web/src/pug/block/pie-bubble/0.0.1/index.pug +0 -40
  102. package/web/src/pug/block/radar/0.0.1/index.ls +0 -113
  103. package/web/src/pug/block/radar/0.0.1/index.pug +0 -1
  104. package/web/src/pug/block/radar/0.0.1/xx +0 -285
  105. package/web/src/pug/block/scatter/0.0.1/index.ls +0 -128
  106. package/web/src/pug/block/scatter/0.0.1/index.pug +0 -30
  107. package/web/src/pug/block/sheet/0.0.1/index.ls +0 -38
  108. package/web/src/pug/block/sheet/0.0.1/index.pug +0 -5
  109. package/web/src/pug/block/table/0.0.1/index.ls +0 -40
  110. package/web/src/pug/block/table/0.0.1/index.pug +0 -3
  111. package/web/src/pug/block/taiwancounty/0.0.1/index.ls +0 -74
  112. package/web/src/pug/block/taiwancounty/0.0.1/index.pug +0 -64
  113. package/web/src/pug/block/taiwantown/0.0.1/index.ls +0 -48
  114. package/web/src/pug/block/taiwantown/0.0.1/index.pug +0 -52
  115. package/web/src/pug/block/taiwanvillage/0.0.1/index.ls +0 -53
  116. package/web/src/pug/block/taiwanvillage/0.0.1/index.pug +0 -52
  117. package/web/src/pug/block/treemap/0.0.1/index.ls +0 -172
  118. package/web/src/pug/block/treemap/0.0.1/index.pug +0 -42
  119. package/web/src/pug/block/voronoi-treemap/0.0.1/index.ls +0 -174
  120. package/web/src/pug/block/voronoi-treemap/0.0.1/index.pug +0 -17
  121. package/web/src/pug/block/voronoi-treemap/0.0.1/sample.js +0 -241
  122. package/web/src/pug/block/wordcloud/0.0.1/index.ls +0 -61
  123. package/web/src/pug/block/wordcloud/0.0.1/index.pug +0 -1
  124. package/web/src/pug/block/worldmap/0.0.1/index.ls +0 -81
  125. package/web/src/pug/block/worldmap/0.0.1/index.pug +0 -12
  126. package/web/src/pug/index.ls +0 -72
  127. package/web/src/pug/index.pug +0 -51
  128. package/web/src/styl/index.styl +0 -0
  129. package/web/static/assets/block/cache.js +0 -4
  130. package/web/static/assets/custom-lib/d3/d3-array.v2.js +0 -1182
  131. package/web/static/assets/custom-lib/d3/d3-array.v2.min.js +0 -2
  132. package/web/static/assets/custom-lib/d3/d3-array.v3.js +0 -1273
  133. package/web/static/assets/custom-lib/d3/d3-array.v3.min.js +0 -1273
  134. package/web/static/assets/custom-lib/d3/d3-axis.v2.min.js +0 -2
  135. package/web/static/assets/custom-lib/d3/d3-brush.v2.min.js +0 -2
  136. package/web/static/assets/custom-lib/d3/d3-color.v2.min.js +0 -2
  137. package/web/static/assets/custom-lib/d3/d3-dispatch.v2.min.js +0 -2
  138. package/web/static/assets/custom-lib/d3/d3-drag.v2.min.js +0 -2
  139. package/web/static/assets/custom-lib/d3/d3-ease.v2.min.js +0 -2
  140. package/web/static/assets/custom-lib/d3/d3-force-boundary.v0.0.1.min.js +0 -2
  141. package/web/static/assets/custom-lib/d3/d3-force.v2.min.js +0 -2
  142. package/web/static/assets/custom-lib/d3/d3-format.v2.min.js +0 -2
  143. package/web/static/assets/custom-lib/d3/d3-geo.v2.js +0 -3127
  144. package/web/static/assets/custom-lib/d3/d3-geo.v2.min.js +0 -2
  145. package/web/static/assets/custom-lib/d3/d3-hierarchy.v2.min.js +0 -2
  146. package/web/static/assets/custom-lib/d3/d3-interpolate.v2.min.js +0 -2
  147. package/web/static/assets/custom-lib/d3/d3-path.v2.min.js +0 -2
  148. package/web/static/assets/custom-lib/d3/d3-quadtree.v2.min.js +0 -2
  149. package/web/static/assets/custom-lib/d3/d3-random.v2.min.js +0 -2
  150. package/web/static/assets/custom-lib/d3/d3-scale-chromatic.v1.min.js +0 -2
  151. package/web/static/assets/custom-lib/d3/d3-selection.v2.min.js +0 -2
  152. package/web/static/assets/custom-lib/d3/d3-shape.v2.min.js +0 -2
  153. package/web/static/assets/custom-lib/d3/d3-timer.v2.min.js +0 -2
  154. package/web/static/assets/custom-lib/d3/d3-transition.v2.min.js +0 -2
  155. package/web/static/assets/custom-lib/d3/d3.v4.js +0 -17178
  156. package/web/static/assets/custom-lib/d3/d3.v4.min.js +0 -2
  157. package/web/static/assets/custom-lib/d3/d3.v6.js +0 -19708
  158. package/web/static/assets/data/countrycode.json +0 -1
  159. package/web/static/assets/data/world-110m.json +0 -1
  160. package/web/static/assets/data/zh-to-alpha2.json +0 -1
  161. package/web/static/assets/img/fluid.svg +0 -16
  162. package/web/static/block/axis/0.0.1/index.html +0 -79
  163. package/web/static/block/axis-bubble/0.0.1/index.html +0 -222
  164. package/web/static/block/bar/0.0.1/index.html +0 -581
  165. package/web/static/block/bar-list/0.0.1/index.html +0 -231
  166. package/web/static/block/bar-race/0.0.1/index.html +0 -184
  167. package/web/static/block/base/0.0.1/index.html +0 -197
  168. package/web/static/block/blank/0.0.1/index.html +0 -42
  169. package/web/static/block/bubble/0.0.1/index.html +0 -402
  170. package/web/static/block/bubble/0.0.1/test.html +0 -0
  171. package/web/static/block/curve-bar/0.0.1/index.html +0 -148
  172. package/web/static/block/dumbbell/0.0.1/index.html +0 -178
  173. package/web/static/block/empty/0.0.1/index.html +0 -76
  174. package/web/static/block/gauge/0.0.1/index.html +0 -150
  175. package/web/static/block/line/0.0.1/index.html +0 -571
  176. package/web/static/block/number/0.0.1/index.html +0 -152
  177. package/web/static/block/percent-list/0.0.1/index.html +0 -316
  178. package/web/static/block/pie/0.0.1/index.html +0 -281
  179. package/web/static/block/pie-bubble/0.0.1/index.html +0 -358
  180. package/web/static/block/radar/0.0.1/index.html +0 -149
  181. package/web/static/block/scatter/0.0.1/index.html +0 -251
  182. package/web/static/block/sheet/0.0.1/index.html +0 -103
  183. package/web/static/block/table/0.0.1/index.html +0 -73
  184. package/web/static/block/taiwancounty/0.0.1/index.html +0 -202
  185. package/web/static/block/taiwantown/0.0.1/index.html +0 -210
  186. package/web/static/block/taiwanvillage/0.0.1/index.html +0 -220
  187. package/web/static/block/treemap/0.0.1/index.html +0 -360
  188. package/web/static/block/voronoi-treemap/0.0.1/index.html +0 -350
  189. package/web/static/block/wordcloud/0.0.1/index.html +0 -92
  190. package/web/static/block/worldmap/0.0.1/index.html +0 -207
  191. package/web/static/css/index.css +0 -0
  192. package/web/static/css/index.min.css +0 -0
  193. package/web/static/favicon.ico +0 -0
  194. package/web/static/index.html +0 -153
@@ -1,3127 +0,0 @@
1
- // https://d3js.org/d3-geo/ v2.0.2 Copyright 2021 Mike Bostock
2
- (function (global, factory) {
3
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-array')) :
4
- typeof define === 'function' && define.amd ? define(['exports', 'd3-array'], factory) :
5
- (global = global || self, factory(global.d3 = global.d3 || {}, global.d3));
6
- }(this, function (exports, d3Array) { 'use strict';
7
-
8
- var epsilon = 1e-6;
9
- var epsilon2 = 1e-12;
10
- var pi = Math.PI;
11
- var halfPi = pi / 2;
12
- var quarterPi = pi / 4;
13
- var tau = pi * 2;
14
-
15
- var degrees = 180 / pi;
16
- var radians = pi / 180;
17
-
18
- var abs = Math.abs;
19
- var atan = Math.atan;
20
- var atan2 = Math.atan2;
21
- var cos = Math.cos;
22
- var ceil = Math.ceil;
23
- var exp = Math.exp;
24
- var hypot = Math.hypot;
25
- var log = Math.log;
26
- var pow = Math.pow;
27
- var sin = Math.sin;
28
- var sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; };
29
- var sqrt = Math.sqrt;
30
- var tan = Math.tan;
31
-
32
- function acos(x) {
33
- return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);
34
- }
35
-
36
- function asin(x) {
37
- return x > 1 ? halfPi : x < -1 ? -halfPi : Math.asin(x);
38
- }
39
-
40
- function haversin(x) {
41
- return (x = sin(x / 2)) * x;
42
- }
43
-
44
- function noop() {}
45
-
46
- function streamGeometry(geometry, stream) {
47
- if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) {
48
- streamGeometryType[geometry.type](geometry, stream);
49
- }
50
- }
51
-
52
- var streamObjectType = {
53
- Feature: function(object, stream) {
54
- streamGeometry(object.geometry, stream);
55
- },
56
- FeatureCollection: function(object, stream) {
57
- var features = object.features, i = -1, n = features.length;
58
- while (++i < n) streamGeometry(features[i].geometry, stream);
59
- }
60
- };
61
-
62
- var streamGeometryType = {
63
- Sphere: function(object, stream) {
64
- stream.sphere();
65
- },
66
- Point: function(object, stream) {
67
- object = object.coordinates;
68
- stream.point(object[0], object[1], object[2]);
69
- },
70
- MultiPoint: function(object, stream) {
71
- var coordinates = object.coordinates, i = -1, n = coordinates.length;
72
- while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]);
73
- },
74
- LineString: function(object, stream) {
75
- streamLine(object.coordinates, stream, 0);
76
- },
77
- MultiLineString: function(object, stream) {
78
- var coordinates = object.coordinates, i = -1, n = coordinates.length;
79
- while (++i < n) streamLine(coordinates[i], stream, 0);
80
- },
81
- Polygon: function(object, stream) {
82
- streamPolygon(object.coordinates, stream);
83
- },
84
- MultiPolygon: function(object, stream) {
85
- var coordinates = object.coordinates, i = -1, n = coordinates.length;
86
- while (++i < n) streamPolygon(coordinates[i], stream);
87
- },
88
- GeometryCollection: function(object, stream) {
89
- var geometries = object.geometries, i = -1, n = geometries.length;
90
- while (++i < n) streamGeometry(geometries[i], stream);
91
- }
92
- };
93
-
94
- function streamLine(coordinates, stream, closed) {
95
- var i = -1, n = coordinates.length - closed, coordinate;
96
- stream.lineStart();
97
- while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]);
98
- stream.lineEnd();
99
- }
100
-
101
- function streamPolygon(coordinates, stream) {
102
- var i = -1, n = coordinates.length;
103
- stream.polygonStart();
104
- while (++i < n) streamLine(coordinates[i], stream, 1);
105
- stream.polygonEnd();
106
- }
107
-
108
- function geoStream(object, stream) {
109
- if (object && streamObjectType.hasOwnProperty(object.type)) {
110
- streamObjectType[object.type](object, stream);
111
- } else {
112
- streamGeometry(object, stream);
113
- }
114
- }
115
-
116
- var areaRingSum = new d3Array.Adder();
117
-
118
- // hello?
119
-
120
- var areaSum = new d3Array.Adder(),
121
- lambda00,
122
- phi00,
123
- lambda0,
124
- cosPhi0,
125
- sinPhi0;
126
-
127
- var areaStream = {
128
- point: noop,
129
- lineStart: noop,
130
- lineEnd: noop,
131
- polygonStart: function() {
132
- areaRingSum = new d3Array.Adder();
133
- areaStream.lineStart = areaRingStart;
134
- areaStream.lineEnd = areaRingEnd;
135
- },
136
- polygonEnd: function() {
137
- var areaRing = +areaRingSum;
138
- areaSum.add(areaRing < 0 ? tau + areaRing : areaRing);
139
- this.lineStart = this.lineEnd = this.point = noop;
140
- },
141
- sphere: function() {
142
- areaSum.add(tau);
143
- }
144
- };
145
-
146
- function areaRingStart() {
147
- areaStream.point = areaPointFirst;
148
- }
149
-
150
- function areaRingEnd() {
151
- areaPoint(lambda00, phi00);
152
- }
153
-
154
- function areaPointFirst(lambda, phi) {
155
- areaStream.point = areaPoint;
156
- lambda00 = lambda, phi00 = phi;
157
- lambda *= radians, phi *= radians;
158
- lambda0 = lambda, cosPhi0 = cos(phi = phi / 2 + quarterPi), sinPhi0 = sin(phi);
159
- }
160
-
161
- function areaPoint(lambda, phi) {
162
- lambda *= radians, phi *= radians;
163
- phi = phi / 2 + quarterPi; // half the angular distance from south pole
164
-
165
- // Spherical excess E for a spherical triangle with vertices: south pole,
166
- // previous point, current point. Uses a formula derived from Cagnoli’s
167
- // theorem. See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2).
168
- var dLambda = lambda - lambda0,
169
- sdLambda = dLambda >= 0 ? 1 : -1,
170
- adLambda = sdLambda * dLambda,
171
- cosPhi = cos(phi),
172
- sinPhi = sin(phi),
173
- k = sinPhi0 * sinPhi,
174
- u = cosPhi0 * cosPhi + k * cos(adLambda),
175
- v = k * sdLambda * sin(adLambda);
176
- areaRingSum.add(atan2(v, u));
177
-
178
- // Advance the previous points.
179
- lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi;
180
- }
181
-
182
- function area(object) {
183
- areaSum = new d3Array.Adder();
184
- geoStream(object, areaStream);
185
- return areaSum * 2;
186
- }
187
-
188
- function spherical(cartesian) {
189
- return [atan2(cartesian[1], cartesian[0]), asin(cartesian[2])];
190
- }
191
-
192
- function cartesian(spherical) {
193
- var lambda = spherical[0], phi = spherical[1], cosPhi = cos(phi);
194
- return [cosPhi * cos(lambda), cosPhi * sin(lambda), sin(phi)];
195
- }
196
-
197
- function cartesianDot(a, b) {
198
- return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
199
- }
200
-
201
- function cartesianCross(a, b) {
202
- return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
203
- }
204
-
205
- // TODO return a
206
- function cartesianAddInPlace(a, b) {
207
- a[0] += b[0], a[1] += b[1], a[2] += b[2];
208
- }
209
-
210
- function cartesianScale(vector, k) {
211
- return [vector[0] * k, vector[1] * k, vector[2] * k];
212
- }
213
-
214
- // TODO return d
215
- function cartesianNormalizeInPlace(d) {
216
- var l = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
217
- d[0] /= l, d[1] /= l, d[2] /= l;
218
- }
219
-
220
- var lambda0$1, phi0, lambda1, phi1, // bounds
221
- lambda2, // previous lambda-coordinate
222
- lambda00$1, phi00$1, // first point
223
- p0, // previous 3D point
224
- deltaSum,
225
- ranges,
226
- range;
227
-
228
- var boundsStream = {
229
- point: boundsPoint,
230
- lineStart: boundsLineStart,
231
- lineEnd: boundsLineEnd,
232
- polygonStart: function() {
233
- boundsStream.point = boundsRingPoint;
234
- boundsStream.lineStart = boundsRingStart;
235
- boundsStream.lineEnd = boundsRingEnd;
236
- deltaSum = new d3Array.Adder();
237
- areaStream.polygonStart();
238
- },
239
- polygonEnd: function() {
240
- areaStream.polygonEnd();
241
- boundsStream.point = boundsPoint;
242
- boundsStream.lineStart = boundsLineStart;
243
- boundsStream.lineEnd = boundsLineEnd;
244
- if (areaRingSum < 0) lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90);
245
- else if (deltaSum > epsilon) phi1 = 90;
246
- else if (deltaSum < -epsilon) phi0 = -90;
247
- range[0] = lambda0$1, range[1] = lambda1;
248
- },
249
- sphere: function() {
250
- lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90);
251
- }
252
- };
253
-
254
- function boundsPoint(lambda, phi) {
255
- ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);
256
- if (phi < phi0) phi0 = phi;
257
- if (phi > phi1) phi1 = phi;
258
- }
259
-
260
- function linePoint(lambda, phi) {
261
- var p = cartesian([lambda * radians, phi * radians]);
262
- if (p0) {
263
- var normal = cartesianCross(p0, p),
264
- equatorial = [normal[1], -normal[0], 0],
265
- inflection = cartesianCross(equatorial, normal);
266
- cartesianNormalizeInPlace(inflection);
267
- inflection = spherical(inflection);
268
- var delta = lambda - lambda2,
269
- sign = delta > 0 ? 1 : -1,
270
- lambdai = inflection[0] * degrees * sign,
271
- phii,
272
- antimeridian = abs(delta) > 180;
273
- if (antimeridian ^ (sign * lambda2 < lambdai && lambdai < sign * lambda)) {
274
- phii = inflection[1] * degrees;
275
- if (phii > phi1) phi1 = phii;
276
- } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign * lambda2 < lambdai && lambdai < sign * lambda)) {
277
- phii = -inflection[1] * degrees;
278
- if (phii < phi0) phi0 = phii;
279
- } else {
280
- if (phi < phi0) phi0 = phi;
281
- if (phi > phi1) phi1 = phi;
282
- }
283
- if (antimeridian) {
284
- if (lambda < lambda2) {
285
- if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
286
- } else {
287
- if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
288
- }
289
- } else {
290
- if (lambda1 >= lambda0$1) {
291
- if (lambda < lambda0$1) lambda0$1 = lambda;
292
- if (lambda > lambda1) lambda1 = lambda;
293
- } else {
294
- if (lambda > lambda2) {
295
- if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
296
- } else {
297
- if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
298
- }
299
- }
300
- }
301
- } else {
302
- ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);
303
- }
304
- if (phi < phi0) phi0 = phi;
305
- if (phi > phi1) phi1 = phi;
306
- p0 = p, lambda2 = lambda;
307
- }
308
-
309
- function boundsLineStart() {
310
- boundsStream.point = linePoint;
311
- }
312
-
313
- function boundsLineEnd() {
314
- range[0] = lambda0$1, range[1] = lambda1;
315
- boundsStream.point = boundsPoint;
316
- p0 = null;
317
- }
318
-
319
- function boundsRingPoint(lambda, phi) {
320
- if (p0) {
321
- var delta = lambda - lambda2;
322
- deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta);
323
- } else {
324
- lambda00$1 = lambda, phi00$1 = phi;
325
- }
326
- areaStream.point(lambda, phi);
327
- linePoint(lambda, phi);
328
- }
329
-
330
- function boundsRingStart() {
331
- areaStream.lineStart();
332
- }
333
-
334
- function boundsRingEnd() {
335
- boundsRingPoint(lambda00$1, phi00$1);
336
- areaStream.lineEnd();
337
- if (abs(deltaSum) > epsilon) lambda0$1 = -(lambda1 = 180);
338
- range[0] = lambda0$1, range[1] = lambda1;
339
- p0 = null;
340
- }
341
-
342
- // Finds the left-right distance between two longitudes.
343
- // This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want
344
- // the distance between ±180° to be 360°.
345
- function angle(lambda0, lambda1) {
346
- return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1;
347
- }
348
-
349
- function rangeCompare(a, b) {
350
- return a[0] - b[0];
351
- }
352
-
353
- function rangeContains(range, x) {
354
- return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;
355
- }
356
-
357
- function bounds(feature) {
358
- var i, n, a, b, merged, deltaMax, delta;
359
-
360
- phi1 = lambda1 = -(lambda0$1 = phi0 = Infinity);
361
- ranges = [];
362
- geoStream(feature, boundsStream);
363
-
364
- // First, sort ranges by their minimum longitudes.
365
- if (n = ranges.length) {
366
- ranges.sort(rangeCompare);
367
-
368
- // Then, merge any ranges that overlap.
369
- for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) {
370
- b = ranges[i];
371
- if (rangeContains(a, b[0]) || rangeContains(a, b[1])) {
372
- if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1];
373
- if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0];
374
- } else {
375
- merged.push(a = b);
376
- }
377
- }
378
-
379
- // Finally, find the largest gap between the merged ranges.
380
- // The final bounding box will be the inverse of this gap.
381
- for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) {
382
- b = merged[i];
383
- if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0$1 = b[0], lambda1 = a[1];
384
- }
385
- }
386
-
387
- ranges = range = null;
388
-
389
- return lambda0$1 === Infinity || phi0 === Infinity
390
- ? [[NaN, NaN], [NaN, NaN]]
391
- : [[lambda0$1, phi0], [lambda1, phi1]];
392
- }
393
-
394
- var W0, W1,
395
- X0, Y0, Z0,
396
- X1, Y1, Z1,
397
- X2, Y2, Z2,
398
- lambda00$2, phi00$2, // first point
399
- x0, y0, z0; // previous point
400
-
401
- var centroidStream = {
402
- sphere: noop,
403
- point: centroidPoint,
404
- lineStart: centroidLineStart,
405
- lineEnd: centroidLineEnd,
406
- polygonStart: function() {
407
- centroidStream.lineStart = centroidRingStart;
408
- centroidStream.lineEnd = centroidRingEnd;
409
- },
410
- polygonEnd: function() {
411
- centroidStream.lineStart = centroidLineStart;
412
- centroidStream.lineEnd = centroidLineEnd;
413
- }
414
- };
415
-
416
- // Arithmetic mean of Cartesian vectors.
417
- function centroidPoint(lambda, phi) {
418
- lambda *= radians, phi *= radians;
419
- var cosPhi = cos(phi);
420
- centroidPointCartesian(cosPhi * cos(lambda), cosPhi * sin(lambda), sin(phi));
421
- }
422
-
423
- function centroidPointCartesian(x, y, z) {
424
- ++W0;
425
- X0 += (x - X0) / W0;
426
- Y0 += (y - Y0) / W0;
427
- Z0 += (z - Z0) / W0;
428
- }
429
-
430
- function centroidLineStart() {
431
- centroidStream.point = centroidLinePointFirst;
432
- }
433
-
434
- function centroidLinePointFirst(lambda, phi) {
435
- lambda *= radians, phi *= radians;
436
- var cosPhi = cos(phi);
437
- x0 = cosPhi * cos(lambda);
438
- y0 = cosPhi * sin(lambda);
439
- z0 = sin(phi);
440
- centroidStream.point = centroidLinePoint;
441
- centroidPointCartesian(x0, y0, z0);
442
- }
443
-
444
- function centroidLinePoint(lambda, phi) {
445
- lambda *= radians, phi *= radians;
446
- var cosPhi = cos(phi),
447
- x = cosPhi * cos(lambda),
448
- y = cosPhi * sin(lambda),
449
- z = sin(phi),
450
- w = atan2(sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z);
451
- W1 += w;
452
- X1 += w * (x0 + (x0 = x));
453
- Y1 += w * (y0 + (y0 = y));
454
- Z1 += w * (z0 + (z0 = z));
455
- centroidPointCartesian(x0, y0, z0);
456
- }
457
-
458
- function centroidLineEnd() {
459
- centroidStream.point = centroidPoint;
460
- }
461
-
462
- // See J. E. Brock, The Inertia Tensor for a Spherical Triangle,
463
- // J. Applied Mechanics 42, 239 (1975).
464
- function centroidRingStart() {
465
- centroidStream.point = centroidRingPointFirst;
466
- }
467
-
468
- function centroidRingEnd() {
469
- centroidRingPoint(lambda00$2, phi00$2);
470
- centroidStream.point = centroidPoint;
471
- }
472
-
473
- function centroidRingPointFirst(lambda, phi) {
474
- lambda00$2 = lambda, phi00$2 = phi;
475
- lambda *= radians, phi *= radians;
476
- centroidStream.point = centroidRingPoint;
477
- var cosPhi = cos(phi);
478
- x0 = cosPhi * cos(lambda);
479
- y0 = cosPhi * sin(lambda);
480
- z0 = sin(phi);
481
- centroidPointCartesian(x0, y0, z0);
482
- }
483
-
484
- function centroidRingPoint(lambda, phi) {
485
- lambda *= radians, phi *= radians;
486
- var cosPhi = cos(phi),
487
- x = cosPhi * cos(lambda),
488
- y = cosPhi * sin(lambda),
489
- z = sin(phi),
490
- cx = y0 * z - z0 * y,
491
- cy = z0 * x - x0 * z,
492
- cz = x0 * y - y0 * x,
493
- m = hypot(cx, cy, cz),
494
- w = asin(m), // line weight = angle
495
- v = m && -w / m; // area weight multiplier
496
- X2.add(v * cx);
497
- Y2.add(v * cy);
498
- Z2.add(v * cz);
499
- W1 += w;
500
- X1 += w * (x0 + (x0 = x));
501
- Y1 += w * (y0 + (y0 = y));
502
- Z1 += w * (z0 + (z0 = z));
503
- centroidPointCartesian(x0, y0, z0);
504
- }
505
-
506
- function centroid(object) {
507
- W0 = W1 =
508
- X0 = Y0 = Z0 =
509
- X1 = Y1 = Z1 = 0;
510
- X2 = new d3Array.Adder();
511
- Y2 = new d3Array.Adder();
512
- Z2 = new d3Array.Adder();
513
- geoStream(object, centroidStream);
514
-
515
- var x = +X2,
516
- y = +Y2,
517
- z = +Z2,
518
- m = hypot(x, y, z);
519
-
520
- // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid.
521
- if (m < epsilon2) {
522
- x = X1, y = Y1, z = Z1;
523
- // If the feature has zero length, fall back to arithmetic mean of point vectors.
524
- if (W1 < epsilon) x = X0, y = Y0, z = Z0;
525
- m = hypot(x, y, z);
526
- // If the feature still has an undefined ccentroid, then return.
527
- if (m < epsilon2) return [NaN, NaN];
528
- }
529
-
530
- return [atan2(y, x) * degrees, asin(z / m) * degrees];
531
- }
532
-
533
- function constant(x) {
534
- return function() {
535
- return x;
536
- };
537
- }
538
-
539
- function compose(a, b) {
540
-
541
- function compose(x, y) {
542
- return x = a(x, y), b(x[0], x[1]);
543
- }
544
-
545
- if (a.invert && b.invert) compose.invert = function(x, y) {
546
- return x = b.invert(x, y), x && a.invert(x[0], x[1]);
547
- };
548
-
549
- return compose;
550
- }
551
-
552
- function rotationIdentity(lambda, phi) {
553
- return [abs(lambda) > pi ? lambda + Math.round(-lambda / tau) * tau : lambda, phi];
554
- }
555
-
556
- rotationIdentity.invert = rotationIdentity;
557
-
558
- function rotateRadians(deltaLambda, deltaPhi, deltaGamma) {
559
- return (deltaLambda %= tau) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma))
560
- : rotationLambda(deltaLambda))
561
- : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma)
562
- : rotationIdentity);
563
- }
564
-
565
- function forwardRotationLambda(deltaLambda) {
566
- return function(lambda, phi) {
567
- return lambda += deltaLambda, [lambda > pi ? lambda - tau : lambda < -pi ? lambda + tau : lambda, phi];
568
- };
569
- }
570
-
571
- function rotationLambda(deltaLambda) {
572
- var rotation = forwardRotationLambda(deltaLambda);
573
- rotation.invert = forwardRotationLambda(-deltaLambda);
574
- return rotation;
575
- }
576
-
577
- function rotationPhiGamma(deltaPhi, deltaGamma) {
578
- var cosDeltaPhi = cos(deltaPhi),
579
- sinDeltaPhi = sin(deltaPhi),
580
- cosDeltaGamma = cos(deltaGamma),
581
- sinDeltaGamma = sin(deltaGamma);
582
-
583
- function rotation(lambda, phi) {
584
- var cosPhi = cos(phi),
585
- x = cos(lambda) * cosPhi,
586
- y = sin(lambda) * cosPhi,
587
- z = sin(phi),
588
- k = z * cosDeltaPhi + x * sinDeltaPhi;
589
- return [
590
- atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi),
591
- asin(k * cosDeltaGamma + y * sinDeltaGamma)
592
- ];
593
- }
594
-
595
- rotation.invert = function(lambda, phi) {
596
- var cosPhi = cos(phi),
597
- x = cos(lambda) * cosPhi,
598
- y = sin(lambda) * cosPhi,
599
- z = sin(phi),
600
- k = z * cosDeltaGamma - y * sinDeltaGamma;
601
- return [
602
- atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi),
603
- asin(k * cosDeltaPhi - x * sinDeltaPhi)
604
- ];
605
- };
606
-
607
- return rotation;
608
- }
609
-
610
- function rotation(rotate) {
611
- rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0);
612
-
613
- function forward(coordinates) {
614
- coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians);
615
- return coordinates[0] *= degrees, coordinates[1] *= degrees, coordinates;
616
- }
617
-
618
- forward.invert = function(coordinates) {
619
- coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians);
620
- return coordinates[0] *= degrees, coordinates[1] *= degrees, coordinates;
621
- };
622
-
623
- return forward;
624
- }
625
-
626
- // Generates a circle centered at [0°, 0°], with a given radius and precision.
627
- function circleStream(stream, radius, delta, direction, t0, t1) {
628
- if (!delta) return;
629
- var cosRadius = cos(radius),
630
- sinRadius = sin(radius),
631
- step = direction * delta;
632
- if (t0 == null) {
633
- t0 = radius + direction * tau;
634
- t1 = radius - step / 2;
635
- } else {
636
- t0 = circleRadius(cosRadius, t0);
637
- t1 = circleRadius(cosRadius, t1);
638
- if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau;
639
- }
640
- for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) {
641
- point = spherical([cosRadius, -sinRadius * cos(t), -sinRadius * sin(t)]);
642
- stream.point(point[0], point[1]);
643
- }
644
- }
645
-
646
- // Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0].
647
- function circleRadius(cosRadius, point) {
648
- point = cartesian(point), point[0] -= cosRadius;
649
- cartesianNormalizeInPlace(point);
650
- var radius = acos(-point[1]);
651
- return ((-point[2] < 0 ? -radius : radius) + tau - epsilon) % tau;
652
- }
653
-
654
- function circle() {
655
- var center = constant([0, 0]),
656
- radius = constant(90),
657
- precision = constant(6),
658
- ring,
659
- rotate,
660
- stream = {point: point};
661
-
662
- function point(x, y) {
663
- ring.push(x = rotate(x, y));
664
- x[0] *= degrees, x[1] *= degrees;
665
- }
666
-
667
- function circle() {
668
- var c = center.apply(this, arguments),
669
- r = radius.apply(this, arguments) * radians,
670
- p = precision.apply(this, arguments) * radians;
671
- ring = [];
672
- rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert;
673
- circleStream(stream, r, p, 1);
674
- c = {type: "Polygon", coordinates: [ring]};
675
- ring = rotate = null;
676
- return c;
677
- }
678
-
679
- circle.center = function(_) {
680
- return arguments.length ? (center = typeof _ === "function" ? _ : constant([+_[0], +_[1]]), circle) : center;
681
- };
682
-
683
- circle.radius = function(_) {
684
- return arguments.length ? (radius = typeof _ === "function" ? _ : constant(+_), circle) : radius;
685
- };
686
-
687
- circle.precision = function(_) {
688
- return arguments.length ? (precision = typeof _ === "function" ? _ : constant(+_), circle) : precision;
689
- };
690
-
691
- return circle;
692
- }
693
-
694
- function clipBuffer() {
695
- var lines = [],
696
- line;
697
- return {
698
- point: function(x, y, m) {
699
- line.push([x, y, m]);
700
- },
701
- lineStart: function() {
702
- lines.push(line = []);
703
- },
704
- lineEnd: noop,
705
- rejoin: function() {
706
- if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));
707
- },
708
- result: function() {
709
- var result = lines;
710
- lines = [];
711
- line = null;
712
- return result;
713
- }
714
- };
715
- }
716
-
717
- function pointEqual(a, b) {
718
- return abs(a[0] - b[0]) < epsilon && abs(a[1] - b[1]) < epsilon;
719
- }
720
-
721
- function Intersection(point, points, other, entry) {
722
- this.x = point;
723
- this.z = points;
724
- this.o = other; // another intersection
725
- this.e = entry; // is an entry?
726
- this.v = false; // visited
727
- this.n = this.p = null; // next & previous
728
- }
729
-
730
- // A generalized polygon clipping algorithm: given a polygon that has been cut
731
- // into its visible line segments, and rejoins the segments by interpolating
732
- // along the clip edge.
733
- function clipRejoin(segments, compareIntersection, startInside, interpolate, stream) {
734
- var subject = [],
735
- clip = [],
736
- i,
737
- n;
738
-
739
- segments.forEach(function(segment) {
740
- if ((n = segment.length - 1) <= 0) return;
741
- var n, p0 = segment[0], p1 = segment[n], x;
742
-
743
- if (pointEqual(p0, p1)) {
744
- if (!p0[2] && !p1[2]) {
745
- stream.lineStart();
746
- for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]);
747
- stream.lineEnd();
748
- return;
749
- }
750
- // handle degenerate cases by moving the point
751
- p1[0] += 2 * epsilon;
752
- }
753
-
754
- subject.push(x = new Intersection(p0, segment, null, true));
755
- clip.push(x.o = new Intersection(p0, null, x, false));
756
- subject.push(x = new Intersection(p1, segment, null, false));
757
- clip.push(x.o = new Intersection(p1, null, x, true));
758
- });
759
-
760
- if (!subject.length) return;
761
-
762
- clip.sort(compareIntersection);
763
- link(subject);
764
- link(clip);
765
-
766
- for (i = 0, n = clip.length; i < n; ++i) {
767
- clip[i].e = startInside = !startInside;
768
- }
769
-
770
- var start = subject[0],
771
- points,
772
- point;
773
-
774
- while (1) {
775
- // Find first unvisited intersection.
776
- var current = start,
777
- isSubject = true;
778
- while (current.v) if ((current = current.n) === start) return;
779
- points = current.z;
780
- stream.lineStart();
781
- do {
782
- current.v = current.o.v = true;
783
- if (current.e) {
784
- if (isSubject) {
785
- for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]);
786
- } else {
787
- interpolate(current.x, current.n.x, 1, stream);
788
- }
789
- current = current.n;
790
- } else {
791
- if (isSubject) {
792
- points = current.p.z;
793
- for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]);
794
- } else {
795
- interpolate(current.x, current.p.x, -1, stream);
796
- }
797
- current = current.p;
798
- }
799
- current = current.o;
800
- points = current.z;
801
- isSubject = !isSubject;
802
- } while (!current.v);
803
- stream.lineEnd();
804
- }
805
- }
806
-
807
- function link(array) {
808
- if (!(n = array.length)) return;
809
- var n,
810
- i = 0,
811
- a = array[0],
812
- b;
813
- while (++i < n) {
814
- a.n = b = array[i];
815
- b.p = a;
816
- a = b;
817
- }
818
- a.n = b = array[0];
819
- b.p = a;
820
- }
821
-
822
- function longitude(point) {
823
- if (abs(point[0]) <= pi)
824
- return point[0];
825
- else
826
- return sign(point[0]) * ((abs(point[0]) + pi) % tau - pi);
827
- }
828
-
829
- function polygonContains(polygon, point) {
830
- var lambda = longitude(point),
831
- phi = point[1],
832
- sinPhi = sin(phi),
833
- normal = [sin(lambda), -cos(lambda), 0],
834
- angle = 0,
835
- winding = 0;
836
-
837
- var sum = new d3Array.Adder();
838
-
839
- if (sinPhi === 1) phi = halfPi + epsilon;
840
- else if (sinPhi === -1) phi = -halfPi - epsilon;
841
-
842
- for (var i = 0, n = polygon.length; i < n; ++i) {
843
- if (!(m = (ring = polygon[i]).length)) continue;
844
- var ring,
845
- m,
846
- point0 = ring[m - 1],
847
- lambda0 = longitude(point0),
848
- phi0 = point0[1] / 2 + quarterPi,
849
- sinPhi0 = sin(phi0),
850
- cosPhi0 = cos(phi0);
851
-
852
- for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) {
853
- var point1 = ring[j],
854
- lambda1 = longitude(point1),
855
- phi1 = point1[1] / 2 + quarterPi,
856
- sinPhi1 = sin(phi1),
857
- cosPhi1 = cos(phi1),
858
- delta = lambda1 - lambda0,
859
- sign = delta >= 0 ? 1 : -1,
860
- absDelta = sign * delta,
861
- antimeridian = absDelta > pi,
862
- k = sinPhi0 * sinPhi1;
863
-
864
- sum.add(atan2(k * sign * sin(absDelta), cosPhi0 * cosPhi1 + k * cos(absDelta)));
865
- angle += antimeridian ? delta + sign * tau : delta;
866
-
867
- // Are the longitudes either side of the point’s meridian (lambda),
868
- // and are the latitudes smaller than the parallel (phi)?
869
- if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) {
870
- var arc = cartesianCross(cartesian(point0), cartesian(point1));
871
- cartesianNormalizeInPlace(arc);
872
- var intersection = cartesianCross(normal, arc);
873
- cartesianNormalizeInPlace(intersection);
874
- var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin(intersection[2]);
875
- if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) {
876
- winding += antimeridian ^ delta >= 0 ? 1 : -1;
877
- }
878
- }
879
- }
880
- }
881
-
882
- // First, determine whether the South pole is inside or outside:
883
- //
884
- // It is inside if:
885
- // * the polygon winds around it in a clockwise direction.
886
- // * the polygon does not (cumulatively) wind around it, but has a negative
887
- // (counter-clockwise) area.
888
- //
889
- // Second, count the (signed) number of times a segment crosses a lambda
890
- // from the point to the South pole. If it is zero, then the point is the
891
- // same side as the South pole.
892
-
893
- return (angle < -epsilon || angle < epsilon && sum < -epsilon2) ^ (winding & 1);
894
- }
895
-
896
- function clip(pointVisible, clipLine, interpolate, start) {
897
- return function(sink) {
898
- var line = clipLine(sink),
899
- ringBuffer = clipBuffer(),
900
- ringSink = clipLine(ringBuffer),
901
- polygonStarted = false,
902
- polygon,
903
- segments,
904
- ring;
905
-
906
- var clip = {
907
- point: point,
908
- lineStart: lineStart,
909
- lineEnd: lineEnd,
910
- polygonStart: function() {
911
- clip.point = pointRing;
912
- clip.lineStart = ringStart;
913
- clip.lineEnd = ringEnd;
914
- segments = [];
915
- polygon = [];
916
- },
917
- polygonEnd: function() {
918
- clip.point = point;
919
- clip.lineStart = lineStart;
920
- clip.lineEnd = lineEnd;
921
- segments = d3Array.merge(segments);
922
- var startInside = polygonContains(polygon, start);
923
- if (segments.length) {
924
- if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
925
- clipRejoin(segments, compareIntersection, startInside, interpolate, sink);
926
- } else if (startInside) {
927
- if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
928
- sink.lineStart();
929
- interpolate(null, null, 1, sink);
930
- sink.lineEnd();
931
- }
932
- if (polygonStarted) sink.polygonEnd(), polygonStarted = false;
933
- segments = polygon = null;
934
- },
935
- sphere: function() {
936
- sink.polygonStart();
937
- sink.lineStart();
938
- interpolate(null, null, 1, sink);
939
- sink.lineEnd();
940
- sink.polygonEnd();
941
- }
942
- };
943
-
944
- function point(lambda, phi) {
945
- if (pointVisible(lambda, phi)) sink.point(lambda, phi);
946
- }
947
-
948
- function pointLine(lambda, phi) {
949
- line.point(lambda, phi);
950
- }
951
-
952
- function lineStart() {
953
- clip.point = pointLine;
954
- line.lineStart();
955
- }
956
-
957
- function lineEnd() {
958
- clip.point = point;
959
- line.lineEnd();
960
- }
961
-
962
- function pointRing(lambda, phi) {
963
- ring.push([lambda, phi]);
964
- ringSink.point(lambda, phi);
965
- }
966
-
967
- function ringStart() {
968
- ringSink.lineStart();
969
- ring = [];
970
- }
971
-
972
- function ringEnd() {
973
- pointRing(ring[0][0], ring[0][1]);
974
- ringSink.lineEnd();
975
-
976
- var clean = ringSink.clean(),
977
- ringSegments = ringBuffer.result(),
978
- i, n = ringSegments.length, m,
979
- segment,
980
- point;
981
-
982
- ring.pop();
983
- polygon.push(ring);
984
- ring = null;
985
-
986
- if (!n) return;
987
-
988
- // No intersections.
989
- if (clean & 1) {
990
- segment = ringSegments[0];
991
- if ((m = segment.length - 1) > 0) {
992
- if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
993
- sink.lineStart();
994
- for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]);
995
- sink.lineEnd();
996
- }
997
- return;
998
- }
999
-
1000
- // Rejoin connected segments.
1001
- // TODO reuse ringBuffer.rejoin()?
1002
- if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
1003
-
1004
- segments.push(ringSegments.filter(validSegment));
1005
- }
1006
-
1007
- return clip;
1008
- };
1009
- }
1010
-
1011
- function validSegment(segment) {
1012
- return segment.length > 1;
1013
- }
1014
-
1015
- // Intersections are sorted along the clip edge. For both antimeridian cutting
1016
- // and circle clipping, the same comparison is used.
1017
- function compareIntersection(a, b) {
1018
- return ((a = a.x)[0] < 0 ? a[1] - halfPi - epsilon : halfPi - a[1])
1019
- - ((b = b.x)[0] < 0 ? b[1] - halfPi - epsilon : halfPi - b[1]);
1020
- }
1021
-
1022
- var clipAntimeridian = clip(
1023
- function() { return true; },
1024
- clipAntimeridianLine,
1025
- clipAntimeridianInterpolate,
1026
- [-pi, -halfPi]
1027
- );
1028
-
1029
- // Takes a line and cuts into visible segments. Return values: 0 - there were
1030
- // intersections or the line was empty; 1 - no intersections; 2 - there were
1031
- // intersections, and the first and last segments should be rejoined.
1032
- function clipAntimeridianLine(stream) {
1033
- var lambda0 = NaN,
1034
- phi0 = NaN,
1035
- sign0 = NaN,
1036
- clean; // no intersections
1037
-
1038
- return {
1039
- lineStart: function() {
1040
- stream.lineStart();
1041
- clean = 1;
1042
- },
1043
- point: function(lambda1, phi1) {
1044
- var sign1 = lambda1 > 0 ? pi : -pi,
1045
- delta = abs(lambda1 - lambda0);
1046
- if (abs(delta - pi) < epsilon) { // line crosses a pole
1047
- stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi : -halfPi);
1048
- stream.point(sign0, phi0);
1049
- stream.lineEnd();
1050
- stream.lineStart();
1051
- stream.point(sign1, phi0);
1052
- stream.point(lambda1, phi0);
1053
- clean = 0;
1054
- } else if (sign0 !== sign1 && delta >= pi) { // line crosses antimeridian
1055
- if (abs(lambda0 - sign0) < epsilon) lambda0 -= sign0 * epsilon; // handle degeneracies
1056
- if (abs(lambda1 - sign1) < epsilon) lambda1 -= sign1 * epsilon;
1057
- phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1);
1058
- stream.point(sign0, phi0);
1059
- stream.lineEnd();
1060
- stream.lineStart();
1061
- stream.point(sign1, phi0);
1062
- clean = 0;
1063
- }
1064
- stream.point(lambda0 = lambda1, phi0 = phi1);
1065
- sign0 = sign1;
1066
- },
1067
- lineEnd: function() {
1068
- stream.lineEnd();
1069
- lambda0 = phi0 = NaN;
1070
- },
1071
- clean: function() {
1072
- return 2 - clean; // if intersections, rejoin first and last segments
1073
- }
1074
- };
1075
- }
1076
-
1077
- function clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) {
1078
- var cosPhi0,
1079
- cosPhi1,
1080
- sinLambda0Lambda1 = sin(lambda0 - lambda1);
1081
- return abs(sinLambda0Lambda1) > epsilon
1082
- ? atan((sin(phi0) * (cosPhi1 = cos(phi1)) * sin(lambda1)
1083
- - sin(phi1) * (cosPhi0 = cos(phi0)) * sin(lambda0))
1084
- / (cosPhi0 * cosPhi1 * sinLambda0Lambda1))
1085
- : (phi0 + phi1) / 2;
1086
- }
1087
-
1088
- function clipAntimeridianInterpolate(from, to, direction, stream) {
1089
- var phi;
1090
- if (from == null) {
1091
- phi = direction * halfPi;
1092
- stream.point(-pi, phi);
1093
- stream.point(0, phi);
1094
- stream.point(pi, phi);
1095
- stream.point(pi, 0);
1096
- stream.point(pi, -phi);
1097
- stream.point(0, -phi);
1098
- stream.point(-pi, -phi);
1099
- stream.point(-pi, 0);
1100
- stream.point(-pi, phi);
1101
- } else if (abs(from[0] - to[0]) > epsilon) {
1102
- var lambda = from[0] < to[0] ? pi : -pi;
1103
- phi = direction * lambda / 2;
1104
- stream.point(-lambda, phi);
1105
- stream.point(0, phi);
1106
- stream.point(lambda, phi);
1107
- } else {
1108
- stream.point(to[0], to[1]);
1109
- }
1110
- }
1111
-
1112
- function clipCircle(radius) {
1113
- var cr = cos(radius),
1114
- delta = 6 * radians,
1115
- smallRadius = cr > 0,
1116
- notHemisphere = abs(cr) > epsilon; // TODO optimise for this common case
1117
-
1118
- function interpolate(from, to, direction, stream) {
1119
- circleStream(stream, radius, delta, direction, from, to);
1120
- }
1121
-
1122
- function visible(lambda, phi) {
1123
- return cos(lambda) * cos(phi) > cr;
1124
- }
1125
-
1126
- // Takes a line and cuts into visible segments. Return values used for polygon
1127
- // clipping: 0 - there were intersections or the line was empty; 1 - no
1128
- // intersections 2 - there were intersections, and the first and last segments
1129
- // should be rejoined.
1130
- function clipLine(stream) {
1131
- var point0, // previous point
1132
- c0, // code for previous point
1133
- v0, // visibility of previous point
1134
- v00, // visibility of first point
1135
- clean; // no intersections
1136
- return {
1137
- lineStart: function() {
1138
- v00 = v0 = false;
1139
- clean = 1;
1140
- },
1141
- point: function(lambda, phi) {
1142
- var point1 = [lambda, phi],
1143
- point2,
1144
- v = visible(lambda, phi),
1145
- c = smallRadius
1146
- ? v ? 0 : code(lambda, phi)
1147
- : v ? code(lambda + (lambda < 0 ? pi : -pi), phi) : 0;
1148
- if (!point0 && (v00 = v0 = v)) stream.lineStart();
1149
- if (v !== v0) {
1150
- point2 = intersect(point0, point1);
1151
- if (!point2 || pointEqual(point0, point2) || pointEqual(point1, point2))
1152
- point1[2] = 1;
1153
- }
1154
- if (v !== v0) {
1155
- clean = 0;
1156
- if (v) {
1157
- // outside going in
1158
- stream.lineStart();
1159
- point2 = intersect(point1, point0);
1160
- stream.point(point2[0], point2[1]);
1161
- } else {
1162
- // inside going out
1163
- point2 = intersect(point0, point1);
1164
- stream.point(point2[0], point2[1], 2);
1165
- stream.lineEnd();
1166
- }
1167
- point0 = point2;
1168
- } else if (notHemisphere && point0 && smallRadius ^ v) {
1169
- var t;
1170
- // If the codes for two points are different, or are both zero,
1171
- // and there this segment intersects with the small circle.
1172
- if (!(c & c0) && (t = intersect(point1, point0, true))) {
1173
- clean = 0;
1174
- if (smallRadius) {
1175
- stream.lineStart();
1176
- stream.point(t[0][0], t[0][1]);
1177
- stream.point(t[1][0], t[1][1]);
1178
- stream.lineEnd();
1179
- } else {
1180
- stream.point(t[1][0], t[1][1]);
1181
- stream.lineEnd();
1182
- stream.lineStart();
1183
- stream.point(t[0][0], t[0][1], 3);
1184
- }
1185
- }
1186
- }
1187
- if (v && (!point0 || !pointEqual(point0, point1))) {
1188
- stream.point(point1[0], point1[1]);
1189
- }
1190
- point0 = point1, v0 = v, c0 = c;
1191
- },
1192
- lineEnd: function() {
1193
- if (v0) stream.lineEnd();
1194
- point0 = null;
1195
- },
1196
- // Rejoin first and last segments if there were intersections and the first
1197
- // and last points were visible.
1198
- clean: function() {
1199
- return clean | ((v00 && v0) << 1);
1200
- }
1201
- };
1202
- }
1203
-
1204
- // Intersects the great circle between a and b with the clip circle.
1205
- function intersect(a, b, two) {
1206
- var pa = cartesian(a),
1207
- pb = cartesian(b);
1208
-
1209
- // We have two planes, n1.p = d1 and n2.p = d2.
1210
- // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2).
1211
- var n1 = [1, 0, 0], // normal
1212
- n2 = cartesianCross(pa, pb),
1213
- n2n2 = cartesianDot(n2, n2),
1214
- n1n2 = n2[0], // cartesianDot(n1, n2),
1215
- determinant = n2n2 - n1n2 * n1n2;
1216
-
1217
- // Two polar points.
1218
- if (!determinant) return !two && a;
1219
-
1220
- var c1 = cr * n2n2 / determinant,
1221
- c2 = -cr * n1n2 / determinant,
1222
- n1xn2 = cartesianCross(n1, n2),
1223
- A = cartesianScale(n1, c1),
1224
- B = cartesianScale(n2, c2);
1225
- cartesianAddInPlace(A, B);
1226
-
1227
- // Solve |p(t)|^2 = 1.
1228
- var u = n1xn2,
1229
- w = cartesianDot(A, u),
1230
- uu = cartesianDot(u, u),
1231
- t2 = w * w - uu * (cartesianDot(A, A) - 1);
1232
-
1233
- if (t2 < 0) return;
1234
-
1235
- var t = sqrt(t2),
1236
- q = cartesianScale(u, (-w - t) / uu);
1237
- cartesianAddInPlace(q, A);
1238
- q = spherical(q);
1239
-
1240
- if (!two) return q;
1241
-
1242
- // Two intersection points.
1243
- var lambda0 = a[0],
1244
- lambda1 = b[0],
1245
- phi0 = a[1],
1246
- phi1 = b[1],
1247
- z;
1248
-
1249
- if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z;
1250
-
1251
- var delta = lambda1 - lambda0,
1252
- polar = abs(delta - pi) < epsilon,
1253
- meridian = polar || delta < epsilon;
1254
-
1255
- if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z;
1256
-
1257
- // Check that the first point is between a and b.
1258
- if (meridian
1259
- ? polar
1260
- ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon ? phi0 : phi1)
1261
- : phi0 <= q[1] && q[1] <= phi1
1262
- : delta > pi ^ (lambda0 <= q[0] && q[0] <= lambda1)) {
1263
- var q1 = cartesianScale(u, (-w + t) / uu);
1264
- cartesianAddInPlace(q1, A);
1265
- return [q, spherical(q1)];
1266
- }
1267
- }
1268
-
1269
- // Generates a 4-bit vector representing the location of a point relative to
1270
- // the small circle's bounding box.
1271
- function code(lambda, phi) {
1272
- var r = smallRadius ? radius : pi - radius,
1273
- code = 0;
1274
- if (lambda < -r) code |= 1; // left
1275
- else if (lambda > r) code |= 2; // right
1276
- if (phi < -r) code |= 4; // below
1277
- else if (phi > r) code |= 8; // above
1278
- return code;
1279
- }
1280
-
1281
- return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi, radius - pi]);
1282
- }
1283
-
1284
- function clipLine(a, b, x0, y0, x1, y1) {
1285
- var ax = a[0],
1286
- ay = a[1],
1287
- bx = b[0],
1288
- by = b[1],
1289
- t0 = 0,
1290
- t1 = 1,
1291
- dx = bx - ax,
1292
- dy = by - ay,
1293
- r;
1294
-
1295
- r = x0 - ax;
1296
- if (!dx && r > 0) return;
1297
- r /= dx;
1298
- if (dx < 0) {
1299
- if (r < t0) return;
1300
- if (r < t1) t1 = r;
1301
- } else if (dx > 0) {
1302
- if (r > t1) return;
1303
- if (r > t0) t0 = r;
1304
- }
1305
-
1306
- r = x1 - ax;
1307
- if (!dx && r < 0) return;
1308
- r /= dx;
1309
- if (dx < 0) {
1310
- if (r > t1) return;
1311
- if (r > t0) t0 = r;
1312
- } else if (dx > 0) {
1313
- if (r < t0) return;
1314
- if (r < t1) t1 = r;
1315
- }
1316
-
1317
- r = y0 - ay;
1318
- if (!dy && r > 0) return;
1319
- r /= dy;
1320
- if (dy < 0) {
1321
- if (r < t0) return;
1322
- if (r < t1) t1 = r;
1323
- } else if (dy > 0) {
1324
- if (r > t1) return;
1325
- if (r > t0) t0 = r;
1326
- }
1327
-
1328
- r = y1 - ay;
1329
- if (!dy && r < 0) return;
1330
- r /= dy;
1331
- if (dy < 0) {
1332
- if (r > t1) return;
1333
- if (r > t0) t0 = r;
1334
- } else if (dy > 0) {
1335
- if (r < t0) return;
1336
- if (r < t1) t1 = r;
1337
- }
1338
-
1339
- if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy;
1340
- if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy;
1341
- return true;
1342
- }
1343
-
1344
- var clipMax = 1e9, clipMin = -clipMax;
1345
-
1346
- // TODO Use d3-polygon’s polygonContains here for the ring check?
1347
- // TODO Eliminate duplicate buffering in clipBuffer and polygon.push?
1348
-
1349
- function clipRectangle(x0, y0, x1, y1) {
1350
-
1351
- function visible(x, y) {
1352
- return x0 <= x && x <= x1 && y0 <= y && y <= y1;
1353
- }
1354
-
1355
- function interpolate(from, to, direction, stream) {
1356
- var a = 0, a1 = 0;
1357
- if (from == null
1358
- || (a = corner(from, direction)) !== (a1 = corner(to, direction))
1359
- || comparePoint(from, to) < 0 ^ direction > 0) {
1360
- do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);
1361
- while ((a = (a + direction + 4) % 4) !== a1);
1362
- } else {
1363
- stream.point(to[0], to[1]);
1364
- }
1365
- }
1366
-
1367
- function corner(p, direction) {
1368
- return abs(p[0] - x0) < epsilon ? direction > 0 ? 0 : 3
1369
- : abs(p[0] - x1) < epsilon ? direction > 0 ? 2 : 1
1370
- : abs(p[1] - y0) < epsilon ? direction > 0 ? 1 : 0
1371
- : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon
1372
- }
1373
-
1374
- function compareIntersection(a, b) {
1375
- return comparePoint(a.x, b.x);
1376
- }
1377
-
1378
- function comparePoint(a, b) {
1379
- var ca = corner(a, 1),
1380
- cb = corner(b, 1);
1381
- return ca !== cb ? ca - cb
1382
- : ca === 0 ? b[1] - a[1]
1383
- : ca === 1 ? a[0] - b[0]
1384
- : ca === 2 ? a[1] - b[1]
1385
- : b[0] - a[0];
1386
- }
1387
-
1388
- return function(stream) {
1389
- var activeStream = stream,
1390
- bufferStream = clipBuffer(),
1391
- segments,
1392
- polygon,
1393
- ring,
1394
- x__, y__, v__, // first point
1395
- x_, y_, v_, // previous point
1396
- first,
1397
- clean;
1398
-
1399
- var clipStream = {
1400
- point: point,
1401
- lineStart: lineStart,
1402
- lineEnd: lineEnd,
1403
- polygonStart: polygonStart,
1404
- polygonEnd: polygonEnd
1405
- };
1406
-
1407
- function point(x, y) {
1408
- if (visible(x, y)) activeStream.point(x, y);
1409
- }
1410
-
1411
- function polygonInside() {
1412
- var winding = 0;
1413
-
1414
- for (var i = 0, n = polygon.length; i < n; ++i) {
1415
- for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) {
1416
- a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1];
1417
- if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; }
1418
- else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; }
1419
- }
1420
- }
1421
-
1422
- return winding;
1423
- }
1424
-
1425
- // Buffer geometry within a polygon and then clip it en masse.
1426
- function polygonStart() {
1427
- activeStream = bufferStream, segments = [], polygon = [], clean = true;
1428
- }
1429
-
1430
- function polygonEnd() {
1431
- var startInside = polygonInside(),
1432
- cleanInside = clean && startInside,
1433
- visible = (segments = d3Array.merge(segments)).length;
1434
- if (cleanInside || visible) {
1435
- stream.polygonStart();
1436
- if (cleanInside) {
1437
- stream.lineStart();
1438
- interpolate(null, null, 1, stream);
1439
- stream.lineEnd();
1440
- }
1441
- if (visible) {
1442
- clipRejoin(segments, compareIntersection, startInside, interpolate, stream);
1443
- }
1444
- stream.polygonEnd();
1445
- }
1446
- activeStream = stream, segments = polygon = ring = null;
1447
- }
1448
-
1449
- function lineStart() {
1450
- clipStream.point = linePoint;
1451
- if (polygon) polygon.push(ring = []);
1452
- first = true;
1453
- v_ = false;
1454
- x_ = y_ = NaN;
1455
- }
1456
-
1457
- // TODO rather than special-case polygons, simply handle them separately.
1458
- // Ideally, coincident intersection points should be jittered to avoid
1459
- // clipping issues.
1460
- function lineEnd() {
1461
- if (segments) {
1462
- linePoint(x__, y__);
1463
- if (v__ && v_) bufferStream.rejoin();
1464
- segments.push(bufferStream.result());
1465
- }
1466
- clipStream.point = point;
1467
- if (v_) activeStream.lineEnd();
1468
- }
1469
-
1470
- function linePoint(x, y) {
1471
- var v = visible(x, y);
1472
- if (polygon) ring.push([x, y]);
1473
- if (first) {
1474
- x__ = x, y__ = y, v__ = v;
1475
- first = false;
1476
- if (v) {
1477
- activeStream.lineStart();
1478
- activeStream.point(x, y);
1479
- }
1480
- } else {
1481
- if (v && v_) activeStream.point(x, y);
1482
- else {
1483
- var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))],
1484
- b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))];
1485
- if (clipLine(a, b, x0, y0, x1, y1)) {
1486
- if (!v_) {
1487
- activeStream.lineStart();
1488
- activeStream.point(a[0], a[1]);
1489
- }
1490
- activeStream.point(b[0], b[1]);
1491
- if (!v) activeStream.lineEnd();
1492
- clean = false;
1493
- } else if (v) {
1494
- activeStream.lineStart();
1495
- activeStream.point(x, y);
1496
- clean = false;
1497
- }
1498
- }
1499
- }
1500
- x_ = x, y_ = y, v_ = v;
1501
- }
1502
-
1503
- return clipStream;
1504
- };
1505
- }
1506
-
1507
- function extent() {
1508
- var x0 = 0,
1509
- y0 = 0,
1510
- x1 = 960,
1511
- y1 = 500,
1512
- cache,
1513
- cacheStream,
1514
- clip;
1515
-
1516
- return clip = {
1517
- stream: function(stream) {
1518
- return cache && cacheStream === stream ? cache : cache = clipRectangle(x0, y0, x1, y1)(cacheStream = stream);
1519
- },
1520
- extent: function(_) {
1521
- return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]];
1522
- }
1523
- };
1524
- }
1525
-
1526
- var lengthSum,
1527
- lambda0$2,
1528
- sinPhi0$1,
1529
- cosPhi0$1;
1530
-
1531
- var lengthStream = {
1532
- sphere: noop,
1533
- point: noop,
1534
- lineStart: lengthLineStart,
1535
- lineEnd: noop,
1536
- polygonStart: noop,
1537
- polygonEnd: noop
1538
- };
1539
-
1540
- function lengthLineStart() {
1541
- lengthStream.point = lengthPointFirst;
1542
- lengthStream.lineEnd = lengthLineEnd;
1543
- }
1544
-
1545
- function lengthLineEnd() {
1546
- lengthStream.point = lengthStream.lineEnd = noop;
1547
- }
1548
-
1549
- function lengthPointFirst(lambda, phi) {
1550
- lambda *= radians, phi *= radians;
1551
- lambda0$2 = lambda, sinPhi0$1 = sin(phi), cosPhi0$1 = cos(phi);
1552
- lengthStream.point = lengthPoint;
1553
- }
1554
-
1555
- function lengthPoint(lambda, phi) {
1556
- lambda *= radians, phi *= radians;
1557
- var sinPhi = sin(phi),
1558
- cosPhi = cos(phi),
1559
- delta = abs(lambda - lambda0$2),
1560
- cosDelta = cos(delta),
1561
- sinDelta = sin(delta),
1562
- x = cosPhi * sinDelta,
1563
- y = cosPhi0$1 * sinPhi - sinPhi0$1 * cosPhi * cosDelta,
1564
- z = sinPhi0$1 * sinPhi + cosPhi0$1 * cosPhi * cosDelta;
1565
- lengthSum.add(atan2(sqrt(x * x + y * y), z));
1566
- lambda0$2 = lambda, sinPhi0$1 = sinPhi, cosPhi0$1 = cosPhi;
1567
- }
1568
-
1569
- function length(object) {
1570
- lengthSum = new d3Array.Adder();
1571
- geoStream(object, lengthStream);
1572
- return +lengthSum;
1573
- }
1574
-
1575
- var coordinates = [null, null],
1576
- object = {type: "LineString", coordinates: coordinates};
1577
-
1578
- function distance(a, b) {
1579
- coordinates[0] = a;
1580
- coordinates[1] = b;
1581
- return length(object);
1582
- }
1583
-
1584
- var containsObjectType = {
1585
- Feature: function(object, point) {
1586
- return containsGeometry(object.geometry, point);
1587
- },
1588
- FeatureCollection: function(object, point) {
1589
- var features = object.features, i = -1, n = features.length;
1590
- while (++i < n) if (containsGeometry(features[i].geometry, point)) return true;
1591
- return false;
1592
- }
1593
- };
1594
-
1595
- var containsGeometryType = {
1596
- Sphere: function() {
1597
- return true;
1598
- },
1599
- Point: function(object, point) {
1600
- return containsPoint(object.coordinates, point);
1601
- },
1602
- MultiPoint: function(object, point) {
1603
- var coordinates = object.coordinates, i = -1, n = coordinates.length;
1604
- while (++i < n) if (containsPoint(coordinates[i], point)) return true;
1605
- return false;
1606
- },
1607
- LineString: function(object, point) {
1608
- return containsLine(object.coordinates, point);
1609
- },
1610
- MultiLineString: function(object, point) {
1611
- var coordinates = object.coordinates, i = -1, n = coordinates.length;
1612
- while (++i < n) if (containsLine(coordinates[i], point)) return true;
1613
- return false;
1614
- },
1615
- Polygon: function(object, point) {
1616
- return containsPolygon(object.coordinates, point);
1617
- },
1618
- MultiPolygon: function(object, point) {
1619
- var coordinates = object.coordinates, i = -1, n = coordinates.length;
1620
- while (++i < n) if (containsPolygon(coordinates[i], point)) return true;
1621
- return false;
1622
- },
1623
- GeometryCollection: function(object, point) {
1624
- var geometries = object.geometries, i = -1, n = geometries.length;
1625
- while (++i < n) if (containsGeometry(geometries[i], point)) return true;
1626
- return false;
1627
- }
1628
- };
1629
-
1630
- function containsGeometry(geometry, point) {
1631
- return geometry && containsGeometryType.hasOwnProperty(geometry.type)
1632
- ? containsGeometryType[geometry.type](geometry, point)
1633
- : false;
1634
- }
1635
-
1636
- function containsPoint(coordinates, point) {
1637
- return distance(coordinates, point) === 0;
1638
- }
1639
-
1640
- function containsLine(coordinates, point) {
1641
- var ao, bo, ab;
1642
- for (var i = 0, n = coordinates.length; i < n; i++) {
1643
- bo = distance(coordinates[i], point);
1644
- if (bo === 0) return true;
1645
- if (i > 0) {
1646
- ab = distance(coordinates[i], coordinates[i - 1]);
1647
- if (
1648
- ab > 0 &&
1649
- ao <= ab &&
1650
- bo <= ab &&
1651
- (ao + bo - ab) * (1 - Math.pow((ao - bo) / ab, 2)) < epsilon2 * ab
1652
- )
1653
- return true;
1654
- }
1655
- ao = bo;
1656
- }
1657
- return false;
1658
- }
1659
-
1660
- function containsPolygon(coordinates, point) {
1661
- return !!polygonContains(coordinates.map(ringRadians), pointRadians(point));
1662
- }
1663
-
1664
- function ringRadians(ring) {
1665
- return ring = ring.map(pointRadians), ring.pop(), ring;
1666
- }
1667
-
1668
- function pointRadians(point) {
1669
- return [point[0] * radians, point[1] * radians];
1670
- }
1671
-
1672
- function contains(object, point) {
1673
- return (object && containsObjectType.hasOwnProperty(object.type)
1674
- ? containsObjectType[object.type]
1675
- : containsGeometry)(object, point);
1676
- }
1677
-
1678
- function graticuleX(y0, y1, dy) {
1679
- var y = d3Array.range(y0, y1 - epsilon, dy).concat(y1);
1680
- return function(x) { return y.map(function(y) { return [x, y]; }); };
1681
- }
1682
-
1683
- function graticuleY(x0, x1, dx) {
1684
- var x = d3Array.range(x0, x1 - epsilon, dx).concat(x1);
1685
- return function(y) { return x.map(function(x) { return [x, y]; }); };
1686
- }
1687
-
1688
- function graticule() {
1689
- var x1, x0, X1, X0,
1690
- y1, y0, Y1, Y0,
1691
- dx = 10, dy = dx, DX = 90, DY = 360,
1692
- x, y, X, Y,
1693
- precision = 2.5;
1694
-
1695
- function graticule() {
1696
- return {type: "MultiLineString", coordinates: lines()};
1697
- }
1698
-
1699
- function lines() {
1700
- return d3Array.range(ceil(X0 / DX) * DX, X1, DX).map(X)
1701
- .concat(d3Array.range(ceil(Y0 / DY) * DY, Y1, DY).map(Y))
1702
- .concat(d3Array.range(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon; }).map(x))
1703
- .concat(d3Array.range(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon; }).map(y));
1704
- }
1705
-
1706
- graticule.lines = function() {
1707
- return lines().map(function(coordinates) { return {type: "LineString", coordinates: coordinates}; });
1708
- };
1709
-
1710
- graticule.outline = function() {
1711
- return {
1712
- type: "Polygon",
1713
- coordinates: [
1714
- X(X0).concat(
1715
- Y(Y1).slice(1),
1716
- X(X1).reverse().slice(1),
1717
- Y(Y0).reverse().slice(1))
1718
- ]
1719
- };
1720
- };
1721
-
1722
- graticule.extent = function(_) {
1723
- if (!arguments.length) return graticule.extentMinor();
1724
- return graticule.extentMajor(_).extentMinor(_);
1725
- };
1726
-
1727
- graticule.extentMajor = function(_) {
1728
- if (!arguments.length) return [[X0, Y0], [X1, Y1]];
1729
- X0 = +_[0][0], X1 = +_[1][0];
1730
- Y0 = +_[0][1], Y1 = +_[1][1];
1731
- if (X0 > X1) _ = X0, X0 = X1, X1 = _;
1732
- if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;
1733
- return graticule.precision(precision);
1734
- };
1735
-
1736
- graticule.extentMinor = function(_) {
1737
- if (!arguments.length) return [[x0, y0], [x1, y1]];
1738
- x0 = +_[0][0], x1 = +_[1][0];
1739
- y0 = +_[0][1], y1 = +_[1][1];
1740
- if (x0 > x1) _ = x0, x0 = x1, x1 = _;
1741
- if (y0 > y1) _ = y0, y0 = y1, y1 = _;
1742
- return graticule.precision(precision);
1743
- };
1744
-
1745
- graticule.step = function(_) {
1746
- if (!arguments.length) return graticule.stepMinor();
1747
- return graticule.stepMajor(_).stepMinor(_);
1748
- };
1749
-
1750
- graticule.stepMajor = function(_) {
1751
- if (!arguments.length) return [DX, DY];
1752
- DX = +_[0], DY = +_[1];
1753
- return graticule;
1754
- };
1755
-
1756
- graticule.stepMinor = function(_) {
1757
- if (!arguments.length) return [dx, dy];
1758
- dx = +_[0], dy = +_[1];
1759
- return graticule;
1760
- };
1761
-
1762
- graticule.precision = function(_) {
1763
- if (!arguments.length) return precision;
1764
- precision = +_;
1765
- x = graticuleX(y0, y1, 90);
1766
- y = graticuleY(x0, x1, precision);
1767
- X = graticuleX(Y0, Y1, 90);
1768
- Y = graticuleY(X0, X1, precision);
1769
- return graticule;
1770
- };
1771
-
1772
- return graticule
1773
- .extentMajor([[-180, -90 + epsilon], [180, 90 - epsilon]])
1774
- .extentMinor([[-180, -80 - epsilon], [180, 80 + epsilon]]);
1775
- }
1776
-
1777
- function graticule10() {
1778
- return graticule()();
1779
- }
1780
-
1781
- function interpolate(a, b) {
1782
- var x0 = a[0] * radians,
1783
- y0 = a[1] * radians,
1784
- x1 = b[0] * radians,
1785
- y1 = b[1] * radians,
1786
- cy0 = cos(y0),
1787
- sy0 = sin(y0),
1788
- cy1 = cos(y1),
1789
- sy1 = sin(y1),
1790
- kx0 = cy0 * cos(x0),
1791
- ky0 = cy0 * sin(x0),
1792
- kx1 = cy1 * cos(x1),
1793
- ky1 = cy1 * sin(x1),
1794
- d = 2 * asin(sqrt(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))),
1795
- k = sin(d);
1796
-
1797
- var interpolate = d ? function(t) {
1798
- var B = sin(t *= d) / k,
1799
- A = sin(d - t) / k,
1800
- x = A * kx0 + B * kx1,
1801
- y = A * ky0 + B * ky1,
1802
- z = A * sy0 + B * sy1;
1803
- return [
1804
- atan2(y, x) * degrees,
1805
- atan2(z, sqrt(x * x + y * y)) * degrees
1806
- ];
1807
- } : function() {
1808
- return [x0 * degrees, y0 * degrees];
1809
- };
1810
-
1811
- interpolate.distance = d;
1812
-
1813
- return interpolate;
1814
- }
1815
-
1816
- var identity = x => x;
1817
-
1818
- var areaSum$1 = new d3Array.Adder(),
1819
- areaRingSum$1 = new d3Array.Adder(),
1820
- x00,
1821
- y00,
1822
- x0$1,
1823
- y0$1;
1824
-
1825
- var areaStream$1 = {
1826
- point: noop,
1827
- lineStart: noop,
1828
- lineEnd: noop,
1829
- polygonStart: function() {
1830
- areaStream$1.lineStart = areaRingStart$1;
1831
- areaStream$1.lineEnd = areaRingEnd$1;
1832
- },
1833
- polygonEnd: function() {
1834
- areaStream$1.lineStart = areaStream$1.lineEnd = areaStream$1.point = noop;
1835
- areaSum$1.add(abs(areaRingSum$1));
1836
- areaRingSum$1 = new d3Array.Adder();
1837
- },
1838
- result: function() {
1839
- var area = areaSum$1 / 2;
1840
- areaSum$1 = new d3Array.Adder();
1841
- return area;
1842
- }
1843
- };
1844
-
1845
- function areaRingStart$1() {
1846
- areaStream$1.point = areaPointFirst$1;
1847
- }
1848
-
1849
- function areaPointFirst$1(x, y) {
1850
- areaStream$1.point = areaPoint$1;
1851
- x00 = x0$1 = x, y00 = y0$1 = y;
1852
- }
1853
-
1854
- function areaPoint$1(x, y) {
1855
- areaRingSum$1.add(y0$1 * x - x0$1 * y);
1856
- x0$1 = x, y0$1 = y;
1857
- }
1858
-
1859
- function areaRingEnd$1() {
1860
- areaPoint$1(x00, y00);
1861
- }
1862
-
1863
- var x0$2 = Infinity,
1864
- y0$2 = x0$2,
1865
- x1 = -x0$2,
1866
- y1 = x1;
1867
-
1868
- var boundsStream$1 = {
1869
- point: boundsPoint$1,
1870
- lineStart: noop,
1871
- lineEnd: noop,
1872
- polygonStart: noop,
1873
- polygonEnd: noop,
1874
- result: function() {
1875
- var bounds = [[x0$2, y0$2], [x1, y1]];
1876
- x1 = y1 = -(y0$2 = x0$2 = Infinity);
1877
- return bounds;
1878
- }
1879
- };
1880
-
1881
- function boundsPoint$1(x, y) {
1882
- if (x < x0$2) x0$2 = x;
1883
- if (x > x1) x1 = x;
1884
- if (y < y0$2) y0$2 = y;
1885
- if (y > y1) y1 = y;
1886
- }
1887
-
1888
- // TODO Enforce positive area for exterior, negative area for interior?
1889
-
1890
- var X0$1 = 0,
1891
- Y0$1 = 0,
1892
- Z0$1 = 0,
1893
- X1$1 = 0,
1894
- Y1$1 = 0,
1895
- Z1$1 = 0,
1896
- X2$1 = 0,
1897
- Y2$1 = 0,
1898
- Z2$1 = 0,
1899
- x00$1,
1900
- y00$1,
1901
- x0$3,
1902
- y0$3;
1903
-
1904
- var centroidStream$1 = {
1905
- point: centroidPoint$1,
1906
- lineStart: centroidLineStart$1,
1907
- lineEnd: centroidLineEnd$1,
1908
- polygonStart: function() {
1909
- centroidStream$1.lineStart = centroidRingStart$1;
1910
- centroidStream$1.lineEnd = centroidRingEnd$1;
1911
- },
1912
- polygonEnd: function() {
1913
- centroidStream$1.point = centroidPoint$1;
1914
- centroidStream$1.lineStart = centroidLineStart$1;
1915
- centroidStream$1.lineEnd = centroidLineEnd$1;
1916
- },
1917
- result: function() {
1918
- var centroid = Z2$1 ? [X2$1 / Z2$1, Y2$1 / Z2$1]
1919
- : Z1$1 ? [X1$1 / Z1$1, Y1$1 / Z1$1]
1920
- : Z0$1 ? [X0$1 / Z0$1, Y0$1 / Z0$1]
1921
- : [NaN, NaN];
1922
- X0$1 = Y0$1 = Z0$1 =
1923
- X1$1 = Y1$1 = Z1$1 =
1924
- X2$1 = Y2$1 = Z2$1 = 0;
1925
- return centroid;
1926
- }
1927
- };
1928
-
1929
- function centroidPoint$1(x, y) {
1930
- X0$1 += x;
1931
- Y0$1 += y;
1932
- ++Z0$1;
1933
- }
1934
-
1935
- function centroidLineStart$1() {
1936
- centroidStream$1.point = centroidPointFirstLine;
1937
- }
1938
-
1939
- function centroidPointFirstLine(x, y) {
1940
- centroidStream$1.point = centroidPointLine;
1941
- centroidPoint$1(x0$3 = x, y0$3 = y);
1942
- }
1943
-
1944
- function centroidPointLine(x, y) {
1945
- var dx = x - x0$3, dy = y - y0$3, z = sqrt(dx * dx + dy * dy);
1946
- X1$1 += z * (x0$3 + x) / 2;
1947
- Y1$1 += z * (y0$3 + y) / 2;
1948
- Z1$1 += z;
1949
- centroidPoint$1(x0$3 = x, y0$3 = y);
1950
- }
1951
-
1952
- function centroidLineEnd$1() {
1953
- centroidStream$1.point = centroidPoint$1;
1954
- }
1955
-
1956
- function centroidRingStart$1() {
1957
- centroidStream$1.point = centroidPointFirstRing;
1958
- }
1959
-
1960
- function centroidRingEnd$1() {
1961
- centroidPointRing(x00$1, y00$1);
1962
- }
1963
-
1964
- function centroidPointFirstRing(x, y) {
1965
- centroidStream$1.point = centroidPointRing;
1966
- centroidPoint$1(x00$1 = x0$3 = x, y00$1 = y0$3 = y);
1967
- }
1968
-
1969
- function centroidPointRing(x, y) {
1970
- var dx = x - x0$3,
1971
- dy = y - y0$3,
1972
- z = sqrt(dx * dx + dy * dy);
1973
-
1974
- X1$1 += z * (x0$3 + x) / 2;
1975
- Y1$1 += z * (y0$3 + y) / 2;
1976
- Z1$1 += z;
1977
-
1978
- z = y0$3 * x - x0$3 * y;
1979
- X2$1 += z * (x0$3 + x);
1980
- Y2$1 += z * (y0$3 + y);
1981
- Z2$1 += z * 3;
1982
- centroidPoint$1(x0$3 = x, y0$3 = y);
1983
- }
1984
-
1985
- function PathContext(context) {
1986
- this._context = context;
1987
- }
1988
-
1989
- PathContext.prototype = {
1990
- _radius: 4.5,
1991
- pointRadius: function(_) {
1992
- return this._radius = _, this;
1993
- },
1994
- polygonStart: function() {
1995
- this._line = 0;
1996
- },
1997
- polygonEnd: function() {
1998
- this._line = NaN;
1999
- },
2000
- lineStart: function() {
2001
- this._point = 0;
2002
- },
2003
- lineEnd: function() {
2004
- if (this._line === 0) this._context.closePath();
2005
- this._point = NaN;
2006
- },
2007
- point: function(x, y) {
2008
- switch (this._point) {
2009
- case 0: {
2010
- this._context.moveTo(x, y);
2011
- this._point = 1;
2012
- break;
2013
- }
2014
- case 1: {
2015
- this._context.lineTo(x, y);
2016
- break;
2017
- }
2018
- default: {
2019
- this._context.moveTo(x + this._radius, y);
2020
- this._context.arc(x, y, this._radius, 0, tau);
2021
- break;
2022
- }
2023
- }
2024
- },
2025
- result: noop
2026
- };
2027
-
2028
- var lengthSum$1 = new d3Array.Adder(),
2029
- lengthRing,
2030
- x00$2,
2031
- y00$2,
2032
- x0$4,
2033
- y0$4;
2034
-
2035
- var lengthStream$1 = {
2036
- point: noop,
2037
- lineStart: function() {
2038
- lengthStream$1.point = lengthPointFirst$1;
2039
- },
2040
- lineEnd: function() {
2041
- if (lengthRing) lengthPoint$1(x00$2, y00$2);
2042
- lengthStream$1.point = noop;
2043
- },
2044
- polygonStart: function() {
2045
- lengthRing = true;
2046
- },
2047
- polygonEnd: function() {
2048
- lengthRing = null;
2049
- },
2050
- result: function() {
2051
- var length = +lengthSum$1;
2052
- lengthSum$1 = new d3Array.Adder();
2053
- return length;
2054
- }
2055
- };
2056
-
2057
- function lengthPointFirst$1(x, y) {
2058
- lengthStream$1.point = lengthPoint$1;
2059
- x00$2 = x0$4 = x, y00$2 = y0$4 = y;
2060
- }
2061
-
2062
- function lengthPoint$1(x, y) {
2063
- x0$4 -= x, y0$4 -= y;
2064
- lengthSum$1.add(sqrt(x0$4 * x0$4 + y0$4 * y0$4));
2065
- x0$4 = x, y0$4 = y;
2066
- }
2067
-
2068
- function PathString() {
2069
- this._string = [];
2070
- }
2071
-
2072
- PathString.prototype = {
2073
- _radius: 4.5,
2074
- _circle: circle$1(4.5),
2075
- pointRadius: function(_) {
2076
- if ((_ = +_) !== this._radius) this._radius = _, this._circle = null;
2077
- return this;
2078
- },
2079
- polygonStart: function() {
2080
- this._line = 0;
2081
- },
2082
- polygonEnd: function() {
2083
- this._line = NaN;
2084
- },
2085
- lineStart: function() {
2086
- this._point = 0;
2087
- },
2088
- lineEnd: function() {
2089
- if (this._line === 0) this._string.push("Z");
2090
- this._point = NaN;
2091
- },
2092
- point: function(x, y) {
2093
- switch (this._point) {
2094
- case 0: {
2095
- this._string.push("M", x, ",", y);
2096
- this._point = 1;
2097
- break;
2098
- }
2099
- case 1: {
2100
- this._string.push("L", x, ",", y);
2101
- break;
2102
- }
2103
- default: {
2104
- if (this._circle == null) this._circle = circle$1(this._radius);
2105
- this._string.push("M", x, ",", y, this._circle);
2106
- break;
2107
- }
2108
- }
2109
- },
2110
- result: function() {
2111
- if (this._string.length) {
2112
- var result = this._string.join("");
2113
- this._string = [];
2114
- return result;
2115
- } else {
2116
- return null;
2117
- }
2118
- }
2119
- };
2120
-
2121
- function circle$1(radius) {
2122
- return "m0," + radius
2123
- + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius
2124
- + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius
2125
- + "z";
2126
- }
2127
-
2128
- function index(projection, context) {
2129
- var pointRadius = 4.5,
2130
- projectionStream,
2131
- contextStream;
2132
-
2133
- function path(object) {
2134
- if (object) {
2135
- if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments));
2136
- geoStream(object, projectionStream(contextStream));
2137
- }
2138
- return contextStream.result();
2139
- }
2140
-
2141
- path.area = function(object) {
2142
- geoStream(object, projectionStream(areaStream$1));
2143
- return areaStream$1.result();
2144
- };
2145
-
2146
- path.measure = function(object) {
2147
- geoStream(object, projectionStream(lengthStream$1));
2148
- return lengthStream$1.result();
2149
- };
2150
-
2151
- path.bounds = function(object) {
2152
- geoStream(object, projectionStream(boundsStream$1));
2153
- return boundsStream$1.result();
2154
- };
2155
-
2156
- path.centroid = function(object) {
2157
- geoStream(object, projectionStream(centroidStream$1));
2158
- return centroidStream$1.result();
2159
- };
2160
-
2161
- path.projection = function(_) {
2162
- return arguments.length ? (projectionStream = _ == null ? (projection = null, identity) : (projection = _).stream, path) : projection;
2163
- };
2164
-
2165
- path.context = function(_) {
2166
- if (!arguments.length) return context;
2167
- contextStream = _ == null ? (context = null, new PathString) : new PathContext(context = _);
2168
- if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius);
2169
- return path;
2170
- };
2171
-
2172
- path.pointRadius = function(_) {
2173
- if (!arguments.length) return pointRadius;
2174
- pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_);
2175
- return path;
2176
- };
2177
-
2178
- return path.projection(projection).context(context);
2179
- }
2180
-
2181
- function transform(methods) {
2182
- return {
2183
- stream: transformer(methods)
2184
- };
2185
- }
2186
-
2187
- function transformer(methods) {
2188
- return function(stream) {
2189
- var s = new TransformStream;
2190
- for (var key in methods) s[key] = methods[key];
2191
- s.stream = stream;
2192
- return s;
2193
- };
2194
- }
2195
-
2196
- function TransformStream() {}
2197
-
2198
- TransformStream.prototype = {
2199
- constructor: TransformStream,
2200
- point: function(x, y) { this.stream.point(x, y); },
2201
- sphere: function() { this.stream.sphere(); },
2202
- lineStart: function() { this.stream.lineStart(); },
2203
- lineEnd: function() { this.stream.lineEnd(); },
2204
- polygonStart: function() { this.stream.polygonStart(); },
2205
- polygonEnd: function() { this.stream.polygonEnd(); }
2206
- };
2207
-
2208
- function fit(projection, fitBounds, object) {
2209
- var clip = projection.clipExtent && projection.clipExtent();
2210
- projection.scale(150).translate([0, 0]);
2211
- if (clip != null) projection.clipExtent(null);
2212
- geoStream(object, projection.stream(boundsStream$1));
2213
- fitBounds(boundsStream$1.result());
2214
- if (clip != null) projection.clipExtent(clip);
2215
- return projection;
2216
- }
2217
-
2218
- function fitExtent(projection, extent, object) {
2219
- return fit(projection, function(b) {
2220
- var w = extent[1][0] - extent[0][0],
2221
- h = extent[1][1] - extent[0][1],
2222
- k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])),
2223
- x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2,
2224
- y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;
2225
- projection.scale(150 * k).translate([x, y]);
2226
- }, object);
2227
- }
2228
-
2229
- function fitSize(projection, size, object) {
2230
- return fitExtent(projection, [[0, 0], size], object);
2231
- }
2232
-
2233
- function fitWidth(projection, width, object) {
2234
- return fit(projection, function(b) {
2235
- var w = +width,
2236
- k = w / (b[1][0] - b[0][0]),
2237
- x = (w - k * (b[1][0] + b[0][0])) / 2,
2238
- y = -k * b[0][1];
2239
- projection.scale(150 * k).translate([x, y]);
2240
- }, object);
2241
- }
2242
-
2243
- function fitHeight(projection, height, object) {
2244
- return fit(projection, function(b) {
2245
- var h = +height,
2246
- k = h / (b[1][1] - b[0][1]),
2247
- x = -k * b[0][0],
2248
- y = (h - k * (b[1][1] + b[0][1])) / 2;
2249
- projection.scale(150 * k).translate([x, y]);
2250
- }, object);
2251
- }
2252
-
2253
- var maxDepth = 16, // maximum depth of subdivision
2254
- cosMinDistance = cos(30 * radians); // cos(minimum angular distance)
2255
-
2256
- function resample(project, delta2) {
2257
- return +delta2 ? resample$1(project, delta2) : resampleNone(project);
2258
- }
2259
-
2260
- function resampleNone(project) {
2261
- return transformer({
2262
- point: function(x, y) {
2263
- x = project(x, y);
2264
- this.stream.point(x[0], x[1]);
2265
- }
2266
- });
2267
- }
2268
-
2269
- function resample$1(project, delta2) {
2270
-
2271
- function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) {
2272
- var dx = x1 - x0,
2273
- dy = y1 - y0,
2274
- d2 = dx * dx + dy * dy;
2275
- if (d2 > 4 * delta2 && depth--) {
2276
- var a = a0 + a1,
2277
- b = b0 + b1,
2278
- c = c0 + c1,
2279
- m = sqrt(a * a + b * b + c * c),
2280
- phi2 = asin(c /= m),
2281
- lambda2 = abs(abs(c) - 1) < epsilon || abs(lambda0 - lambda1) < epsilon ? (lambda0 + lambda1) / 2 : atan2(b, a),
2282
- p = project(lambda2, phi2),
2283
- x2 = p[0],
2284
- y2 = p[1],
2285
- dx2 = x2 - x0,
2286
- dy2 = y2 - y0,
2287
- dz = dy * dx2 - dx * dy2;
2288
- if (dz * dz / d2 > delta2 // perpendicular projected distance
2289
- || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end
2290
- || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance
2291
- resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream);
2292
- stream.point(x2, y2);
2293
- resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream);
2294
- }
2295
- }
2296
- }
2297
- return function(stream) {
2298
- var lambda00, x00, y00, a00, b00, c00, // first point
2299
- lambda0, x0, y0, a0, b0, c0; // previous point
2300
-
2301
- var resampleStream = {
2302
- point: point,
2303
- lineStart: lineStart,
2304
- lineEnd: lineEnd,
2305
- polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; },
2306
- polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; }
2307
- };
2308
-
2309
- function point(x, y) {
2310
- x = project(x, y);
2311
- stream.point(x[0], x[1]);
2312
- }
2313
-
2314
- function lineStart() {
2315
- x0 = NaN;
2316
- resampleStream.point = linePoint;
2317
- stream.lineStart();
2318
- }
2319
-
2320
- function linePoint(lambda, phi) {
2321
- var c = cartesian([lambda, phi]), p = project(lambda, phi);
2322
- resampleLineTo(x0, y0, lambda0, a0, b0, c0, x0 = p[0], y0 = p[1], lambda0 = lambda, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);
2323
- stream.point(x0, y0);
2324
- }
2325
-
2326
- function lineEnd() {
2327
- resampleStream.point = point;
2328
- stream.lineEnd();
2329
- }
2330
-
2331
- function ringStart() {
2332
- lineStart();
2333
- resampleStream.point = ringPoint;
2334
- resampleStream.lineEnd = ringEnd;
2335
- }
2336
-
2337
- function ringPoint(lambda, phi) {
2338
- linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;
2339
- resampleStream.point = linePoint;
2340
- }
2341
-
2342
- function ringEnd() {
2343
- resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream);
2344
- resampleStream.lineEnd = lineEnd;
2345
- lineEnd();
2346
- }
2347
-
2348
- return resampleStream;
2349
- };
2350
- }
2351
-
2352
- var transformRadians = transformer({
2353
- point: function(x, y) {
2354
- this.stream.point(x * radians, y * radians);
2355
- }
2356
- });
2357
-
2358
- function transformRotate(rotate) {
2359
- return transformer({
2360
- point: function(x, y) {
2361
- var r = rotate(x, y);
2362
- return this.stream.point(r[0], r[1]);
2363
- }
2364
- });
2365
- }
2366
-
2367
- function scaleTranslate(k, dx, dy, sx, sy) {
2368
- function transform(x, y) {
2369
- x *= sx; y *= sy;
2370
- return [dx + k * x, dy - k * y];
2371
- }
2372
- transform.invert = function(x, y) {
2373
- return [(x - dx) / k * sx, (dy - y) / k * sy];
2374
- };
2375
- return transform;
2376
- }
2377
-
2378
- function scaleTranslateRotate(k, dx, dy, sx, sy, alpha) {
2379
- if (!alpha) return scaleTranslate(k, dx, dy, sx, sy);
2380
- var cosAlpha = cos(alpha),
2381
- sinAlpha = sin(alpha),
2382
- a = cosAlpha * k,
2383
- b = sinAlpha * k,
2384
- ai = cosAlpha / k,
2385
- bi = sinAlpha / k,
2386
- ci = (sinAlpha * dy - cosAlpha * dx) / k,
2387
- fi = (sinAlpha * dx + cosAlpha * dy) / k;
2388
- function transform(x, y) {
2389
- x *= sx; y *= sy;
2390
- return [a * x - b * y + dx, dy - b * x - a * y];
2391
- }
2392
- transform.invert = function(x, y) {
2393
- return [sx * (ai * x - bi * y + ci), sy * (fi - bi * x - ai * y)];
2394
- };
2395
- return transform;
2396
- }
2397
-
2398
- function projection(project) {
2399
- return projectionMutator(function() { return project; })();
2400
- }
2401
-
2402
- function projectionMutator(projectAt) {
2403
- var project,
2404
- k = 150, // scale
2405
- x = 480, y = 250, // translate
2406
- lambda = 0, phi = 0, // center
2407
- deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, // pre-rotate
2408
- alpha = 0, // post-rotate angle
2409
- sx = 1, // reflectX
2410
- sy = 1, // reflectX
2411
- theta = null, preclip = clipAntimeridian, // pre-clip angle
2412
- x0 = null, y0, x1, y1, postclip = identity, // post-clip extent
2413
- delta2 = 0.5, // precision
2414
- projectResample,
2415
- projectTransform,
2416
- projectRotateTransform,
2417
- cache,
2418
- cacheStream;
2419
-
2420
- function projection(point) {
2421
- return projectRotateTransform(point[0] * radians, point[1] * radians);
2422
- }
2423
-
2424
- function invert(point) {
2425
- point = projectRotateTransform.invert(point[0], point[1]);
2426
- return point && [point[0] * degrees, point[1] * degrees];
2427
- }
2428
-
2429
- projection.stream = function(stream) {
2430
- return cache && cacheStream === stream ? cache : cache = transformRadians(transformRotate(rotate)(preclip(projectResample(postclip(cacheStream = stream)))));
2431
- };
2432
-
2433
- projection.preclip = function(_) {
2434
- return arguments.length ? (preclip = _, theta = undefined, reset()) : preclip;
2435
- };
2436
-
2437
- projection.postclip = function(_) {
2438
- return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip;
2439
- };
2440
-
2441
- projection.clipAngle = function(_) {
2442
- return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees;
2443
- };
2444
-
2445
- projection.clipExtent = function(_) {
2446
- return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity) : clipRectangle(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
2447
- };
2448
-
2449
- projection.scale = function(_) {
2450
- return arguments.length ? (k = +_, recenter()) : k;
2451
- };
2452
-
2453
- projection.translate = function(_) {
2454
- return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y];
2455
- };
2456
-
2457
- projection.center = function(_) {
2458
- return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees, phi * degrees];
2459
- };
2460
-
2461
- projection.rotate = function(_) {
2462
- return arguments.length ? (deltaLambda = _[0] % 360 * radians, deltaPhi = _[1] % 360 * radians, deltaGamma = _.length > 2 ? _[2] % 360 * radians : 0, recenter()) : [deltaLambda * degrees, deltaPhi * degrees, deltaGamma * degrees];
2463
- };
2464
-
2465
- projection.angle = function(_) {
2466
- return arguments.length ? (alpha = _ % 360 * radians, recenter()) : alpha * degrees;
2467
- };
2468
-
2469
- projection.reflectX = function(_) {
2470
- return arguments.length ? (sx = _ ? -1 : 1, recenter()) : sx < 0;
2471
- };
2472
-
2473
- projection.reflectY = function(_) {
2474
- return arguments.length ? (sy = _ ? -1 : 1, recenter()) : sy < 0;
2475
- };
2476
-
2477
- projection.precision = function(_) {
2478
- return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt(delta2);
2479
- };
2480
-
2481
- projection.fitExtent = function(extent, object) {
2482
- return fitExtent(projection, extent, object);
2483
- };
2484
-
2485
- projection.fitSize = function(size, object) {
2486
- return fitSize(projection, size, object);
2487
- };
2488
-
2489
- projection.fitWidth = function(width, object) {
2490
- return fitWidth(projection, width, object);
2491
- };
2492
-
2493
- projection.fitHeight = function(height, object) {
2494
- return fitHeight(projection, height, object);
2495
- };
2496
-
2497
- function recenter() {
2498
- var center = scaleTranslateRotate(k, 0, 0, sx, sy, alpha).apply(null, project(lambda, phi)),
2499
- transform = scaleTranslateRotate(k, x - center[0], y - center[1], sx, sy, alpha);
2500
- rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma);
2501
- projectTransform = compose(project, transform);
2502
- projectRotateTransform = compose(rotate, projectTransform);
2503
- projectResample = resample(projectTransform, delta2);
2504
- return reset();
2505
- }
2506
-
2507
- function reset() {
2508
- cache = cacheStream = null;
2509
- return projection;
2510
- }
2511
-
2512
- return function() {
2513
- project = projectAt.apply(this, arguments);
2514
- projection.invert = project.invert && invert;
2515
- return recenter();
2516
- };
2517
- }
2518
-
2519
- function conicProjection(projectAt) {
2520
- var phi0 = 0,
2521
- phi1 = pi / 3,
2522
- m = projectionMutator(projectAt),
2523
- p = m(phi0, phi1);
2524
-
2525
- p.parallels = function(_) {
2526
- return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees, phi1 * degrees];
2527
- };
2528
-
2529
- return p;
2530
- }
2531
-
2532
- function cylindricalEqualAreaRaw(phi0) {
2533
- var cosPhi0 = cos(phi0);
2534
-
2535
- function forward(lambda, phi) {
2536
- return [lambda * cosPhi0, sin(phi) / cosPhi0];
2537
- }
2538
-
2539
- forward.invert = function(x, y) {
2540
- return [x / cosPhi0, asin(y * cosPhi0)];
2541
- };
2542
-
2543
- return forward;
2544
- }
2545
-
2546
- function conicEqualAreaRaw(y0, y1) {
2547
- var sy0 = sin(y0), n = (sy0 + sin(y1)) / 2;
2548
-
2549
- // Are the parallels symmetrical around the Equator?
2550
- if (abs(n) < epsilon) return cylindricalEqualAreaRaw(y0);
2551
-
2552
- var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt(c) / n;
2553
-
2554
- function project(x, y) {
2555
- var r = sqrt(c - 2 * n * sin(y)) / n;
2556
- return [r * sin(x *= n), r0 - r * cos(x)];
2557
- }
2558
-
2559
- project.invert = function(x, y) {
2560
- var r0y = r0 - y,
2561
- l = atan2(x, abs(r0y)) * sign(r0y);
2562
- if (r0y * n < 0)
2563
- l -= pi * sign(x) * sign(r0y);
2564
- return [l / n, asin((c - (x * x + r0y * r0y) * n * n) / (2 * n))];
2565
- };
2566
-
2567
- return project;
2568
- }
2569
-
2570
- function conicEqualArea() {
2571
- return conicProjection(conicEqualAreaRaw)
2572
- .scale(155.424)
2573
- .center([0, 33.6442]);
2574
- }
2575
-
2576
- function albers() {
2577
- return conicEqualArea()
2578
- .parallels([29.5, 45.5])
2579
- .scale(1070)
2580
- .translate([480, 250])
2581
- .rotate([96, 0])
2582
- .center([-0.6, 38.7]);
2583
- }
2584
-
2585
- // The projections must have mutually exclusive clip regions on the sphere,
2586
- // as this will avoid emitting interleaving lines and polygons.
2587
- function multiplex(streams) {
2588
- var n = streams.length;
2589
- return {
2590
- point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); },
2591
- sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); },
2592
- lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); },
2593
- lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); },
2594
- polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); },
2595
- polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); }
2596
- };
2597
- }
2598
-
2599
- // A composite projection for the United States, configured by default for
2600
- // 960×500. The projection also works quite well at 960×600 if you change the
2601
- // scale to 1285 and adjust the translate accordingly. The set of standard
2602
- // parallels for each region comes from USGS, which is published here:
2603
- // http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
2604
- function albersUsa() {
2605
- var cache,
2606
- cacheStream,
2607
- lower48 = albers(), lower48Point,
2608
- alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338
2609
- hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007
2610
- point, pointStream = {point: function(x, y) { point = [x, y]; }};
2611
-
2612
- function albersUsa(coordinates) {
2613
- var x = coordinates[0], y = coordinates[1];
2614
- return point = null,
2615
- (lower48Point.point(x, y), point)
2616
- || (alaskaPoint.point(x, y), point)
2617
- || (hawaiiPoint.point(x, y), point);
2618
- }
2619
-
2620
- albersUsa.invert = function(coordinates) {
2621
- var k = lower48.scale(),
2622
- t = lower48.translate(),
2623
- x = (coordinates[0] - t[0]) / k,
2624
- y = (coordinates[1] - t[1]) / k;
2625
- return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska
2626
- : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii
2627
- : lower48).invert(coordinates);
2628
- };
2629
-
2630
- albersUsa.stream = function(stream) {
2631
- return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]);
2632
- };
2633
-
2634
- albersUsa.precision = function(_) {
2635
- if (!arguments.length) return lower48.precision();
2636
- lower48.precision(_), alaska.precision(_), hawaii.precision(_);
2637
- return reset();
2638
- };
2639
-
2640
- albersUsa.scale = function(_) {
2641
- if (!arguments.length) return lower48.scale();
2642
- lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_);
2643
- return albersUsa.translate(lower48.translate());
2644
- };
2645
-
2646
- albersUsa.translate = function(_) {
2647
- if (!arguments.length) return lower48.translate();
2648
- var k = lower48.scale(), x = +_[0], y = +_[1];
2649
-
2650
- lower48Point = lower48
2651
- .translate(_)
2652
- .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]])
2653
- .stream(pointStream);
2654
-
2655
- alaskaPoint = alaska
2656
- .translate([x - 0.307 * k, y + 0.201 * k])
2657
- .clipExtent([[x - 0.425 * k + epsilon, y + 0.120 * k + epsilon], [x - 0.214 * k - epsilon, y + 0.234 * k - epsilon]])
2658
- .stream(pointStream);
2659
-
2660
- hawaiiPoint = hawaii
2661
- .translate([x - 0.205 * k, y + 0.212 * k])
2662
- .clipExtent([[x - 0.214 * k + epsilon, y + 0.166 * k + epsilon], [x - 0.115 * k - epsilon, y + 0.234 * k - epsilon]])
2663
- .stream(pointStream);
2664
-
2665
- return reset();
2666
- };
2667
-
2668
- albersUsa.fitExtent = function(extent, object) {
2669
- return fitExtent(albersUsa, extent, object);
2670
- };
2671
-
2672
- albersUsa.fitSize = function(size, object) {
2673
- return fitSize(albersUsa, size, object);
2674
- };
2675
-
2676
- albersUsa.fitWidth = function(width, object) {
2677
- return fitWidth(albersUsa, width, object);
2678
- };
2679
-
2680
- albersUsa.fitHeight = function(height, object) {
2681
- return fitHeight(albersUsa, height, object);
2682
- };
2683
-
2684
- function reset() {
2685
- cache = cacheStream = null;
2686
- return albersUsa;
2687
- }
2688
-
2689
- return albersUsa.scale(1070);
2690
- }
2691
-
2692
- function azimuthalRaw(scale) {
2693
- return function(x, y) {
2694
- var cx = cos(x),
2695
- cy = cos(y),
2696
- k = scale(cx * cy);
2697
- if (k === Infinity) return [2, 0];
2698
- return [
2699
- k * cy * sin(x),
2700
- k * sin(y)
2701
- ];
2702
- }
2703
- }
2704
-
2705
- function azimuthalInvert(angle) {
2706
- return function(x, y) {
2707
- var z = sqrt(x * x + y * y),
2708
- c = angle(z),
2709
- sc = sin(c),
2710
- cc = cos(c);
2711
- return [
2712
- atan2(x * sc, z * cc),
2713
- asin(z && y * sc / z)
2714
- ];
2715
- }
2716
- }
2717
-
2718
- var azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) {
2719
- return sqrt(2 / (1 + cxcy));
2720
- });
2721
-
2722
- azimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) {
2723
- return 2 * asin(z / 2);
2724
- });
2725
-
2726
- function azimuthalEqualArea() {
2727
- return projection(azimuthalEqualAreaRaw)
2728
- .scale(124.75)
2729
- .clipAngle(180 - 1e-3);
2730
- }
2731
-
2732
- var azimuthalEquidistantRaw = azimuthalRaw(function(c) {
2733
- return (c = acos(c)) && c / sin(c);
2734
- });
2735
-
2736
- azimuthalEquidistantRaw.invert = azimuthalInvert(function(z) {
2737
- return z;
2738
- });
2739
-
2740
- function azimuthalEquidistant() {
2741
- return projection(azimuthalEquidistantRaw)
2742
- .scale(79.4188)
2743
- .clipAngle(180 - 1e-3);
2744
- }
2745
-
2746
- function mercatorRaw(lambda, phi) {
2747
- return [lambda, log(tan((halfPi + phi) / 2))];
2748
- }
2749
-
2750
- mercatorRaw.invert = function(x, y) {
2751
- return [x, 2 * atan(exp(y)) - halfPi];
2752
- };
2753
-
2754
- function mercator() {
2755
- return mercatorProjection(mercatorRaw)
2756
- .scale(961 / tau);
2757
- }
2758
-
2759
- function mercatorProjection(project) {
2760
- var m = projection(project),
2761
- center = m.center,
2762
- scale = m.scale,
2763
- translate = m.translate,
2764
- clipExtent = m.clipExtent,
2765
- x0 = null, y0, x1, y1; // clip extent
2766
-
2767
- m.scale = function(_) {
2768
- return arguments.length ? (scale(_), reclip()) : scale();
2769
- };
2770
-
2771
- m.translate = function(_) {
2772
- return arguments.length ? (translate(_), reclip()) : translate();
2773
- };
2774
-
2775
- m.center = function(_) {
2776
- return arguments.length ? (center(_), reclip()) : center();
2777
- };
2778
-
2779
- m.clipExtent = function(_) {
2780
- return arguments.length ? ((_ == null ? x0 = y0 = x1 = y1 = null : (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1])), reclip()) : x0 == null ? null : [[x0, y0], [x1, y1]];
2781
- };
2782
-
2783
- function reclip() {
2784
- var k = pi * scale(),
2785
- t = m(rotation(m.rotate()).invert([0, 0]));
2786
- return clipExtent(x0 == null
2787
- ? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project === mercatorRaw
2788
- ? [[Math.max(t[0] - k, x0), y0], [Math.min(t[0] + k, x1), y1]]
2789
- : [[x0, Math.max(t[1] - k, y0)], [x1, Math.min(t[1] + k, y1)]]);
2790
- }
2791
-
2792
- return reclip();
2793
- }
2794
-
2795
- function tany(y) {
2796
- return tan((halfPi + y) / 2);
2797
- }
2798
-
2799
- function conicConformalRaw(y0, y1) {
2800
- var cy0 = cos(y0),
2801
- n = y0 === y1 ? sin(y0) : log(cy0 / cos(y1)) / log(tany(y1) / tany(y0)),
2802
- f = cy0 * pow(tany(y0), n) / n;
2803
-
2804
- if (!n) return mercatorRaw;
2805
-
2806
- function project(x, y) {
2807
- if (f > 0) { if (y < -halfPi + epsilon) y = -halfPi + epsilon; }
2808
- else { if (y > halfPi - epsilon) y = halfPi - epsilon; }
2809
- var r = f / pow(tany(y), n);
2810
- return [r * sin(n * x), f - r * cos(n * x)];
2811
- }
2812
-
2813
- project.invert = function(x, y) {
2814
- var fy = f - y, r = sign(n) * sqrt(x * x + fy * fy),
2815
- l = atan2(x, abs(fy)) * sign(fy);
2816
- if (fy * n < 0)
2817
- l -= pi * sign(x) * sign(fy);
2818
- return [l / n, 2 * atan(pow(f / r, 1 / n)) - halfPi];
2819
- };
2820
-
2821
- return project;
2822
- }
2823
-
2824
- function conicConformal() {
2825
- return conicProjection(conicConformalRaw)
2826
- .scale(109.5)
2827
- .parallels([30, 30]);
2828
- }
2829
-
2830
- function equirectangularRaw(lambda, phi) {
2831
- return [lambda, phi];
2832
- }
2833
-
2834
- equirectangularRaw.invert = equirectangularRaw;
2835
-
2836
- function equirectangular() {
2837
- return projection(equirectangularRaw)
2838
- .scale(152.63);
2839
- }
2840
-
2841
- function conicEquidistantRaw(y0, y1) {
2842
- var cy0 = cos(y0),
2843
- n = y0 === y1 ? sin(y0) : (cy0 - cos(y1)) / (y1 - y0),
2844
- g = cy0 / n + y0;
2845
-
2846
- if (abs(n) < epsilon) return equirectangularRaw;
2847
-
2848
- function project(x, y) {
2849
- var gy = g - y, nx = n * x;
2850
- return [gy * sin(nx), g - gy * cos(nx)];
2851
- }
2852
-
2853
- project.invert = function(x, y) {
2854
- var gy = g - y,
2855
- l = atan2(x, abs(gy)) * sign(gy);
2856
- if (gy * n < 0)
2857
- l -= pi * sign(x) * sign(gy);
2858
- return [l / n, g - sign(n) * sqrt(x * x + gy * gy)];
2859
- };
2860
-
2861
- return project;
2862
- }
2863
-
2864
- function conicEquidistant() {
2865
- return conicProjection(conicEquidistantRaw)
2866
- .scale(131.154)
2867
- .center([0, 13.9389]);
2868
- }
2869
-
2870
- var A1 = 1.340264,
2871
- A2 = -0.081106,
2872
- A3 = 0.000893,
2873
- A4 = 0.003796,
2874
- M = sqrt(3) / 2,
2875
- iterations = 12;
2876
-
2877
- function equalEarthRaw(lambda, phi) {
2878
- var l = asin(M * sin(phi)), l2 = l * l, l6 = l2 * l2 * l2;
2879
- return [
2880
- lambda * cos(l) / (M * (A1 + 3 * A2 * l2 + l6 * (7 * A3 + 9 * A4 * l2))),
2881
- l * (A1 + A2 * l2 + l6 * (A3 + A4 * l2))
2882
- ];
2883
- }
2884
-
2885
- equalEarthRaw.invert = function(x, y) {
2886
- var l = y, l2 = l * l, l6 = l2 * l2 * l2;
2887
- for (var i = 0, delta, fy, fpy; i < iterations; ++i) {
2888
- fy = l * (A1 + A2 * l2 + l6 * (A3 + A4 * l2)) - y;
2889
- fpy = A1 + 3 * A2 * l2 + l6 * (7 * A3 + 9 * A4 * l2);
2890
- l -= delta = fy / fpy, l2 = l * l, l6 = l2 * l2 * l2;
2891
- if (abs(delta) < epsilon2) break;
2892
- }
2893
- return [
2894
- M * x * (A1 + 3 * A2 * l2 + l6 * (7 * A3 + 9 * A4 * l2)) / cos(l),
2895
- asin(sin(l) / M)
2896
- ];
2897
- };
2898
-
2899
- function equalEarth() {
2900
- return projection(equalEarthRaw)
2901
- .scale(177.158);
2902
- }
2903
-
2904
- function gnomonicRaw(x, y) {
2905
- var cy = cos(y), k = cos(x) * cy;
2906
- return [cy * sin(x) / k, sin(y) / k];
2907
- }
2908
-
2909
- gnomonicRaw.invert = azimuthalInvert(atan);
2910
-
2911
- function gnomonic() {
2912
- return projection(gnomonicRaw)
2913
- .scale(144.049)
2914
- .clipAngle(60);
2915
- }
2916
-
2917
- function identity$1() {
2918
- var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, // scale, translate and reflect
2919
- alpha = 0, ca, sa, // angle
2920
- x0 = null, y0, x1, y1, // clip extent
2921
- kx = 1, ky = 1,
2922
- transform = transformer({
2923
- point: function(x, y) {
2924
- var p = projection([x, y]);
2925
- this.stream.point(p[0], p[1]);
2926
- }
2927
- }),
2928
- postclip = identity,
2929
- cache,
2930
- cacheStream;
2931
-
2932
- function reset() {
2933
- kx = k * sx;
2934
- ky = k * sy;
2935
- cache = cacheStream = null;
2936
- return projection;
2937
- }
2938
-
2939
- function projection (p) {
2940
- var x = p[0] * kx, y = p[1] * ky;
2941
- if (alpha) {
2942
- var t = y * ca - x * sa;
2943
- x = x * ca + y * sa;
2944
- y = t;
2945
- }
2946
- return [x + tx, y + ty];
2947
- }
2948
- projection.invert = function(p) {
2949
- var x = p[0] - tx, y = p[1] - ty;
2950
- if (alpha) {
2951
- var t = y * ca + x * sa;
2952
- x = x * ca - y * sa;
2953
- y = t;
2954
- }
2955
- return [x / kx, y / ky];
2956
- };
2957
- projection.stream = function(stream) {
2958
- return cache && cacheStream === stream ? cache : cache = transform(postclip(cacheStream = stream));
2959
- };
2960
- projection.postclip = function(_) {
2961
- return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip;
2962
- };
2963
- projection.clipExtent = function(_) {
2964
- return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity) : clipRectangle(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
2965
- };
2966
- projection.scale = function(_) {
2967
- return arguments.length ? (k = +_, reset()) : k;
2968
- };
2969
- projection.translate = function(_) {
2970
- return arguments.length ? (tx = +_[0], ty = +_[1], reset()) : [tx, ty];
2971
- };
2972
- projection.angle = function(_) {
2973
- return arguments.length ? (alpha = _ % 360 * radians, sa = sin(alpha), ca = cos(alpha), reset()) : alpha * degrees;
2974
- };
2975
- projection.reflectX = function(_) {
2976
- return arguments.length ? (sx = _ ? -1 : 1, reset()) : sx < 0;
2977
- };
2978
- projection.reflectY = function(_) {
2979
- return arguments.length ? (sy = _ ? -1 : 1, reset()) : sy < 0;
2980
- };
2981
- projection.fitExtent = function(extent, object) {
2982
- return fitExtent(projection, extent, object);
2983
- };
2984
- projection.fitSize = function(size, object) {
2985
- return fitSize(projection, size, object);
2986
- };
2987
- projection.fitWidth = function(width, object) {
2988
- return fitWidth(projection, width, object);
2989
- };
2990
- projection.fitHeight = function(height, object) {
2991
- return fitHeight(projection, height, object);
2992
- };
2993
-
2994
- return projection;
2995
- }
2996
-
2997
- function naturalEarth1Raw(lambda, phi) {
2998
- var phi2 = phi * phi, phi4 = phi2 * phi2;
2999
- return [
3000
- lambda * (0.8707 - 0.131979 * phi2 + phi4 * (-0.013791 + phi4 * (0.003971 * phi2 - 0.001529 * phi4))),
3001
- phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4)))
3002
- ];
3003
- }
3004
-
3005
- naturalEarth1Raw.invert = function(x, y) {
3006
- var phi = y, i = 25, delta;
3007
- do {
3008
- var phi2 = phi * phi, phi4 = phi2 * phi2;
3009
- phi -= delta = (phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4))) - y) /
3010
- (1.007226 + phi2 * (0.015085 * 3 + phi4 * (-0.044475 * 7 + 0.028874 * 9 * phi2 - 0.005916 * 11 * phi4)));
3011
- } while (abs(delta) > epsilon && --i > 0);
3012
- return [
3013
- x / (0.8707 + (phi2 = phi * phi) * (-0.131979 + phi2 * (-0.013791 + phi2 * phi2 * phi2 * (0.003971 - 0.001529 * phi2)))),
3014
- phi
3015
- ];
3016
- };
3017
-
3018
- function naturalEarth1() {
3019
- return projection(naturalEarth1Raw)
3020
- .scale(175.295);
3021
- }
3022
-
3023
- function orthographicRaw(x, y) {
3024
- return [cos(y) * sin(x), sin(y)];
3025
- }
3026
-
3027
- orthographicRaw.invert = azimuthalInvert(asin);
3028
-
3029
- function orthographic() {
3030
- return projection(orthographicRaw)
3031
- .scale(249.5)
3032
- .clipAngle(90 + epsilon);
3033
- }
3034
-
3035
- function stereographicRaw(x, y) {
3036
- var cy = cos(y), k = 1 + cos(x) * cy;
3037
- return [cy * sin(x) / k, sin(y) / k];
3038
- }
3039
-
3040
- stereographicRaw.invert = azimuthalInvert(function(z) {
3041
- return 2 * atan(z);
3042
- });
3043
-
3044
- function stereographic() {
3045
- return projection(stereographicRaw)
3046
- .scale(250)
3047
- .clipAngle(142);
3048
- }
3049
-
3050
- function transverseMercatorRaw(lambda, phi) {
3051
- return [log(tan((halfPi + phi) / 2)), -lambda];
3052
- }
3053
-
3054
- transverseMercatorRaw.invert = function(x, y) {
3055
- return [-y, 2 * atan(exp(x)) - halfPi];
3056
- };
3057
-
3058
- function transverseMercator() {
3059
- var m = mercatorProjection(transverseMercatorRaw),
3060
- center = m.center,
3061
- rotate = m.rotate;
3062
-
3063
- m.center = function(_) {
3064
- return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]);
3065
- };
3066
-
3067
- m.rotate = function(_) {
3068
- return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]);
3069
- };
3070
-
3071
- return rotate([0, 0, 90])
3072
- .scale(159.155);
3073
- }
3074
-
3075
- exports.geoAlbers = albers;
3076
- exports.geoAlbersUsa = albersUsa;
3077
- exports.geoArea = area;
3078
- exports.geoAzimuthalEqualArea = azimuthalEqualArea;
3079
- exports.geoAzimuthalEqualAreaRaw = azimuthalEqualAreaRaw;
3080
- exports.geoAzimuthalEquidistant = azimuthalEquidistant;
3081
- exports.geoAzimuthalEquidistantRaw = azimuthalEquidistantRaw;
3082
- exports.geoBounds = bounds;
3083
- exports.geoCentroid = centroid;
3084
- exports.geoCircle = circle;
3085
- exports.geoClipAntimeridian = clipAntimeridian;
3086
- exports.geoClipCircle = clipCircle;
3087
- exports.geoClipExtent = extent;
3088
- exports.geoClipRectangle = clipRectangle;
3089
- exports.geoConicConformal = conicConformal;
3090
- exports.geoConicConformalRaw = conicConformalRaw;
3091
- exports.geoConicEqualArea = conicEqualArea;
3092
- exports.geoConicEqualAreaRaw = conicEqualAreaRaw;
3093
- exports.geoConicEquidistant = conicEquidistant;
3094
- exports.geoConicEquidistantRaw = conicEquidistantRaw;
3095
- exports.geoContains = contains;
3096
- exports.geoDistance = distance;
3097
- exports.geoEqualEarth = equalEarth;
3098
- exports.geoEqualEarthRaw = equalEarthRaw;
3099
- exports.geoEquirectangular = equirectangular;
3100
- exports.geoEquirectangularRaw = equirectangularRaw;
3101
- exports.geoGnomonic = gnomonic;
3102
- exports.geoGnomonicRaw = gnomonicRaw;
3103
- exports.geoGraticule = graticule;
3104
- exports.geoGraticule10 = graticule10;
3105
- exports.geoIdentity = identity$1;
3106
- exports.geoInterpolate = interpolate;
3107
- exports.geoLength = length;
3108
- exports.geoMercator = mercator;
3109
- exports.geoMercatorRaw = mercatorRaw;
3110
- exports.geoNaturalEarth1 = naturalEarth1;
3111
- exports.geoNaturalEarth1Raw = naturalEarth1Raw;
3112
- exports.geoOrthographic = orthographic;
3113
- exports.geoOrthographicRaw = orthographicRaw;
3114
- exports.geoPath = index;
3115
- exports.geoProjection = projection;
3116
- exports.geoProjectionMutator = projectionMutator;
3117
- exports.geoRotation = rotation;
3118
- exports.geoStereographic = stereographic;
3119
- exports.geoStereographicRaw = stereographicRaw;
3120
- exports.geoStream = geoStream;
3121
- exports.geoTransform = transform;
3122
- exports.geoTransverseMercator = transverseMercator;
3123
- exports.geoTransverseMercatorRaw = transverseMercatorRaw;
3124
-
3125
- Object.defineProperty(exports, '__esModule', { value: true });
3126
-
3127
- }));