uomtiles 0.1.1 → 0.1.3

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 (351) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/7KYNy7kZ.js +1 -0
  3. package/.output/public/_nuxt/7Rgc2iDI2.js +1 -0
  4. package/.output/public/_nuxt/BA52uD81.js +1 -0
  5. package/.output/public/_nuxt/{B2648adu2.js → BHSn2vP72.js} +2 -2
  6. package/.output/public/_nuxt/BRsHq3Fz2.js +1 -0
  7. package/.output/public/_nuxt/Bh2Uv1S7.js +1 -0
  8. package/.output/public/_nuxt/BiRI-vq-.js +1 -0
  9. package/.output/public/_nuxt/Bpc1HTfh.js +1 -0
  10. package/.output/public/_nuxt/C-b4mqsD.js +1 -0
  11. package/.output/public/_nuxt/C5Y76DD6.js +1 -0
  12. package/.output/public/_nuxt/CD84FXNW.js +1 -0
  13. package/.output/public/_nuxt/CGkIG2vL2.js +1 -0
  14. package/.output/public/_nuxt/CM9IbYJz.js +1 -0
  15. package/.output/public/_nuxt/CUJ4QmLF.js +1 -0
  16. package/.output/public/_nuxt/CUQ3MZqI.js +1 -0
  17. package/.output/public/_nuxt/CVwoxklV.js +1 -0
  18. package/.output/public/_nuxt/CeHZqNQ0.js +1 -0
  19. package/.output/public/_nuxt/CgcnoKpi.js +1 -0
  20. package/.output/public/_nuxt/CkfS_Wbu.js +3 -0
  21. package/.output/public/_nuxt/CoPjdBwX.js +1 -0
  22. package/.output/public/_nuxt/CxkDmpVY.js +1 -0
  23. package/.output/public/_nuxt/CzRdWh7s2.js +1 -0
  24. package/.output/public/_nuxt/D-IOtyQX.js +1 -0
  25. package/.output/public/_nuxt/D3Us7gX72.js +1 -0
  26. package/.output/public/_nuxt/{54er8ZVX.js → D8GHPYwQ.js} +44 -44
  27. package/.output/public/_nuxt/DLIy3f3M.js +1 -0
  28. package/.output/public/_nuxt/{dj2oMyB1.js → DQ8r1OSk.js} +1 -1
  29. package/.output/public/_nuxt/D_9SjQFe.js +1 -0
  30. package/.output/public/_nuxt/D_Ggu6R_2.js +1 -0
  31. package/.output/public/_nuxt/{DC3bhq63.js → DnVJUY7B.js} +1 -1
  32. package/.output/public/_nuxt/{BiWblTbb.js → DuGgjt-h2.js} +1 -1
  33. package/.output/public/_nuxt/GEOST6As.js +1 -0
  34. package/.output/public/_nuxt/GqgcWtrL.js +1 -0
  35. package/.output/public/_nuxt/{BQlj8Xoe.js → Hbp_Okvs.js} +1 -1
  36. package/.output/public/_nuxt/JdUwgqKv.js +1 -0
  37. package/.output/public/_nuxt/KttxEAyP2.js +1 -0
  38. package/.output/public/_nuxt/L0GXeO1Y2.js +1 -0
  39. package/.output/public/_nuxt/builds/latest.json +1 -1
  40. package/.output/public/_nuxt/builds/meta/ad8f3148-5aa4-4a0f-8e7a-e55147c5de1a.json +1 -0
  41. package/.output/public/_nuxt/entry.U-KS0GEu.css +1 -0
  42. package/.output/public/_nuxt/sMWyPZfC2.js +1 -0
  43. package/.output/public/_nuxt/zUWhKXtw2.js +1 -0
  44. package/.output/server/chunks/_/antigravity-nfz.mjs +629 -0
  45. package/.output/server/chunks/_/antigravity-nfz.mjs.map +1 -0
  46. package/.output/server/chunks/_/config.mjs +53 -6
  47. package/.output/server/chunks/_/config.mjs.map +1 -1
  48. package/.output/server/chunks/_/export.mjs +7 -0
  49. package/.output/server/chunks/_/export.mjs.map +1 -0
  50. package/.output/server/chunks/_/file-workspace.mjs +131 -36
  51. package/.output/server/chunks/_/file-workspace.mjs.map +1 -1
  52. package/.output/server/chunks/_/map-layer-update-manager.mjs +770 -0
  53. package/.output/server/chunks/_/map-layer-update-manager.mjs.map +1 -0
  54. package/.output/server/chunks/_/map-service.mjs +1 -1
  55. package/.output/server/chunks/_/pixel-diff.mjs +1 -1
  56. package/.output/server/chunks/_/uom-auth.mjs +1 -1
  57. package/.output/server/chunks/build/{Alert-CBMepLwP.mjs → CompletedTaskSelect-Ba03kTs9.mjs} +30 -725
  58. package/.output/server/chunks/build/CompletedTaskSelect-Ba03kTs9.mjs.map +1 -0
  59. package/.output/server/chunks/build/{Empty-CkW3mADt.mjs → Empty-CKvANuoV.mjs} +4 -103
  60. package/.output/server/chunks/build/Empty-CKvANuoV.mjs.map +1 -0
  61. package/.output/server/chunks/build/{FormField-CEUZHcv7.mjs → FormField-BJHVyy1m.mjs} +4 -35
  62. package/.output/server/chunks/build/FormField-BJHVyy1m.mjs.map +1 -0
  63. package/.output/server/chunks/build/{Input-BeNavYXb.mjs → Input-DnAric-z.mjs} +1 -1
  64. package/.output/server/chunks/build/{Input-BeNavYXb.mjs.map → Input-DnAric-z.mjs.map} +1 -1
  65. package/.output/server/chunks/build/MapLayerControl-DpNmYvcU.mjs +5720 -0
  66. package/.output/server/chunks/build/MapLayerControl-DpNmYvcU.mjs.map +1 -0
  67. package/.output/server/chunks/build/{Modal-D-dPQW3w.mjs → Modal-BLhN9Eg2.mjs} +12 -18
  68. package/.output/server/chunks/build/{Modal-D-dPQW3w.mjs.map → Modal-BLhN9Eg2.mjs.map} +1 -1
  69. package/.output/server/chunks/build/{OnlineMap-CKwiuqUY.mjs → OnlineMap-B-sCfHkC.mjs} +6 -3
  70. package/.output/server/chunks/build/OnlineMap-B-sCfHkC.mjs.map +1 -0
  71. package/.output/server/chunks/build/{Pagination-CkUsaatC.mjs → Pagination-CUzoLc_-.mjs} +1 -1
  72. package/.output/server/chunks/build/{Pagination-CkUsaatC.mjs.map → Pagination-CUzoLc_-.mjs.map} +1 -1
  73. package/.output/server/chunks/build/Skeleton-CHp-GjOx.mjs +59 -0
  74. package/.output/server/chunks/build/Skeleton-CHp-GjOx.mjs.map +1 -0
  75. package/.output/server/chunks/build/{Slider-CRpk8Y2j.mjs → Slider-CrIUK3pl.mjs} +10 -25
  76. package/.output/server/chunks/build/Slider-CrIUK3pl.mjs.map +1 -0
  77. package/.output/server/chunks/build/{MapBaseLayerTabs-Xu5bXAvH.mjs → Tabs-cdLsZZoL.mjs} +429 -931
  78. package/.output/server/chunks/build/Tabs-cdLsZZoL.mjs.map +1 -0
  79. package/.output/server/chunks/build/{Tooltip-BQHl07T-.mjs → Tooltip-DExIlyhu.mjs} +4 -196
  80. package/.output/server/chunks/build/Tooltip-DExIlyhu.mjs.map +1 -0
  81. package/.output/server/chunks/build/{advanced-C2aEmUTl.mjs → advanced-DaSpS8Px.mjs} +31 -35
  82. package/.output/server/chunks/build/advanced-DaSpS8Px.mjs.map +1 -0
  83. package/.output/server/chunks/build/clamp-CdZXprXk.mjs +65 -0
  84. package/.output/server/chunks/build/clamp-CdZXprXk.mjs.map +1 -0
  85. package/.output/server/chunks/build/{compare-NMjjryG_.mjs → compare-DaE10Dhp.mjs} +59 -40
  86. package/.output/server/chunks/build/compare-DaE10Dhp.mjs.map +1 -0
  87. package/.output/server/chunks/build/cookie-CziAmOf1.mjs +175 -0
  88. package/.output/server/chunks/build/cookie-CziAmOf1.mjs.map +1 -0
  89. package/.output/server/chunks/build/{dashboard-DYapNywh.mjs → dashboard-Dq8mphss.mjs} +21 -8
  90. package/.output/server/chunks/build/{dashboard-DYapNywh.mjs.map → dashboard-Dq8mphss.mjs.map} +1 -1
  91. package/.output/server/chunks/build/{details-Cyq3FQAG.mjs → details-DCNvSBgn.mjs} +5 -4
  92. package/.output/server/chunks/build/{details-Cyq3FQAG.mjs.map → details-DCNvSBgn.mjs.map} +1 -1
  93. package/.output/server/chunks/build/error-404-D9aQjJRn.mjs +1 -1
  94. package/.output/server/chunks/build/error-500-BNyA3wrb.mjs +1 -1
  95. package/.output/server/chunks/build/file-workspace-DMzPuPyG.mjs +104 -0
  96. package/.output/server/chunks/build/file-workspace-DMzPuPyG.mjs.map +1 -0
  97. package/.output/server/chunks/build/{interval-BxUMpo78.mjs → interval-i5OZnTaK.mjs} +2 -2
  98. package/.output/server/chunks/build/{interval-BxUMpo78.mjs.map → interval-i5OZnTaK.mjs.map} +1 -1
  99. package/.output/server/chunks/build/layers-50nqoWES.mjs +553 -0
  100. package/.output/server/chunks/build/layers-50nqoWES.mjs.map +1 -0
  101. package/.output/server/chunks/build/{login-gQQfuSWN.mjs → login-BHSHtO-R.mjs} +6 -5
  102. package/.output/server/chunks/build/{login-gQQfuSWN.mjs.map → login-BHSHtO-R.mjs.map} +1 -1
  103. package/.output/server/chunks/build/map-layers-C3HJoCLw.mjs +86 -0
  104. package/.output/server/chunks/build/map-layers-C3HJoCLw.mjs.map +1 -0
  105. package/.output/server/chunks/build/{PopperArrow-xcjACqm-.mjs → overlay-BS4_B29H.mjs} +974 -5
  106. package/.output/server/chunks/build/overlay-BS4_B29H.mjs.map +1 -0
  107. package/.output/server/chunks/build/pages-5yYRS5nX.mjs +37 -0
  108. package/.output/server/chunks/build/pages-5yYRS5nX.mjs.map +1 -0
  109. package/.output/server/chunks/build/{pages-CLVitjz2.mjs → pages-DfOPr0fC.mjs} +21 -22
  110. package/.output/server/chunks/build/pages-DfOPr0fC.mjs.map +1 -0
  111. package/.output/server/chunks/build/{services-C9oQ6UZi.mjs → services-DWlDpsbi.mjs} +46 -42
  112. package/.output/server/chunks/build/{services-C9oQ6UZi.mjs.map → services-DWlDpsbi.mjs.map} +1 -1
  113. package/.output/server/chunks/build/tasks-4b6D39Uy.mjs +6065 -0
  114. package/.output/server/chunks/build/tasks-4b6D39Uy.mjs.map +1 -0
  115. package/.output/server/chunks/build/{tasks-HCUoEUbh.mjs → tasks-BPPx2UMG.mjs} +10 -6
  116. package/.output/server/chunks/build/tasks-BPPx2UMG.mjs.map +1 -0
  117. package/.output/server/chunks/nitro/nitro.mjs +305 -244
  118. package/.output/server/chunks/routes/api/map/layers/_overlayLayer/update.get.mjs +29 -0
  119. package/.output/server/chunks/routes/api/map/layers/_overlayLayer/update.get.mjs.map +1 -0
  120. package/.output/server/chunks/routes/api/map/layers/_overlayLayer/update.post.mjs +31 -0
  121. package/.output/server/chunks/routes/api/map/layers/_overlayLayer/update.post.mjs.map +1 -0
  122. package/.output/server/chunks/routes/api/map/layers/_overlayLayer_.get.mjs +39 -0
  123. package/.output/server/chunks/routes/api/map/layers/_overlayLayer_.get.mjs.map +1 -0
  124. package/.output/server/chunks/routes/api/map/layers/status.get.mjs +60 -0
  125. package/.output/server/chunks/routes/api/map/layers/status.get.mjs.map +1 -0
  126. package/.output/server/chunks/routes/api/map/live/status.get.mjs +1 -1
  127. package/.output/server/chunks/routes/api/map/online/_layerGroup/_zoom/_tileX/_tileY_.get.mjs +1 -1
  128. package/.output/server/chunks/routes/api/map/online-root/_layerGroup/_rootX/_rootY_.get.mjs +1 -1
  129. package/.output/server/chunks/routes/api/map-service/config.post.mjs +1 -0
  130. package/.output/server/chunks/routes/api/map-service/config.post.mjs.map +1 -1
  131. package/.output/server/chunks/routes/api/map-service/file.post.mjs +1 -0
  132. package/.output/server/chunks/routes/api/map-service/file.post.mjs.map +1 -1
  133. package/.output/server/chunks/routes/api/map-service/source.post.mjs +1 -0
  134. package/.output/server/chunks/routes/api/map-service/source.post.mjs.map +1 -1
  135. package/.output/server/chunks/routes/api/map-service/status.get.mjs +1 -0
  136. package/.output/server/chunks/routes/api/map-service/status.get.mjs.map +1 -1
  137. package/.output/server/chunks/routes/api/workspace/_filename/analysis.get.mjs +2 -1
  138. package/.output/server/chunks/routes/api/workspace/_filename/analysis.get.mjs.map +1 -1
  139. package/.output/server/chunks/routes/api/workspace/_filename/download.get.mjs +2 -1
  140. package/.output/server/chunks/routes/api/workspace/_filename/download.get.mjs.map +1 -1
  141. package/.output/server/chunks/routes/api/workspace/_filename/export/_format_.get.mjs +10 -3
  142. package/.output/server/chunks/routes/api/workspace/_filename/export/_format_.get.mjs.map +1 -1
  143. package/.output/server/chunks/routes/api/workspace/_filename/export-estimate.get.mjs +39 -0
  144. package/.output/server/chunks/routes/api/workspace/_filename/export-estimate.get.mjs.map +1 -0
  145. package/.output/server/chunks/routes/api/workspace/_filename/tile.get.mjs +3 -2
  146. package/.output/server/chunks/routes/api/workspace/_filename/tile.get.mjs.map +1 -1
  147. package/.output/server/chunks/routes/api/workspace/_filename/tiles.get.mjs +2 -1
  148. package/.output/server/chunks/routes/api/workspace/_filename/tiles.get.mjs.map +1 -1
  149. package/.output/server/chunks/routes/api/workspace/_filename_.delete.mjs +2 -1
  150. package/.output/server/chunks/routes/api/workspace/_filename_.delete.mjs.map +1 -1
  151. package/.output/server/chunks/routes/api/workspace/compare/batch.get.mjs +2 -1
  152. package/.output/server/chunks/routes/api/workspace/compare/batch.get.mjs.map +1 -1
  153. package/.output/server/chunks/routes/api/workspace/compare.post.mjs +1 -0
  154. package/.output/server/chunks/routes/api/workspace/compare.post.mjs.map +1 -1
  155. package/.output/server/chunks/routes/api/workspace/fetch.post.mjs +1 -0
  156. package/.output/server/chunks/routes/api/workspace/fetch.post.mjs.map +1 -1
  157. package/.output/server/chunks/routes/api/workspace/files.get.mjs +1 -0
  158. package/.output/server/chunks/routes/api/workspace/files.get.mjs.map +1 -1
  159. package/.output/server/chunks/routes/api/workspace/files.post.mjs +2 -1
  160. package/.output/server/chunks/routes/api/workspace/files.post.mjs.map +1 -1
  161. package/.output/server/chunks/routes/api/workspace/stop.post.mjs +2 -1
  162. package/.output/server/chunks/routes/api/workspace/stop.post.mjs.map +1 -1
  163. package/.output/server/chunks/routes/api/workspace/tasks.post.mjs +3 -2
  164. package/.output/server/chunks/routes/api/workspace/tasks.post.mjs.map +1 -1
  165. package/.output/server/chunks/routes/renderer.mjs +3 -3
  166. package/.output/server/chunks/routes/services/wms.get.mjs +2 -1
  167. package/.output/server/chunks/routes/services/wms.get.mjs.map +1 -1
  168. package/.output/server/chunks/routes/services/wmts.get.mjs +2 -1
  169. package/.output/server/chunks/routes/services/wmts.get.mjs.map +1 -1
  170. package/.output/server/chunks/virtual/entry.mjs +320 -443
  171. package/.output/server/chunks/virtual/entry.mjs.map +1 -1
  172. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  173. package/.output/server/chunks/virtual/styles.mjs +1 -1
  174. package/.output/server/node_modules/undici/index.js +234 -0
  175. package/.output/server/node_modules/undici/lib/api/abort-signal.js +59 -0
  176. package/.output/server/node_modules/undici/lib/api/api-connect.js +110 -0
  177. package/.output/server/node_modules/undici/lib/api/api-pipeline.js +252 -0
  178. package/.output/server/node_modules/undici/lib/api/api-request.js +214 -0
  179. package/.output/server/node_modules/undici/lib/api/api-stream.js +209 -0
  180. package/.output/server/node_modules/undici/lib/api/api-upgrade.js +111 -0
  181. package/.output/server/node_modules/undici/lib/api/index.js +7 -0
  182. package/.output/server/node_modules/undici/lib/api/readable.js +580 -0
  183. package/.output/server/node_modules/undici/lib/cache/memory-cache-store.js +279 -0
  184. package/.output/server/node_modules/undici/lib/cache/sqlite-cache-store.js +467 -0
  185. package/.output/server/node_modules/undici/lib/core/connect.js +153 -0
  186. package/.output/server/node_modules/undici/lib/core/constants.js +143 -0
  187. package/.output/server/node_modules/undici/lib/core/diagnostics.js +227 -0
  188. package/.output/server/node_modules/undici/lib/core/errors.js +477 -0
  189. package/.output/server/node_modules/undici/lib/core/request.js +464 -0
  190. package/.output/server/node_modules/undici/lib/core/socks5-client.js +422 -0
  191. package/.output/server/node_modules/undici/lib/core/socks5-utils.js +212 -0
  192. package/.output/server/node_modules/undici/lib/core/symbols.js +75 -0
  193. package/.output/server/node_modules/undici/lib/core/tree.js +160 -0
  194. package/.output/server/node_modules/undici/lib/core/util.js +992 -0
  195. package/.output/server/node_modules/undici/lib/dispatcher/agent.js +158 -0
  196. package/.output/server/node_modules/undici/lib/dispatcher/balanced-pool.js +219 -0
  197. package/.output/server/node_modules/undici/lib/dispatcher/client-h1.js +1731 -0
  198. package/.output/server/node_modules/undici/lib/dispatcher/client-h2.js +995 -0
  199. package/.output/server/node_modules/undici/lib/dispatcher/client.js +664 -0
  200. package/.output/server/node_modules/undici/lib/dispatcher/dispatcher-base.js +184 -0
  201. package/.output/server/node_modules/undici/lib/dispatcher/dispatcher.js +48 -0
  202. package/.output/server/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +146 -0
  203. package/.output/server/node_modules/undici/lib/dispatcher/fixed-queue.js +135 -0
  204. package/.output/server/node_modules/undici/lib/dispatcher/h2c-client.js +51 -0
  205. package/.output/server/node_modules/undici/lib/dispatcher/pool-base.js +214 -0
  206. package/.output/server/node_modules/undici/lib/dispatcher/pool.js +118 -0
  207. package/.output/server/node_modules/undici/lib/dispatcher/proxy-agent.js +319 -0
  208. package/.output/server/node_modules/undici/lib/dispatcher/retry-agent.js +35 -0
  209. package/.output/server/node_modules/undici/lib/dispatcher/round-robin-pool.js +137 -0
  210. package/.output/server/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +260 -0
  211. package/.output/server/node_modules/undici/lib/encoding/index.js +33 -0
  212. package/.output/server/node_modules/undici/lib/global.js +59 -0
  213. package/.output/server/node_modules/undici/lib/handler/cache-handler.js +760 -0
  214. package/.output/server/node_modules/undici/lib/handler/cache-revalidation-handler.js +124 -0
  215. package/.output/server/node_modules/undici/lib/handler/decorator-handler.js +67 -0
  216. package/.output/server/node_modules/undici/lib/handler/deduplication-handler.js +460 -0
  217. package/.output/server/node_modules/undici/lib/handler/redirect-handler.js +238 -0
  218. package/.output/server/node_modules/undici/lib/handler/retry-handler.js +418 -0
  219. package/.output/server/node_modules/undici/lib/handler/unwrap-handler.js +106 -0
  220. package/.output/server/node_modules/undici/lib/handler/wrap-handler.js +105 -0
  221. package/.output/server/node_modules/undici/lib/interceptor/cache.js +602 -0
  222. package/.output/server/node_modules/undici/lib/interceptor/decompress.js +259 -0
  223. package/.output/server/node_modules/undici/lib/interceptor/deduplicate.js +117 -0
  224. package/.output/server/node_modules/undici/lib/interceptor/dns.js +571 -0
  225. package/.output/server/node_modules/undici/lib/interceptor/dump.js +112 -0
  226. package/.output/server/node_modules/undici/lib/interceptor/redirect.js +21 -0
  227. package/.output/server/node_modules/undici/lib/interceptor/response-error.js +95 -0
  228. package/.output/server/node_modules/undici/lib/interceptor/retry.js +19 -0
  229. package/.output/server/node_modules/undici/lib/llhttp/constants.js +531 -0
  230. package/.output/server/node_modules/undici/lib/llhttp/llhttp-wasm.js +15 -0
  231. package/.output/server/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +15 -0
  232. package/.output/server/node_modules/undici/lib/llhttp/utils.js +12 -0
  233. package/.output/server/node_modules/undici/lib/mock/mock-agent.js +232 -0
  234. package/.output/server/node_modules/undici/lib/mock/mock-call-history.js +248 -0
  235. package/.output/server/node_modules/undici/lib/mock/mock-client.js +68 -0
  236. package/.output/server/node_modules/undici/lib/mock/mock-errors.js +29 -0
  237. package/.output/server/node_modules/undici/lib/mock/mock-interceptor.js +209 -0
  238. package/.output/server/node_modules/undici/lib/mock/mock-pool.js +68 -0
  239. package/.output/server/node_modules/undici/lib/mock/mock-symbols.js +32 -0
  240. package/.output/server/node_modules/undici/lib/mock/mock-utils.js +486 -0
  241. package/.output/server/node_modules/undici/lib/mock/pending-interceptors-formatter.js +43 -0
  242. package/.output/server/node_modules/undici/lib/mock/snapshot-agent.js +353 -0
  243. package/.output/server/node_modules/undici/lib/mock/snapshot-recorder.js +588 -0
  244. package/.output/server/node_modules/undici/lib/mock/snapshot-utils.js +158 -0
  245. package/.output/server/node_modules/undici/lib/util/cache.js +676 -0
  246. package/.output/server/node_modules/undici/lib/util/date.js +670 -0
  247. package/.output/server/node_modules/undici/lib/util/promise.js +28 -0
  248. package/.output/server/node_modules/undici/lib/util/runtime-features.js +124 -0
  249. package/.output/server/node_modules/undici/lib/util/stats.js +32 -0
  250. package/.output/server/node_modules/undici/lib/util/timers.js +425 -0
  251. package/.output/server/node_modules/undici/lib/web/cache/cache.js +864 -0
  252. package/.output/server/node_modules/undici/lib/web/cache/cachestorage.js +152 -0
  253. package/.output/server/node_modules/undici/lib/web/cache/util.js +45 -0
  254. package/.output/server/node_modules/undici/lib/web/cookies/constants.js +12 -0
  255. package/.output/server/node_modules/undici/lib/web/cookies/index.js +199 -0
  256. package/.output/server/node_modules/undici/lib/web/cookies/parse.js +314 -0
  257. package/.output/server/node_modules/undici/lib/web/cookies/util.js +352 -0
  258. package/.output/server/node_modules/undici/lib/web/eventsource/eventsource-stream.js +399 -0
  259. package/.output/server/node_modules/undici/lib/web/eventsource/eventsource.js +501 -0
  260. package/.output/server/node_modules/undici/lib/web/eventsource/util.js +29 -0
  261. package/.output/server/node_modules/undici/lib/web/fetch/body.js +509 -0
  262. package/.output/server/node_modules/undici/lib/web/fetch/constants.js +131 -0
  263. package/.output/server/node_modules/undici/lib/web/fetch/data-url.js +596 -0
  264. package/.output/server/node_modules/undici/lib/web/fetch/formdata-parser.js +586 -0
  265. package/.output/server/node_modules/undici/lib/web/fetch/formdata.js +259 -0
  266. package/.output/server/node_modules/undici/lib/web/fetch/global.js +40 -0
  267. package/.output/server/node_modules/undici/lib/web/fetch/headers.js +719 -0
  268. package/.output/server/node_modules/undici/lib/web/fetch/index.js +2413 -0
  269. package/.output/server/node_modules/undici/lib/web/fetch/request.js +1115 -0
  270. package/.output/server/node_modules/undici/lib/web/fetch/response.js +641 -0
  271. package/.output/server/node_modules/undici/lib/web/fetch/util.js +1522 -0
  272. package/.output/server/node_modules/undici/lib/web/infra/index.js +229 -0
  273. package/.output/server/node_modules/undici/lib/web/subresource-integrity/subresource-integrity.js +307 -0
  274. package/.output/server/node_modules/undici/lib/web/webidl/index.js +1006 -0
  275. package/.output/server/node_modules/undici/lib/web/websocket/connection.js +329 -0
  276. package/.output/server/node_modules/undici/lib/web/websocket/constants.js +126 -0
  277. package/.output/server/node_modules/undici/lib/web/websocket/events.js +331 -0
  278. package/.output/server/node_modules/undici/lib/web/websocket/frame.js +133 -0
  279. package/.output/server/node_modules/undici/lib/web/websocket/permessage-deflate.js +100 -0
  280. package/.output/server/node_modules/undici/lib/web/websocket/receiver.js +507 -0
  281. package/.output/server/node_modules/undici/lib/web/websocket/sender.js +109 -0
  282. package/.output/server/node_modules/undici/lib/web/websocket/stream/websocketerror.js +104 -0
  283. package/.output/server/node_modules/undici/lib/web/websocket/stream/websocketstream.js +498 -0
  284. package/.output/server/node_modules/undici/lib/web/websocket/util.js +347 -0
  285. package/.output/server/node_modules/undici/lib/web/websocket/websocket.js +758 -0
  286. package/.output/server/node_modules/undici/package.json +152 -0
  287. package/.output/server/package.json +2 -1
  288. package/LICENSE +201 -2
  289. package/README.md +23 -5
  290. package/dist/package.json +3 -2
  291. package/dist/shared/antigravity-schema.js +45 -0
  292. package/dist/shared/dji-grid.js +62 -0
  293. package/dist/shared/export.js +4 -0
  294. package/dist/shared/types/export.js +1 -0
  295. package/dist/shared/types/map-layers.js +2 -0
  296. package/dist/src/cli.js +67 -6
  297. package/dist/src/core/dji-snapshot.js +135 -0
  298. package/dist/src/core/grid-renderer.js +29 -15
  299. package/dist/src/core/map-layer-paths.js +11 -0
  300. package/dist/src/core/png.js +59 -6
  301. package/dist/src/core/uomtiles.js +96 -13
  302. package/dist/src/map-layer-update.js +646 -0
  303. package/package.json +3 -2
  304. package/.output/public/_nuxt/BBJwRf9k.js +0 -1
  305. package/.output/public/_nuxt/BWYASl8D.js +0 -1
  306. package/.output/public/_nuxt/B_S8P0kE2.js +0 -1
  307. package/.output/public/_nuxt/BalC97Hq2.js +0 -1
  308. package/.output/public/_nuxt/Bd0XS-K-.js +0 -1
  309. package/.output/public/_nuxt/BdQwPExE.js +0 -1
  310. package/.output/public/_nuxt/Bt5oyQw_.js +0 -1
  311. package/.output/public/_nuxt/BuYkCss52.js +0 -1
  312. package/.output/public/_nuxt/BvQDTQww.js +0 -1
  313. package/.output/public/_nuxt/By4gkuDZ.js +0 -1
  314. package/.output/public/_nuxt/ByRlKR9F.js +0 -1
  315. package/.output/public/_nuxt/C4qlzA4o.js +0 -1
  316. package/.output/public/_nuxt/C6YoBcbT.js +0 -1
  317. package/.output/public/_nuxt/CNs_Ozdc.js +0 -1
  318. package/.output/public/_nuxt/D4tzFemo.js +0 -1
  319. package/.output/public/_nuxt/DCT2aLwC.js +0 -1
  320. package/.output/public/_nuxt/DIt0vOP7.js +0 -1
  321. package/.output/public/_nuxt/DV5CwoOP2.js +0 -1
  322. package/.output/public/_nuxt/DkcySee1.js +0 -1
  323. package/.output/public/_nuxt/Dq-XSsAz.js +0 -1
  324. package/.output/public/_nuxt/DrLbKQlJ.js +0 -3
  325. package/.output/public/_nuxt/DtFVCXI9.js +0 -1
  326. package/.output/public/_nuxt/Dz7VMlHR.js +0 -1
  327. package/.output/public/_nuxt/P_icVLkX.js +0 -1
  328. package/.output/public/_nuxt/XZ59tThl.js +0 -1
  329. package/.output/public/_nuxt/builds/meta/0e6b25d2-67d5-42d2-8971-b7374bfbdda5.json +0 -1
  330. package/.output/public/_nuxt/entry.BmEdVIZg.css +0 -1
  331. package/.output/public/_nuxt/yq0nsLQU.js +0 -1
  332. package/.output/server/chunks/build/Alert-CBMepLwP.mjs.map +0 -1
  333. package/.output/server/chunks/build/DashboardSidebarToggle-D24DGyKq.mjs +0 -569
  334. package/.output/server/chunks/build/DashboardSidebarToggle-D24DGyKq.mjs.map +0 -1
  335. package/.output/server/chunks/build/Empty-CkW3mADt.mjs.map +0 -1
  336. package/.output/server/chunks/build/FocusScope-BJ-B0nKb.mjs +0 -207
  337. package/.output/server/chunks/build/FocusScope-BJ-B0nKb.mjs.map +0 -1
  338. package/.output/server/chunks/build/FormField-CEUZHcv7.mjs.map +0 -1
  339. package/.output/server/chunks/build/MapBaseLayerTabs-Xu5bXAvH.mjs.map +0 -1
  340. package/.output/server/chunks/build/OnlineMap-CKwiuqUY.mjs.map +0 -1
  341. package/.output/server/chunks/build/PopperArrow-xcjACqm-.mjs.map +0 -1
  342. package/.output/server/chunks/build/ScrollArea-QgwoohKb.mjs +0 -379
  343. package/.output/server/chunks/build/ScrollArea-QgwoohKb.mjs.map +0 -1
  344. package/.output/server/chunks/build/Slider-CRpk8Y2j.mjs.map +0 -1
  345. package/.output/server/chunks/build/Tooltip-BQHl07T-.mjs.map +0 -1
  346. package/.output/server/chunks/build/advanced-C2aEmUTl.mjs.map +0 -1
  347. package/.output/server/chunks/build/compare-NMjjryG_.mjs.map +0 -1
  348. package/.output/server/chunks/build/pages-CLVitjz2.mjs.map +0 -1
  349. package/.output/server/chunks/build/tasks-Cr8nWwss.mjs +0 -915
  350. package/.output/server/chunks/build/tasks-Cr8nWwss.mjs.map +0 -1
  351. package/.output/server/chunks/build/tasks-HCUoEUbh.mjs.map +0 -1
