neighbors.js 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. import bisect from "./bisect.js";
  2. export default function(objects) {
  3. var indexesByArc = {}, // arc index -> array of object indexes
  4. neighbors = objects.map(function() { return []; });
  5. function line(arcs, i) {
  6. arcs.forEach(function(a) {
  7. if (a < 0) a = ~a;
  8. var o = indexesByArc[a];
  9. if (o) o.push(i);
  10. else indexesByArc[a] = [i];
  11. });
  12. }
  13. function polygon(arcs, i) {
  14. arcs.forEach(function(arc) { line(arc, i); });
  15. }
  16. function geometry(o, i) {
  17. if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); });
  18. else if (o.type in geometryType) geometryType[o.type](o.arcs, i);
  19. }
  20. var geometryType = {
  21. LineString: line,
  22. MultiLineString: polygon,
  23. Polygon: polygon,
  24. MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); }
  25. };
  26. objects.forEach(geometry);
  27. for (var i in indexesByArc) {
  28. for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) {
  29. for (var k = j + 1; k < m; ++k) {
  30. var ij = indexes[j], ik = indexes[k], n;
  31. if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik);
  32. if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij);
  33. }
  34. }
  35. }
  36. return neighbors;
  37. }