d3js-plugins-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (152) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/README.md +28 -0
  5. data/Rakefile +1 -0
  6. data/d3js-plugins-rails.gemspec +21 -0
  7. data/lib/d3js-plugins-rails/version.rb +7 -0
  8. data/lib/d3js-plugins-rails.rb +10 -0
  9. data/vendor/assets/javascripts/d3/plugins/.gitignore +1 -0
  10. data/vendor/assets/javascripts/d3/plugins/LICENSE +26 -0
  11. data/vendor/assets/javascripts/d3/plugins/Makefile +87 -0
  12. data/vendor/assets/javascripts/d3/plugins/README.md +19 -0
  13. data/vendor/assets/javascripts/d3/plugins/box/box.js +301 -0
  14. data/vendor/assets/javascripts/d3/plugins/bullet/README.md +14 -0
  15. data/vendor/assets/javascripts/d3/plugins/bullet/bullet.js +241 -0
  16. data/vendor/assets/javascripts/d3/plugins/chernoff/README.md +15 -0
  17. data/vendor/assets/javascripts/d3/plugins/chernoff/chernoff.js +176 -0
  18. data/vendor/assets/javascripts/d3/plugins/cie/README.md +54 -0
  19. data/vendor/assets/javascripts/d3/plugins/cie/cie.js +155 -0
  20. data/vendor/assets/javascripts/d3/plugins/fisheye/README.md +43 -0
  21. data/vendor/assets/javascripts/d3/plugins/fisheye/fisheye.js +85 -0
  22. data/vendor/assets/javascripts/d3/plugins/force_labels/README.md +29 -0
  23. data/vendor/assets/javascripts/d3/plugins/force_labels/force_labels.js +56 -0
  24. data/vendor/assets/javascripts/d3/plugins/geo/polyhedron/README.md +7 -0
  25. data/vendor/assets/javascripts/d3/plugins/geo/polyhedron/polyhedron.js +436 -0
  26. data/vendor/assets/javascripts/d3/plugins/geo/projection/README.md +107 -0
  27. data/vendor/assets/javascripts/d3/plugins/geo/projection/aitoff.js +40 -0
  28. data/vendor/assets/javascripts/d3/plugins/geo/projection/armadillo.js +79 -0
  29. data/vendor/assets/javascripts/d3/plugins/geo/projection/august.js +15 -0
  30. data/vendor/assets/javascripts/d3/plugins/geo/projection/baker.js +28 -0
  31. data/vendor/assets/javascripts/d3/plugins/geo/projection/berghaus.js +60 -0
  32. data/vendor/assets/javascripts/d3/plugins/geo/projection/boggs.js +27 -0
  33. data/vendor/assets/javascripts/d3/plugins/geo/projection/bonne.js +29 -0
  34. data/vendor/assets/javascripts/d3/plugins/geo/projection/bromley.js +5 -0
  35. data/vendor/assets/javascripts/d3/plugins/geo/projection/collignon.js +17 -0
  36. data/vendor/assets/javascripts/d3/plugins/geo/projection/conic-conformal.js +29 -0
  37. data/vendor/assets/javascripts/d3/plugins/geo/projection/conic-equidistant.js +27 -0
  38. data/vendor/assets/javascripts/d3/plugins/geo/projection/craig.js +24 -0
  39. data/vendor/assets/javascripts/d3/plugins/geo/projection/craster.js +18 -0
  40. data/vendor/assets/javascripts/d3/plugins/geo/projection/cylindrical-equal-area.js +23 -0
  41. data/vendor/assets/javascripts/d3/plugins/geo/projection/eckert1.js +18 -0
  42. data/vendor/assets/javascripts/d3/plugins/geo/projection/eckert2.js +17 -0
  43. data/vendor/assets/javascripts/d3/plugins/geo/projection/eckert3.js +17 -0
  44. data/vendor/assets/javascripts/d3/plugins/geo/projection/eckert4.js +24 -0
  45. data/vendor/assets/javascripts/d3/plugins/geo/projection/eckert5.js +17 -0
  46. data/vendor/assets/javascripts/d3/plugins/geo/projection/eckert6.js +22 -0
  47. data/vendor/assets/javascripts/d3/plugins/geo/projection/eisenlohr.js +16 -0
  48. data/vendor/assets/javascripts/d3/plugins/geo/projection/end.js +1 -0
  49. data/vendor/assets/javascripts/d3/plugins/geo/projection/gringorten.js +111 -0
  50. data/vendor/assets/javascripts/d3/plugins/geo/projection/guyou.js +46 -0
  51. data/vendor/assets/javascripts/d3/plugins/geo/projection/hammer-retroazimuthal.js +75 -0
  52. data/vendor/assets/javascripts/d3/plugins/geo/projection/hammer.js +51 -0
  53. data/vendor/assets/javascripts/d3/plugins/geo/projection/hatano.js +25 -0
  54. data/vendor/assets/javascripts/d3/plugins/geo/projection/healpix.js +64 -0
  55. data/vendor/assets/javascripts/d3/plugins/geo/projection/hill.js +64 -0
  56. data/vendor/assets/javascripts/d3/plugins/geo/projection/homolosine.js +17 -0
  57. data/vendor/assets/javascripts/d3/plugins/geo/projection/interrupt.js +111 -0
  58. data/vendor/assets/javascripts/d3/plugins/geo/projection/kavrayskiy7.js +15 -0
  59. data/vendor/assets/javascripts/d3/plugins/geo/projection/lagrange.js +27 -0
  60. data/vendor/assets/javascripts/d3/plugins/geo/projection/larrivee.js +39 -0
  61. data/vendor/assets/javascripts/d3/plugins/geo/projection/laskowski.js +31 -0
  62. data/vendor/assets/javascripts/d3/plugins/geo/projection/littrow.js +21 -0
  63. data/vendor/assets/javascripts/d3/plugins/geo/projection/loximuthal.js +29 -0
  64. data/vendor/assets/javascripts/d3/plugins/geo/projection/miller.js +15 -0
  65. data/vendor/assets/javascripts/d3/plugins/geo/projection/mollweide.js +35 -0
  66. data/vendor/assets/javascripts/d3/plugins/geo/projection/mt-flat-polar-parabolic.js +21 -0
  67. data/vendor/assets/javascripts/d3/plugins/geo/projection/mt-flat-polar-quartic.js +23 -0
  68. data/vendor/assets/javascripts/d3/plugins/geo/projection/mt-flat-polar-sinusoidal.js +25 -0
  69. data/vendor/assets/javascripts/d3/plugins/geo/projection/natural-earth.js +22 -0
  70. data/vendor/assets/javascripts/d3/plugins/geo/projection/nell-hammer.js +20 -0
  71. data/vendor/assets/javascripts/d3/plugins/geo/projection/parallel1.js +12 -0
  72. data/vendor/assets/javascripts/d3/plugins/geo/projection/parallel2.js +13 -0
  73. data/vendor/assets/javascripts/d3/plugins/geo/projection/peirce-quincuncial.js +14 -0
  74. data/vendor/assets/javascripts/d3/plugins/geo/projection/polyconic.js +25 -0
  75. data/vendor/assets/javascripts/d3/plugins/geo/projection/projection.js +29 -0
  76. data/vendor/assets/javascripts/d3/plugins/geo/projection/robinson.js +83 -0
  77. data/vendor/assets/javascripts/d3/plugins/geo/projection/satellite.js +68 -0
  78. data/vendor/assets/javascripts/d3/plugins/geo/projection/sinu-mollweide.js +19 -0
  79. data/vendor/assets/javascripts/d3/plugins/geo/projection/sinusoidal.js +15 -0
  80. data/vendor/assets/javascripts/d3/plugins/geo/projection/start.js +1 -0
  81. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/aitoff-test.js +26 -0
  82. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/armadillo-test.js +28 -0
  83. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/baker-test.js +26 -0
  84. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/boggs-test.js +26 -0
  85. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/bonne-test.js +45 -0
  86. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/craig-test.js +25 -0
  87. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/craster-test.js +25 -0
  88. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/env.js +32 -0
  89. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/equirectangular-test.js +97 -0
  90. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/hammer-test.js +29 -0
  91. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/hatano-test.js +25 -0
  92. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/hill-test.js +26 -0
  93. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/larrivee-test.js +25 -0
  94. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/laskowski-test.js +26 -0
  95. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/littrow-test.js +24 -0
  96. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/loximuthal-test.js +25 -0
  97. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/mollweide-test.js +26 -0
  98. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/mt-flat-polar-parabolic-test.js +25 -0
  99. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/mt-flat-polar-quartic-test.js +25 -0
  100. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/mt-flat-polar-sinusoidal-test.js +25 -0
  101. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/natural-earth-test.js +26 -0
  102. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/quartic-authalic-test.js +0 -0
  103. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/robinson-test.js +26 -0
  104. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/wagner6-test.js +25 -0
  105. data/vendor/assets/javascripts/d3/plugins/geo/projection/test/winkel3-test.js +26 -0
  106. data/vendor/assets/javascripts/d3/plugins/geo/projection/van-der-grinten.js +41 -0
  107. data/vendor/assets/javascripts/d3/plugins/geo/projection/van-der-grinten4.js +22 -0
  108. data/vendor/assets/javascripts/d3/plugins/geo/projection/wagner4.js +9 -0
  109. data/vendor/assets/javascripts/d3/plugins/geo/projection/wagner6.js +15 -0
  110. data/vendor/assets/javascripts/d3/plugins/geo/projection/wagner7.js +22 -0
  111. data/vendor/assets/javascripts/d3/plugins/geo/projection/wiechel.js +14 -0
  112. data/vendor/assets/javascripts/d3/plugins/geo/projection/winkel3.js +40 -0
  113. data/vendor/assets/javascripts/d3/plugins/geo/tile/README.md +6 -0
  114. data/vendor/assets/javascripts/d3/plugins/geo/tile/tile.js +53 -0
  115. data/vendor/assets/javascripts/d3/plugins/geodesic/README.md +3 -0
  116. data/vendor/assets/javascripts/d3/plugins/geodesic/geodesic.js +130 -0
  117. data/vendor/assets/javascripts/d3/plugins/geom/contour/README.md +5 -0
  118. data/vendor/assets/javascripts/d3/plugins/geom/contour/contour.js +72 -0
  119. data/vendor/assets/javascripts/d3/plugins/graph/README.md +148 -0
  120. data/vendor/assets/javascripts/d3/plugins/graph/data/cities-matrix.json +37 -0
  121. data/vendor/assets/javascripts/d3/plugins/graph/data/cities.csv +36 -0
  122. data/vendor/assets/javascripts/d3/plugins/graph/data/miserables.json +338 -0
  123. data/vendor/assets/javascripts/d3/plugins/graph/graph.js +161 -0
  124. data/vendor/assets/javascripts/d3/plugins/graph/index.html +37 -0
  125. data/vendor/assets/javascripts/d3/plugins/hexbin/README.md +58 -0
  126. data/vendor/assets/javascripts/d3/plugins/hexbin/hexbin.js +96 -0
  127. data/vendor/assets/javascripts/d3/plugins/hive/README.md +5 -0
  128. data/vendor/assets/javascripts/d3/plugins/hive/hive.js +80 -0
  129. data/vendor/assets/javascripts/d3/plugins/horizon/README.md +11 -0
  130. data/vendor/assets/javascripts/d3/plugins/horizon/horizon.js +192 -0
  131. data/vendor/assets/javascripts/d3/plugins/interpolate-zoom/README.md +11 -0
  132. data/vendor/assets/javascripts/d3/plugins/interpolate-zoom/interpolate-zoom.js +75 -0
  133. data/vendor/assets/javascripts/d3/plugins/jsonp/README.md +26 -0
  134. data/vendor/assets/javascripts/d3/plugins/jsonp/jsonp.js +25 -0
  135. data/vendor/assets/javascripts/d3/plugins/keybinding/README.md +17 -0
  136. data/vendor/assets/javascripts/d3/plugins/keybinding/keybinding.js +120 -0
  137. data/vendor/assets/javascripts/d3/plugins/longscroll/README.md +10 -0
  138. data/vendor/assets/javascripts/d3/plugins/longscroll/longscroll.js +75 -0
  139. data/vendor/assets/javascripts/d3/plugins/package.json +20 -0
  140. data/vendor/assets/javascripts/d3/plugins/qq/README.md +3 -0
  141. data/vendor/assets/javascripts/d3/plugins/qq/qq.js +249 -0
  142. data/vendor/assets/javascripts/d3/plugins/rollup/README.md +5 -0
  143. data/vendor/assets/javascripts/d3/plugins/rollup/rollup.js +131 -0
  144. data/vendor/assets/javascripts/d3/plugins/sankey/README.md +17 -0
  145. data/vendor/assets/javascripts/d3/plugins/sankey/sankey.js +292 -0
  146. data/vendor/assets/javascripts/d3/plugins/simplify/README.md +6 -0
  147. data/vendor/assets/javascripts/d3/plugins/simplify/simplify-test.js +193 -0
  148. data/vendor/assets/javascripts/d3/plugins/simplify/simplify.js +446 -0
  149. data/vendor/assets/javascripts/d3/plugins/superformula/superformula.js +98 -0
  150. data/vendor/assets/javascripts/d3/plugins/urlencode/urlencode-test.js +68 -0
  151. data/vendor/assets/javascripts/d3/plugins/urlencode/urlencode.js +37 -0
  152. metadata +218 -0