package/dist/src/cli.js CHANGED
@@ -9,10 +9,12 @@ import { isSea } from 'node:sea';
9
9
  import { defineCommand, runMain } from 'citty';
10
10
  import { accountFile, uomtilesDataDir, workspaceDirectory } from "./core/paths.js";
11
11
  import { DEFAULT_GRID_CRAWL_OPTIONS, runGridCrawl } from "./grid-crawl.js";
12
+ import { DEFAULT_DJI_CONCURRENCY, updateMapLayers } from "./map-layer-update.js";
12
13
  import { FETCH_PROCESS_ENV } from "./core/fetch-process.js";
13
14
  import { shellEnvironmentHint } from "./core/shell.js";
14
15
  import { diffUomtiles, exportTiles, inspectUomtiles, migrateToUomtiles } from "./core/uomtiles.js";
15
16
  import { SPACE_APP_ID, UOM_BASE, LOCATION_SSO_PATH, UOMTILES_VERSION } from "./config.js";
17
+ import { DEFAULT_EXPORT_MAX_ZOOM, DEFAULT_EXPORT_MIN_ZOOM } from "../shared/export.js";
16
18
  const sea = isSea();
17
19
  const cliPath = sea ? null : fileURLToPath(import.meta.url);
18
20
  const compiled = cliPath ? extname(cliPath) === '.js' : false;
