Source: centroid.js

  1. import { check } from "./helpers/check.js";
  2. import { geoArea, geoCentroid, geoIdentity, geoPath } from "d3-geo";
  3. const d3 = Object.assign({}, { geoArea, geoCentroid, geoIdentity, geoPath });
  4. /**
  5. * @function centroid
  6. * @summary Calculates the centroids of geometries.
  7. * @description Based on `d3.geoArea()` and `d3.geoCentroid()`
  8. * @param {object|array} data - A GeoJSON FeatureCollection, an array of features, an array of geometries, a single feature or a single geometry.
  9. * @param {object} options - Optional parameters.
  10. * @param {boolean} [options.larget = true] - If true, set the point at the centre of the largest polygon.
  11. * @param {boolean} [options.geo = true] - Use true to consider the centroid from world coordinates on the globe. If you use false, then you are considering the coordinates within the svg document.
  12. * @returns {object|array} - A GeoJSON FeatureCollection, an array of features, an array of geometries, a single feature or a single geometry (it depends on what you've set as `data`)
  13. * @example
  14. * geotoolbox.centroid(*a geojson*, {largest: true})
  15. */
  16. export function centroid(data, { largest = true, geo = true } = {}) {
  17. const handle = check(data);
  18. let x = handle.import(data);
  19. let path = d3.geoPath(d3.geoIdentity());
  20. function largestPolygon(d) {
  21. var best = {};
  22. var bestArea = 0;
  23. d.geometry.coordinates.forEach(function (coords) {
  24. var poly = { type: "Polygon", coordinates: coords };
  25. var area = geo ? d3.geoArea(poly) : path.area(poly);
  26. if (area > bestArea) {
  27. bestArea = area;
  28. best = poly;
  29. }
  30. });
  31. return best;
  32. }
  33. let centers = x.features.map((d) => {
  34. if (geo) {
  35. console.log(d);
  36. d.geometry.coordinates = d3.geoCentroid(
  37. largest == true
  38. ? d.geometry.type == "Polygon"
  39. ? d
  40. : largestPolygon(d, true)
  41. : d
  42. );
  43. } else {
  44. d.geometry.coordinates = path.centroid(
  45. largest == true
  46. ? d.geometry.type == "Polygon"
  47. ? d
  48. : largestPolygon(d, false)
  49. : d
  50. );
  51. }
  52. d.geometry.type = "Point";
  53. return d;
  54. });
  55. x.features = centers;
  56. x.name = "centroid";
  57. return handle.export(x);
  58. }