feature.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import reverse from "./reverse.js";
  2. import transform from "./transform.js";
  3. export default function(topology, o) {
  4. if (typeof o === "string") o = topology.objects[o];
  5. return o.type === "GeometryCollection"
  6. ? {type: "FeatureCollection", features: o.geometries.map(function(o) { return feature(topology, o); })}
  7. : feature(topology, o);
  8. }
  9. function feature(topology, o) {
  10. var id = o.id,
  11. bbox = o.bbox,
  12. properties = o.properties == null ? {} : o.properties,
  13. geometry = object(topology, o);
  14. return id == null && bbox == null ? {type: "Feature", properties: properties, geometry: geometry}
  15. : bbox == null ? {type: "Feature", id: id, properties: properties, geometry: geometry}
  16. : {type: "Feature", id: id, bbox: bbox, properties: properties, geometry: geometry};
  17. }
  18. export function object(topology, o) {
  19. var transformPoint = transform(topology.transform),
  20. arcs = topology.arcs;
  21. function arc(i, points) {
  22. if (points.length) points.pop();
  23. for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length; k < n; ++k) {
  24. points.push(transformPoint(a[k], k));
  25. }
  26. if (i < 0) reverse(points, n);
  27. }
  28. function point(p) {
  29. return transformPoint(p);
  30. }
  31. function line(arcs) {
  32. var points = [];
  33. for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points);
  34. if (points.length < 2) points.push(points[0]); // This should never happen per the specification.
  35. return points;
  36. }
  37. function ring(arcs) {
  38. var points = line(arcs);
  39. while (points.length < 4) points.push(points[0]); // This may happen if an arc has only two points.
  40. return points;
  41. }
  42. function polygon(arcs) {
  43. return arcs.map(ring);
  44. }
  45. function geometry(o) {
  46. var type = o.type, coordinates;
  47. switch (type) {
  48. case "GeometryCollection": return {type: type, geometries: o.geometries.map(geometry)};
  49. case "Point": coordinates = point(o.coordinates); break;
  50. case "MultiPoint": coordinates = o.coordinates.map(point); break;
  51. case "LineString": coordinates = line(o.arcs); break;
  52. case "MultiLineString": coordinates = o.arcs.map(line); break;
  53. case "Polygon": coordinates = polygon(o.arcs); break;
  54. case "MultiPolygon": coordinates = o.arcs.map(polygon); break;
  55. default: return null;
  56. }
  57. return {type: type, coordinates: coordinates};
  58. }
  59. return geometry(o);
  60. }