@@ -145,16 +147,22 @@ function openUrl(url) {
145
147
  child.unref();
146
148
  }
147
149
  function loadWebEnvironment() {
148
- const environmentFile = resolve(process.cwd(), '.env');
149
- if (existsSync(environmentFile))
150
- loadEnvFile(environmentFile);
150
+ loadProjectEnvironment();
151
151
  if (process.env.NUXT_TIANDITU_TOKEN?.trim())
152
152
  return;
153
153
  const shell = shellEnvironmentHint(process.platform, process.env);
154
154
  console.warn('天地图令牌未配置,工作台将使用 OSM,天地图选项不可用。');
155
- console.warn(`持久配置:在 ${environmentFile} 中添加 NUXT_TIANDITU_TOKEN=你的天地图令牌`);
155
+ console.warn(`持久配置:在 ${projectEnvironmentFile()} 中添加 NUXT_TIANDITU_TOKEN=你的天地图令牌`);
156
156
  console.warn(`当前 ${shell.name} 临时配置:${shell.command}`);
157
157
  }
158
+ function projectEnvironmentFile() {
159
+ return resolve(process.cwd(), '.env');
160
+ }
161
+ function loadProjectEnvironment() {
162
+ const environmentFile = projectEnvironmentFile();
163
+ if (existsSync(environmentFile))
164
+ loadEnvFile(environmentFile);
165
+ }
158
166
  async function web() {
159
167
  loadWebEnvironment();
160
168
  const entry = resolve(root, '.output/server/index.mjs');
@@ -214,9 +222,11 @@ const exportCommand = defineCommand({
214
222
  args: {
215
223
  input: { type: 'positional', description: '输入 .uomtiles 文件', required: true },
216
224
  output: { type: 'positional', description: '输出 .mbtiles 或 .pmtiles 文件', required: true },
225
+ 'min-zoom': { type: 'string', description: '最小导出层级', default: String(DEFAULT_EXPORT_MIN_ZOOM) },
226
+ 'max-zoom': { type: 'string', description: '最大导出层级', default: String(DEFAULT_EXPORT_MAX_ZOOM) },
217
227
  },
218
228
  run: async ({ args }) => {
219
- await exportTiles(args.input, args.output);
229
+ await exportTiles(args.input, args.output, { minZoom: Number(args['min-zoom']), maxZoom: Number(args['max-zoom']) });
220
230
  console.log(`已导出:${resolve(args.output)}`);
221
231
  },
222
232
  });
@@ -248,6 +258,51 @@ const migrateCommand = defineCommand({
248
258
  console.log(JSON.stringify(migrateToUomtiles(args.input, args.output, account?.username || null), null, 2));
249
259
  },
250
260
  });
