mapHelpers.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import * as turf from '@turf/turf';
  2. import { Feature } from '@turf/turf';
  3. import { ItemSeries, RegionData } from '../types/map';
  4. export const findRegionInDataset = (dataset: RegionData, point: turf.helpers.Position | turf.helpers.Point | turf.helpers.Feature<turf.helpers.Point, turf.helpers.Properties>): Feature | undefined => {
  5. return dataset.features.find((region: any) => {
  6. const coordinates = region?.geometry?.coordinates;
  7. const type = region?.geometry?.type;
  8. if (!Array.isArray(coordinates) || coordinates.length === 0) {
  9. return false;
  10. }
  11. try {
  12. const polygon: any = type === 'Polygon'
  13. ? turf.polygon(coordinates)
  14. : turf.multiPolygon(coordinates);
  15. return turf.booleanPointInPolygon(point, polygon);
  16. } catch (error) {
  17. console.error('Error creating polygon:', error);
  18. return false;
  19. }
  20. });
  21. };
  22. export const calculateMapRegion = (bounds: turf.BBox): any => {
  23. const padding = 1;
  24. return {
  25. latitude: (bounds[1] + bounds[3]) / 2,
  26. longitude: (bounds[0] + bounds[2]) / 2,
  27. latitudeDelta: Math.abs(bounds[3] - bounds[1]) + padding,
  28. longitudeDelta: Math.abs(bounds[2] - bounds[0]) + padding,
  29. };
  30. };
  31. const isBBoxOverlap = (bbox1: number[], bbox2: number[]) => {
  32. return bbox1[0] <= bbox2[2] &&
  33. bbox1[2] >= bbox2[0] &&
  34. bbox1[1] <= bbox2[3] &&
  35. bbox1[3] >= bbox2[1];
  36. };
  37. export const filterCandidates = (candidates: { features?: any; }, areaPolygon: turf.BBox) => {
  38. const visibleAreaPolygon = turf.bboxPolygon(areaPolygon);
  39. const candidateRegions = candidates.features.filter((feature: any) => {
  40. const featureBBox = turf.bbox(feature);
  41. return isBBoxOverlap(featureBBox, areaPolygon);
  42. });
  43. return candidateRegions.filter((feature: turf.helpers.Geometry | turf.helpers.Feature<any, turf.helpers.Properties>) => {
  44. return turf.booleanIntersects(feature, visibleAreaPolygon) ||
  45. turf.booleanOverlap(feature, visibleAreaPolygon);
  46. });
  47. };
  48. export const processMarkerData = (marker: ItemSeries) => {
  49. let coordinates = null;
  50. if (marker.pointJSON) {
  51. coordinates = JSON.parse(marker.pointJSON);
  52. }
  53. else if (marker.polygonJSON) {
  54. const polygon = JSON.parse(marker.polygonJSON);
  55. const polygonFeature = turf.polygon(polygon);
  56. const center = turf.center(polygonFeature);
  57. coordinates = center.geometry.coordinates;
  58. }
  59. return {
  60. ...marker,
  61. pointJSON: coordinates ?? null,
  62. };
  63. };
  64. export const filterCandidatesMarkers = (candidatesMarkers: any[], visibleAreaPolygon: turf.helpers.Geometry | turf.helpers.Feature<any, turf.helpers.Properties>) => (
  65. candidatesMarkers.filter((marker: { pointJSON: string; polygonJSON: string; }) => {
  66. if (marker.pointJSON) {
  67. const coordinates = JSON.parse(marker.pointJSON);
  68. const point = turf.point([coordinates[1], coordinates[0]]);
  69. return turf.booleanPointInPolygon(point, visibleAreaPolygon);
  70. }
  71. else if (marker.polygonJSON) {
  72. const polygonCoords = JSON.parse(marker.polygonJSON);
  73. const polygon = turf.polygon(polygonCoords);
  74. return turf.booleanOverlap(polygon, visibleAreaPolygon) ||
  75. turf.booleanContains(visibleAreaPolygon, polygon) ||
  76. turf.booleanWithin(polygon, visibleAreaPolygon);
  77. }
  78. return false;
  79. }
  80. ));