topology.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import bounds from "./bounds.js";
  2. import cut from "./cut.js";
  3. import dedup from "./dedup.js";
  4. import delta from "./delta.js";
  5. import extract from "./extract.js";
  6. import geometry from "./geometry.js";
  7. import hashmap from "./hash/hashmap.js";
  8. import {hasOwnProperty} from "./object.js";
  9. import prequantize from "./prequantize.js";
  10. // Constructs the TopoJSON Topology for the specified hash of features.
  11. // Each object in the specified hash must be a GeoJSON object,
  12. // meaning FeatureCollection, a Feature or a geometry object.
  13. export default function(objects, quantization) {
  14. var bbox = bounds(objects = geometry(objects)),
  15. transform = quantization > 0 && bbox && prequantize(objects, bbox, quantization),
  16. topology = dedup(cut(extract(objects))),
  17. coordinates = topology.coordinates,
  18. indexByArc = hashmap(topology.arcs.length * 1.4, hashArc, equalArc);
  19. objects = topology.objects; // for garbage collection
  20. topology.bbox = bbox;
  21. topology.arcs = topology.arcs.map(function(arc, i) {
  22. indexByArc.set(arc, i);
  23. return coordinates.slice(arc[0], arc[1] + 1);
  24. });
  25. delete topology.coordinates;
  26. coordinates = null;
  27. function indexGeometry(geometry) {
  28. if (geometry && hasOwnProperty.call(indexGeometryType, geometry.type)) indexGeometryType[geometry.type](geometry);
  29. }
  30. var indexGeometryType = {
  31. GeometryCollection: function(o) { o.geometries.forEach(indexGeometry); },
  32. LineString: function(o) { o.arcs = indexArcs(o.arcs); },
  33. MultiLineString: function(o) { o.arcs = o.arcs.map(indexArcs); },
  34. Polygon: function(o) { o.arcs = o.arcs.map(indexArcs); },
  35. MultiPolygon: function(o) { o.arcs = o.arcs.map(indexMultiArcs); }
  36. };
  37. function indexArcs(arc) {
  38. var indexes = [];
  39. do {
  40. var index = indexByArc.get(arc);
  41. indexes.push(arc[0] < arc[1] ? index : ~index);
  42. } while (arc = arc.next);
  43. return indexes;
  44. }
  45. function indexMultiArcs(arcs) {
  46. return arcs.map(indexArcs);
  47. }
  48. for (var key in objects) {
  49. indexGeometry(objects[key]);
  50. }
  51. if (transform) {
  52. topology.transform = transform;
  53. topology.arcs = delta(topology.arcs);
  54. }
  55. return topology;
  56. }
  57. function hashArc(arc) {
  58. var i = arc[0], j = arc[1], t;
  59. if (j < i) t = i, i = j, j = t;
  60. return i + 31 * j;
  61. }
  62. function equalArc(arcA, arcB) {
  63. var ia = arcA[0], ja = arcA[1],
  64. ib = arcB[0], jb = arcB[1], t;
  65. if (ja < ia) t = ia, ia = ja, ja = t;
  66. if (jb < ib) t = ib, ib = jb, jb = t;
  67. return ia === ib && ja === jb;
  68. }