2 - * Embed of the topojson library from Mike Bostock v1.6.26
3 - * https://github.com/mbostock/topojson
7 (function (global
, factory
) {
8 typeof exports
=== 'object' && typeof module
!== 'undefined' ? factory(exports
) :
9 typeof define
=== 'function' && define
.amd
? define(['exports'], factory
) :
10 (factory((global
.topojson
= global
.topojson
|| {})));
11 }(this, function (exports
) { 'use strict';
15 function transformAbsolute(transform
) {
16 if (!transform
) return noop
;
19 kx
= transform
.scale
[0],
20 ky
= transform
.scale
[1],
21 dx
= transform
.translate
[0],
22 dy
= transform
.translate
[1];
23 return function(point
, i
) {
25 point
[0] = (x0
+= point
[0]) * kx
+ dx
;
26 point
[1] = (y0
+= point
[1]) * ky
+ dy
;
30 function transformRelative(transform
) {
31 if (!transform
) return noop
;
34 kx
= transform
.scale
[0],
35 ky
= transform
.scale
[1],
36 dx
= transform
.translate
[0],
37 dy
= transform
.translate
[1];
38 return function(point
, i
) {
40 var x1
= Math
.round((point
[0] - dx
) / kx
),
41 y1
= Math
.round((point
[1] - dy
) / ky
);
49 function reverse(array
, n
) {
50 var t
, j
= array
.length
, i
= j
- n
;
51 while (i
< --j
) t
= array
[i
], array
[i
++] = array
[j
], array
[j
] = t
;
54 function bisect(a
, x
) {
55 var lo
= 0, hi
= a
.length
;
57 var mid
= lo
+ hi
>>> 1;
58 if (a
[mid
] < x
) lo
= mid
+ 1;
64 function feature(topology
, o
) {
65 return o
.type
=== "GeometryCollection" ? {
66 type
: "FeatureCollection",
67 features
: o
.geometries
.map(function(o
) { return feature
$1(topology
, o
); })
68 } : feature
$1(topology
, o
);
71 function feature
$1(topology
, o
) {
75 properties
: o
.properties
|| {},
76 geometry
: object(topology
, o
)
78 if (o
.id
== null) delete f
.id
;
82 function object(topology
, o
) {
83 var absolute
= transformAbsolute(topology
.transform
),
86 function arc(i
, points
) {
87 if (points
.length
) points
.pop();
88 for (var a
= arcs
[i
< 0 ? ~i
: i
], k
= 0, n
= a
.length
, p
; k
< n
; ++k
) {
89 points
.push(p
= a
[k
].slice());
92 if (i
< 0) reverse(points
, n
);
101 function line(arcs
) {
103 for (var i
= 0, n
= arcs
.length
; i
< n
; ++i
) arc(arcs
[i
], points
);
104 if (points
.length
< 2) points
.push(points
[0].slice());
108 function ring(arcs
) {
109 var points
= line(arcs
);
110 while (points
.length
< 4) points
.push(points
[0].slice());
114 function polygon(arcs
) {
115 return arcs
.map(ring
);
118 function geometry(o
) {
120 return t
=== "GeometryCollection" ? {type
: t
, geometries
: o
.geometries
.map(geometry
)}
121 : t
in geometryType
? {type
: t
, coordinates
: geometryType
[t
](o
)}
126 Point: function(o
) { return point(o
.coordinates
); },
127 MultiPoint: function(o
) { return o
.coordinates
.map(point
); },
128 LineString: function(o
) { return line(o
.arcs
); },
129 MultiLineString: function(o
) { return o
.arcs
.map(line
); },
130 Polygon: function(o
) { return polygon(o
.arcs
); },
131 MultiPolygon: function(o
) { return o
.arcs
.map(polygon
); }
137 function stitchArcs(topology
, arcs
) {
138 var stitchedArcs
= {},
139 fragmentByStart
= {},
144 // Stitch empty arcs first, since they may be subsumed by other arcs.
145 arcs
.forEach(function(i
, j
) {
146 var arc
= topology
.arcs
[i
< 0 ? ~i
: i
], t
;
147 if (arc
.length
< 3 && !arc
[1][0] && !arc
[1][1]) {
148 t
= arcs
[++emptyIndex
], arcs
[emptyIndex
] = i
, arcs
[j
] = t
;
152 arcs
.forEach(function(i
) {
158 if (f
= fragmentByEnd
[start
]) {
159 delete fragmentByEnd
[f
.end
];
162 if (g
= fragmentByStart
[end
]) {
163 delete fragmentByStart
[g
.start
];
164 var fg
= g
=== f
? f
: f
.concat(g
);
165 fragmentByStart
[fg
.start
= f
.start
] = fragmentByEnd
[fg
.end
= g
.end
] = fg
;
167 fragmentByStart
[f
.start
] = fragmentByEnd
[f
.end
] = f
;
169 } else if (f
= fragmentByStart
[end
]) {
170 delete fragmentByStart
[f
.start
];
173 if (g
= fragmentByEnd
[start
]) {
174 delete fragmentByEnd
[g
.end
];
175 var gf
= g
=== f
? f
: g
.concat(f
);
176 fragmentByStart
[gf
.start
= g
.start
] = fragmentByEnd
[gf
.end
= f
.end
] = gf
;
178 fragmentByStart
[f
.start
] = fragmentByEnd
[f
.end
] = f
;
182 fragmentByStart
[f
.start
= start
] = fragmentByEnd
[f
.end
= end
] = f
;
187 var arc
= topology
.arcs
[i
< 0 ? ~i
: i
], p0
= arc
[0], p1
;
188 if (topology
.transform
) p1
= [0, 0], arc
.forEach(function(dp
) { p1
[0] += dp
[0], p1
[1] += dp
[1]; });
189 else p1
= arc
[arc
.length
- 1];
190 return i
< 0 ? [p1
, p0
] : [p0
, p1
];
193 function flush(fragmentByEnd
, fragmentByStart
) {
194 for (var k
in fragmentByEnd
) {
195 var f
= fragmentByEnd
[k
];
196 delete fragmentByStart
[f
.start
];
199 f
.forEach(function(i
) { stitchedArcs
[i
< 0 ? ~i
: i
] = 1; });
204 flush(fragmentByEnd
, fragmentByStart
);
205 flush(fragmentByStart
, fragmentByEnd
);
206 arcs
.forEach(function(i
) { if (!stitchedArcs
[i
< 0 ? ~i
: i
]) fragments
.push([i
]); });
211 function mesh(topology
) {
212 return object(topology
, meshArcs
.apply(this, arguments
));
215 function meshArcs(topology
, o
, filter
) {
219 var j
= i
< 0 ? ~i
: i
;
220 (geomsByArc
[j
] || (geomsByArc
[j
] = [])).push({i
: i
, g
: geom
});
223 function line(arcs
) {
227 function polygon(arcs
) {
231 function geometry(o
) {
232 if (o
.type
=== "GeometryCollection") o
.geometries
.forEach(geometry
);
233 else if (o
.type
in geometryType
) geom
= o
, geometryType
[o
.type
](o
.arcs
);
236 if (arguments
.length
> 1) {
242 MultiLineString
: polygon
,
244 MultiPolygon: function(arcs
) { arcs
.forEach(polygon
); }
249 geomsByArc
.forEach(arguments
.length
< 3
250 ? function(geoms
) { arcs
.push(geoms
[0].i
); }
251 : function(geoms
) { if (filter(geoms
[0].g
, geoms
[geoms
.length
- 1].g
)) arcs
.push(geoms
[0].i
); });
253 for (var i
= 0, n
= topology
.arcs
.length
; i
< n
; ++i
) arcs
.push(i
);
256 return {type
: "MultiLineString", arcs
: stitchArcs(topology
, arcs
)};
259 function cartesianTriangleArea(triangle
) {
260 var a
= triangle
[0], b
= triangle
[1], c
= triangle
[2];
261 return Math
.abs((a
[0] - c
[0]) * (b
[1] - a
[1]) - (a
[0] - b
[0]) * (c
[1] - a
[1]));
264 function ring(ring
) {
274 area
+= a
[0] * b
[1] - a
[1] * b
[0];
280 function merge(topology
) {
281 return object(topology
, mergeArcs
.apply(this, arguments
));
284 function mergeArcs(topology
, objects
) {
285 var polygonsByArc
= {},
289 objects
.forEach(function(o
) {
290 if (o
.type
=== "Polygon") register(o
.arcs
);
291 else if (o
.type
=== "MultiPolygon") o
.arcs
.forEach(register
);
294 function register(polygon
) {
295 polygon
.forEach(function(ring
$$) {
296 ring
$$.forEach(function(arc
) {
297 (polygonsByArc
[arc
= arc
< 0 ? ~arc
: arc
] || (polygonsByArc
[arc
] = [])).push(polygon
);
300 polygons
.push(polygon
);
303 function area(ring
$$) {
304 return Math
.abs(ring(object(topology
, {type
: "Polygon", arcs
: [ring
$$]}).coordinates
[0]));
307 polygons
.forEach(function(polygon
) {
310 neighbors
= [polygon
];
312 components
.push(component
);
313 while (polygon
= neighbors
.pop()) {
314 component
.push(polygon
);
315 polygon
.forEach(function(ring
$$) {
316 ring
$$.forEach(function(arc
) {
317 polygonsByArc
[arc
< 0 ? ~arc
: arc
].forEach(function(polygon
) {
320 neighbors
.push(polygon
);
329 polygons
.forEach(function(polygon
) {
334 type
: "MultiPolygon",
335 arcs
: components
.map(function(polygons
) {
338 // Extract the exterior (unique) arcs.
339 polygons
.forEach(function(polygon
) {
340 polygon
.forEach(function(ring
$$) {
341 ring
$$.forEach(function(arc
) {
342 if (polygonsByArc
[arc
< 0 ? ~arc
: arc
].length
< 2) {
349 // Stitch the arcs into one or more rings.
350 arcs
= stitchArcs(topology
, arcs
);
352 // If more than one ring is returned,
353 // at most one of these rings can be the exterior;
354 // choose the one with the greatest absolute area.
355 if ((n
= arcs
.length
) > 1) {
356 for (var i
= 1, k
= area(arcs
[0]), ki
, t
; i
< n
; ++i
) {
357 if ((ki
= area(arcs
[i
])) > k
) {
358 t
= arcs
[0], arcs
[0] = arcs
[i
], arcs
[i
] = t
, k
= ki
;
368 function neighbors(objects
) {
369 var indexesByArc
= {}, // arc index -> array of object indexes
370 neighbors
= objects
.map(function() { return []; });
372 function line(arcs
, i
) {
373 arcs
.forEach(function(a
) {
375 var o
= indexesByArc
[a
];
377 else indexesByArc
[a
] = [i
];
381 function polygon(arcs
, i
) {
382 arcs
.forEach(function(arc
) { line(arc
, i
); });
385 function geometry(o
, i
) {
386 if (o
.type
=== "GeometryCollection") o
.geometries
.forEach(function(o
) { geometry(o
, i
); });
387 else if (o
.type
in geometryType
) geometryType
[o
.type
](o
.arcs
, i
);
392 MultiLineString
: polygon
,
394 MultiPolygon: function(arcs
, i
) { arcs
.forEach(function(arc
) { polygon(arc
, i
); }); }
397 objects
.forEach(geometry
);
399 for (var i
in indexesByArc
) {
400 for (var indexes
= indexesByArc
[i
], m
= indexes
.length
, j
= 0; j
< m
; ++j
) {
401 for (var k
= j
+ 1; k
< m
; ++k
) {
402 var ij
= indexes
[j
], ik
= indexes
[k
], n
;
403 if ((n
= neighbors
[ij
])[i
= bisect(n
, ik
)] !== ik
) n
.splice(i
, 0, ik
);
404 if ((n
= neighbors
[ik
])[i
= bisect(n
, ij
)] !== ij
) n
.splice(i
, 0, ij
);
412 function compareArea(a
, b
) {
413 return a
[1][2] - b
[1][2];
416 function minAreaHeap() {
421 heap
.push = function(object
) {
422 up(array
[object
._
= size
] = object
, size
++);
426 heap
.pop = function() {
427 if (size
<= 0) return;
428 var removed
= array
[0], object
;
429 if (--size
> 0) object
= array
[size
], down(array
[object
._
= 0] = object
, 0);
433 heap
.remove = function(removed
) {
434 var i
= removed
._
, object
;
435 if (array
[i
] !== removed
) return; // invalid request
436 if (i
!== --size
) object
= array
[size
], (compareArea(object
, removed
) < 0 ? up
: down
)(array
[object
._
= i
] = object
, i
);
440 function up(object
, i
) {
442 var j
= ((i
+ 1) >> 1) - 1,
444 if (compareArea(object
, parent
) >= 0) break;
445 array
[parent
._
= i
] = parent
;
446 array
[object
._
= i
= j
] = object
;
450 function down(object
, i
) {
452 var r
= (i
+ 1) << 1,
456 if (l
< size
&& compareArea(array
[l
], child
) < 0) child
= array
[j
= l
];
457 if (r
< size
&& compareArea(array
[r
], child
) < 0) child
= array
[j
= r
];
459 array
[child
._
= i
] = child
;
460 array
[object
._
= i
= j
] = object
;
467 function presimplify(topology
, triangleArea
) {
468 var absolute
= transformAbsolute(topology
.transform
),
469 relative
= transformRelative(topology
.transform
),
470 heap
= minAreaHeap();
472 if (!triangleArea
) triangleArea
= cartesianTriangleArea
;
474 topology
.arcs
.forEach(function(arc
) {
482 // To store each point’s effective area, we create a new array rather than
483 // extending the passed-in point to workaround a Chrome/V8 bug (getting
484 // stuck in smi mode). For midpoints, the initial effective area of
485 // Infinity will be computed in the next step.
486 for (i
= 0, n
= arc
.length
; i
< n
; ++i
) {
488 absolute(arc
[i
] = [p
[0], p
[1], Infinity
], i
);
491 for (i
= 1, n
= arc
.length
- 1; i
< n
; ++i
) {
492 triangle
= arc
.slice(i
- 1, i
+ 2);
493 triangle
[1][2] = triangleArea(triangle
);
494 triangles
.push(triangle
);
498 for (i
= 0, n
= triangles
.length
; i
< n
; ++i
) {
499 triangle
= triangles
[i
];
500 triangle
.previous
= triangles
[i
- 1];
501 triangle
.next
= triangles
[i
+ 1];
504 while (triangle
= heap
.pop()) {
505 var previous
= triangle
.previous
,
506 next
= triangle
.next
;
508 // If the area of the current point is less than that of the previous point
509 // to be eliminated, use the latter's area instead. This ensures that the
510 // current point cannot be eliminated without eliminating previously-
511 // eliminated points.
512 if (triangle
[1][2] < maxArea
) triangle
[1][2] = maxArea
;
513 else maxArea
= triangle
[1][2];
516 previous
.next
= next
;
517 previous
[2] = triangle
[2];
522 next
.previous
= previous
;
523 next
[0] = triangle
[0];
528 arc
.forEach(relative
);
531 function update(triangle
) {
532 heap
.remove(triangle
);
533 triangle
[1][2] = triangleArea(triangle
);
540 var version
= "1.6.26";
542 exports
.version
= version
;
544 exports
.meshArcs
= meshArcs
;
545 exports
.merge
= merge
;
546 exports
.mergeArcs
= mergeArcs
;
547 exports
.feature
= feature
;
548 exports
.neighbors
= neighbors
;
549 exports
.presimplify
= presimplify
;
553 L
.TOPOJSON
= L
.FeatureGroup
.extend({
558 initialize: function (data
, options
) {
559 L
.Util
.setOptions(this, options
);
560 this._topojson
= data
;
564 this.addTOPOJSON(data
, options
, this.options
.async
);
568 loadJSON: function (url
, cb
, options
, async
) {
569 if (async
=== undefined) async
= this.options
.async
;
570 if (options
=== undefined) options
= this.options
;
572 var req
= new window
.XMLHttpRequest();
574 // Check for IE8 and IE9 Fix Cors for those browsers
575 if (req
.withCredentials
=== undefined && typeof window
.XDomainRequest
!== 'undefined') {
576 var xdr
= new window
.XDomainRequest();
577 xdr
.open('GET', url
, async
);
578 xdr
.onprogress = function () { };
579 xdr
.ontimeout = function () { };
580 xdr
.onerror = function () { };
581 xdr
.onload = function () {
582 if (xdr
.responseText
) {
583 //var xml = new window.ActiveXObject('Microsoft.XMLDOM');
584 //xml.loadJSON(xdr.responseText);
585 cb(xdr
.responseText
, options
);
588 setTimeout(function () { xdr
.send(); }, 0);
590 req
.open('GET', url
, async
);
592 req
.overrideMimeType('application/json'); // unsupported by IE
594 req
.onreadystatechange = function () {
595 if (req
.readyState
!== 4) return;
596 if (req
.status
=== 200) cb(req
.response
, options
);
602 addTOPOJSON: function (url
, options
, async
) {
604 cb = function (data
) { _this
._addTOPOJSON(data
); };
605 this.loadJSON(url
, cb
, options
, async
);
608 _addTOPOJSON: function (data
) {
609 var layers
= this.parseTOPOJSON(data
);
610 if (!layers
|| !layers
.length
) return;
611 for (var i
= 0; i
< layers
.length
; i
++) {
612 this.fire('addlayer', {
615 this.addLayer(layers
[i
]);
619 _addData : function (l
, d
) {
620 if ('addData' in l
) l
.addData(d
);
621 if ('setGeoJSON' in l
) l
.setGeoJSON(d
);
623 parseTOPOJSON : function (data
) {
625 o
= typeof data
=== 'string' ? JSON
.parse(data
) : data
;
626 for (var i
in o
.objects
) {
627 var layer
= L
.geoJson(),
628 ft
= topojson
.feature(o
, o
.objects
[i
]);
629 if (ft
.features
) this._addData(layer
, ft
.features
);
630 else _this
._addData(layer
, ft
);