1!function() { 2 var topojson = { 3 version: "1.6.19", 4 mesh: function(topology) { return object(topology, meshArcs.apply(this, arguments)); }, 5 meshArcs: meshArcs, 6 merge: function(topology) { return object(topology, mergeArcs.apply(this, arguments)); }, 7 mergeArcs: mergeArcs, 8 feature: featureOrCollection, 9 neighbors: neighbors, 10 presimplify: presimplify 11 }; 12 13 function stitchArcs(topology, arcs) { 14 var stitchedArcs = {}, 15 fragmentByStart = {}, 16 fragmentByEnd = {}, 17 fragments = [], 18 emptyIndex = -1; 19 20 // Stitch empty arcs first, since they may be subsumed by other arcs. 21 arcs.forEach(function(i, j) { 22 var arc = topology.arcs[i < 0 ? ~i : i], t; 23 if (arc.length < 3 && !arc[1][0] && !arc[1][1]) { 24 t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t; 25 } 26 }); 27 28 arcs.forEach(function(i) { 29 var e = ends(i), 30 start = e[0], 31 end = e[1], 32 f, g; 33 34 if (f = fragmentByEnd[start]) { 35 delete fragmentByEnd[f.end]; 36 f.push(i); 37 f.end = end; 38 if (g = fragmentByStart[end]) { 39 delete fragmentByStart[g.start]; 40 var fg = g === f ? f : f.concat(g); 41 fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg; 42 } else { 43 fragmentByStart[f.start] = fragmentByEnd[f.end] = f; 44 } 45 } else if (f = fragmentByStart[end]) { 46 delete fragmentByStart[f.start]; 47 f.unshift(i); 48 f.start = start; 49 if (g = fragmentByEnd[start]) { 50 delete fragmentByEnd[g.end]; 51 var gf = g === f ? f : g.concat(f); 52 fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf; 53 } else { 54 fragmentByStart[f.start] = fragmentByEnd[f.end] = f; 55 } 56 } else { 57 f = [i]; 58 fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f; 59 } 60 }); 61 62 function ends(i) { 63 var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1; 64 if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; }); 65 else p1 = arc[arc.length - 1]; 66 return i < 0 ? [p1, p0] : [p0, p1]; 67 } 68 69 function flush(fragmentByEnd, fragmentByStart) { 70 for (var k in fragmentByEnd) { 71 var f = fragmentByEnd[k]; 72 delete fragmentByStart[f.start]; 73 delete f.start; 74 delete f.end; 75 f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; }); 76 fragments.push(f); 77 } 78 } 79 80 flush(fragmentByEnd, fragmentByStart); 81 flush(fragmentByStart, fragmentByEnd); 82 arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); }); 83 84 return fragments; 85 } 86 87 function meshArcs(topology, o, filter) { 88 var arcs = []; 89 90 if (arguments.length > 1) { 91 var geomsByArc = [], 92 geom; 93 94 function arc(i) { 95 var j = i < 0 ? ~i : i; 96 (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom}); 97 } 98 99 function line(arcs) { 100 arcs.forEach(arc); 101 } 102 103 function polygon(arcs) { 104 arcs.forEach(line); 105 } 106 107 function geometry(o) { 108 if (o.type === "GeometryCollection") o.geometries.forEach(geometry); 109 else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs); 110 } 111 112 var geometryType = { 113 LineString: line, 114 MultiLineString: polygon, 115 Polygon: polygon, 116 MultiPolygon: function(arcs) { arcs.forEach(polygon); } 117 }; 118 119 geometry(o); 120 121 geomsByArc.forEach(arguments.length < 3 122 ? function(geoms) { arcs.push(geoms[0].i); } 123 : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); }); 124 } else { 125 for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i); 126 } 127 128 return {type: "MultiLineString", arcs: stitchArcs(topology, arcs)}; 129 } 130 131 function mergeArcs(topology, objects) { 132 var polygonsByArc = {}, 133 polygons = [], 134 components = []; 135
136 objects.forEach(function(o) { 137 if (o.type === "Polygon") register(o.arcs); 138 else if (o.type === "MultiPolygon") o.arcs.forEach(register); 139 }); 140 141 function register(polygon) { 142 polygon.forEach(function(ring) { 143 ring.forEach(function(arc) { 144 (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon); 145 }); 146 }); 147 polygons.push(polygon); 148 } 149 150 function exterior(ring) { 151 return cartesianRingArea(object(topology, {type: "Polygon", arcs: [ring]}).coordinates[0]) > 0; // TODO allow spherical? 152 } 153 154 polygons.forEach(function(polygon) { 155 if (!polygon._) { 156 var component = [], 157 neighbors = [polygon]; 158 polygon._ = 1; 159 components.push(component); 160 while (polygon = neighbors.pop()) { 161 component.push(polygon); 162 polygon.forEach(function(ring) { 163 ring.forEach(function(arc) { 164 polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) { 165 if (!polygon._) { 166 polygon._ = 1; 167 neighbors.push(polygon); 168 } 169 }); 170 }); 171 }); 172 } 173 } 174 }); 175 176 polygons.forEach(function(polygon) { 177 delete polygon._; 178 }); 179 180 return { 181 type: "MultiPolygon", 182 arcs: components.map(function(polygons) { 183 var arcs = []; 184 185 // Extract the exterior (unique) arcs. 186 polygons.forEach(function(polygon) { 187 polygon.forEach(function(ring) { 188 ring.forEach(function(arc) { 189 if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) { 190 arcs.push(arc); 191 } 192 }); 193 }); 194 }); 195 196 // Stitch the arcs into one or more rings. 197 arcs = stitchArcs(topology, arcs); 198 199 // If more than one ring is returned, 200 // at most one of these rings can be the exterior; 201 // this exterior ring has the same winding order 202 // as any exterior ring in the original polygons. 203 if ((n = arcs.length) > 1) { 204 var sgn = exterior(polygons[0][0]); 205 for (var i = 0, t; i < n; ++i) { 206 if (sgn === exterior(arcs[i])) { 207 t = arcs[0], arcs[0] = arcs[i], arcs[i] = t; 208 break; 209 } 210 } 211 } 212 213 return arcs; 214 }) 215 }; 216 } 217 218 function featureOrCollection(topology, o) { 219 return o.type === "GeometryCollection" ? { 220 type: "FeatureCollection", 221 features: o.geometries.map(function(o) { return feature(topology, o); }) 222 } : feature(topology, o); 223 } 224 225 function feature(topology, o) { 226 var f = { 227 type: "Feature", 228 id: o.id, 229 properties: o.properties || {}, 230 geometry: object(topology, o) 231 }; 232 if (o.id == null) delete f.id; 233 return f; 234 } 235 236 function object(topology, o) { 237 var absolute = transformAbsolute(topology.transform), 238 arcs = topology.arcs; 239 240 function arc(i, points) { 241 if (points.length) points.pop(); 242 for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) { 243 points.push(p = a[k].slice()); 244 absolute(p, k); 245 } 246 if (i < 0) reverse(points, n); 247 } 248 249 function point(p) { 250 p = p.slice(); 251 absolute(p, 0); 252 return p; 253 } 254 255 function line(arcs) { 256 var points = []; 257 for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points); 258 if (points.length < 2) points.push(points[0].slice()); 259 return points; 260 } 261 262 function ring(arcs) { 263 var points = line(arcs); 264 while (points.length < 4) points.push(points[0].slice()); 265 return points; 266 } 267 268 function polygon(arcs) { 269 return arcs.map(ring); 270 } 271 272 function geometry(o) { 273 var t = o.type; 274 return t === "GeometryCollection" ? {type: t, geometries: o.geometries.map(geometry)} 275 : t in geometryType ? {type: t, coordinates: geometryType[t](o)} 276 : null; 277 } 278 279 var geometryType = { 280 Point: function(o) { return point(o.coordinates); }, 281 MultiPoint: function(o) { return o.coordinates.map(point); }, 282 LineString: function(o) { return line(o.arcs); }, 283 MultiLineString: function(o) { return o.arcs.map(line); }, 284 Polygon: function(o) { return polygon(o.arcs); }, 285 MultiPolygon: function(o) { return o.arcs.map(polygon); } 286 }; 287 288 return geometry(o); 289 } 290 291 function reverse(array, n) { 292 var t, j = array.length, i = j - n; while (i < --j) t = array[i], array[i++] = array[j], array[j] = t; 293 } 294 295 function bisect(a, x) { 296 var lo = 0, hi = a.length; 297 while (lo < hi) { 298 var mid = lo + hi >>> 1; 299 if (a[mid] < x) lo = mid + 1; 300 else hi = mid; 301 } 302 return lo; 303 } 304 305 function neighbors(objects) { 306 var indexesByArc = {}, // arc index -> array of object indexes 307 neighbors = objects.map(function() { return []; }); 308 309 function line(arcs, i) { 310 arcs.forEach(function(a) { 311 if (a < 0) a = ~a; 312 var o = indexesByArc[a]; 313 if (o) o.push(i); 314 else indexesByArc[a] = [i]; 315 }); 316 } 317 318 function polygon(arcs, i) {
319 arcs.forEach(function(arc) { line(arc, i); }); 320 } 321 322 function geometry(o, i) { 323 if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); }); 324 else if (o.type in geometryType) geometryType[o.type](o.arcs, i); 325 } 326 327 var geometryType = { 328 LineString: line, 329 MultiLineString: polygon, 330 Polygon: polygon, 331 MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); } 332 }; 333 334 objects.forEach(geometry); 335 336 for (var i in indexesByArc) { 337 for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) { 338 for (var k = j + 1; k < m; ++k) { 339 var ij = indexes[j], ik = indexes[k], n; 340 if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik); 341 if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij); 342 } 343 } 344 } 345 346 return neighbors; 347 } 348 349 function presimplify(topology, triangleArea) { 350 var absolute = transformAbsolute(topology.transform), 351 relative = transformRelative(topology.transform), 352 heap = minAreaHeap(); 353 354 if (!triangleArea) triangleArea = cartesianTriangleArea; 355 356 topology.arcs.forEach(function(arc) { 357 var triangles = [], 358 maxArea = 0, 359 triangle; 360 361 // To store each pointâs effective area, we create a new array rather than 362 // extending the passed-in point to workaround a Chrome/V8 bug (getting 363 // stuck in smi mode). For midpoints, the initial effective area of 364 // Infinity will be computed in the next step. 365 for (var i = 0, n = arc.length, p; i < n; ++i) { 366 p = arc[i]; 367 absolute(arc[i] = [p[0], p[1], Infinity], i); 368 } 369 370 for (var i = 1, n = arc.length - 1; i < n; ++i) { 371 triangle = arc.slice(i - 1, i + 2); 372 triangle[1][2] = triangleArea(triangle); 373 triangles.push(triangle); 374 heap.push(triangle); 375 } 376 377 for (var i = 0, n = triangles.length; i < n; ++i) { 378 triangle = triangles[i]; 379 triangle.previous = triangles[i - 1]; 380 triangle.next = triangles[i + 1]; 381 } 382 383 while (triangle = heap.pop()) { 384 var previous = triangle.previous, 385 next = triangle.next; 386 387 // If the area of the current point is less than that of the previous point 388 // to be eliminated, use the latter's area instead. This ensures that the 389 // current point cannot be eliminated without eliminating previously- 390 // eliminated points. 391 if (triangle[1][2] < maxArea) triangle[1][2] = maxArea; 392 else maxArea = triangle[1][2]; 393 394 if (previous) { 395 previous.next = next; 396 previous[2] = triangle[2]; 397 update(previous); 398 } 399 400 if (next) { 401 next.previous = previous; 402 next[0] = triangle[0]; 403 update(next); 404 } 405 } 406 407 arc.forEach(relative); 408 }); 409 410 function update(triangle) { 411 heap.remove(triangle); 412 triangle[1][2] = triangleArea(triangle); 413 heap.push(triangle); 414 } 415 416 return topology; 417 }; 418 419 function cartesianRingArea(ring) { 420 var i = -1, 421 n = ring.length, 422 a, 423 b = ring[n - 1], 424 area = 0; 425 426 while (++i < n) { 427 a = b; 428 b = ring[i]; 429 area += a[0] * b[1] - a[1] * b[0]; 430 } 431 432 return area * .5; 433 } 434 435 function cartesianTriangleArea(triangle) { 436 var a = triangle[0], b = triangle[1], c = triangle[2]; 437 return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1])); 438 } 439 440 function compareArea(a, b) { 441 return a[1][2] - b[1][2]; 442 } 443 444 function minAreaHeap() { 445 var heap = {}, 446 array = [], 447 size = 0; 448 449 heap.push = function(object) { 450 up(array[object._ = size] = object, size++); 451 return size; 452 }; 453 454 heap.pop = function() { 455 if (size <= 0) return; 456 var removed = array[0], object; 457 if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0); 458 return removed; 459 }; 460 461 heap.remove = function(removed) { 462 var i = removed._, object; 463 if (array[i] !== removed) return; // invalid request 464 if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i); 465 return i; 466 }; 467 468 function up(object, i) { 469 while (i > 0) { 470 var j = ((i + 1) >> 1) - 1, 471 parent = array[j]; 472 if (compareArea(object, parent) >= 0) break; 473 array[parent._ = i] = parent; 474 array[object._ = i = j] = object; 475 } 476 } 477 478 function down(object, i) { 479 while (true) { 480 var r = (i + 1) << 1, 481 l = r - 1, 482 j = i, 483 child = array[j]; 484 if (l < size && compareArea(array[l], child) < 0) child = array[j = l]; 485 if (r < size && compareArea(array[r], child) < 0) child = array[j = r]; 486 if (j === i) break; 487 array[child._ = i] = child; 488 array[object._ = i = j] = object; 489 } 490 } 491 492 return heap; 493 } 494 495 function transformAbsolute(transform) { 496 if (!transform) return noop; 497 var x0, 498 y0, 499 kx = transform.scale[0], 500 ky = transform.scale[1], 501 dx = transform.translate[0], 502 dy = transform.translate[1]; 503 return function(point, i) { 504 if (!i) x0 = y0 = 0; 505 point[0] = (x0 += point[0]) * kx + dx; 506 point[1] = (y0 += point[1]) * ky + dy; 507 }; 508 } 509 510 function transformRelative(transform) { 511 if (!transform) return noop; 512 var x0, 513 y0, 514 kx = transform.scale[0], 515 ky = transform.scale[1], 516 dx = transform.translate[0], 517 dy = transform.translate[1]; 518 return function(point, i) { 519 if (!i) x0 = y0 = 0; 520 var x1 = (point[0] - dx) / kx | 0, 521 y1 = (point[1] - dy) / ky | 0; 522 point[0] = x1 - x0; 523 point[1] = y1 - y0; 524 x0 = x1; 525 y0 = y1; 526 }; 527 } 528 529 function noop() {} 530 531 if (typeof define === "function" && define.amd) define(topojson); 532 else if (typeof module === "object" && module.exports) module.exports = topojson; 533 else this.topojson = topojson; 534}();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.