@accelint/map-toolkit 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/catalog-info.yaml +5 -3
  3. package/dist/camera/use-camera-state.js +1 -2
  4. package/dist/camera/use-camera-state.js.map +1 -1
  5. package/dist/deckgl/base-map/constants.d.ts +9 -2
  6. package/dist/deckgl/base-map/constants.js +9 -2
  7. package/dist/deckgl/base-map/constants.js.map +1 -1
  8. package/dist/deckgl/base-map/index.d.ts +4 -2
  9. package/dist/deckgl/base-map/index.js +5 -6
  10. package/dist/deckgl/base-map/index.js.map +1 -1
  11. package/dist/deckgl/base-map/types.d.ts +6 -1
  12. package/dist/deckgl/index.d.ts +8 -2
  13. package/dist/deckgl/index.js +6 -2
  14. package/dist/deckgl/saved-viewports/index.d.ts +1 -1
  15. package/dist/deckgl/saved-viewports/index.js +1 -2
  16. package/dist/deckgl/saved-viewports/index.js.map +1 -1
  17. package/dist/deckgl/shapes/display-shape-layer/constants.d.ts +44 -0
  18. package/dist/deckgl/shapes/display-shape-layer/constants.js +61 -0
  19. package/dist/deckgl/shapes/display-shape-layer/constants.js.map +1 -0
  20. package/dist/{node_modules/.pnpm/@math.gl_web-mercator@4.1.0/node_modules/@math.gl/web-mercator/dist/assert.js → deckgl/shapes/display-shape-layer/fiber.d.ts} +11 -7
  21. package/dist/{packages/hotkey-manager/dist/lib/is-client/index.js → deckgl/shapes/display-shape-layer/fiber.js} +6 -7
  22. package/dist/deckgl/shapes/display-shape-layer/fiber.js.map +1 -0
  23. package/dist/deckgl/shapes/display-shape-layer/index.d.ts +206 -0
  24. package/dist/deckgl/shapes/display-shape-layer/index.js +416 -0
  25. package/dist/deckgl/shapes/display-shape-layer/index.js.map +1 -0
  26. package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.d.ts +66 -0
  27. package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.js +116 -0
  28. package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.js.map +1 -0
  29. package/dist/deckgl/shapes/display-shape-layer/store.d.ts +87 -0
  30. package/dist/deckgl/shapes/display-shape-layer/store.js +316 -0
  31. package/dist/deckgl/shapes/display-shape-layer/store.js.map +1 -0
  32. package/dist/deckgl/shapes/display-shape-layer/types.d.ts +115 -0
  33. package/dist/{node_modules/.pnpm/@math.gl_web-mercator@4.1.0/node_modules/@math.gl/web-mercator/dist/fly-to-viewport.js → deckgl/shapes/display-shape-layer/types.js} +0 -2
  34. package/dist/deckgl/shapes/display-shape-layer/use-shape-selection.d.ts +89 -0
  35. package/dist/deckgl/shapes/display-shape-layer/use-shape-selection.js +88 -0
  36. package/dist/deckgl/shapes/display-shape-layer/use-shape-selection.js.map +1 -0
  37. package/dist/deckgl/shapes/display-shape-layer/utils/display-style.d.ts +61 -0
  38. package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js +111 -0
  39. package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js.map +1 -0
  40. package/dist/deckgl/shapes/display-shape-layer/utils/labels.d.ts +196 -0
  41. package/dist/deckgl/shapes/display-shape-layer/utils/labels.js +368 -0
  42. package/dist/deckgl/shapes/display-shape-layer/utils/labels.js.map +1 -0
  43. package/dist/deckgl/shapes/index.d.ts +20 -0
  44. package/dist/{node_modules/.pnpm/@math.gl_web-mercator@4.1.0/node_modules/@math.gl/web-mercator/dist/math-utils.js → deckgl/shapes/index.js} +6 -11
  45. package/dist/deckgl/shapes/shared/constants.d.ts +78 -0
  46. package/dist/deckgl/shapes/shared/constants.js +109 -0
  47. package/dist/deckgl/shapes/shared/constants.js.map +1 -0
  48. package/dist/deckgl/shapes/shared/events.d.ts +73 -0
  49. package/dist/deckgl/shapes/shared/events.js +58 -0
  50. package/dist/deckgl/shapes/shared/events.js.map +1 -0
  51. package/dist/deckgl/shapes/shared/types.d.ts +158 -0
  52. package/dist/{node_modules/.pnpm/@math.gl_web-mercator@4.1.0/node_modules/@math.gl/web-mercator/dist/get-bounds.js → deckgl/shapes/shared/types.js} +13 -4
  53. package/dist/deckgl/shapes/shared/types.js.map +1 -0
  54. package/dist/deckgl/symbol-layer/index.d.ts +1 -1
  55. package/dist/viewport/viewport-size.d.ts +2 -2
  56. package/package.json +36 -20
  57. package/dist/_virtual/rolldown_runtime.js +0 -22
  58. package/dist/decorators/deckgl.d.ts +0 -19
  59. package/dist/decorators/deckgl.js +0 -32
  60. package/dist/decorators/deckgl.js.map +0 -1
  61. package/dist/node_modules/.pnpm/@math.gl_web-mercator@4.1.0/node_modules/@math.gl/web-mercator/dist/assert.js.map +0 -1
  62. package/dist/node_modules/.pnpm/@math.gl_web-mercator@4.1.0/node_modules/@math.gl/web-mercator/dist/fit-bounds.js +0 -63
  63. package/dist/node_modules/.pnpm/@math.gl_web-mercator@4.1.0/node_modules/@math.gl/web-mercator/dist/fit-bounds.js.map +0 -1
  64. package/dist/node_modules/.pnpm/@math.gl_web-mercator@4.1.0/node_modules/@math.gl/web-mercator/dist/get-bounds.js.map +0 -1
  65. package/dist/node_modules/.pnpm/@math.gl_web-mercator@4.1.0/node_modules/@math.gl/web-mercator/dist/index.js +0 -19
  66. package/dist/node_modules/.pnpm/@math.gl_web-mercator@4.1.0/node_modules/@math.gl/web-mercator/dist/math-utils.js.map +0 -1
  67. package/dist/node_modules/.pnpm/@math.gl_web-mercator@4.1.0/node_modules/@math.gl/web-mercator/dist/normalize-viewport-props.js +0 -14
  68. package/dist/node_modules/.pnpm/@math.gl_web-mercator@4.1.0/node_modules/@math.gl/web-mercator/dist/web-mercator-utils.js +0 -59
  69. package/dist/node_modules/.pnpm/@math.gl_web-mercator@4.1.0/node_modules/@math.gl/web-mercator/dist/web-mercator-utils.js.map +0 -1
  70. package/dist/node_modules/.pnpm/@math.gl_web-mercator@4.1.0/node_modules/@math.gl/web-mercator/dist/web-mercator-viewport.js +0 -16
  71. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/attribution-control.js +0 -29
  72. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/attribution-control.js.map +0 -1
  73. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/fullscreen-control.js +0 -29
  74. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/fullscreen-control.js.map +0 -1
  75. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/geolocate-control.js +0 -54
  76. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/geolocate-control.js.map +0 -1
  77. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/layer.js +0 -15
  78. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/logo-control.js +0 -29
  79. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/logo-control.js.map +0 -1
  80. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/map.js +0 -91
  81. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/map.js.map +0 -1
  82. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/marker.js +0 -88
  83. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/marker.js.map +0 -1
  84. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/navigation-control.js +0 -29
  85. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/navigation-control.js.map +0 -1
  86. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/popup.js +0 -69
  87. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/popup.js.map +0 -1
  88. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/scale-control.js +0 -35
  89. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/scale-control.js.map +0 -1
  90. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/source.js +0 -15
  91. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/terrain-control.js +0 -29
  92. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/terrain-control.js.map +0 -1
  93. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/use-control.js +0 -40
  94. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/use-control.js.map +0 -1
  95. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/use-map.js +0 -23
  96. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/components/use-map.js.map +0 -1
  97. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/index.js +0 -27
  98. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/maplibre/create-ref.js +0 -57
  99. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/maplibre/create-ref.js.map +0 -1
  100. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/maplibre/maplibre.js +0 -343
  101. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/maplibre/maplibre.js.map +0 -1
  102. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/utils/apply-react-style.js +0 -28
  103. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/utils/apply-react-style.js.map +0 -1
  104. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/utils/compare-class-names.js +0 -31
  105. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/utils/compare-class-names.js.map +0 -1
  106. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/utils/deep-equal.js +0 -57
  107. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/utils/deep-equal.js.map +0 -1
  108. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/utils/set-globals.js +0 -30
  109. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/utils/set-globals.js.map +0 -1
  110. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/utils/style-utils.js +0 -53
  111. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/utils/style-utils.js.map +0 -1
  112. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/utils/transform.js +0 -52
  113. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/utils/transform.js.map +0 -1
  114. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/utils/use-isomorphic-layout-effect.js +0 -22
  115. package/dist/node_modules/.pnpm/@vis.gl_react-maplibre@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@vis.gl/react-maplibre/dist/utils/use-isomorphic-layout-effect.js.map +0 -1
  116. package/dist/node_modules/.pnpm/immer@10.2.0/node_modules/immer/dist/immer.js +0 -812
  117. package/dist/node_modules/.pnpm/immer@10.2.0/node_modules/immer/dist/immer.js.map +0 -1
  118. package/dist/node_modules/.pnpm/radashi@12.7.1/node_modules/radashi/dist/radashi.js +0 -35
  119. package/dist/node_modules/.pnpm/radashi@12.7.1/node_modules/radashi/dist/radashi.js.map +0 -1
  120. package/dist/node_modules/.pnpm/react-dom@19.2.3_react@19.2.3/node_modules/react-dom/cjs/react-dom.development.js +0 -195
  121. package/dist/node_modules/.pnpm/react-dom@19.2.3_react@19.2.3/node_modules/react-dom/cjs/react-dom.development.js.map +0 -1
  122. package/dist/node_modules/.pnpm/react-dom@19.2.3_react@19.2.3/node_modules/react-dom/cjs/react-dom.production.js +0 -76
  123. package/dist/node_modules/.pnpm/react-dom@19.2.3_react@19.2.3/node_modules/react-dom/cjs/react-dom.production.js.map +0 -1
  124. package/dist/node_modules/.pnpm/react-dom@19.2.3_react@19.2.3/node_modules/react-dom/index.js +0 -39
  125. package/dist/node_modules/.pnpm/react-dom@19.2.3_react@19.2.3/node_modules/react-dom/index.js.map +0 -1
  126. package/dist/node_modules/.pnpm/react-map-gl@8.1.0_maplibre-gl@5.15.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/react-map-gl/dist/maplibre.js +0 -16
  127. package/dist/node_modules/.pnpm/zustand@5.0.9_@types_react@19.2.7_immer@10.2.0_react@19.2.3_use-sync-external-store@1.6.0_react@19.2.3_/node_modules/zustand/esm/middleware/immer.js +0 -27
  128. package/dist/node_modules/.pnpm/zustand@5.0.9_@types_react@19.2.7_immer@10.2.0_react@19.2.3_use-sync-external-store@1.6.0_react@19.2.3_/node_modules/zustand/esm/middleware/immer.js.map +0 -1
  129. package/dist/node_modules/.pnpm/zustand@5.0.9_@types_react@19.2.7_immer@10.2.0_react@19.2.3_use-sync-external-store@1.6.0_react@19.2.3_/node_modules/zustand/esm/vanilla.js +0 -45
  130. package/dist/node_modules/.pnpm/zustand@5.0.9_@types_react@19.2.7_immer@10.2.0_react@19.2.3_use-sync-external-store@1.6.0_react@19.2.3_/node_modules/zustand/esm/vanilla.js.map +0 -1
  131. package/dist/packages/hotkey-manager/dist/actions/register-hotkey/index.js +0 -78
  132. package/dist/packages/hotkey-manager/dist/actions/register-hotkey/index.js.map +0 -1
  133. package/dist/packages/hotkey-manager/dist/constants.js +0 -47
  134. package/dist/packages/hotkey-manager/dist/constants.js.map +0 -1
  135. package/dist/packages/hotkey-manager/dist/enums/keycode.js +0 -130
  136. package/dist/packages/hotkey-manager/dist/enums/keycode.js.map +0 -1
  137. package/dist/packages/hotkey-manager/dist/lib/is-client/index.js.map +0 -1
  138. package/dist/packages/hotkey-manager/dist/lib/is-mac/index.js +0 -24
  139. package/dist/packages/hotkey-manager/dist/lib/is-mac/index.js.map +0 -1
  140. package/dist/packages/hotkey-manager/dist/lib/key-to-id/index.js +0 -39
  141. package/dist/packages/hotkey-manager/dist/lib/key-to-id/index.js.map +0 -1
  142. package/dist/packages/hotkey-manager/dist/lib/key-to-string/index.js +0 -27
  143. package/dist/packages/hotkey-manager/dist/lib/key-to-string/index.js.map +0 -1
  144. package/dist/packages/hotkey-manager/dist/stores/hotkey-store/index.js +0 -95
  145. package/dist/packages/hotkey-manager/dist/stores/hotkey-store/index.js.map +0 -1