@@ -0,0 +1,6 @@
1
+ # Line Simplification
2
+
3
+ Demos:
4
+
5
+ * <http://bost.ocks.org/mike/simplify/>
6
+ * <http://www.jasondavies.com/maps/simplify/>
@@ -0,0 +1,193 @@
1
+ require("d3");
2
+ require("./simplify");
3
+
4
+ var vows = require("vows"),
5
+ assert = require("assert");
6
+
7
+ var suite = vows.describe("d3.simplify");
8
+
9
+ suite.addBatch({
10
+ "d3.simplify": {
11
+ "area(0)": {
12
+ topic: function() {
13
+ var simplify = d3.simplify().area(0).projection(d3.geo.equirectangular());
14
+ return function(d) { return simplify(simplify.project(d)); };
15
+ },
16
+ "LineString": {
17
+ "2 points": function(simplify) {
18
+ var p = {type: "LineString", coordinates: [[0, 0], [1, 1]]};
19
+ assert.deepEqual(simplify(p), p);
20
+ },
21
+ "9 points": function(simplify) {
22
+ var p = {type: "LineString", coordinates: [[0, 0], [0, 5], [0, 10], [5, 10], [10, 10], [10, 5], [10, 0], [5, 0], [0, 0]]};
23
+ assert.deepEqual(simplify(p), p);
24
+ }
25
+ },
26
+ "FeatureCollection": {
27
+ "preserves properties": function(simplify) {
28
+ var p = {type: "FeatureCollection", features: [], id: "test"};
29
+ assert.deepEqual(simplify(p), p);
30
+ }
31
+ },
32
+ "Feature": {
33
+ "preserves properties": function(simplify) {
34
+ var p = {type: "Feature", geometry: {type: "GeometryCollection", geometries: []}, properties: {name: "test"}, id: "test"};
35
+ assert.deepEqual(simplify(p), p);
36
+ }
37
+ },
38
+ "GeometryCollection": {
39
+ "preserves properties": function(simplify) {
40
+ var p = {type: "GeometryCollection", geometries: [], id: "test"};
41
+ assert.deepEqual(simplify(p), p);
42
+ }
43
+ }
44
+ },
45
+ "area(10)": {
46
+ topic: function() {
47
+ var simplify = d3.simplify().area(10).projection(d3.geo.equirectangular());
48
+ return function(d) { return simplify(simplify.project(d)); };
49
+ },
50
+ "LineString": {
51
+ "2 points": function(simplify) {
52
+ var p = {type: "LineString", coordinates: [[0, 0], [1, 1]]};
53
+ assert.deepEqual(simplify(p).coordinates, []);
54
+ },
55
+ "3 collinear points": function(simplify) {
56
+ var p = {type: "LineString", coordinates: [[0, 0], [1, 1], [45, 45]]};
57
+ assert.deepEqual(simplify(p).coordinates, []);
58
+ },
59
+ "3 points": function(simplify) {
60
+ var p = {type: "LineString", coordinates: [[0, 0], [10, 10], [0, 20]]};
61
+ assert.deepEqual(simplify(p), p);
62
+ }
63
+ },
64
+ "MultiLineString": {
65
+ "1 line": {
66
+ "3 collinear points": function(simplify) {
67
+ var p = {type: "MultiLineString", coordinates: [[[0, 0], [1, 1], [2, 2]]]};
68
+ assert.deepEqual(simplify(p).coordinates, []);
69
+ }
70
+ },
71
+ "2 lines": function(simplify) {
72
+ var p = {type: "MultiLineString", coordinates: [[[0, 0], [1, 1], [0, 2]], [[10, 0], [15, 15], [20, 0]]]};
73
+ assert.deepEqual(simplify(p).coordinates, [p.coordinates[1]]);
74
+ }
75
+ },
76
+ "Polygon": {
77
+ "empty result": function(simplify) {
78
+ var p = {type: "Polygon", coordinates: [[[0, 0], [1, 1], [1, 0], [0, 0]]]};
79
+ assert.deepEqual(simplify(p).coordinates, []);
80
+ },
81
+ "1 ring": function(simplify) {
82
+ // TODO verify that LinearRings all have >= 4 points?
83
+ var p = {type: "Polygon", coordinates: [[[0, 0], [10, 10], [10, 0], [0, 0]]]};
84
+ assert.deepEqual(simplify(p), p);
85
+ }
86
+ },
87
+ "MultiPolygon": {
88
+ "empty result": function(simplify) {
89
+ var p = {type: "MultiPolygon", coordinates: [[[[0, 0], [1, 1], [1, 0], [0, 0]]]]};
90
+ assert.deepEqual(simplify(p).coordinates, []);
91
+ },
92
+ "1 polygon": function(simplify) {
93
+ var p = {type: "MultiPolygon", coordinates: [[[[0, 0], [10, 10], [10, 0], [0, 0]]]]};
94
+ assert.deepEqual(simplify(p), p);
95
+ }
96
+ },
97
+ "GeometryCollection": {
98
+ "empty result": function(simplify) {
99
+ var p = {type: "GeometryCollection", geometries: [{type: "Polygon", coordinates: [[[0, 0], [1, 1], [1, 0], [0, 0]]]}]};
100
+ assert.deepEqual(simplify(p).geometries, []);
101
+ },
102
+ "1 polygon": function(simplify) {
103
+ var p = {type: "GeometryCollection", geometries: [{type: "MultiPolygon", coordinates: [[[[0, 0], [10, 10], [10, 0], [0, 0]]]]}]};
104
+ assert.deepEqual(simplify(p), p);
105
+ }
106
+ },
107
+ "FeatureCollection": {
108
+ "empty result": function(simplify) {
109
+ var p = {type: "FeatureCollection", features: [{type: "Feature", geometry: {type: "Polygon", coordinates: [[[0, 0], [1, 1], [1, 0], [0, 0]]]}}]};
110
+ assert.deepEqual(simplify(p).features, []);
111
+ },
112
+ "1 polygon": function(simplify) {
113
+ var p = {type: "FeatureCollection", features: [{type: "Feature", geometry: {type: "MultiPolygon", coordinates: [[[[0, 0], [10, 10], [10, 0], [0, 0]]]]}}]};
114
+ assert.deepEqual(simplify(p), p);
115
+ }
116
+ }
117
+ },
118
+ "topology": {
119
+ topic: function() {
120
+ var simplify = d3.simplify().topology(true).area(10).projection(d3.geo.equirectangular());
121
+ return function(d) { return simplify(simplify.project(d)); };
122
+ },
123
+ "Polygon": {
124
+ "preserves topology": function(simplify) {
125
+ assert.inDelta(simplify({
126
+ type: "GeometryCollection",
127
+ geometries: [
128
+ {type: "Polygon", coordinates: [octagon(-2)]},
129
+ {type: "Polygon", coordinates: [octagon(2)]}
130
+ ]
131
+ }).geometries.map(function(d) { return d.coordinates; }), [[[
132
+ [474.444444, 250, 19.290123],
133
+ [475.833333, 247.222222, 13.503086],
134
+ [480, 248.611111, 19.290123],
135
+ [480, 250, 19.290123],
136
+ [480, 251.388888, 19.290123],
137
+ [475.833333, 252.777777, 13.503086],
138
+ [474.444444, 250, 19.290123]]], [[
139
+ [480, 250, 19.290123],
140
+ [480, 248.611111, 19.290123],
141
+ [485.555555, 248.611111, 19.290123],
142
+ [484.166666, 252.777777, 19.290123],
143
+ [480, 251.388888, 19.290123],
144
+ [480, 250, 19.290123]]]
145
+ ], 1e-6);
146
+ },
147
+ "doesn't increase effective area of endpoints unless they touch another line": function(simplify) {
148
+ assert.inDelta(simplify({type: "Polygon", coordinates: [octagon()]}).coordinates, [[
149
+ [477.222222, 250, 21.219135],
150
+ [478.611111, 247.222222, 13.503086],
151
+ [482.777777, 248.611111, 21.219135],
152
+ [481.388888, 252.777777, 21.219135],
153
+ [477.222222, 250, 21.219135]
154
+ ]], 1e-6);
155
+ }
156
+ }
157
+ }
158
+ }
159
+ });
160
+
161
+ suite.export(module);
162
+
163
+ assert.inDelta = function(actual, expected, delta, message) {
164
+ if (!inDelta(actual, expected, delta)) {
165
+ assert.fail(actual, expected, message || "expected {actual} to be in within *" + delta + "* of {expected}", null, assert.inDelta);
166
+ }
167
+ };
168
+
169
+ function inDelta(actual, expected, delta) {
170
+ return (Array.isArray(expected) ? inDeltaArray : inDeltaNumber)(actual, expected, delta);
171
+ }
172
+
173
+ function inDeltaArray(actual, expected, delta) {
174
+ var n = expected.length, i = -1;
175
+ if (actual.length !== n) return false;
176
+ while (++i < n) if (!inDelta(actual[i], expected[i], delta)) return false;
177
+ return true;
178
+ }
179
+
180
+ function inDeltaNumber(actual, expected, delta) {
181
+ return actual >= expected - delta && actual <= expected + delta;
182
+ }
183
+
184
+ function octagon(dx) {
185
+ dx = dx || 0;
186
+ return [
187
+ [-2, 0], [-2, 1], [-1, 2], [0, 2], [ 1, 2], [ 2, 1],
188
+ [ 2, 0], [ 2, -1], [ 1, -2], [0, -2], [-1, -2], [-2, -1],
189
+ [-2, 0]
190
+ ].map(function(point) {
191
+ return [point[0] + dx, point[1]];
192
+ });
193
+ }
@@ -0,0 +1,446 @@
1
+ (function() {
2
+
3
+ d3.simplify = function() {
4
+ var projection = d3.geo.albers(),
5
+ triangulateLineString = triangulateLineStringSimple,
6
+ heap,
7
+ minArea = 3,
8
+ topology = false,
9
+ ringId,
10
+ id,
11
+ idByRings,
12
+ idByPoint,
13
+ ringsByPoint,
14
+ sharedPoints,
15
+ lastRingByPoint,
16
+ isShared,
17
+ graph;
18
+
19
+ var projectCoordinates = {
20
+ MultiPolygon: projectMultiPolygon,
21
+ Polygon: projectPolygon,
22
+ MultiLineString: projectPolygon,
23
+ LineString: projectLineString
24
+ };
25
+
26
+ var triangulateCoordinates = {
27
+ MultiPolygon: triangulateMultiPolygon,
28
+ Polygon: triangulatePolygon,
29
+ MultiLineString: triangulatePolygon,
30
+ LineString: triangulateLineString
31
+ };
32
+
33
+ var simplifyCoordinates = {
34
+ MultiPolygon: simplifyMultiPolygon,
35
+ Polygon: simplifyPolygon,
36
+ MultiLineString: simplifyPolygon,
37
+ LineString: simplifyLineString
38
+ };
39
+
40
+ function simplify(object) {
41
+ var type = object.type;
42
+ if (type === "FeatureCollection") {
43
+ object = copy(object);
44
+ object.features = object.features.map(simplifyFeature).filter(nonemptyFeature);
45
+ return object;
46
+ }
47
+ return (type === "Feature" ? simplifyFeature : simplifyGeometry)(object);
48
+ }
49
+
50
+ simplify.project = function(feature) {
51
+ var maxArea = 0,
52
+ maxAreas = {},
53
+ triangle;
54
+
55
+ heap = minHeap();
56
+
57
+ if (topology) {
58
+ id = 0;
59
+ idByRings = {};
60
+ ringsByPoint = {};
61
+ idByPoint = {};
62
+ sharedPoints = {};
63
+ lastRingByPoint = {};
64
+ isShared = {};
65
+ graph = {};
66
+ triangulateTopology(feature);
67
+ } else {
68
+ triangulateSimple(feature);
69
+ }
70
+
71
+ while (triangle = heap.pop()) {
72
+ // If the area of the current point is less than that of the previous point
73
+ // to be eliminated, use the latter’s area instead. This ensures that the
74
+ // current point cannot be eliminated without eliminating previously-
75
+ // eliminated points.
76
+ if (triangle[1][2] < maxArea) triangle[1][2] = maxArea;
77
+ else maxArea = triangle[1][2];
78
+
79
+ if (triangle.previous) {
80
+ triangle.previous.next = triangle.next;
81
+ triangle.previous[2] = triangle[2];
82
+ update(triangle.previous);
83
+ } else if (topology) {
84
+ maxAreas[triangle.ring] = triangle[1][2];
85
+ } else {
86
+ triangle[0][2] = triangle[1][2];
87
+ }
88
+
89
+ if (triangle.next) {
90
+ triangle.next.previous = triangle.previous;
91
+ triangle.next[0] = triangle[0];
92
+ update(triangle.next);
93
+ } else if (topology) {
94
+ maxAreas[triangle.ring] = triangle[1][2];
95
+ } else {
96
+ triangle[2][2] = triangle[1][2];
97
+ }
98
+ }
99
+
100
+ function update(triangle) {
101
+ heap.remove(triangle);
102
+ triangle[1][2] = area(triangle);
103
+ heap.push(triangle);
104
+ }
105
+
106
+ if (topology) {
107
+ var seen = {},
108
+ max,
109
+ m,
110
+ c;
111
+ for (var key in graph) {
112
+ if (seen.hasOwnProperty(key)) continue;
113
+ max = 0;
114
+ for (var k in (c = components(graph, key))) if ((m = maxAreas[k]) > max) max = m;
115
+ for (var k in c) maxAreas[k] = max, seen[k] = 1;
116
+ }
117
+
118
+ for (var key in sharedPoints) {
119
+ maxArea = maxAreas[ringsByPoint[key][0]];
120
+ sharedPoints[key].forEach(function(point) { point[2] = maxArea; });
121
+ }
122
+ idByPoint = idByRings = ringsByPoint = sharedPoints = isShared = lastRingByPoint = graph = null;
123
+ }
124
+
125
+ heap = null;
126
+ return feature;
127
+ };
128
+
129
+ function components(graph, source) {
130
+ var seen = {},
131
+ nextLevel = {},
132
+ thisLevel,
133
+ empty;
134
+ nextLevel[source] = 1;
135
+ while (1) {
136
+ empty = true;
137
+ for (var k in nextLevel) empty = false;
138
+ if (empty) break;
139
+ thisLevel = nextLevel;
140
+ nextLevel = {};
141
+ for (var v in thisLevel) {
142
+ if (seen.hasOwnProperty(v)) continue;
143
+ seen[v] = 1;
144
+ var neighbors = graph[v];
145
+ for (var k in neighbors) nextLevel[k] = neighbors[k];
146
+ }
147
+ }
148
+ return seen;
149
+ }
150
+
151
+ function projectFeature(feature) {
152
+ projectGeometry(feature.geometry);
153
+ }
154
+
155
+ function projectGeometry(geometry) {
156
+ var type = geometry.type;
157
+ if (type === "GeometryCollection") geometry.geometries.forEach(projectGeometry);
158
+ else geometry.coordinates = projectCoordinates[type](geometry.coordinates);
159
+ }
160
+
161
+ function projectMultiPolygon(multiPolygon) {
162
+ return multiPolygon.map(projectPolygon);
163
+ }
164
+
165
+ function projectPolygon(polygon) {
166
+ return polygon.map(projectLineString);
167
+ }
168
+
169
+ function projectLineString(lineString) {
170
+ ++ringId;
171
+ return lineString.map(projectPoint);
172
+ }
173
+
174
+ function projectPoint(point) {
175
+ var pointKey = (point = projection(point))[0] + "," + point[1],
176
+ key = (idByPoint.hasOwnProperty(pointKey) ? idByPoint[pointKey] + ":" : "") + ringId;
177
+ idByPoint[pointKey] = idByRings.hasOwnProperty(key)
178
+ ? idByRings[key]
179
+ : idByRings[key] = ++id;
180
+ if (lastRingByPoint.hasOwnProperty(pointKey) && lastRingByPoint[pointKey] !== ringId) {
181
+ isShared[pointKey] = 1;
182
+ }
183
+ lastRingByPoint[pointKey] = ringId;
184
+ return point;
185
+ }
186
+
187
+ function triangulateLineStringTopology(lineString) {
188
+ ++ringId;
189
+ var n = lineString.length - 1,
190
+ triangle0,
191
+ triangle,
192
+ a = lineString[0],
193
+ b = lineString[1],
194
+ c,
195
+ key0,
196
+ key,
197
+ idA = idByPoint[a[0] + "," + a[1]],
198
+ idB = idByPoint[key0 = b[0] + "," + b[1]],
199
+ idC;
200
+
201
+ lineString[0][2] = lineString[n][2] = 0;
202
+ if (n < 2) return lineString;
203
+
204
+ graph[ringId] = {};
205
+
206
+ addSharedPoint(a);
207
+ for (var i = 2; i <= n; ++i, a = b, b = c, idA = idB, idB = idC, key0 = key) {
208
+ c = lineString[i];
209
+ idC = idByPoint[key = c[0] + "," + c[1]];
210
+ if (idA === idB && idB === idC || !isShared.hasOwnProperty(key0)) {
211
+ triangle = [a, b, c];
212
+ triangle.ring = ringId;
213
+ b[2] = area(triangle);
214
+ heap.push(triangle);
215
+ if (triangle0) (triangle.previous = triangle0).next = triangle;
216
+ triangle0 = triangle;
217
+ } else {
218
+ addSharedPoint(b);
219
+ triangle0 = null;
220
+ }
221
+ }
222
+ addSharedPoint(b);
223
+
224
+ function addSharedPoint(point) {
225
+ var key = point[0] + "," + point[1],
226
+ rings = ringsByPoint.hasOwnProperty(key) ? ringsByPoint[key] : (ringsByPoint[key] = []);
227
+ rings.forEach(function(ring) {
228
+ graph[ring][ringId] = graph[ringId][ring] = 1;
229
+ });
230
+ rings.push(ringId);
231
+ if (sharedPoints.hasOwnProperty(key)) sharedPoints[key].push(point);
232
+ else sharedPoints[key] = [point];
233
+ }
234
+
235
+ return lineString;
236
+ }
237
+
238
+ // Project and triangulate.
239
+ function triangulateLineStringSimple(lineString) {
240
+ var points = lineString.map(projection),
241
+ n = points.length - 1,
242
+ triangle0,
243
+ triangle,
244
+ a = points[0],
245
+ b = points[1],
246
+ c;
247
+
248
+ points[0][2] = points[n][2] = 0;
249
+
250
+ for (var i = 2; i <= n; ++i) {
251
+ triangle = [a, b, c = points[i]];
252
+ b[2] = area(triangle);
253
+ heap.push(triangle);
254
+ if (triangle0) (triangle.previous = triangle0).next = triangle;
255
+ triangle0 = triangle;
256
+ a = b;
257
+ b = c;
258
+ }
259
+
260
+ return points;
261
+ }
262
+
263
+ function triangulateSimple(object) {
264
+ var type = object.type;
265
+ if (type === "FeatureCollection") object.features.forEach(triangulateFeature);
266
+ else (type === "Feature" ? triangulateFeature : triangulateGeometry)(object);
267
+ }
268
+
269
+ function triangulateTopology(object) {
270
+ var type = object.type;
271
+ ringId = 0;
272
+ if (type === "FeatureCollection") {
273
+ object.features.forEach(projectFeature);
274
+ ringId = 0;
275
+ object.features.forEach(triangulateFeature);
276
+ } else if (type === "Feature") {
277
+ projectFeature(object);
278
+ ringId = 0;
279
+ triangulateFeature(object);
280
+ } else {
281
+ projectGeometry(object);
282
+ ringId = 0;
283
+ triangulateGeometry(object);
284
+ }
285
+ }
286
+
287
+ function triangulateFeature(feature) {
288
+ triangulateGeometry(feature.geometry);
289
+ }
290
+
291
+ function triangulateGeometry(geometry) {
292
+ var type = geometry.type;
293
+ if (type === "GeometryCollection") geometry.geometries.forEach(triangulateGeometry);
294
+ else geometry.coordinates = triangulateCoordinates[type](geometry.coordinates);
295
+ }
296
+
297
+ function triangulateMultiPolygon(multiPolygon) {
298
+ return multiPolygon.map(triangulatePolygon);
299
+ }
300
+
301
+ function triangulatePolygon(polygon) {
302
+ return polygon.map(triangulateLineString);
303
+ }
304
+
305
+ function simplifyFeature(feature) {
306
+ feature = copy(feature);
307
+ feature.geometry = simplifyGeometry(feature.geometry);
308
+ return feature;
309
+ }
310
+
311
+ function simplifyGeometry(geometry) {
312
+ var type = geometry.type;
313
+ geometry = copy(geometry);
314
+ if (type === "GeometryCollection") {
315
+ geometry.geometries = geometry.geometries.map(simplifyGeometry).filter(nonemptyGeometry);
316
+ } else {
317
+ geometry.coordinates = simplifyCoordinates[type](geometry.coordinates);
318
+ }
319
+ return geometry;
320
+ }
321
+
322
+ function simplifyMultiPolygon(multiPolygon) {
323
+ return multiPolygon.map(simplifyPolygon).filter(length);
324
+ }
325
+
326
+ function simplifyPolygon(polygon) {
327
+ return polygon.map(simplifyLineString).filter(length);
328
+ }
329
+
330
+ function simplifyLineString(lineString) {
331
+ return lineString.filter(filterLineString);
332
+ }
333
+
334
+ function filterLineString(point) {
335
+ return point[2] >= minArea;
336
+ }
337
+
338
+ simplify.projection = function(_) {
339
+ if (!arguments.length) return projection;
340
+ projection = _;
341
+ return simplify;
342
+ };
343
+
344
+ simplify.area = function(_) {
345
+ if (!arguments.length) return minArea;
346
+ minArea = +_;
347
+ return simplify;
348
+ };
349
+
350
+ simplify.topology = function(_) {
351
+ if (!arguments.length) return topology;
352
+ triangulateCoordinates.LineString =
353
+ triangulateLineString = (topology = !!_)
354
+ ? triangulateLineStringTopology
355
+ : triangulateLineStringSimple;
356
+ return simplify;
357
+ };
358
+
359
+ return simplify;
360
+ };
361
+
362
+ function compare(a, b) {
363
+ return a[1][2] - b[1][2] || a[1][1] - b[1][1] || a[1][0] - b[1][0];
364
+ }
365
+
366
+ function area(t) {
367
+ return Math.abs((t[0][0] - t[2][0]) * (t[1][1] - t[0][1]) - (t[0][0] - t[1][0]) * (t[2][1] - t[0][1]));
368
+ }
369
+
370
+ function minHeap() {
371
+ var heap = {},
372
+ array = [];
373
+
374
+ heap.push = function() {
375
+ for (var i = 0, n = arguments.length; i < n; ++i) {
376
+ var object = arguments[i];
377
+ up(object.index = array.push(object) - 1);
378
+ }
379
+ return array.length;
380
+ };
381
+
382
+ heap.pop = function() {
383
+ var removed = array[0],
384
+ object = array.pop();
385
+ if (array.length) {
386
+ array[object.index = 0] = object;
387
+ down(0);
388
+ }
389
+ return removed;
390
+ };
391
+
392
+ heap.remove = function(removed) {
393
+ var i = removed.index,
394
+ object = array.pop();
395
+ if (i !== array.length) {
396
+ array[object.index = i] = object;
397
+ (compare(object, removed) < 0 ? up : down)(i);
398
+ }
399
+ return i;
400
+ };
401
+
402
+ function up(i) {
403
+ var object = array[i];
404
+ while (i > 0) {
405
+ var up = ((i + 1) >> 1) - 1,
406
+ parent = array[up];
407
+ if (compare(object, parent) >= 0) break;
408
+ array[parent.index = i] = parent;
409
+ array[object.index = i = up] = object;
410
+ }
411
+ }
412
+
413
+ function down(i) {
414
+ var object = array[i];
415
+ while (true) {
416
+ var right = (i + 1) << 1,
417
+ left = right - 1,
418
+ down = i,
419
+ child = array[down];
420
+ if (left < array.length && compare(array[left], child) < 0) child = array[down = left];
421
+ if (right < array.length && compare(array[right], child) < 0) child = array[down = right];
422
+ if (down === i) break;
423
+ array[child.index = i] = child;
424
+ array[object.index = i = down] = object;
425
+ }
426
+ }
427
+
428
+ return heap;
429
+ }
430
+
431
+ function nonemptyFeature(d) { return nonemptyGeometry(d.geometry); }
432
+
433
+ function nonemptyGeometry(d) {
434
+ return length(d.type === "GeometryCollection"
435
+ ? d.geometries : d.coordinates);
436
+ }
437
+
438
+ function length(d) { return d.length; }
439
+
440
+ function copy(object) {
441
+ var o = {};
442
+ for (var key in object) o[key] = object[key];
443
+ return o;
444
+ }
445
+
446
+ })();