261
+ const mapLayersUpdateCommand = defineCommand({
262
+ meta: { name: 'map-layers-update', description: '在线更新 DJI Flysafe 与 Antigravity 图层快照' },
263
+ args: () => {
264
+ loadProjectEnvironment();
265
+ return {
266
+ output: {
267
+ type: 'string',
268
+ description: '快照输出目录',
269
+ valueHint: 'PATH',
270
+ default: resolve(uomtilesDataDir(), 'map-layers'),
271
+ },
272
+ 'dji-raw-dir': {
273
+ type: 'string',
274
+ description: '用于断点续传的 DJI 原始响应目录',
275
+ valueHint: 'PATH',
276
+ required: false,
277
+ },
278
+ 'dji-concurrency': {
279
+ type: 'string',
280
+ description: 'DJI 并发请求数',
281
+ valueHint: 'N',
282
+ default: String(DEFAULT_DJI_CONCURRENCY),
283
+ },
284
+ 'dji-resume': {
285
+ type: 'boolean',
286
+ description: '复用当前更新会话中已验证的 DJI 原始响应',
287
+ negativeDescription: '忽略当前 DJI 更新会话并重新下载',
288
+ default: true,
289
+ },
290
+ };
291
+ },
292
+ run: async ({ args }) => {
293
+ const djiConcurrency = Number(args['dji-concurrency']);
294
+ if (!Number.isInteger(djiConcurrency) || djiConcurrency <= 0) {
295
+ throw new Error('--dji-concurrency 必须是正整数');
296
+ }
297
+ const result = await updateMapLayers({
298
+ outputDirectory: args.output,
299
+ djiRawDirectory: args['dji-raw-dir'],
300
+ djiConcurrency,
301
+ djiResume: args['dji-resume'],
302
+ });
303
+ console.log(JSON.stringify(result, null, 2));
304
+ },
305
+ });
251
306
  const mainCommand = defineCommand({
252
307
  meta: {
253
308
  name: 'uomtiles',
@@ -264,6 +319,12 @@ const mainCommand = defineCommand({
264
319
  export: exportCommand,
265
320
  diff: diffCommand,
266
321
  migrate: migrateCommand,
322
+ 'map-layers-update': mapLayersUpdateCommand,
267
323
  },
268
324
  });
269
- await runMain(mainCommand);
325
+ function cliArguments(arguments_) {
326
+ if (arguments_[0] !== 'map-layers-update')
327
+ return arguments_;
328
+ return arguments_.filter(argument => argument !== '--');
329
+ }
330
+ await runMain(mainCommand, { rawArgs: cliArguments(process.argv.slice(2)) });
@@ -0,0 +1,135 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { DJI_COVERAGE, DJI_ENDPOINT, DJI_LEVELS, DJI_MAX_SPLIT_DEPTH, DJI_OVERLAP_DEGREES, DJI_ROW_DEGREES, DJI_SATURATION_LIMIT, DJI_TARGET_DIAGONAL_KM, djiBoundsEqual, makeDjiBaseGrid, splitDjiCell, } from "../../shared/dji-grid.js";
3
+ /**
4
+ * Parse and fully validate a downloaded DJI snapshot.
5
+ *
6
+ * This is intentionally kept independent from Nitro/server runtime code so
7
+ * the updater and the runtime renderer cannot disagree about snapshot validity.
8
+ */
9
+ export function parseDjiSnapshot(contents) {
10
+ const parsed = JSON.parse(contents);
11
+ if (!isRecord(parsed) || parsed.formatVersion !== 2 || parsed.source !== 'DJI FlySafe' || parsed.scope !== 'global')
12
+ invalidSnapshot();
13
+ if (!isIsoDate(parsed.startedAt) || !isIsoDate(parsed.completedAt) || parsed.fetchedAt !== parsed.completedAt)
14
+ invalidSnapshot();
15
+ if (Date.parse(parsed.startedAt) > Date.parse(parsed.completedAt))
16
+ invalidSnapshot();
17
+ const coverage = parsed.coverage;
18
+ if (!isRecord(coverage) || coverage.west !== DJI_COVERAGE.west || coverage.south !== DJI_COVERAGE.south || coverage.east !== DJI_COVERAGE.east || coverage.north !== DJI_COVERAGE.north)
19
+ invalidSnapshot();
20
+ const query = parsed.query;
21
+ if (!isRecord(query) || query.algorithmVersion !== 'global-adaptive-grid-v1' || query.endpoint !== DJI_ENDPOINT || query.zonesMode !== 'flysafe_website' || query.drone !== 'dji-mavic-3' || query.levels !== DJI_LEVELS)
22
+ invalidSnapshot();
23
+ if (query.rowDegrees !== DJI_ROW_DEGREES || query.targetDiagonalKm !== DJI_TARGET_DIAGONAL_KM || query.overlapDegrees !== DJI_OVERLAP_DEGREES || query.saturationLimit !== DJI_SATURATION_LIMIT || query.maxSplitDepth !== DJI_MAX_SPLIT_DEPTH)
24
+ invalidSnapshot();
25
+ if (!positiveInteger(query.queryCount) || !positiveInteger(query.baseQueryCount) || !nonNegativeInteger(query.recursiveQueryCount))
26
+ invalidSnapshot();
27
+ if (!nonNegativeInteger(query.saturatedQueryCount) || !nonNegativeInteger(query.maximumLeafResultCount) || query.allLeafQueriesBelowSaturationLimit !== true)
28
+ invalidSnapshot();
29
+ if (!nonNegativeInteger(query.occurrenceCount) || !nonNegativeInteger(query.uniqueAreaCount) || !nonNegativeInteger(query.duplicateOccurrences) || query.conflictingDuplicateCount !== 0 || !nonNegativeInteger(query.resumedQueryCount) || query.resumedQueryCount > query.queryCount)
30
+ invalidSnapshot();
31
+ if (!Array.isArray(query.queries) || query.queryCount !== query.queries.length || query.queryCount !== query.baseQueryCount + query.recursiveQueryCount)
32
+ invalidSnapshot();
33
+ if (!Array.isArray(parsed.areas) || query.uniqueAreaCount !== parsed.areas.length || query.duplicateOccurrences !== query.occurrenceCount - query.uniqueAreaCount)
34
+ invalidSnapshot();
35
+ if (typeof parsed.areasSha256 !== 'string' || !/^[0-9a-f]{64}$/.test(parsed.areasSha256))
36
+ invalidSnapshot();
37
+ if (createHash('sha256').update(JSON.stringify(parsed.areas)).digest('hex') !== parsed.areasSha256)
38
+ invalidSnapshot();
39
+ const queryIds = new Set();
40
+ const summaries = [];
41
+ let saturatedCount = 0;
42
+ let maximumLeafResultCount = 0;
43
+ let baseQueryCount = 0;
44
+ let occurrenceCount = 0;
45
+ for (const summary of query.queries) {
46
+ if (!isQuerySummary(summary) || queryIds.has(summary.id) || summary.depth > DJI_MAX_SPLIT_DEPTH)
47
+ invalidSnapshot();
48
+ queryIds.add(summary.id);
49
+ summaries.push(summary);
50
+ occurrenceCount += summary.resultCount;
51
+ if (summary.depth === 0)
52
+ baseQueryCount++;
53
+ if (summary.saturated) {
54
+ if (summary.resultCount < query.saturationLimit)
55
+ invalidSnapshot();
56
+ saturatedCount++;
57
+ }
58
+ else {
59
+ if (summary.resultCount >= query.saturationLimit)
60
+ invalidSnapshot();
61
+ maximumLeafResultCount = Math.max(maximumLeafResultCount, summary.resultCount);
62
+ }
63
+ }
64
+ if (baseQueryCount !== query.baseQueryCount || summaries.length - baseQueryCount !== query.recursiveQueryCount || occurrenceCount !== query.occurrenceCount)
65
+ invalidSnapshot();
66
+ if (saturatedCount !== query.saturatedQueryCount || maximumLeafResultCount !== query.maximumLeafResultCount)
67
+ invalidSnapshot();
68
+ const summariesById = new Map(summaries.map(summary => [summary.id, summary]));
69
+ const expectedBaseCells = makeDjiBaseGrid();
70
+ if (query.baseQueryCount !== expectedBaseCells.length)
71
+ invalidSnapshot();
72
+ for (const expected of expectedBaseCells) {
73
+ const actual = summariesById.get(expected.id);
74
+ if (!actual || actual.depth !== 0 || actual.parentId !== undefined || !djiBoundsEqual(actual.bounds, expected.bounds))
75
+ invalidSnapshot();
76
+ }
77
+ for (const summary of summaries) {
78
+ if (summary.depth === 0)
79
+ continue;
80
+ const parent = summary.parentId ? summariesById.get(summary.parentId) : undefined;
81
+ if (!parent?.saturated || parent.depth + 1 !== summary.depth)
82
+ invalidSnapshot();
83
+ }
84
+ for (const parent of summaries) {
85
+ const children = summaries.filter(summary => summary.parentId === parent.id);
86
+ if (!parent.saturated) {
87
+ if (children.length)
88
+ invalidSnapshot();
89
+ continue;
90
+ }
91
+ const expectedChildren = splitDjiCell(parent);
92
+ if (children.length !== expectedChildren.length)
93
+ invalidSnapshot();
94
+ for (const expected of expectedChildren) {
95
+ const actual = summariesById.get(expected.id);
96
+ if (!actual || actual.parentId !== parent.id || actual.depth !== expected.depth || !djiBoundsEqual(actual.bounds, expected.bounds))
97
+ invalidSnapshot();
98
+ }
99
+ }
100
+ const areaIds = new Set();
101
+ for (const area of parsed.areas) {
102
+ if (!isRecord(area) || area.area_id === null || area.area_id === undefined || String(area.area_id).trim() === '')
103
+ invalidSnapshot();
104
+ const id = String(area.area_id);
105
+ if (areaIds.has(id))
106
+ invalidSnapshot();
107
+ areaIds.add(id);
108
+ }
109
+ return parsed;
110
+ }
111
+ function isQuerySummary(value) {
112
+ if (!isRecord(value) || typeof value.id !== 'string' || !value.id || !nonNegativeInteger(value.depth) || !nonNegativeInteger(value.resultCount) || typeof value.saturated !== 'boolean')
113
+ return false;
114
+ if (value.parentId !== undefined && (typeof value.parentId !== 'string' || !value.parentId))
115
+ return false;
116
+ if (!Array.isArray(value.bounds) || value.bounds.length !== 4 || !value.bounds.every(item => typeof item === 'number' && Number.isFinite(item)))
117
+ return false;
118
+ const [west, south, east, north] = value.bounds;
119
+ return west >= -180 && east <= 180 && south >= -90 && north <= 90 && west < east && south < north;
120
+ }
121
+ function isIsoDate(value) {
122
+ return typeof value === 'string' && Number.isFinite(Date.parse(value)) && new Date(value).toISOString() === value;
123
+ }
124
+ function positiveInteger(value) {
125
+ return Number.isInteger(value) && Number(value) > 0;
126
+ }
127
+ function nonNegativeInteger(value) {
128
+ return Number.isInteger(value) && Number(value) >= 0;
129
+ }
130
+ function isRecord(value) {
131
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
132
+ }
133
+ function invalidSnapshot() {
134
+ throw new Error('DJI Flysafe 快照格式或完整性校验失败');
135
+ }
@@ -120,30 +120,44 @@ export class GeographicGridRenderer {
120
120
  return;
121
121
  }
122
122
  const scale = 2 ** (z - SOURCE_ZOOM);
123
- for (const root of this.roots.values())
123
+ const worldMax = 2 ** z - 1;
124
+ const roots = [...this.roots.values()].sort((left, right) => left.x - right.x || left.y - right.y);
125
+ for (const root of roots) {
126
+ const rows = new Map();
127
+ const sourceX0 = root.x * sourceRootSize;
128
+ const sourceY0 = root.y * sourceRootSize;
124
129
  for (const rect of root.rects) {
125
- const sourceX0 = root.x * sourceRootSize;
126
- const sourceY0 = root.y * sourceRootSize;
127
130
  const pixelX0 = Math.round((sourceX0 + root.xLines[rect.col0]) * scale);
128
131
  const pixelY0 = Math.round((sourceY0 + root.yLines[rect.row0]) * scale);
129
132
  const pixelX1 = Math.round((sourceX0 + root.xLines[rect.col1]) * scale);
130
133
  const pixelY1 = Math.round((sourceY0 + root.yLines[rect.row1]) * scale);
131
134
  if (pixelX0 >= pixelX1 || pixelY0 >= pixelY1)
132
135
  continue;
133
- const x0 = Math.floor(pixelX0 / 256), y0 = Math.floor(pixelY0 / 256);
134
- const x1 = Math.floor((pixelX1 - 1) / 256), y1 = Math.floor((pixelY1 - 1) / 256);
135
- const worldMax = 2 ** z - 1;
136
- for (let tileY = Math.max(0, y0); tileY <= Math.min(worldMax, y1); tileY++) {
137
- for (let tileX = Math.max(0, x0); tileX <= Math.min(worldMax, x1); tileX++)
138
- coordinates.add(`${tileX}/${tileY}`);
136
+ const x0 = Math.max(0, Math.floor(pixelX0 / 256));
137
+ const y0 = Math.max(0, Math.floor(pixelY0 / 256));
138
+ const x1 = Math.min(worldMax, Math.floor((pixelX1 - 1) / 256));
139
+ const y1 = Math.min(worldMax, Math.floor((pixelY1 - 1) / 256));
140
+ for (let tileY = y0; tileY <= y1; tileY++) {
141
+ const intervals = rows.get(tileY) || [];
142
+ intervals.push([x0, x1]);
143
+ rows.set(tileY, intervals);
144
+ }
145
+ }
146
+ for (const tileY of [...rows.keys()].sort((left, right) => left - right)) {
147
+ const intervals = rows.get(tileY).sort((left, right) => left[0] - right[0] || left[1] - right[1]);
148
+ let [start, end] = intervals[0];
149
+ for (let index = 1; index <= intervals.length; index++) {
150
+ const next = intervals[index];
151
+ if (next && next[0] <= end + 1) {
152
+ end = Math.max(end, next[1]);
153
+ continue;
154
+ }
155
+ for (let tileX = start; tileX <= end; tileX++)
156
+ yield { z, x: tileX, y: tileY };
157
+ if (next)
158
+ [start, end] = next;
139
159
  }
140
160
  }
141
- for (const coordinate of [...coordinates].sort((left, right) => {
142
- const [leftX, leftY] = left.split('/').map(Number), [rightX, rightY] = right.split('/').map(Number);
143
- return leftX - rightX || leftY - rightY;
144
- })) {
145
- const [x, y] = coordinate.split('/').map(Number);
146
- yield { z, x: x, y: y };
147
161
  }
148
162
  }
149
163
  }
@@ -0,0 +1,11 @@
1
+ import { resolve } from 'node:path';
2
+ export const MAP_LAYER_SNAPSHOT_FILENAMES = {
3
+ dji: 'dji-nfz.json',
4
+ antigravity: 'antigravity-nfz.sqlite',
5
+ };
6
+ export function resolveMapLayerSnapshotPath(options) {
7
+ const explicitPath = options.explicitPath?.trim();
8
+ if (explicitPath)
9
+ return resolve(explicitPath);
10
+ return resolve(options.dataDir, 'map-layers', options.filename);
11
+ }
@@ -167,20 +167,73 @@ export function decodeUomAlphaMask(png, expectedWidth, expectedHeight = expected
167
167
  export function decodeCanonicalAlphaMask(png, expectedWidth, expectedHeight = expectedWidth) {
168
168
  return alphaMask(decodeIndexedPng(png, true), expectedWidth, expectedHeight);
169
169
  }
170
+ function paeth(left, up, upLeft) {
171
+ const estimate = left + up - upLeft;
172
+ const leftDistance = Math.abs(estimate - left);
173
+ const upDistance = Math.abs(estimate - up);
174
+ const cornerDistance = Math.abs(estimate - upLeft);
175
+ return leftDistance <= upDistance && leftDistance <= cornerDistance ? left : upDistance <= cornerDistance ? up : upLeft;
176
+ }
177
+ function filterRows(rows, rowBytes, height) {
178
+ const output = Buffer.allocUnsafe((rowBytes + 1) * height);
179
+ for (let y = 0; y < height; y++) {
180
+ const rowOffset = y * rowBytes;
181
+ const outputOffset = y * (rowBytes + 1);
182
+ let bestFilter = 0;
183
+ let bestScore = Number.POSITIVE_INFINITY;
184
+ let best = Buffer.allocUnsafe(rowBytes);
185
+ for (let filter = 0; filter <= 4; filter++) {
186
+ const candidate = Buffer.allocUnsafe(rowBytes);
187
+ let score = 0;
188
+ for (let x = 0; x < rowBytes; x++) {
189
+ const current = rows[rowOffset + x];
190
+ const left = x > 0 ? rows[rowOffset + x - 1] : 0;
191
+ const up = y > 0 ? rows[rowOffset - rowBytes + x] : 0;
192
+ const upLeft = x > 0 && y > 0 ? rows[rowOffset - rowBytes + x - 1] : 0;
193
+ const prediction = filter === 0 ? 0
194
+ : filter === 1 ? left
195
+ : filter === 2 ? up
196
+ : filter === 3 ? Math.floor((left + up) / 2)
197
+ : paeth(left, up, upLeft);
198
+ const value = (current - prediction) & 0xff;
199
+ candidate[x] = value;
200
+ score += value < 128 ? value : 256 - value;
201
+ }
202
+ if (score < bestScore) {
203
+ bestFilter = filter;
204
+ bestScore = score;
205
+ best = candidate;
206
+ }
207
+ }
208
+ output[outputOffset] = bestFilter;
209
+ best.copy(output, outputOffset + 1);
210
+ }
211
+ return output;
212
+ }
170
213
  export function encodeIndexedPng(width, height, indexes, palette, alpha) {
171
214
  if (indexes.length !== width * height)
172
215
  throw new RangeError('indexed PNG dimensions do not match pixels');
173
216
  if (palette.length === 0 || palette.length % 3 !== 0 || palette.length / 3 > 256)
174
217
  throw new RangeError('invalid indexed PNG palette');
175
- const raw = Buffer.allocUnsafe((width + 1) * height);
176
- for (let y = 0; y < height; y++) {
177
- raw[y * (width + 1)] = 0;
178
- raw.set(indexes.subarray(y * width, (y + 1) * width), y * (width + 1) + 1);
179
- }
218
+ const paletteEntries = palette.length / 3;
219
+ const bitDepth = paletteEntries <= 2 ? 1 : paletteEntries <= 4 ? 2 : paletteEntries <= 16 ? 4 : 8;
220
+ const rowBytes = Math.ceil(width * bitDepth / 8);
221
+ const pixelsPerByte = 8 / bitDepth;
222
+ const rows = Buffer.alloc(rowBytes * height);
223
+ for (let y = 0; y < height; y++)
224
+ for (let x = 0; x < width; x++) {
225
+ const index = indexes[y * width + x];
226
+ if (index >= paletteEntries)
227
+ throw new RangeError('indexed PNG pixel exceeds palette');
228
+ const byte = y * rowBytes + Math.floor(x / pixelsPerByte);
229
+ const shift = 8 - bitDepth * (x % pixelsPerByte + 1);
230
+ rows[byte] = rows[byte] | index << shift;
231
+ }
232
+ const raw = filterRows(rows, rowBytes, height);
180
233
  const ihdr = Buffer.alloc(13);
181
234
  ihdr.writeUInt32BE(width, 0);
182
235
  ihdr.writeUInt32BE(height, 4);
183
- ihdr[8] = 8;
236
+ ihdr[8] = bitDepth;
184
237
  ihdr[9] = 3;
185
238
  ihdr[10] = 0;
186
239
  ihdr[11] = 0;
@@ -5,12 +5,14 @@ import { execFile } from 'node:child_process';
5
5
  import { promisify } from 'node:util';
6
6
  import { DatabaseSync } from 'node:sqlite';
7
7
  import { UOMTILES_VERSION } from "../config.js";
8
+ import { DEFAULT_EXPORT_MAX_ZOOM, DEFAULT_EXPORT_MIN_ZOOM, EXPORT_MAX_ZOOM, EXPORT_MIN_ZOOM, } from "../../shared/export.js";
8
9
  import { acquireSqliteLease } from "./lease.js";
9
10
  import { decodeCanonicalAlphaMask } from "./png.js";
10
- import { GeographicGridRenderer, PUBLISH_MAX_ZOOM } from "./grid-renderer.js";
11
+ import { GeographicGridRenderer } from "./grid-renderer.js";
11
12
  import { xyzYToTmsY } from "../bbox.js";
12
13
  const execFileAsync = promisify(execFile);
13
14
  const UOMTILES_SCHEMA_VERSION = 1;
15
+ const MIN_NONEMPTY_PNG_BYTES = 120;
14
16
  function tables(db) {
15
17
  return new Set(db.prepare("SELECT name FROM sqlite_master WHERE type='table'").all().map(row => row.name));
16
18
  }
@@ -19,6 +21,63 @@ function metadata(db) {
19
21
  return {};
20
22
  return Object.fromEntries(db.prepare('SELECT name,value FROM metadata').all().map(row => [row.name, row.value]));
21
23
  }
24
+ export function exportZoomRange(options = {}) {
25
+ const minZoom = options.minZoom ?? DEFAULT_EXPORT_MIN_ZOOM;
26
+ const maxZoom = options.maxZoom ?? DEFAULT_EXPORT_MAX_ZOOM;
27
+ if (!Number.isInteger(minZoom) || minZoom < EXPORT_MIN_ZOOM || minZoom > EXPORT_MAX_ZOOM) {
28
+ throw new RangeError(`最小导出层级必须是 z${EXPORT_MIN_ZOOM}–z${EXPORT_MAX_ZOOM} 的整数`);
29
+ }
30
+ if (!Number.isInteger(maxZoom) || maxZoom < EXPORT_MIN_ZOOM || maxZoom > EXPORT_MAX_ZOOM) {
31
+ throw new RangeError(`最大导出层级必须是 z${EXPORT_MIN_ZOOM}–z${EXPORT_MAX_ZOOM} 的整数`);
32
+ }
33
+ if (minZoom > maxZoom)
34
+ throw new RangeError('最小导出层级不能大于最大导出层级');
35
+ return { minZoom, maxZoom };
36
+ }
37
+ function projectedLevel(summary, zoom) {
38
+ const reencodedPngRatio = zoom <= 8 ? 0.93 : Math.max(0.58, 0.93 - (zoom - 8) * 0.075);
39
+ const known = new Map(summary.tiles.map(level => [level.z, level]));
40
+ const exact = known.get(zoom);
41
+ if (exact)
42
+ return {
43
+ tileCount: exact.count,
44
+ pngBytes: Math.max(exact.count * MIN_NONEMPTY_PNG_BYTES, Math.round(exact.bytes * reencodedPngRatio)),
45
+ tileCountExact: true,
46
+ };
47
+ const levels = [...known.values()].sort((left, right) => left.z - right.z);
48
+ const base = levels.reduce((nearest, level) => Math.abs(level.z - zoom) < Math.abs(nearest.z - zoom) ? level : nearest, levels[0]);
49
+ if (!base)
50
+ return { tileCount: 0, pngBytes: 0, tileCountExact: false };
51
+ const baseRatio = base.z <= 8 ? 0.93 : Math.max(0.58, 0.93 - (base.z - 8) * 0.075);
52
+ const baseAverage = Math.max(MIN_NONEMPTY_PNG_BYTES, base.bytes / Math.max(1, base.count) * baseRatio);
53
+ const distance = Math.abs(zoom - base.z);
54
+ if (zoom > base.z) {
55
+ const tileCount = Math.max(1, Math.round(base.count * 3.75 ** distance));
56
+ const average = MIN_NONEMPTY_PNG_BYTES + (baseAverage - MIN_NONEMPTY_PNG_BYTES) * 0.55 ** distance;
57
+ return { tileCount, pngBytes: Math.round(tileCount * average), tileCountExact: false };
58
+ }
59
+ const tileCount = Math.max(1, Math.round(base.count / 3.5 ** distance));
60
+ const average = Math.min(1_600, baseAverage * 1.25 ** distance);
61
+ return { tileCount, pngBytes: Math.round(tileCount * average), tileCountExact: false };
62
+ }
63
+ export function estimateExport(source, format, options = {}) {
64
+ const range = exportZoomRange(options);
65
+ const summary = inspectUomtiles(source);
66
+ const levels = [];
67
+ let tileCount = 0;
68
+ let pngBytes = 0;
69
+ for (let zoom = range.minZoom; zoom <= range.maxZoom; zoom++) {
70
+ const level = projectedLevel(summary, zoom);
71
+ tileCount += level.tileCount;
72
+ pngBytes += level.pngBytes;
73
+ levels.push({ zoom, tileCount: level.tileCount, estimatedBytes: level.pngBytes, tileCountExact: level.tileCountExact });
74
+ }
75
+ // Fresh MBTiles files pay for SQLite B-trees; PMTiles deduplicates PNG blobs and has compact varint directories.
76
+ const estimatedBytes = format === 'mbtiles'
77
+ ? pngBytes + tileCount * 80 + 128 * 1024
78
+ : Math.round(pngBytes * 0.82 + tileCount * 16 + 64 * 1024);
79
+ return { ...range, format, estimatedBytes, tileCount, levels, omitsEmptyTiles: true };
80
+ }
22
81
  export function initializeUomtiles(path, publisher) {
23
82
  mkdirSync(dirname(path), { recursive: true });
24
83
  const db = new DatabaseSync(path);
@@ -131,9 +190,10 @@ export function inspectUomtiles(path) {
131
190
  db.close();
132
191
  }
133
192
  }
134
- export function exportMbtiles(source, target) {
193
+ export function exportMbtiles(source, target, options = {}) {
135
194
  const input = resolve(source);
136
195
  const output = resolve(target);
196
+ const range = exportZoomRange(options);
137
197
  if (extname(output).toLowerCase() !== '.mbtiles')
138
198
  throw new Error('MBTiles 输出文件必须使用 .mbtiles 扩展名');
139
199
  const lock = acquireSqliteLease(input, 'writer');
@@ -143,29 +203,45 @@ export function exportMbtiles(source, target) {
143
203
  mkdirSync(dirname(output), { recursive: true });
144
204
  const sourceDb = new DatabaseSync(input, { readOnly: true });
145
205
  const outputDb = new DatabaseSync(temporary);
206
+ let complete = false;
146
207
  try {
147
208
  outputDb.exec(`PRAGMA journal_mode=OFF; PRAGMA synchronous=OFF;
148
209
  CREATE TABLE metadata(name TEXT PRIMARY KEY,value TEXT NOT NULL);
149
210
  CREATE TABLE tiles(zoom_level INTEGER NOT NULL,tile_column INTEGER NOT NULL,tile_row INTEGER NOT NULL,tile_data BLOB NOT NULL,
150
211
  PRIMARY KEY(zoom_level,tile_column,tile_row));`);
151
212
  const insertMeta = outputDb.prepare('INSERT INTO metadata(name,value) VALUES(?,?)');
152
- const standard = new Set(['name', 'type', 'version', 'description', 'format', 'bounds', 'center', 'minzoom', 'attribution']);
153
213
  const meta = metadata(sourceDb);
154
214
  outputDb.exec('BEGIN');
155
- for (const name of standard)
156
- if (meta[name])
157
- insertMeta.run(name, meta[name]);
158
215
  const summary = inspectUomtiles(input);
216
+ const bounds = meta.bounds || '73,17.5,135.5,54';
217
+ const [west, south, east, north] = bounds.split(',').map(Number);
218
+ const sourceCenter = meta.center?.split(',').map(Number);
219
+ const centerZoom = Math.min(range.maxZoom, Math.max(range.minZoom, Number.isFinite(sourceCenter?.[2]) ? sourceCenter[2] : 9));
220
+ const center = `${Number.isFinite(sourceCenter?.[0]) ? sourceCenter[0] : (west + east) / 2},${Number.isFinite(sourceCenter?.[1]) ? sourceCenter[1] : (south + north) / 2},${centerZoom}`;
221
+ const standard = {
222
+ name: meta.name || 'UOM适飞地图',
223
+ format: 'png',
224
+ bounds,
225
+ center,
226
+ minzoom: String(range.minZoom),
227
+ maxzoom: String(range.maxZoom),
228
+ type: 'overlay',
229
+ version: UOMTILES_VERSION,
230
+ description: meta.description || 'UOM适飞空域',
231
+ attribution: meta.attribution || 'CAAC UOM',
232
+ };
233
+ for (const [name, value] of Object.entries(standard))
234
+ insertMeta.run(name, value);
159
235
  insertMeta.run('uomtiles:publisher', summary.publisher || 'unknown');
160
236
  insertMeta.run('uomtiles:fetched_at', summary.finishedAt || summary.startedAt || 'unknown');
161
237
  insertMeta.run('uomtiles:source_zoom', String(summary.sourceZoom ?? 'unknown'));
162
238
  insertMeta.run('uomtiles:grid_level', String(summary.gridLevel ?? 'unknown'));
239
+ insertMeta.run('uomtiles:tool_version', UOMTILES_VERSION);
163
240
  const renderer = new GeographicGridRenderer(input);
164
- insertMeta.run('maxzoom', String(renderer.available ? PUBLISH_MAX_ZOOM : Math.max(0, ...summary.tiles.map(tile => tile.z))));
165
241
  const insertTile = outputDb.prepare('INSERT INTO tiles VALUES(?,?,?,?)');
166
242
  let copied = 0;
167
243
  if (renderer.available) {
168
- for (let z = 0; z <= PUBLISH_MAX_ZOOM; z++)
244
+ for (let z = range.minZoom; z <= range.maxZoom; z++)
169
245
  for (const coordinate of renderer.contentCoordinates(z)) {
170
246
  const tile = renderer.renderTile(z, coordinate.x, coordinate.y);
171
247
  if (!tile)
@@ -177,7 +253,10 @@ export function exportMbtiles(source, target) {
177
253
  }
178
254
  }
179
255
  else {
180
- for (const row of sourceDb.prepare('SELECT zoom_level,tile_column,tile_row,tile_data FROM tiles ORDER BY zoom_level,tile_column,tile_row').iterate()) {
256
+ for (const row of sourceDb.prepare(`SELECT zoom_level,tile_column,tile_row,tile_data FROM tiles
257
+ WHERE zoom_level BETWEEN ? AND ? ORDER BY zoom_level,tile_column,tile_row`).iterate(range.minZoom, range.maxZoom)) {
258
+ if (!decodeCanonicalAlphaMask(row.tile_data, 256).some(Boolean))
259
+ continue;
181
260
  insertTile.run(row.zoom_level, row.tile_column, row.tile_row, row.tile_data);
182
261
  copied++;
183
262
  if (copied % 1_000 === 0)
@@ -186,7 +265,8 @@ export function exportMbtiles(source, target) {
186
265
  }
187
266
  lock.heartbeat();
188
267
  outputDb.exec('COMMIT');
189
- outputDb.exec('CREATE UNIQUE INDEX tile_index ON tiles(zoom_level,tile_column,tile_row); PRAGMA optimize;');
268
+ outputDb.exec('PRAGMA optimize;');
269
+ complete = true;
190
270
  }
191
271
  catch (error) {
192
272
  try {
@@ -199,23 +279,26 @@ export function exportMbtiles(source, target) {
199
279
  outputDb.close();
200
280
  sourceDb.close();
201
281
  lock.release();
282
+ if (!complete && existsSync(temporary))
283
+ unlinkSync(temporary);
202
284
  }
203
285
  if (existsSync(output))
204
286
  unlinkSync(output);
205
287
  renameSync(temporary, output);
206
288
  return inspectUomtiles(output);
207
289
  }
208
- export async function exportTiles(source, target, pmtilesCommand = process.env.UOMTILES_PMTILES_COMMAND || 'pmtiles') {
290
+ export async function exportTiles(source, target, options = {}) {
209
291
  const extension = extname(target).toLowerCase();
210
292
  if (extension === '.mbtiles') {
211
- exportMbtiles(source, target);
293
+ exportMbtiles(source, target, options);
212
294
  return;
213
295
  }
214
296
  if (extension !== '.pmtiles')
215
297
  throw new Error('输出文件必须使用 .mbtiles 或 .pmtiles 扩展名');
216
298
  const intermediate = `${resolve(target)}.${process.pid}.mbtiles`;
299
+ const pmtilesCommand = options.pmtilesCommand || process.env.UOMTILES_PMTILES_COMMAND || 'pmtiles';
217
300
  try {
218
- exportMbtiles(source, intermediate);
301
+ exportMbtiles(source, intermediate, options);
219
302
  await execFileAsync(pmtilesCommand, ['convert', intermediate, resolve(target), '--force', '--quiet'], { timeout: 30 * 60_000 });
220
303
  }
221
304
  catch (error) {