@@ -0,0 +1,196 @@
1
+ /*
2
+ * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at https://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import { EditableShape } from "../../shared/types.js";
14
+
15
+ //#region src/deckgl/shapes/display-shape-layer/utils/labels.d.ts
16
+ /**
17
+ * Label positioning information including coordinates and screen-space offsets
18
+ */
19
+ interface LabelPosition2d {
20
+ /** Geographic coordinates [longitude, latitude] */
21
+ coordinates: [number, number];
22
+ /** Horizontal text anchor point */
23
+ textAnchor: 'start' | 'middle' | 'end';
24
+ /** Vertical text alignment */
25
+ alignmentBaseline: 'top' | 'center' | 'bottom';
26
+ /** Pixel offset from coordinates [x, y] */
27
+ pixelOffset: [number, number];
28
+ }
29
+ /**
30
+ * Calculate a point along a line segment
31
+ * @param start - Start coordinate [lon, lat]
32
+ * @param end - End coordinate [lon, lat]
33
+ * @param ratio - Position along segment (0 = start, 0.5 = middle, 1 = end)
34
+ * @returns Interpolated coordinate [lon, lat]
35
+ *
36
+ * @example
37
+ * // Get a point 25% along a line segment
38
+ * const start: [number, number] = [-122.4, 37.8];
39
+ * const end: [number, number] = [-122.3, 37.9];
40
+ * const point = interpolatePoint(start, end, 0.25);
41
+ */
42
+ declare function interpolatePoint(start: [number, number], end: [number, number], ratio: number): [number, number];
43
+ /**
44
+ * Get the midpoint of a LineString
45
+ * @param coordinates - LineString coordinates array
46
+ * @returns Midpoint coordinate [lon, lat]
47
+ */
48
+ declare function getLineStringMidpoint(coordinates: [number, number][]): [number, number];
49
+ /**
50
+ * Get the end point of a LineString
51
+ * @param coordinates - LineString coordinates array
52
+ * @returns End coordinate [lon, lat]
53
+ */
54
+ declare function getLineStringEndpoint(coordinates: [number, number][]): [number, number];
55
+ /**
56
+ * Get the midpoint of a Polygon's outer ring
57
+ * @param coordinates - Polygon coordinates array (rings)
58
+ * @returns Midpoint of outer ring [lon, lat]
59
+ */
60
+ declare function getPolygonMidpoint(coordinates: [number, number][][]): [number, number];
61
+ /**
62
+ * Vertical label position relative to anchor point
63
+ */
64
+ type LabelVerticalPosition = 'top' | 'middle' | 'bottom';
65
+ /**
66
+ * Horizontal label position relative to anchor point
67
+ */
68
+ type LabelHorizontalPosition = 'left' | 'center' | 'right';
69
+ /**
70
+ * Cardinal direction anchor for positioning labels on geometry edges
71
+ * Uses edge positions relative to the geometry's bounding box
72
+ * Works for LineString, Polygon, and Circle geometries
73
+ * - 'center': centroid/midpoint of the geometry
74
+ * - 'top'/'right'/'bottom'/'left': edge positions
75
+ */
76
+ type CardinalLabelCoordinateAnchor = 'center' | 'top' | 'right' | 'bottom' | 'left';
77
+ /**
78
+ * Global label positioning options for DisplayShapeLayer
79
+ *
80
+ * ## Priority System
81
+ * Label positioning follows a three-tier priority system:
82
+ * 1. **Per-shape properties** in `styleProperties` (highest priority)
83
+ * 2. **Global options** via this interface
84
+ * 3. **Default values** (geometry-specific fallbacks)
85
+ *
86
+ * ## Label Appearance
87
+ *
88
+ * Labels use a clean text-only style:
89
+ * - **Text**: White uppercase, bold Roboto Mono, 10px
90
+ * - **Outline**: Black 2px outline for contrast
91
+ * - **No background or border**
92
+ *
93
+ * Text height ≈ 10px
94
+ *
95
+ * ## Positioning Concepts
96
+ *
97
+ * ### Coordinate Anchor
98
+ * Determines *where* on the geometry to place the label:
99
+ * - **Point**: Label is always at the point coordinate
100
+ * - **LineString/Polygon**: 'start', 'middle', or 'end' along the geometry
101
+ * - **Circle**: 'top', 'right', 'bottom', or 'left' on the perimeter
102
+ *
103
+ * ### Vertical/Horizontal Anchor
104
+ * Determines how the label aligns *relative to* the anchor point:
105
+ * - **Vertical**: 'top' (label text below point), 'middle' (centered), 'bottom' (label text above point)
106
+ * - **Horizontal**: 'left' (label text right of point), 'center' (centered), 'right' (label text left of point)
107
+ *
108
+ * ### Pixel Offset
109
+ * Fine-tune label position with [x, y] pixel offsets:
110
+ * - Positive x moves right, negative moves left
111
+ * - Positive y moves down, negative moves up
112
+ *
113
+ * @example Position circle labels at the top with 5px clearance
114
+ * ```tsx
115
+ * const labelOptions: LabelPositionOptions = {
116
+ * circleLabelCoordinateAnchor: 'top',
117
+ * circleLabelVerticalAnchor: 'bottom', // Label above the top point
118
+ * circleLabelOffset: [0, -15], // -(10px text height + 5px clearance)
119
+ * };
120
+ * ```
121
+ *
122
+ * @example Position line labels at middle with offset to the right
123
+ * ```tsx
124
+ * const labelOptions: LabelPositionOptions = {
125
+ * lineStringLabelCoordinateAnchor: 'middle',
126
+ * lineStringLabelHorizontalAnchor: 'left',
127
+ * lineStringLabelOffset: [10, 0], // 10px to the right
128
+ * };
129
+ * ```
130
+ */
131
+ interface LabelPositionOptions {
132
+ /** Vertical anchor for Point labels @default 'top' */
133
+ pointLabelVerticalAnchor?: LabelVerticalPosition;
134
+ /** Horizontal anchor for Point labels @default 'center' */
135
+ pointLabelHorizontalAnchor?: LabelHorizontalPosition;
136
+ /** Pixel offset for Point labels [x, y] @default [0, 10] */
137
+ pointLabelOffset?: [number, number];
138
+ /** Position on LineString edge (top/right/bottom/left) @default 'bottom' */
139
+ lineStringLabelCoordinateAnchor?: CardinalLabelCoordinateAnchor;
140
+ /** Vertical anchor for LineString labels @default 'top' */
141
+ lineStringLabelVerticalAnchor?: LabelVerticalPosition;
142
+ /** Horizontal anchor for LineString labels @default 'center' */
143
+ lineStringLabelHorizontalAnchor?: LabelHorizontalPosition;
144
+ /** Pixel offset for LineString labels [x, y] @default [0, 10] */
145
+ lineStringLabelOffset?: [number, number];
146
+ /** Position on Polygon edge (top/right/bottom/left) @default 'bottom' */
147
+ polygonLabelCoordinateAnchor?: CardinalLabelCoordinateAnchor;
148
+ /** Vertical anchor for Polygon labels @default 'top' */
149
+ polygonLabelVerticalAnchor?: LabelVerticalPosition;
150
+ /** Horizontal anchor for Polygon labels @default 'center' */
151
+ polygonLabelHorizontalAnchor?: LabelHorizontalPosition;
152
+ /** Pixel offset for Polygon labels [x, y] @default [0, 10] */
153
+ polygonLabelOffset?: [number, number];
154
+ /** Position on Circle perimeter (top/right/bottom/left) @default 'bottom' */
155
+ circleLabelCoordinateAnchor?: CardinalLabelCoordinateAnchor;
156
+ /** Vertical anchor for Circle labels @default 'top' */
157
+ circleLabelVerticalAnchor?: LabelVerticalPosition;
158
+ /** Horizontal anchor for Circle labels @default 'center' */
159
+ circleLabelHorizontalAnchor?: LabelHorizontalPosition;
160
+ /** Pixel offset for Circle labels [x, y] @default [0, 10] */
161
+ circleLabelOffset?: [number, number];
162
+ }
163
+ /**
164
+ * Get 2D position for label based on geometry type
165
+ * Uses pixel-based offsets for consistent positioning at all zoom levels
166
+ *
167
+ * Priority for positioning:
168
+ * 1. Per-shape properties in styleProperties (highest)
169
+ * 2. Global labelOptions from layer props
170
+ * 3. Default values (fallback)
171
+ *
172
+ * Returns null if no valid coordinates can be determined
173
+ */
174
+ declare function getLabelPosition2d(shape: EditableShape, options?: LabelPositionOptions): LabelPosition2d | null;
175
+ /**
176
+ * Get label text for a shape
177
+ *
178
+ * Returns the display label for the shape on the map in uppercase.
179
+ * - `label`: Optional short display name shown on the map (e.g., "NYC")
180
+ * - `name`: Full shape name used internally (e.g., "New York City Office")
181
+ *
182
+ * If `label` is not provided, falls back to using `name`.
183
+ * Text is automatically converted to uppercase for display.
184
+ */
185
+ declare function getLabelText(shape: EditableShape): string;
186
+ /**
187
+ * Get label background color (uses RGB from shape fill color with fixed label opacity)
188
+ */
189
+ declare function getLabelFillColor(shape: EditableShape): [number, number, number, number];
190
+ /**
191
+ * Get label border color (uses RGB from shape stroke color with full opacity)
192
+ */
193
+ declare function getLabelBorderColor(shape: EditableShape): [number, number, number, number];
194
+ //#endregion
195
+ export { CardinalLabelCoordinateAnchor, LabelHorizontalPosition, LabelPosition2d, LabelPositionOptions, LabelVerticalPosition, getLabelBorderColor, getLabelFillColor, getLabelPosition2d, getLabelText, getLineStringEndpoint, getLineStringMidpoint, getPolygonMidpoint, interpolatePoint };
196
+ //# sourceMappingURL=labels.d.ts.map
@@ -0,0 +1,368 @@
1
+ /*
2
+ * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at https://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+
14
+ 'use client';
15
+
16
+ import { LABEL_BACKGROUND_OPACITY, LABEL_BORDER_OPACITY } from "../../shared/constants.js";
17
+
18
+ //#region src/deckgl/shapes/display-shape-layer/utils/labels.ts
19
+ /**
20
+ * Label positioning utilities for shapes
21
+ *
22
+ * This module provides utilities for positioning labels on shapes and calculating
23
+ * points along line segments. Use these to customize label placement in your shape data.
24
+ *
25
+ * ## Label Styling
26
+ *
27
+ * Labels use a text-only style for legibility across different map backgrounds:
28
+ * - **Text**: White uppercase with bold Roboto Mono font at 10px
29
+ * - **Outline**: Black 2px outline around text for contrast
30
+ * - **No background or border**: Clean text-only appearance
31
+ *
32
+ * ### Calculating Offsets
33
+ *
34
+ * When positioning labels, the text height is approximately 10px.
35
+ * For example, to position a label exactly 5px above a point:
36
+ * - Label height ≈ text height (10px)
37
+ * - Offset needed: [0, -(10 + 5)] = [0, -15]
38
+ *
39
+ * @example Position label at the middle of a LineString
40
+ * ```typescript
41
+ * import { getLineStringMidpoint } from '@accelint/map-toolkit/deckgl/shapes/display-shape-layer/utils/labels';
42
+ *
43
+ * // Calculate midpoint for custom positioning
44
+ * const coordinates = [[-122.4, 37.8], [-122.3, 37.9], [-122.2, 38.0]];
45
+ * const midpoint = getLineStringMidpoint(coordinates);
46
+ *
47
+ * // Use in shape data with custom label properties
48
+ * const shape = {
49
+ * feature: {
50
+ * properties: {
51
+ * styleProperties: {
52
+ * labelVerticalAnchor: 'top',
53
+ * labelHorizontalAnchor: 'center',
54
+ * labelOffset: [0, -10], // Small offset above the line
55
+ * }
56
+ * }
57
+ * }
58
+ * };
59
+ * ```
60
+ */
61
+ /**
62
+ * Calculate a point along a line segment
63
+ * @param start - Start coordinate [lon, lat]
64
+ * @param end - End coordinate [lon, lat]
65
+ * @param ratio - Position along segment (0 = start, 0.5 = middle, 1 = end)
66
+ * @returns Interpolated coordinate [lon, lat]
67
+ *
68
+ * @example
69
+ * // Get a point 25% along a line segment
70
+ * const start: [number, number] = [-122.4, 37.8];
71
+ * const end: [number, number] = [-122.3, 37.9];
72
+ * const point = interpolatePoint(start, end, 0.25);
73
+ */
74
+ function interpolatePoint(start, end, ratio) {
75
+ const clampedRatio = Math.max(0, Math.min(1, ratio));
76
+ return [start[0] + (end[0] - start[0]) * clampedRatio, start[1] + (end[1] - start[1]) * clampedRatio];
77
+ }
78
+ /**
79
+ * Calculate segment lengths for a line
80
+ */
81
+ function calculateSegmentLengths(coordinates) {
82
+ let total = 0;
83
+ const lengths = [];
84
+ for (let i = 0; i < coordinates.length - 1; i++) {
85
+ const start = coordinates[i];
86
+ const end = coordinates[i + 1];
87
+ if (start && end) {
88
+ const length = Math.sqrt((end[0] - start[0]) ** 2 + (end[1] - start[1]) ** 2);
89
+ lengths.push(length);
90
+ total += length;
91
+ }
92
+ }
93
+ return {
94
+ lengths,
95
+ total
96
+ };
97
+ }
98
+ /**
99
+ * Find point at specific distance along line
100
+ */
101
+ function findPointAtDistance(coordinates, segmentLengths, targetDistance) {
102
+ let accumulatedLength = 0;
103
+ for (let i = 0; i < segmentLengths.length; i++) {
104
+ const segmentLength = segmentLengths[i];
105
+ if (!segmentLength) continue;
106
+ if (accumulatedLength + segmentLength >= targetDistance) {
107
+ const start = coordinates[i];
108
+ const end = coordinates[i + 1];
109
+ if (start && end) return interpolatePoint(start, end, (targetDistance - accumulatedLength) / segmentLength);
110
+ }
111
+ accumulatedLength += segmentLength;
112
+ }
113
+ return coordinates[coordinates.length - 1] ?? [0, 0];
114
+ }
115
+ /**
116
+ * Get the midpoint of a LineString
117
+ * @param coordinates - LineString coordinates array
118
+ * @returns Midpoint coordinate [lon, lat]
119
+ */
120
+ function getLineStringMidpoint(coordinates) {
121
+ if (coordinates.length === 0) return [0, 0];
122
+ if (coordinates.length === 1) return coordinates[0] ?? [0, 0];
123
+ const { lengths, total } = calculateSegmentLengths(coordinates);
124
+ return findPointAtDistance(coordinates, lengths, total / 2);
125
+ }
126
+ /**
127
+ * Get the end point of a LineString
128
+ * @param coordinates - LineString coordinates array
129
+ * @returns End coordinate [lon, lat]
130
+ */
131
+ function getLineStringEndpoint(coordinates) {
132
+ if (coordinates.length === 0) return [0, 0];
133
+ return coordinates[coordinates.length - 1] ?? [0, 0];
134
+ }
135
+ /**
136
+ * Get the midpoint of a Polygon's outer ring
137
+ * @param coordinates - Polygon coordinates array (rings)
138
+ * @returns Midpoint of outer ring [lon, lat]
139
+ */
140
+ function getPolygonMidpoint(coordinates) {
141
+ const outerRing = coordinates[0];
142
+ if (!outerRing || outerRing.length === 0) return [0, 0];
143
+ return getLineStringMidpoint(outerRing);
144
+ }
145
+ /**
146
+ * Convert vertical/horizontal position to deck.gl textAnchor and alignmentBaseline
147
+ */
148
+ function convertPositionToAnchors(vertical, horizontal) {
149
+ return {
150
+ textAnchor: {
151
+ left: "start",
152
+ center: "middle",
153
+ right: "end"
154
+ }[horizontal],
155
+ alignmentBaseline: {
156
+ top: "top",
157
+ middle: "center",
158
+ bottom: "bottom"
159
+ }[vertical]
160
+ };
161
+ }
162
+ /**
163
+ * Helper to resolve label properties with priority: shape > options > default
164
+ */
165
+ function resolveLabelProperties(shapeOffset, shapeVertical, shapeHorizontal, defaultOffset, defaultVertical, defaultHorizontal, optionsOffset, optionsVertical, optionsHorizontal) {
166
+ return {
167
+ pixelOffset: shapeOffset ?? optionsOffset ?? defaultOffset,
168
+ ...convertPositionToAnchors(shapeVertical ?? optionsVertical ?? defaultVertical, shapeHorizontal ?? optionsHorizontal ?? defaultHorizontal)
169
+ };
170
+ }
171
+ /**
172
+ * Get position for Point geometry
173
+ */
174
+ function getPointPosition(geometry, shapeOffset, shapeVertical, shapeHorizontal, options) {
175
+ const resolved = resolveLabelProperties(shapeOffset, shapeVertical, shapeHorizontal, [0, 10], "top", "center", options?.pointLabelOffset, options?.pointLabelVerticalAnchor, options?.pointLabelHorizontalAnchor);
176
+ return {
177
+ coordinates: [geometry.coordinates[0] ?? 0, geometry.coordinates[1] ?? 0],
178
+ ...resolved
179
+ };
180
+ }
181
+ /**
182
+ * Get position for LineString geometry
183
+ * Uses cardinal direction positioning to find the edge point
184
+ */
185
+ function getLineStringPosition(geometry, shapeOffset, shapeVertical, shapeHorizontal, shapeCoordinateAnchor, options) {
186
+ const defaultOffset = [0, 10];
187
+ const defaultVertical = "top";
188
+ const defaultHorizontal = "center";
189
+ const defaultCoordinateAnchor = "bottom";
190
+ const resolved = resolveLabelProperties(shapeOffset, shapeVertical, shapeHorizontal, defaultOffset, defaultVertical, defaultHorizontal, options?.lineStringLabelOffset, options?.lineStringLabelVerticalAnchor, options?.lineStringLabelHorizontalAnchor);
191
+ const coordinateAnchor = shapeCoordinateAnchor ?? options?.lineStringLabelCoordinateAnchor ?? defaultCoordinateAnchor;
192
+ const coordinates = findEdgePoint(geometry.coordinates, coordinateAnchor);
193
+ if (!coordinates) return null;
194
+ return {
195
+ coordinates,
196
+ ...resolved
197
+ };
198
+ }
199
+ /**
200
+ * Get vertex coordinate from ring
201
+ */
202
+ function getVertexCoordinate(vertex) {
203
+ if (!vertex || vertex[0] === void 0 || vertex[1] === void 0) return null;
204
+ return [vertex[0], vertex[1]];
205
+ }
206
+ /**
207
+ * Check if a vertex should replace the current target based on edge position
208
+ */
209
+ function shouldUpdateEdgeVertex(vertexValue, targetValue, position) {
210
+ return position === "top" || position === "right" ? vertexValue > targetValue : vertexValue < targetValue;
211
+ }
212
+ /**
213
+ * Get the coordinate index based on edge position (0 for x/longitude, 1 for y/latitude)
214
+ */
215
+ function getCoordinateIndexForEdgePosition(position) {
216
+ return position === "top" || position === "bottom" ? 1 : 0;
217
+ }
218
+ /**
219
+ * Calculate the centroid (center point) of a set of coordinates
220
+ * For polygons, this calculates the geometric center
221
+ * For lines, this calculates the midpoint of the bounding box
222
+ * Returns null if no valid coordinates exist
223
+ */
224
+ function calculateCentroid(coordinates) {
225
+ if (coordinates.length === 0) return null;
226
+ let sumX = 0;
227
+ let sumY = 0;
228
+ let count = 0;
229
+ for (const coord of coordinates) if (coord && coord[0] !== void 0 && coord[1] !== void 0) {
230
+ sumX += coord[0];
231
+ sumY += coord[1];
232
+ count++;
233
+ }
234
+ if (count === 0) return null;
235
+ return [sumX / count, sumY / count];
236
+ }
237
+ /**
238
+ * Find the point on a geometry's perimeter at the specified edge position
239
+ * @param coordinates - Array of coordinates (ring or line)
240
+ * @param position - Edge position (center/top/right/bottom/left) relative to bounding box
241
+ * @returns Coordinate at the specified edge position, or null if no valid coordinates
242
+ */
243
+ function findEdgePoint(coordinates, position) {
244
+ if (!coordinates || coordinates.length === 0) return null;
245
+ if (position === "center") return calculateCentroid(coordinates);
246
+ let targetVertex = coordinates[0];
247
+ const coordinateIndex = getCoordinateIndexForEdgePosition(position);
248
+ for (const vertex of coordinates) {
249
+ if (!vertex) continue;
250
+ if (!targetVertex) continue;
251
+ const vertexValue = vertex[coordinateIndex];
252
+ const targetValue = targetVertex[coordinateIndex];
253
+ if (vertexValue === void 0 || targetValue === void 0) continue;
254
+ if (shouldUpdateEdgeVertex(vertexValue, targetValue, position)) targetVertex = vertex;
255
+ }
256
+ return getVertexCoordinate(targetVertex);
257
+ }
258
+ /**
259
+ * Get position for Circle geometry (special case of Polygon)
260
+ */
261
+ function getCirclePosition(ring, shapeOffset, shapeVertical, shapeHorizontal, shapeCoordinateAnchor, options) {
262
+ const defaultOffset = [0, 10];
263
+ const defaultVertical = "top";
264
+ const defaultHorizontal = "center";
265
+ const defaultCoordinateAnchor = "bottom";
266
+ const resolved = resolveLabelProperties(shapeOffset, shapeVertical, shapeHorizontal, defaultOffset, defaultVertical, defaultHorizontal, options?.circleLabelOffset, options?.circleLabelVerticalAnchor, options?.circleLabelHorizontalAnchor);
267
+ const coordinates = findEdgePoint(ring, shapeCoordinateAnchor ?? options?.circleLabelCoordinateAnchor ?? defaultCoordinateAnchor);
268
+ if (!coordinates) return null;
269
+ return {
270
+ coordinates,
271
+ ...resolved
272
+ };
273
+ }
274
+ /**
275
+ * Get position for Polygon geometry
276
+ * Uses cardinal direction positioning to find the edge point
277
+ */
278
+ function getPolygonPosition(geometry, shape, shapeOffset, shapeVertical, shapeHorizontal, shapeCoordinateAnchor, options) {
279
+ const ring = geometry.coordinates[0];
280
+ if (shape.shapeType === "Circle") return getCirclePosition(ring, shapeOffset, shapeVertical, shapeHorizontal, shapeCoordinateAnchor, options);
281
+ const defaultOffset = [0, 10];
282
+ const defaultVertical = "top";
283
+ const defaultHorizontal = "center";
284
+ const defaultCoordinateAnchor = "bottom";
285
+ const resolved = resolveLabelProperties(shapeOffset, shapeVertical, shapeHorizontal, defaultOffset, defaultVertical, defaultHorizontal, options?.polygonLabelOffset, options?.polygonLabelVerticalAnchor, options?.polygonLabelHorizontalAnchor);
286
+ const coordinates = findEdgePoint(ring, shapeCoordinateAnchor ?? options?.polygonLabelCoordinateAnchor ?? defaultCoordinateAnchor);
287
+ if (!coordinates) return null;
288
+ return {
289
+ coordinates,
290
+ ...resolved
291
+ };
292
+ }
293
+ /**
294
+ * Get 2D position for label based on geometry type
295
+ * Uses pixel-based offsets for consistent positioning at all zoom levels
296
+ *
297
+ * Priority for positioning:
298
+ * 1. Per-shape properties in styleProperties (highest)
299
+ * 2. Global labelOptions from layer props
300
+ * 3. Default values (fallback)
301
+ *
302
+ * Returns null if no valid coordinates can be determined
303
+ */
304
+ function getLabelPosition2d(shape, options) {
305
+ const { geometry } = shape.feature;
306
+ const styleProps = shape.feature.properties?.styleProperties;
307
+ const shapeOffset = styleProps?.labelOffset;
308
+ const shapeVertical = styleProps?.labelVerticalAnchor;
309
+ const shapeHorizontal = styleProps?.labelHorizontalAnchor;
310
+ const shapeCoordinateAnchor = styleProps?.labelCoordinateAnchor;
311
+ switch (geometry.type) {
312
+ case "Point": return getPointPosition(geometry, shapeOffset, shapeVertical, shapeHorizontal, options);
313
+ case "LineString": return getLineStringPosition(geometry, shapeOffset, shapeVertical, shapeHorizontal, shapeCoordinateAnchor, options);
314
+ case "Polygon": return getPolygonPosition(geometry, shape, shapeOffset, shapeVertical, shapeHorizontal, shapeCoordinateAnchor, options);
315
+ default: return null;
316
+ }
317
+ }
318
+ /**
319
+ * Get label text for a shape
320
+ *
321
+ * Returns the display label for the shape on the map in uppercase.
322
+ * - `label`: Optional short display name shown on the map (e.g., "NYC")
323
+ * - `name`: Full shape name used internally (e.g., "New York City Office")
324
+ *
325
+ * If `label` is not provided, falls back to using `name`.
326
+ * Text is automatically converted to uppercase for display.
327
+ */
328
+ function getLabelText(shape) {
329
+ return (shape.label || shape.name).toUpperCase();
330
+ }
331
+ /**
332
+ * Get label background color (uses RGB from shape fill color with fixed label opacity)
333
+ */
334
+ function getLabelFillColor(shape) {
335
+ const fillColor = (shape.feature.properties?.styleProperties)?.fillColor ?? [
336
+ 98,
337
+ 166,
338
+ 255,
339
+ 255
340
+ ];
341
+ return [
342
+ fillColor[0] ?? 98,
343
+ fillColor[1] ?? 166,
344
+ fillColor[2] ?? 255,
345
+ LABEL_BACKGROUND_OPACITY
346
+ ];
347
+ }
348
+ /**
349
+ * Get label border color (uses RGB from shape stroke color with full opacity)
350
+ */
351
+ function getLabelBorderColor(shape) {
352
+ const strokeColor = (shape.feature.properties?.styleProperties)?.strokeColor ?? [
353
+ 98,
354
+ 166,
355
+ 255,
356
+ 255
357
+ ];
358
+ return [
359
+ strokeColor[0] ?? 98,
360
+ strokeColor[1] ?? 166,
361
+ strokeColor[2] ?? 255,
362
+ LABEL_BORDER_OPACITY
363
+ ];
364
+ }
365
+
366
+ //#endregion
367
+ export { getLabelBorderColor, getLabelFillColor, getLabelPosition2d, getLabelText, getLineStringEndpoint, getLineStringMidpoint, getPolygonMidpoint, interpolatePoint };
368
+ //# sourceMappingURL=labels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"labels.js","names":["lengths: number[]","defaultOffset: [number, number]","defaultVertical: LabelVerticalPosition","defaultHorizontal: LabelHorizontalPosition","defaultCoordinateAnchor: CardinalLabelCoordinateAnchor"],"sources":["../../../../../src/deckgl/shapes/display-shape-layer/utils/labels.ts"],"sourcesContent":["/*\n * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n/**\n * Label positioning utilities for shapes\n *\n * This module provides utilities for positioning labels on shapes and calculating\n * points along line segments. Use these to customize label placement in your shape data.\n *\n * ## Label Styling\n *\n * Labels use a text-only style for legibility across different map backgrounds:\n * - **Text**: White uppercase with bold Roboto Mono font at 10px\n * - **Outline**: Black 2px outline around text for contrast\n * - **No background or border**: Clean text-only appearance\n *\n * ### Calculating Offsets\n *\n * When positioning labels, the text height is approximately 10px.\n * For example, to position a label exactly 5px above a point:\n * - Label height ≈ text height (10px)\n * - Offset needed: [0, -(10 + 5)] = [0, -15]\n *\n * @example Position label at the middle of a LineString\n * ```typescript\n * import { getLineStringMidpoint } from '@accelint/map-toolkit/deckgl/shapes/display-shape-layer/utils/labels';\n *\n * // Calculate midpoint for custom positioning\n * const coordinates = [[-122.4, 37.8], [-122.3, 37.9], [-122.2, 38.0]];\n * const midpoint = getLineStringMidpoint(coordinates);\n *\n * // Use in shape data with custom label properties\n * const shape = {\n * feature: {\n * properties: {\n * styleProperties: {\n * labelVerticalAnchor: 'top',\n * labelHorizontalAnchor: 'center',\n * labelOffset: [0, -10], // Small offset above the line\n * }\n * }\n * }\n * };\n * ```\n */\n\n'use client';\n\nimport {\n LABEL_BACKGROUND_OPACITY,\n LABEL_BORDER_OPACITY,\n} from '../../shared/constants';\nimport type { LineString, Point, Polygon } from 'geojson';\nimport type { EditableShape } from '../../shared/types';\n\n/**\n * Label positioning information including coordinates and screen-space offsets\n */\nexport interface LabelPosition2d {\n /** Geographic coordinates [longitude, latitude] */\n coordinates: [number, number];\n /** Horizontal text anchor point */\n textAnchor: 'start' | 'middle' | 'end';\n /** Vertical text alignment */\n alignmentBaseline: 'top' | 'center' | 'bottom';\n /** Pixel offset from coordinates [x, y] */\n pixelOffset: [number, number];\n}\n\n/**\n * Calculate a point along a line segment\n * @param start - Start coordinate [lon, lat]\n * @param end - End coordinate [lon, lat]\n * @param ratio - Position along segment (0 = start, 0.5 = middle, 1 = end)\n * @returns Interpolated coordinate [lon, lat]\n *\n * @example\n * // Get a point 25% along a line segment\n * const start: [number, number] = [-122.4, 37.8];\n * const end: [number, number] = [-122.3, 37.9];\n * const point = interpolatePoint(start, end, 0.25);\n */\nexport function interpolatePoint(\n start: [number, number],\n end: [number, number],\n ratio: number,\n): [number, number] {\n const clampedRatio = Math.max(0, Math.min(1, ratio));\n return [\n start[0] + (end[0] - start[0]) * clampedRatio,\n start[1] + (end[1] - start[1]) * clampedRatio,\n ];\n}\n\n/**\n * Calculate segment lengths for a line\n */\nfunction calculateSegmentLengths(coordinates: [number, number][]): {\n lengths: number[];\n total: number;\n} {\n let total = 0;\n const lengths: number[] = [];\n\n for (let i = 0; i < coordinates.length - 1; i++) {\n const start = coordinates[i];\n const end = coordinates[i + 1];\n if (start && end) {\n const length = Math.sqrt(\n (end[0] - start[0]) ** 2 + (end[1] - start[1]) ** 2,\n );\n lengths.push(length);\n total += length;\n }\n }\n\n return { lengths, total };\n}\n\n/**\n * Find point at specific distance along line\n */\nfunction findPointAtDistance(\n coordinates: [number, number][],\n segmentLengths: number[],\n targetDistance: number,\n): [number, number] {\n let accumulatedLength = 0;\n\n for (let i = 0; i < segmentLengths.length; i++) {\n const segmentLength = segmentLengths[i];\n if (!segmentLength) {\n continue;\n }\n\n if (accumulatedLength + segmentLength >= targetDistance) {\n const start = coordinates[i];\n const end = coordinates[i + 1];\n if (start && end) {\n const ratio = (targetDistance - accumulatedLength) / segmentLength;\n return interpolatePoint(start, end, ratio);\n }\n }\n accumulatedLength += segmentLength;\n }\n\n return coordinates[coordinates.length - 1] ?? [0, 0];\n}\n\n/**\n * Get the midpoint of a LineString\n * @param coordinates - LineString coordinates array\n * @returns Midpoint coordinate [lon, lat]\n */\nexport function getLineStringMidpoint(\n coordinates: [number, number][],\n): [number, number] {\n if (coordinates.length === 0) {\n return [0, 0];\n }\n if (coordinates.length === 1) {\n return coordinates[0] ?? [0, 0];\n }\n\n const { lengths, total } = calculateSegmentLengths(coordinates);\n const halfLength = total / 2;\n\n return findPointAtDistance(coordinates, lengths, halfLength);\n}\n\n/**\n * Get the end point of a LineString\n * @param coordinates - LineString coordinates array\n * @returns End coordinate [lon, lat]\n */\nexport function getLineStringEndpoint(\n coordinates: [number, number][],\n): [number, number] {\n if (coordinates.length === 0) {\n return [0, 0];\n }\n return coordinates[coordinates.length - 1] ?? [0, 0];\n}\n\n/**\n * Get the midpoint of a Polygon's outer ring\n * @param coordinates - Polygon coordinates array (rings)\n * @returns Midpoint of outer ring [lon, lat]\n */\nexport function getPolygonMidpoint(\n coordinates: [number, number][][],\n): [number, number] {\n const outerRing = coordinates[0];\n if (!outerRing || outerRing.length === 0) {\n return [0, 0];\n }\n // Use the outer ring (first ring)\n return getLineStringMidpoint(outerRing);\n}\n\n/**\n * Vertical label position relative to anchor point\n */\nexport type LabelVerticalPosition = 'top' | 'middle' | 'bottom';\n\n/**\n * Horizontal label position relative to anchor point\n */\nexport type LabelHorizontalPosition = 'left' | 'center' | 'right';\n\n/**\n * Cardinal direction anchor for positioning labels on geometry edges\n * Uses edge positions relative to the geometry's bounding box\n * Works for LineString, Polygon, and Circle geometries\n * - 'center': centroid/midpoint of the geometry\n * - 'top'/'right'/'bottom'/'left': edge positions\n */\nexport type CardinalLabelCoordinateAnchor =\n | 'center'\n | 'top'\n | 'right'\n | 'bottom'\n | 'left';\n\n/**\n * Global label positioning options for DisplayShapeLayer\n *\n * ## Priority System\n * Label positioning follows a three-tier priority system:\n * 1. **Per-shape properties** in `styleProperties` (highest priority)\n * 2. **Global options** via this interface\n * 3. **Default values** (geometry-specific fallbacks)\n *\n * ## Label Appearance\n *\n * Labels use a clean text-only style:\n * - **Text**: White uppercase, bold Roboto Mono, 10px\n * - **Outline**: Black 2px outline for contrast\n * - **No background or border**\n *\n * Text height ≈ 10px\n *\n * ## Positioning Concepts\n *\n * ### Coordinate Anchor\n * Determines *where* on the geometry to place the label:\n * - **Point**: Label is always at the point coordinate\n * - **LineString/Polygon**: 'start', 'middle', or 'end' along the geometry\n * - **Circle**: 'top', 'right', 'bottom', or 'left' on the perimeter\n *\n * ### Vertical/Horizontal Anchor\n * Determines how the label aligns *relative to* the anchor point:\n * - **Vertical**: 'top' (label text below point), 'middle' (centered), 'bottom' (label text above point)\n * - **Horizontal**: 'left' (label text right of point), 'center' (centered), 'right' (label text left of point)\n *\n * ### Pixel Offset\n * Fine-tune label position with [x, y] pixel offsets:\n * - Positive x moves right, negative moves left\n * - Positive y moves down, negative moves up\n *\n * @example Position circle labels at the top with 5px clearance\n * ```tsx\n * const labelOptions: LabelPositionOptions = {\n * circleLabelCoordinateAnchor: 'top',\n * circleLabelVerticalAnchor: 'bottom', // Label above the top point\n * circleLabelOffset: [0, -15], // -(10px text height + 5px clearance)\n * };\n * ```\n *\n * @example Position line labels at middle with offset to the right\n * ```tsx\n * const labelOptions: LabelPositionOptions = {\n * lineStringLabelCoordinateAnchor: 'middle',\n * lineStringLabelHorizontalAnchor: 'left',\n * lineStringLabelOffset: [10, 0], // 10px to the right\n * };\n * ```\n */\nexport interface LabelPositionOptions {\n // Point geometry options\n /** Vertical anchor for Point labels @default 'top' */\n pointLabelVerticalAnchor?: LabelVerticalPosition;\n /** Horizontal anchor for Point labels @default 'center' */\n pointLabelHorizontalAnchor?: LabelHorizontalPosition;\n /** Pixel offset for Point labels [x, y] @default [0, 10] */\n pointLabelOffset?: [number, number];\n\n // LineString geometry options\n /** Position on LineString edge (top/right/bottom/left) @default 'bottom' */\n lineStringLabelCoordinateAnchor?: CardinalLabelCoordinateAnchor;\n /** Vertical anchor for LineString labels @default 'top' */\n lineStringLabelVerticalAnchor?: LabelVerticalPosition;\n /** Horizontal anchor for LineString labels @default 'center' */\n lineStringLabelHorizontalAnchor?: LabelHorizontalPosition;\n /** Pixel offset for LineString labels [x, y] @default [0, 10] */\n lineStringLabelOffset?: [number, number];\n\n // Polygon geometry options\n /** Position on Polygon edge (top/right/bottom/left) @default 'bottom' */\n polygonLabelCoordinateAnchor?: CardinalLabelCoordinateAnchor;\n /** Vertical anchor for Polygon labels @default 'top' */\n polygonLabelVerticalAnchor?: LabelVerticalPosition;\n /** Horizontal anchor for Polygon labels @default 'center' */\n polygonLabelHorizontalAnchor?: LabelHorizontalPosition;\n /** Pixel offset for Polygon labels [x, y] @default [0, 10] */\n polygonLabelOffset?: [number, number];\n\n // Circle geometry options\n /** Position on Circle perimeter (top/right/bottom/left) @default 'bottom' */\n circleLabelCoordinateAnchor?: CardinalLabelCoordinateAnchor;\n /** Vertical anchor for Circle labels @default 'top' */\n circleLabelVerticalAnchor?: LabelVerticalPosition;\n /** Horizontal anchor for Circle labels @default 'center' */\n circleLabelHorizontalAnchor?: LabelHorizontalPosition;\n /** Pixel offset for Circle labels [x, y] @default [0, 10] */\n circleLabelOffset?: [number, number];\n}\n\n/**\n * Convert vertical/horizontal position to deck.gl textAnchor and alignmentBaseline\n */\nfunction convertPositionToAnchors(\n vertical: LabelVerticalPosition,\n horizontal: LabelHorizontalPosition,\n): {\n textAnchor: 'start' | 'middle' | 'end';\n alignmentBaseline: 'top' | 'center' | 'bottom';\n} {\n // Map horizontal to textAnchor\n const textAnchorMap: Record<\n LabelHorizontalPosition,\n 'start' | 'middle' | 'end'\n > = {\n left: 'start',\n center: 'middle',\n right: 'end',\n };\n\n // Map vertical to alignmentBaseline\n const alignmentBaselineMap: Record<\n LabelVerticalPosition,\n 'top' | 'center' | 'bottom'\n > = {\n top: 'top',\n middle: 'center',\n bottom: 'bottom',\n };\n\n return {\n textAnchor: textAnchorMap[horizontal],\n alignmentBaseline: alignmentBaselineMap[vertical],\n };\n}\n\n/**\n * Helper to resolve label properties with priority: shape > options > default\n */\nfunction resolveLabelProperties(\n shapeOffset: [number, number] | undefined,\n shapeVertical: string | undefined,\n shapeHorizontal: string | undefined,\n defaultOffset: [number, number],\n defaultVertical: LabelVerticalPosition,\n defaultHorizontal: LabelHorizontalPosition,\n optionsOffset?: [number, number],\n optionsVertical?: LabelVerticalPosition,\n optionsHorizontal?: LabelHorizontalPosition,\n) {\n const vertical = (shapeVertical ??\n optionsVertical ??\n defaultVertical) as LabelVerticalPosition;\n const horizontal = (shapeHorizontal ??\n optionsHorizontal ??\n defaultHorizontal) as LabelHorizontalPosition;\n const pixelOffset = shapeOffset ?? optionsOffset ?? defaultOffset;\n\n const anchors = convertPositionToAnchors(vertical, horizontal);\n\n return {\n pixelOffset,\n ...anchors,\n };\n}\n\n/**\n * Get position for Point geometry\n */\nfunction getPointPosition(\n geometry: Point,\n shapeOffset: [number, number] | undefined,\n shapeVertical: string | undefined,\n shapeHorizontal: string | undefined,\n options?: LabelPositionOptions,\n): LabelPosition2d {\n const defaultOffset: [number, number] = [0, 10];\n const defaultVertical: LabelVerticalPosition = 'top';\n const defaultHorizontal: LabelHorizontalPosition = 'center';\n\n const resolved = resolveLabelProperties(\n shapeOffset,\n shapeVertical,\n shapeHorizontal,\n defaultOffset,\n defaultVertical,\n defaultHorizontal,\n options?.pointLabelOffset,\n options?.pointLabelVerticalAnchor,\n options?.pointLabelHorizontalAnchor,\n );\n\n return {\n coordinates: [\n geometry.coordinates[0] ?? 0,\n geometry.coordinates[1] ?? 0,\n ] as [number, number],\n ...resolved,\n };\n}\n\n/**\n * Get position for LineString geometry\n * Uses cardinal direction positioning to find the edge point\n */\nfunction getLineStringPosition(\n geometry: LineString,\n shapeOffset: [number, number] | undefined,\n shapeVertical: string | undefined,\n shapeHorizontal: string | undefined,\n shapeCoordinateAnchor: string | undefined,\n options?: LabelPositionOptions,\n): LabelPosition2d | null {\n const defaultOffset: [number, number] = [0, 10];\n const defaultVertical: LabelVerticalPosition = 'top';\n const defaultHorizontal: LabelHorizontalPosition = 'center';\n const defaultCoordinateAnchor: CardinalLabelCoordinateAnchor = 'bottom';\n\n const resolved = resolveLabelProperties(\n shapeOffset,\n shapeVertical,\n shapeHorizontal,\n defaultOffset,\n defaultVertical,\n defaultHorizontal,\n options?.lineStringLabelOffset,\n options?.lineStringLabelVerticalAnchor,\n options?.lineStringLabelHorizontalAnchor,\n );\n\n // Determine coordinate anchor (priority: shape > options > default)\n const coordinateAnchor = (shapeCoordinateAnchor ??\n options?.lineStringLabelCoordinateAnchor ??\n defaultCoordinateAnchor) as CardinalLabelCoordinateAnchor;\n\n // Calculate position based on cardinal direction\n const coordinates = findEdgePoint(\n geometry.coordinates as number[][],\n coordinateAnchor,\n );\n\n if (!coordinates) {\n return null;\n }\n\n return {\n coordinates,\n ...resolved,\n };\n}\n\n/**\n * Get vertex coordinate from ring\n */\nfunction getVertexCoordinate(\n vertex: number[] | undefined,\n): [number, number] | null {\n if (!vertex || vertex[0] === undefined || vertex[1] === undefined) {\n return null;\n }\n return [vertex[0], vertex[1]];\n}\n\n/**\n * Check if a vertex should replace the current target based on edge position\n */\nfunction shouldUpdateEdgeVertex(\n vertexValue: number,\n targetValue: number,\n position: CardinalLabelCoordinateAnchor,\n): boolean {\n // For top and right, find maximum value\n // For bottom and left, find minimum value\n return position === 'top' || position === 'right'\n ? vertexValue > targetValue\n : vertexValue < targetValue;\n}\n\n/**\n * Get the coordinate index based on edge position (0 for x/longitude, 1 for y/latitude)\n */\nfunction getCoordinateIndexForEdgePosition(\n position: CardinalLabelCoordinateAnchor,\n): number {\n return position === 'top' || position === 'bottom' ? 1 : 0;\n}\n\n/**\n * Calculate the centroid (center point) of a set of coordinates\n * For polygons, this calculates the geometric center\n * For lines, this calculates the midpoint of the bounding box\n * Returns null if no valid coordinates exist\n */\nfunction calculateCentroid(coordinates: number[][]): [number, number] | null {\n if (coordinates.length === 0) {\n return null;\n }\n\n let sumX = 0;\n let sumY = 0;\n let count = 0;\n\n for (const coord of coordinates) {\n if (coord && coord[0] !== undefined && coord[1] !== undefined) {\n sumX += coord[0];\n sumY += coord[1];\n count++;\n }\n }\n\n if (count === 0) {\n return null;\n }\n\n return [sumX / count, sumY / count];\n}\n\n/**\n * Find the point on a geometry's perimeter at the specified edge position\n * @param coordinates - Array of coordinates (ring or line)\n * @param position - Edge position (center/top/right/bottom/left) relative to bounding box\n * @returns Coordinate at the specified edge position, or null if no valid coordinates\n */\nfunction findEdgePoint(\n coordinates: number[][] | undefined,\n position: CardinalLabelCoordinateAnchor,\n): [number, number] | null {\n if (!coordinates || coordinates.length === 0) {\n return null;\n }\n\n // Handle center positioning\n if (position === 'center') {\n return calculateCentroid(coordinates);\n }\n\n // Find the vertex with max/min latitude or longitude\n let targetVertex = coordinates[0];\n const coordinateIndex = getCoordinateIndexForEdgePosition(position);\n\n for (const vertex of coordinates) {\n if (!vertex) {\n continue;\n }\n if (!targetVertex) {\n continue;\n }\n\n const vertexValue = vertex[coordinateIndex];\n const targetValue = targetVertex[coordinateIndex];\n\n if (vertexValue === undefined || targetValue === undefined) {\n continue;\n }\n\n if (shouldUpdateEdgeVertex(vertexValue, targetValue, position)) {\n targetVertex = vertex;\n }\n }\n\n return getVertexCoordinate(targetVertex);\n}\n\n/**\n * Get position for Circle geometry (special case of Polygon)\n */\nfunction getCirclePosition(\n ring: number[][] | undefined,\n shapeOffset: [number, number] | undefined,\n shapeVertical: string | undefined,\n shapeHorizontal: string | undefined,\n shapeCoordinateAnchor: string | undefined,\n options?: LabelPositionOptions,\n): LabelPosition2d | null {\n const defaultOffset: [number, number] = [0, 10];\n const defaultVertical: LabelVerticalPosition = 'top';\n const defaultHorizontal: LabelHorizontalPosition = 'center';\n const defaultCoordinateAnchor: CardinalLabelCoordinateAnchor = 'bottom';\n\n const resolved = resolveLabelProperties(\n shapeOffset,\n shapeVertical,\n shapeHorizontal,\n defaultOffset,\n defaultVertical,\n defaultHorizontal,\n options?.circleLabelOffset,\n options?.circleLabelVerticalAnchor,\n options?.circleLabelHorizontalAnchor,\n );\n\n // Determine coordinate anchor (priority: shape > options > default)\n const coordinateAnchor = (shapeCoordinateAnchor ??\n options?.circleLabelCoordinateAnchor ??\n defaultCoordinateAnchor) as CardinalLabelCoordinateAnchor;\n\n // Calculate position based on coordinate anchor\n const coordinates = findEdgePoint(ring, coordinateAnchor);\n\n if (!coordinates) {\n return null;\n }\n\n return {\n coordinates,\n ...resolved,\n };\n}\n\n/**\n * Get position for Polygon geometry\n * Uses cardinal direction positioning to find the edge point\n */\nfunction getPolygonPosition(\n geometry: Polygon,\n shape: EditableShape,\n shapeOffset: [number, number] | undefined,\n shapeVertical: string | undefined,\n shapeHorizontal: string | undefined,\n shapeCoordinateAnchor: string | undefined,\n options?: LabelPositionOptions,\n): LabelPosition2d | null {\n const ring = geometry.coordinates[0];\n\n // Circle shapes use circle-specific options\n if (shape.shapeType === 'Circle') {\n return getCirclePosition(\n ring,\n shapeOffset,\n shapeVertical,\n shapeHorizontal,\n shapeCoordinateAnchor,\n options,\n );\n }\n\n // Regular polygons use cardinal direction positioning\n const defaultOffset: [number, number] = [0, 10];\n const defaultVertical: LabelVerticalPosition = 'top';\n const defaultHorizontal: LabelHorizontalPosition = 'center';\n const defaultCoordinateAnchor: CardinalLabelCoordinateAnchor = 'bottom';\n\n const resolved = resolveLabelProperties(\n shapeOffset,\n shapeVertical,\n shapeHorizontal,\n defaultOffset,\n defaultVertical,\n defaultHorizontal,\n options?.polygonLabelOffset,\n options?.polygonLabelVerticalAnchor,\n options?.polygonLabelHorizontalAnchor,\n );\n\n // Determine coordinate anchor (priority: shape > options > default)\n const coordinateAnchor = (shapeCoordinateAnchor ??\n options?.polygonLabelCoordinateAnchor ??\n defaultCoordinateAnchor) as CardinalLabelCoordinateAnchor;\n\n // Calculate position based on cardinal direction\n const coordinates = findEdgePoint(ring, coordinateAnchor);\n\n if (!coordinates) {\n return null;\n }\n\n return {\n coordinates,\n ...resolved,\n };\n}\n\n/**\n * Get 2D position for label based on geometry type\n * Uses pixel-based offsets for consistent positioning at all zoom levels\n *\n * Priority for positioning:\n * 1. Per-shape properties in styleProperties (highest)\n * 2. Global labelOptions from layer props\n * 3. Default values (fallback)\n *\n * Returns null if no valid coordinates can be determined\n */\nexport function getLabelPosition2d(\n shape: EditableShape,\n options?: LabelPositionOptions,\n): LabelPosition2d | null {\n const { geometry } = shape.feature;\n const styleProps = shape.feature.properties?.styleProperties;\n\n // Check if shape has custom label properties\n const shapeOffset = styleProps?.labelOffset as [number, number] | undefined;\n const shapeVertical = styleProps?.labelVerticalAnchor;\n const shapeHorizontal = styleProps?.labelHorizontalAnchor;\n const shapeCoordinateAnchor = styleProps?.labelCoordinateAnchor;\n\n switch (geometry.type) {\n case 'Point':\n return getPointPosition(\n geometry,\n shapeOffset,\n shapeVertical,\n shapeHorizontal,\n options,\n );\n\n case 'LineString':\n return getLineStringPosition(\n geometry,\n shapeOffset,\n shapeVertical,\n shapeHorizontal,\n shapeCoordinateAnchor,\n options,\n );\n\n case 'Polygon':\n return getPolygonPosition(\n geometry,\n shape,\n shapeOffset,\n shapeVertical,\n shapeHorizontal,\n shapeCoordinateAnchor,\n options,\n );\n\n default:\n // Unknown geometry type - return null\n return null;\n }\n}\n\n/**\n * Get label text for a shape\n *\n * Returns the display label for the shape on the map in uppercase.\n * - `label`: Optional short display name shown on the map (e.g., \"NYC\")\n * - `name`: Full shape name used internally (e.g., \"New York City Office\")\n *\n * If `label` is not provided, falls back to using `name`.\n * Text is automatically converted to uppercase for display.\n */\nexport function getLabelText(shape: EditableShape): string {\n return (shape.label || shape.name).toUpperCase();\n}\n\n/**\n * Get label background color (uses RGB from shape fill color with fixed label opacity)\n */\nexport function getLabelFillColor(\n shape: EditableShape,\n): [number, number, number, number] {\n const styleProps = shape.feature.properties?.styleProperties;\n const fillColor = styleProps?.fillColor ?? [98, 166, 255, 255];\n\n // Extract RGB, use fixed opacity for label background\n const r = fillColor[0] ?? 98;\n const g = fillColor[1] ?? 166;\n const b = fillColor[2] ?? 255;\n\n return [r, g, b, LABEL_BACKGROUND_OPACITY];\n}\n\n/**\n * Get label border color (uses RGB from shape stroke color with full opacity)\n */\nexport function getLabelBorderColor(\n shape: EditableShape,\n): [number, number, number, number] {\n const styleProps = shape.feature.properties?.styleProperties;\n const strokeColor = styleProps?.strokeColor ?? [98, 166, 255, 255];\n\n // Extract RGB, use full opacity for border\n const r = strokeColor[0] ?? 98;\n const g = strokeColor[1] ?? 166;\n const b = strokeColor[2] ?? 255;\n\n return [r, g, b, LABEL_BORDER_OPACITY];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2FA,SAAgB,iBACd,OACA,KACA,OACkB;CAClB,MAAM,eAAe,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,MAAM,CAAC;AACpD,QAAO,CACL,MAAM,MAAM,IAAI,KAAK,MAAM,MAAM,cACjC,MAAM,MAAM,IAAI,KAAK,MAAM,MAAM,aAClC;;;;;AAMH,SAAS,wBAAwB,aAG/B;CACA,IAAI,QAAQ;CACZ,MAAMA,UAAoB,EAAE;AAE5B,MAAK,IAAI,IAAI,GAAG,IAAI,YAAY,SAAS,GAAG,KAAK;EAC/C,MAAM,QAAQ,YAAY;EAC1B,MAAM,MAAM,YAAY,IAAI;AAC5B,MAAI,SAAS,KAAK;GAChB,MAAM,SAAS,KAAK,MACjB,IAAI,KAAK,MAAM,OAAO,KAAK,IAAI,KAAK,MAAM,OAAO,EACnD;AACD,WAAQ,KAAK,OAAO;AACpB,YAAS;;;AAIb,QAAO;EAAE;EAAS;EAAO;;;;;AAM3B,SAAS,oBACP,aACA,gBACA,gBACkB;CAClB,IAAI,oBAAoB;AAExB,MAAK,IAAI,IAAI,GAAG,IAAI,eAAe,QAAQ,KAAK;EAC9C,MAAM,gBAAgB,eAAe;AACrC,MAAI,CAAC,cACH;AAGF,MAAI,oBAAoB,iBAAiB,gBAAgB;GACvD,MAAM,QAAQ,YAAY;GAC1B,MAAM,MAAM,YAAY,IAAI;AAC5B,OAAI,SAAS,IAEX,QAAO,iBAAiB,OAAO,MADhB,iBAAiB,qBAAqB,cACX;;AAG9C,uBAAqB;;AAGvB,QAAO,YAAY,YAAY,SAAS,MAAM,CAAC,GAAG,EAAE;;;;;;;AAQtD,SAAgB,sBACd,aACkB;AAClB,KAAI,YAAY,WAAW,EACzB,QAAO,CAAC,GAAG,EAAE;AAEf,KAAI,YAAY,WAAW,EACzB,QAAO,YAAY,MAAM,CAAC,GAAG,EAAE;CAGjC,MAAM,EAAE,SAAS,UAAU,wBAAwB,YAAY;AAG/D,QAAO,oBAAoB,aAAa,SAFrB,QAAQ,EAEiC;;;;;;;AAQ9D,SAAgB,sBACd,aACkB;AAClB,KAAI,YAAY,WAAW,EACzB,QAAO,CAAC,GAAG,EAAE;AAEf,QAAO,YAAY,YAAY,SAAS,MAAM,CAAC,GAAG,EAAE;;;;;;;AAQtD,SAAgB,mBACd,aACkB;CAClB,MAAM,YAAY,YAAY;AAC9B,KAAI,CAAC,aAAa,UAAU,WAAW,EACrC,QAAO,CAAC,GAAG,EAAE;AAGf,QAAO,sBAAsB,UAAU;;;;;AA4HzC,SAAS,yBACP,UACA,YAIA;AAqBA,QAAO;EACL,YAjBE;GACF,MAAM;GACN,QAAQ;GACR,OAAO;GACR,CAa2B;EAC1B,mBARE;GACF,KAAK;GACL,QAAQ;GACR,QAAQ;GACT,CAIyC;EACzC;;;;;AAMH,SAAS,uBACP,aACA,eACA,iBACA,eACA,iBACA,mBACA,eACA,iBACA,mBACA;AAWA,QAAO;EACL,aALkB,eAAe,iBAAiB;EAMlD,GAJc,yBARE,iBAChB,mBACA,iBACkB,mBAClB,qBACA,kBAG4D;EAK7D;;;;;AAMH,SAAS,iBACP,UACA,aACA,eACA,iBACA,SACiB;CAKjB,MAAM,WAAW,uBACf,aACA,eACA,iBAPsC,CAAC,GAAG,GAAG,EACA,OACI,UASjD,SAAS,kBACT,SAAS,0BACT,SAAS,2BACV;AAED,QAAO;EACL,aAAa,CACX,SAAS,YAAY,MAAM,GAC3B,SAAS,YAAY,MAAM,EAC5B;EACD,GAAG;EACJ;;;;;;AAOH,SAAS,sBACP,UACA,aACA,eACA,iBACA,uBACA,SACwB;CACxB,MAAMC,gBAAkC,CAAC,GAAG,GAAG;CAC/C,MAAMC,kBAAyC;CAC/C,MAAMC,oBAA6C;CACnD,MAAMC,0BAAyD;CAE/D,MAAM,WAAW,uBACf,aACA,eACA,iBACA,eACA,iBACA,mBACA,SAAS,uBACT,SAAS,+BACT,SAAS,gCACV;CAGD,MAAM,mBAAoB,yBACxB,SAAS,mCACT;CAGF,MAAM,cAAc,cAClB,SAAS,aACT,iBACD;AAED,KAAI,CAAC,YACH,QAAO;AAGT,QAAO;EACL;EACA,GAAG;EACJ;;;;;AAMH,SAAS,oBACP,QACyB;AACzB,KAAI,CAAC,UAAU,OAAO,OAAO,UAAa,OAAO,OAAO,OACtD,QAAO;AAET,QAAO,CAAC,OAAO,IAAI,OAAO,GAAG;;;;;AAM/B,SAAS,uBACP,aACA,aACA,UACS;AAGT,QAAO,aAAa,SAAS,aAAa,UACtC,cAAc,cACd,cAAc;;;;;AAMpB,SAAS,kCACP,UACQ;AACR,QAAO,aAAa,SAAS,aAAa,WAAW,IAAI;;;;;;;;AAS3D,SAAS,kBAAkB,aAAkD;AAC3E,KAAI,YAAY,WAAW,EACzB,QAAO;CAGT,IAAI,OAAO;CACX,IAAI,OAAO;CACX,IAAI,QAAQ;AAEZ,MAAK,MAAM,SAAS,YAClB,KAAI,SAAS,MAAM,OAAO,UAAa,MAAM,OAAO,QAAW;AAC7D,UAAQ,MAAM;AACd,UAAQ,MAAM;AACd;;AAIJ,KAAI,UAAU,EACZ,QAAO;AAGT,QAAO,CAAC,OAAO,OAAO,OAAO,MAAM;;;;;;;;AASrC,SAAS,cACP,aACA,UACyB;AACzB,KAAI,CAAC,eAAe,YAAY,WAAW,EACzC,QAAO;AAIT,KAAI,aAAa,SACf,QAAO,kBAAkB,YAAY;CAIvC,IAAI,eAAe,YAAY;CAC/B,MAAM,kBAAkB,kCAAkC,SAAS;AAEnE,MAAK,MAAM,UAAU,aAAa;AAChC,MAAI,CAAC,OACH;AAEF,MAAI,CAAC,aACH;EAGF,MAAM,cAAc,OAAO;EAC3B,MAAM,cAAc,aAAa;AAEjC,MAAI,gBAAgB,UAAa,gBAAgB,OAC/C;AAGF,MAAI,uBAAuB,aAAa,aAAa,SAAS,CAC5D,gBAAe;;AAInB,QAAO,oBAAoB,aAAa;;;;;AAM1C,SAAS,kBACP,MACA,aACA,eACA,iBACA,uBACA,SACwB;CACxB,MAAMH,gBAAkC,CAAC,GAAG,GAAG;CAC/C,MAAMC,kBAAyC;CAC/C,MAAMC,oBAA6C;CACnD,MAAMC,0BAAyD;CAE/D,MAAM,WAAW,uBACf,aACA,eACA,iBACA,eACA,iBACA,mBACA,SAAS,mBACT,SAAS,2BACT,SAAS,4BACV;CAQD,MAAM,cAAc,cAAc,MALR,yBACxB,SAAS,+BACT,wBAGuD;AAEzD,KAAI,CAAC,YACH,QAAO;AAGT,QAAO;EACL;EACA,GAAG;EACJ;;;;;;AAOH,SAAS,mBACP,UACA,OACA,aACA,eACA,iBACA,uBACA,SACwB;CACxB,MAAM,OAAO,SAAS,YAAY;AAGlC,KAAI,MAAM,cAAc,SACtB,QAAO,kBACL,MACA,aACA,eACA,iBACA,uBACA,QACD;CAIH,MAAMH,gBAAkC,CAAC,GAAG,GAAG;CAC/C,MAAMC,kBAAyC;CAC/C,MAAMC,oBAA6C;CACnD,MAAMC,0BAAyD;CAE/D,MAAM,WAAW,uBACf,aACA,eACA,iBACA,eACA,iBACA,mBACA,SAAS,oBACT,SAAS,4BACT,SAAS,6BACV;CAQD,MAAM,cAAc,cAAc,MALR,yBACxB,SAAS,gCACT,wBAGuD;AAEzD,KAAI,CAAC,YACH,QAAO;AAGT,QAAO;EACL;EACA,GAAG;EACJ;;;;;;;;;;;;;AAcH,SAAgB,mBACd,OACA,SACwB;CACxB,MAAM,EAAE,aAAa,MAAM;CAC3B,MAAM,aAAa,MAAM,QAAQ,YAAY;CAG7C,MAAM,cAAc,YAAY;CAChC,MAAM,gBAAgB,YAAY;CAClC,MAAM,kBAAkB,YAAY;CACpC,MAAM,wBAAwB,YAAY;AAE1C,SAAQ,SAAS,MAAjB;EACE,KAAK,QACH,QAAO,iBACL,UACA,aACA,eACA,iBACA,QACD;EAEH,KAAK,aACH,QAAO,sBACL,UACA,aACA,eACA,iBACA,uBACA,QACD;EAEH,KAAK,UACH,QAAO,mBACL,UACA,OACA,aACA,eACA,iBACA,uBACA,QACD;EAEH,QAEE,QAAO;;;;;;;;;;;;;AAcb,SAAgB,aAAa,OAA8B;AACzD,SAAQ,MAAM,SAAS,MAAM,MAAM,aAAa;;;;;AAMlD,SAAgB,kBACd,OACkC;CAElC,MAAM,aADa,MAAM,QAAQ,YAAY,kBACf,aAAa;EAAC;EAAI;EAAK;EAAK;EAAI;AAO9D,QAAO;EAJG,UAAU,MAAM;EAChB,UAAU,MAAM;EAChB,UAAU,MAAM;EAET;EAAyB;;;;;AAM5C,SAAgB,oBACd,OACkC;CAElC,MAAM,eADa,MAAM,QAAQ,YAAY,kBACb,eAAe;EAAC;EAAI;EAAK;EAAK;EAAI;AAOlE,QAAO;EAJG,YAAY,MAAM;EAClB,YAAY,MAAM;EAClB,YAAY,MAAM;EAEX;EAAqB"}
@@ -0,0 +1,20 @@
1
+ /*
2
+ * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at https://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import { CircleProperties, CircleRadius, DisplayShape, EditableShape, ShapeFeature, ShapeFeatureProperties, ShapeFeatureType, ShapeFeatureTypeValues, ShapeId, StyleProperties } from "./shared/types.js";
14
+ import { CardinalLabelCoordinateAnchor, LabelHorizontalPosition, LabelPosition2d, LabelPositionOptions, LabelVerticalPosition } from "./display-shape-layer/utils/labels.js";
15
+ import { DisplayShapeLayerProps, StyledFeature, StyledFeatureProperties } from "./display-shape-layer/types.js";
16
+ import { DisplayShapeLayer } from "./display-shape-layer/index.js";
17
+ import { UseShapeSelectionReturn, useShapeSelection } from "./display-shape-layer/use-shape-selection.js";
18
+ import { BASE_FILL_OPACITY, DASH_ARRAYS, DEFAULT_COLORS, DEFAULT_STYLE_PROPERTIES, SHAPE_LAYER_IDS, STROKE_PATTERNS, STROKE_WIDTHS } from "./shared/constants.js";
19
+ import { SHAPE_EVENTS, ShapeEventHandler, ShapeEventPayload, ShapeEventType, ShapeEvents } from "./shared/events.js";
20
+ export { BASE_FILL_OPACITY, type CardinalLabelCoordinateAnchor, type CircleProperties, type CircleRadius, DASH_ARRAYS, DEFAULT_COLORS, DEFAULT_STYLE_PROPERTIES, type DisplayShape, DisplayShapeLayer, type DisplayShapeLayerProps, type EditableShape, type LabelHorizontalPosition, type LabelPosition2d, type LabelPositionOptions, type LabelVerticalPosition, SHAPE_EVENTS, SHAPE_LAYER_IDS, STROKE_PATTERNS, STROKE_WIDTHS, type ShapeEventHandler, type ShapeEventPayload, type ShapeEventType, ShapeEvents, type ShapeFeature, type ShapeFeatureProperties, ShapeFeatureType, type ShapeFeatureTypeValues, type ShapeId, type StyleProperties, type StyledFeature, type StyledFeatureProperties, type UseShapeSelectionReturn, useShapeSelection };