isard 1.5.0 → 1.7.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 (159) hide show
  1. package/CHANGELOG.md +213 -1
  2. package/README.md +3 -2
  3. package/dist/basemap/furniture.d.ts +26 -0
  4. package/dist/basemap/furniture.js +95 -0
  5. package/dist/basemap/furniture.js.map +1 -0
  6. package/dist/basemap/meshes.d.ts +21 -0
  7. package/dist/basemap/meshes.js +159 -0
  8. package/dist/basemap/meshes.js.map +1 -0
  9. package/dist/basemap/placed.d.ts +13 -0
  10. package/dist/basemap/placed.js +14 -0
  11. package/dist/basemap/placed.js.map +1 -0
  12. package/dist/basemap/trees.d.ts +25 -8
  13. package/dist/basemap/trees.js +77 -105
  14. package/dist/basemap/trees.js.map +1 -1
  15. package/dist/basemap/vectorstyle.d.ts +9 -3
  16. package/dist/basemap/vectorstyle.js +5 -6
  17. package/dist/basemap/vectorstyle.js.map +1 -1
  18. package/dist/basemap/vectortiles/context.d.ts +7 -2
  19. package/dist/basemap/vectortiles/context.js.map +1 -1
  20. package/dist/basemap/vectortiles/extrusions.d.ts +4 -0
  21. package/dist/basemap/vectortiles/extrusions.js +9 -3
  22. package/dist/basemap/vectortiles/extrusions.js.map +1 -1
  23. package/dist/basemap/vectortiles/furniture.d.ts +19 -0
  24. package/dist/basemap/vectortiles/furniture.js +29 -0
  25. package/dist/basemap/vectortiles/furniture.js.map +1 -0
  26. package/dist/basemap/vectortiles/labels.d.ts +3 -0
  27. package/dist/basemap/vectortiles/labels.js +50 -18
  28. package/dist/basemap/vectortiles/labels.js.map +1 -1
  29. package/dist/basemap/vectortiles/lamps.d.ts +23 -0
  30. package/dist/basemap/vectortiles/lamps.js +25 -0
  31. package/dist/basemap/vectortiles/lamps.js.map +1 -0
  32. package/dist/basemap/vectortiles/placed.d.ts +38 -0
  33. package/dist/basemap/vectortiles/placed.js +143 -0
  34. package/dist/basemap/vectortiles/placed.js.map +1 -0
  35. package/dist/basemap/vectortiles/requests.d.ts +4 -0
  36. package/dist/basemap/vectortiles/requests.js +15 -2
  37. package/dist/basemap/vectortiles/requests.js.map +1 -1
  38. package/dist/basemap/vectortiles/street-wind.js +4 -6
  39. package/dist/basemap/vectortiles/street-wind.js.map +1 -1
  40. package/dist/basemap/vectortiles/trees.d.ts +2 -0
  41. package/dist/basemap/vectortiles/trees.js +40 -86
  42. package/dist/basemap/vectortiles/trees.js.map +1 -1
  43. package/dist/basemap/vectortiles/vectors.d.ts +16 -0
  44. package/dist/basemap/vectortiles/vectors.js +76 -11
  45. package/dist/basemap/vectortiles/vectors.js.map +1 -1
  46. package/dist/basemap/vectortiles.d.ts +37 -7
  47. package/dist/basemap/vectortiles.js +78 -17
  48. package/dist/basemap/vectortiles.js.map +1 -1
  49. package/dist/basemap/wmts.js +2 -2
  50. package/dist/basemap/wmts.js.map +1 -1
  51. package/dist/basemap.worker.js +2 -2
  52. package/dist/basemap.worker.js.map +19 -13
  53. package/dist/bind/layers.js +1 -0
  54. package/dist/bind/layers.js.map +1 -1
  55. package/dist/data/collada.d.ts +19 -0
  56. package/dist/data/collada.js +305 -0
  57. package/dist/data/collada.js.map +1 -0
  58. package/dist/data/crs.js +1 -1
  59. package/dist/data/crs.js.map +1 -1
  60. package/dist/data/ifc.d.ts +100 -0
  61. package/dist/data/ifc.js +371 -0
  62. package/dist/data/ifc.js.map +1 -0
  63. package/dist/decoder.worker.js +5 -5
  64. package/dist/decoder.worker.js.map +3 -3
  65. package/dist/formats.d.ts +7 -2
  66. package/dist/formats.js +7 -2
  67. package/dist/formats.js.map +1 -1
  68. package/dist/geoplateforme.d.ts +14 -2
  69. package/dist/geoplateforme.js +24 -2
  70. package/dist/geoplateforme.js.map +1 -1
  71. package/dist/index.d.ts +11 -3
  72. package/dist/index.js +8 -3
  73. package/dist/index.js.map +1 -1
  74. package/dist/isard_bg.wasm +0 -0
  75. package/dist/isard_core_bg.wasm +0 -0
  76. package/dist/isard_grid_bg.wasm +0 -0
  77. package/dist/isard_tess_bg.wasm +0 -0
  78. package/dist/layers/extrusions.d.ts +10 -0
  79. package/dist/layers/extrusions.js +33 -6
  80. package/dist/layers/extrusions.js.map +1 -1
  81. package/dist/layers/features.d.ts +0 -2
  82. package/dist/layers/features.js +5 -6
  83. package/dist/layers/features.js.map +1 -1
  84. package/dist/layers/layers.d.ts +14 -0
  85. package/dist/layers/layers.js +55 -1
  86. package/dist/layers/layers.js.map +1 -1
  87. package/dist/layers/panoramas.d.ts +32 -10
  88. package/dist/layers/panoramas.js +55 -28
  89. package/dist/layers/panoramas.js.map +1 -1
  90. package/dist/layers/photos.d.ts +48 -0
  91. package/dist/layers/photos.js +139 -0
  92. package/dist/layers/photos.js.map +1 -0
  93. package/dist/layers/symbols.d.ts +5 -1
  94. package/dist/layers/symbols.js +111 -32
  95. package/dist/layers/symbols.js.map +1 -1
  96. package/dist/layers/trees.d.ts +28 -0
  97. package/dist/layers/trees.js +51 -0
  98. package/dist/layers/trees.js.map +1 -0
  99. package/dist/layers/vectors.d.ts +29 -2
  100. package/dist/layers/vectors.js +98 -9
  101. package/dist/layers/vectors.js.map +1 -1
  102. package/dist/map/frame-loop.d.ts +2 -0
  103. package/dist/map/frame-loop.js +3 -3
  104. package/dist/map/frame-loop.js.map +1 -1
  105. package/dist/map/layer-spec.d.ts +3 -0
  106. package/dist/map/layer-spec.js +2 -0
  107. package/dist/map/layer-spec.js.map +1 -1
  108. package/dist/map.d.ts +8 -0
  109. package/dist/map.js +32 -2
  110. package/dist/map.js.map +1 -1
  111. package/dist/panoramax.d.ts +55 -0
  112. package/dist/panoramax.js +97 -0
  113. package/dist/panoramax.js.map +1 -0
  114. package/dist/react/Layer.d.ts +1 -0
  115. package/dist/react/Layer.js.map +1 -1
  116. package/dist/react/VectorGeometry.d.ts +22 -8
  117. package/dist/react/VectorGeometry.js +36 -14
  118. package/dist/react/VectorGeometry.js.map +1 -1
  119. package/dist/react/VectorTiles.d.ts +65 -0
  120. package/dist/react/VectorTiles.js +112 -0
  121. package/dist/react/VectorTiles.js.map +1 -0
  122. package/dist/react/context.d.ts +9 -0
  123. package/dist/react/context.js +32 -0
  124. package/dist/react/context.js.map +1 -1
  125. package/dist/react/index.d.ts +7 -1
  126. package/dist/react/index.js +7 -1
  127. package/dist/react/index.js.map +1 -1
  128. package/dist/types.d.ts +2 -0
  129. package/dist/types.js.map +1 -1
  130. package/dist/util/geo.d.ts +8 -0
  131. package/dist/util/geo.js +8 -0
  132. package/dist/util/geo.js.map +1 -1
  133. package/dist/util/gltf.d.ts +26 -0
  134. package/dist/util/gltf.js +52 -0
  135. package/dist/util/gltf.js.map +1 -0
  136. package/dist/util/roofs.d.ts +18 -0
  137. package/dist/util/roofs.js +44 -0
  138. package/dist/util/roofs.js.map +1 -0
  139. package/dist/util/style-floats.d.ts +33 -0
  140. package/dist/util/style-floats.js +34 -0
  141. package/dist/util/style-floats.js.map +1 -0
  142. package/dist/util/sun.js +1 -1
  143. package/dist/util/sun.js.map +1 -1
  144. package/dist/wasm/isard.d.ts +56 -17
  145. package/dist/wasm/isard.js +128 -18
  146. package/dist/wasm/isard_core.d.ts +44 -17
  147. package/dist/wasm/isard_core.js +104 -18
  148. package/dist/wasm/isard_tess.d.ts +6 -3
  149. package/dist/wasm/isard_tess.js +27 -4
  150. package/dist/workers/basemap/furniture.d.ts +13 -0
  151. package/dist/workers/basemap/geometry.d.ts +35 -22
  152. package/dist/workers/basemap/labels.d.ts +18 -2
  153. package/dist/workers/basemap/lamps.d.ts +10 -0
  154. package/dist/workers/basemap/tiles.d.ts +2 -0
  155. package/dist/workers/basemap/trees.d.ts +6 -1
  156. package/dist/workers/basemap.worker.d.ts +58 -2
  157. package/dist/workers/basemap.worker.js +26 -3
  158. package/dist/workers/basemap.worker.js.map +1 -1
  159. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"crs.js","sourceRoot":"","sources":["../../src/data/crs.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Coordinate reference systems of the data: a CRS turns longitudes and latitudes (degrees) into its coordinates\n * (`forward`) and back (`inverse`). The map stays in Web Mercator (or the globe): data in another CRS is reprojected\n * into it, as rasters (see `TileGrid`) or as GeoJSON (`reproject`).\n *\n * Built in, exact to the millimetre against PROJ: EPSG:4326 (and the geographic ETRS89, RGF93), EPSG:3857, Lambert-93\n * (EPSG:2154), the nine conic zones CC42 to CC50 (EPSG:3942 to 3950), the UTM zones of WGS 84 (EPSG:32601 to 32660\n * north, 32701 to 32760 south) and of ETRS89 (EPSG:25828 to 25838). WGS 84, ETRS89 and RGF93 are taken as one datum:\n * they differ by less than a metre. Any other CRS is plugged in as an object with `forward` and `inverse`, such as\n * `proj4('EPSG:27572')`, directly or by name through `registerCrs`.\n */\nimport type { Feature, FeatureCollection, FeatureData, Geometry, Position } from '../layers/features.ts';\nimport { isRecord } from '../util/guards.ts';\n\n/** A CRS: longitudes and latitudes (degrees) to its coordinates (x east, y north), and back. A converter of proj4\n * (`proj4('EPSG:2154')`) is one */\nexport interface Crs {\n forward(lonLat: [number, number]): readonly number[];\n inverse(xy: [number, number]): readonly number[];\n}\n\n/** A CRS by name (`'EPSG:2154'`, `'urn:ogc:def:crs:EPSG::2154'`, `'CRS:84'`…; built in or registered), or itself */\nexport type CrsLike = string | Crs;\n\n/** An ellipsoid: semi-major axis (metres) and flattening */\ntype Ellipsoid = [a: number, f: number];\nconst GRS80: Ellipsoid = [6378137, 1 / 298.257222101];\nconst WGS84: Ellipsoid = [6378137, 1 / 298.257223563];\n\nconst RAD = Math.PI / 180;\n\n/** Isometric latitude of a latitude (radians) on an ellipsoid of eccentricity `e` */\nconst isometric = (phi: number, e: number) => Math.atanh(Math.sin(phi)) - e * Math.atanh(e * Math.sin(phi));\n\n/** Latitude (radians) of an isometric latitude, by fixed-point iteration (converges by e² at each step) */\nconst fromIsometric = (psi: number, e: number): number => {\n let phi = Math.asin(Math.tanh(psi));\n\n for (let i = 0; i < 20; i += 1) {\n const next = Math.asin(Math.tanh(psi + e * Math.atanh(e * Math.sin(phi))));\n\n if (Math.abs(next - phi) < 1e-15) return next;\n phi = next;\n }\n\n return phi;\n};\n\n/** An angle (radians) brought into [-π, π] */\nconst wrap = (angle: number) => angle - 2 * Math.PI * Math.round(angle / (2 * Math.PI));\n\n/**\n * Lambert Conformal Conic with two standard parallels (EPSG method 9802), angles in degrees: the projection of\n * Lambert-93 and of the CC zones, and of many national grids\n */\nexport const lambertConformalConic = (p: {\n /** Semi-major axis (metres) and flattening (default GRS80) */\n ellipsoid?: [a: number, f: number];\n lat0: number;\n lon0: number;\n lat1: number;\n lat2: number;\n x0: number;\n y0: number;\n}): Crs => {\n const [a, f] = p.ellipsoid ?? GRS80;\n const e = Math.sqrt(f * (2 - f));\n const m = (phi: number) => Math.cos(phi) / Math.sqrt(1 - (e * Math.sin(phi)) ** 2);\n const [phi1, phi2] = [p.lat1 * RAD, p.lat2 * RAD];\n const n =\n phi1 === phi2\n ? Math.sin(phi1)\n : (Math.log(m(phi1)) - Math.log(m(phi2))) / (isometric(phi2, e) - isometric(phi1, e));\n const aF = (a * m(phi1) * Math.exp(n * isometric(phi1, e))) / n;\n const r0 = aF * Math.exp(-n * isometric(p.lat0 * RAD, e));\n const lon0 = p.lon0 * RAD;\n\n return {\n forward: ([lon, lat]) => {\n const r = aF * Math.exp(-n * isometric(lat * RAD, e));\n const theta = n * wrap(lon * RAD - lon0);\n\n return [p.x0 + r * Math.sin(theta), p.y0 + r0 - r * Math.cos(theta)];\n },\n inverse: ([x, y]) => {\n const s = Math.sign(n);\n const [dx, dy] = [x - p.x0, r0 - (y - p.y0)];\n const r = s * Math.hypot(dx, dy);\n const theta = Math.atan2(s * dx, s * dy);\n\n return [(theta / n + lon0) / RAD, fromIsometric(-Math.log(r / aF) / n, e) / RAD];\n },\n };\n};\n\n/**\n * Transverse Mercator (EPSG method 9807) by Krüger's series to the sixth order (Karney, 2011), angles in degrees:\n * exact to the tenth of a millimetre within 4000 km of the central meridian. The projection of the UTM zones\n */\nexport const transverseMercator = (p: {\n /** Semi-major axis (metres) and flattening (default GRS80) */\n ellipsoid?: [a: number, f: number];\n lon0: number;\n /** Scale on the central meridian */\n k0: number;\n x0: number;\n y0: number;\n}): Crs => {\n const [a, f] = p.ellipsoid ?? GRS80;\n const e = Math.sqrt(f * (2 - f));\n const n = f / (2 - f);\n const [n2, n3, n4, n5, n6] = [n ** 2, n ** 3, n ** 4, n ** 5, n ** 6];\n const kA = (p.k0 * a * (1 + n2 / 4 + n4 / 64 + n6 / 256)) / (1 + n);\n const alpha = [\n n / 2 - (2 * n2) / 3 + (5 * n3) / 16 + (41 * n4) / 180 - (127 * n5) / 288 + (7891 * n6) / 37800,\n (13 * n2) / 48 - (3 * n3) / 5 + (557 * n4) / 1440 + (281 * n5) / 630 - (1983433 * n6) / 1935360,\n (61 * n3) / 240 - (103 * n4) / 140 + (15061 * n5) / 26880 + (167603 * n6) / 181440,\n (49561 * n4) / 161280 - (179 * n5) / 168 + (6601661 * n6) / 7257600,\n (34729 * n5) / 80640 - (3418889 * n6) / 1995840,\n (212378941 * n6) / 319334400,\n ];\n const beta = [\n n / 2 - (2 * n2) / 3 + (37 * n3) / 96 - n4 / 360 - (81 * n5) / 512 + (96199 * n6) / 604800,\n n2 / 48 + n3 / 15 - (437 * n4) / 1440 + (46 * n5) / 105 - (1118711 * n6) / 3870720,\n (17 * n3) / 480 - (37 * n4) / 840 - (209 * n5) / 4480 + (5569 * n6) / 90720,\n (4397 * n4) / 161280 - (11 * n5) / 504 - (830251 * n6) / 7257600,\n (4583 * n5) / 161280 - (108847 * n6) / 3991680,\n (20648693 * n6) / 638668800,\n ];\n /** ξ, η moved by the series of coefficients `c`, added (forward) or subtracted (inverse) */\n const series = (xi: number, eta: number, c: number[], sign: number): [number, number] => {\n let [x, y] = [xi, eta];\n\n c.forEach((k, j) => {\n const w = 2 * (j + 1);\n\n x += sign * k * Math.sin(w * xi) * Math.cosh(w * eta);\n y += sign * k * Math.cos(w * xi) * Math.sinh(w * eta);\n });\n\n return [x, y];\n };\n const lon0 = p.lon0 * RAD;\n\n return {\n forward: ([lon, lat]) => {\n const lambda = wrap(lon * RAD - lon0);\n // The conformal latitude's tangent\n const t = Math.sinh(isometric(lat * RAD, e));\n const [xi, eta] = series(\n Math.atan2(t, Math.cos(lambda)),\n Math.asinh(Math.sin(lambda) / Math.hypot(t, Math.cos(lambda))),\n alpha,\n 1,\n );\n\n return [p.x0 + kA * eta, p.y0 + kA * xi];\n },\n inverse: ([x, y]) => {\n const [xi, eta] = series((y - p.y0) / kA, (x - p.x0) / kA, beta, -1);\n const t = Math.sin(xi) / Math.hypot(Math.sinh(eta), Math.cos(xi));\n\n return [(lon0 + Math.atan2(Math.sinh(eta), Math.cos(xi))) / RAD, fromIsometric(Math.asinh(t), e) / RAD];\n },\n };\n};\n\n/** Longitudes and latitudes themselves */\nconst GEOGRAPHIC: Crs = {\n forward: ([lon, lat]) => [lon, lat],\n inverse: ([x, y]) => [x, y],\n};\n\n/** Web Mercator in metres (EPSG:3857) */\nconst R = 6378137;\nconst WEB_MERCATOR: Crs = {\n forward: ([lon, lat]) => [R * lon * RAD, R * Math.log(Math.tan(Math.PI / 4 + (lat * RAD) / 2))],\n inverse: ([x, y]) => [x / R / RAD, (2 * Math.atan(Math.exp(y / R)) - Math.PI / 2) / RAD],\n};\n\n/** The CRSs registered by the application, by name */\nconst registered = new Map<string, Crs>();\n/** The built-in CRSs made so far, by EPSG code */\nconst made = new Map<number, Crs>();\n\n/**\n * The EPSG code of a CRS name: `EPSG:2154`, `urn:ogc:def:crs:EPSG::2154`, `urn:ogc:def:crs:EPSG:6.3:2154`,\n * `http://www.opengis.net/def/crs/EPSG/0/2154`; `CRS:84`, `OGC:CRS84` and the IGN's `IGNF:WGS84G` are 4326, its\n * `IGNF:LAMB93` 2154, the old names of Web Mercator 3857. Undefined for another name\n */\nexport const epsgCode = (name: string): number | undefined => {\n const n = name.trim().toUpperCase();\n\n if (/CRS:?84$/.test(n) || n === 'IGNF:WGS84G') return 4326;\n if (n === 'IGNF:LAMB93') return 2154;\n\n const code = /EPSG(?::+|\\/)(?:[\\d.]+[:/]+)?(\\d+)$/.exec(n)?.[1];\n\n if (code === undefined) return undefined;\n\n const c = Number(code);\n\n return c === 900913 || c === 3785 || c === 102100 || c === 102113 ? 3857 : c;\n};\n\n/** A built-in CRS by EPSG code; undefined if not built in */\nconst builtin = (code: number): Crs | undefined => {\n if (code === 4326 || code === 4258 || code === 4171) return GEOGRAPHIC;\n if (code === 3857) return WEB_MERCATOR;\n if (code === 2154) {\n return lambertConformalConic({ lat0: 46.5, lon0: 3, lat1: 49, lat2: 44, x0: 700000, y0: 6600000 });\n }\n if (code >= 3942 && code <= 3950) {\n const lat0 = code - 3900;\n const y0 = (lat0 - 41) * 1000000 + 200000;\n\n return lambertConformalConic({ lat0, lon0: 3, lat1: lat0 - 0.75, lat2: lat0 + 0.75, x0: 1700000, y0 });\n }\n\n const utm = (zone: number, south: boolean, ellipsoid: Ellipsoid) =>\n transverseMercator({ ellipsoid, lon0: zone * 6 - 183, k0: 0.9996, x0: 500000, y0: south ? 10000000 : 0 });\n\n if (code >= 32601 && code <= 32660) return utm(code - 32600, false, WGS84);\n if (code >= 32701 && code <= 32760) return utm(code - 32700, true, WGS84);\n if (code >= 25828 && code <= 25838) return utm(code - 25800, false, GRS80);\n\n return undefined;\n};\n\n/** Whether a CRS name is longitudes and latitudes (needs no reprojection) */\nexport const isGeographic = (name: string): boolean => {\n const code = epsgCode(name);\n\n return !registered.has(normalize(name)) && code !== undefined && builtin(code) === GEOGRAPHIC;\n};\n\nconst normalize = (name: string) => {\n const code = epsgCode(name);\n\n return code === undefined ? name.trim().toUpperCase() : `EPSG:${code}`;\n};\n\n/**\n * Names a CRS for every place that takes one (`registerCrs('EPSG:27572', proj4('EPSG:27572'))`): the `crs` of a tile\n * grid, the `crs` member of GeoJSON, `reproject`. A registered name wins over a built-in one\n */\nexport const registerCrs = (name: string, crs: Crs): void => {\n registered.set(normalize(name), crs);\n};\n\n/** The CRS of a name (registered or built in), or the CRS given; throws for an unknown name */\nexport const getCrs = (crs: CrsLike): Crs => {\n if (typeof crs !== 'string') return crs;\n\n const found = registered.get(normalize(crs));\n\n if (found) return found;\n\n const code = epsgCode(crs);\n\n if (code !== undefined) {\n const c = made.get(code) ?? builtin(code);\n\n if (c) {\n made.set(code, c);\n\n return c;\n }\n }\n throw new Error(`isard: unknown CRS ${crs}: registerCrs('${crs}', proj4('${crs}')) names it`);\n};\n\n/** The name in the legacy `crs` member of GeoJSON (`{ type: 'name', properties: { name } }`), if any */\nexport const crsOf = (data: unknown): string | undefined => {\n const member = isRecord(data) ? data.crs : undefined;\n const properties = isRecord(member) ? member.properties : undefined;\n const name = isRecord(properties) ? properties.name : undefined;\n\n return typeof name === 'string' ? name : undefined;\n};\n\n/** A geometry with its positions mapped */\nconst mapGeometry = (g: Geometry, f: (p: Position) => Position): Geometry => {\n switch (g.type) {\n case 'Point':\n return { type: g.type, coordinates: f(g.coordinates) };\n case 'MultiPoint':\n case 'LineString':\n return { type: g.type, coordinates: g.coordinates.map(f) };\n case 'MultiLineString':\n case 'Polygon':\n return { type: g.type, coordinates: g.coordinates.map((line) => line.map(f)) };\n case 'MultiPolygon':\n return { type: g.type, coordinates: g.coordinates.map((poly) => poly.map((line) => line.map(f))) };\n case 'GeometryCollection':\n return { type: g.type, geometries: g.geometries.map((child) => mapGeometry(child, f)) };\n }\n};\n\n/**\n * GeoJSON in `from` (default: the CRS its `crs` member names) as GeoJSON in longitudes and latitudes, for the feature\n * layers: `map.addFills({ data: reproject(parcels, 'EPSG:2154') })`. The features are copied with new geometries, their\n * properties shared; altitudes are kept. Data without a CRS, or in longitudes and latitudes, comes back as it is.\n * The feature layers do this by themselves for a collection whose `crs` member names its CRS (a WFS's output in\n * EPSG:2154)\n */\nexport const reproject = <P>(data: FeatureData<P>, from?: CrsLike): FeatureCollection<P> => {\n const featuresOf = (): Feature<P>[] => {\n if (Array.isArray(data)) return data;\n if (data.type === 'FeatureCollection') return data.features;\n\n return [data];\n };\n const features = featuresOf();\n const source = from ?? crsOf(data);\n\n if (source === undefined || (typeof source === 'string' && isGeographic(source))) {\n return { type: 'FeatureCollection', features };\n }\n\n const crs = getCrs(source);\n const f = (p: Position): Position => {\n const [lon, lat] = crs.inverse([p[0], p[1]]);\n\n return [lon ?? Number.NaN, lat ?? Number.NaN, ...p.slice(2)];\n };\n\n return {\n type: 'FeatureCollection',\n features: features.map(\n (feature): Feature<P> => ({\n ...feature,\n geometry: feature.geometry && mapGeometry(feature.geometry, f),\n }),\n ),\n };\n};\n"]}
1
+ {"version":3,"file":"crs.js","sourceRoot":"","sources":["../../src/data/crs.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Coordinate reference systems of the data: a CRS turns longitudes and latitudes (degrees) into its coordinates\n * (`forward`) and back (`inverse`). The map stays in Web Mercator (or the globe): data in another CRS is reprojected\n * into it, as rasters (see `TileGrid`) or as GeoJSON (`reproject`).\n *\n * Built in, exact to the millimetre against PROJ: EPSG:4326 (and the geographic ETRS89, RGF93), EPSG:3857, Lambert-93\n * (EPSG:2154), the nine conic zones CC42 to CC50 (EPSG:3942 to 3950), the UTM zones of WGS 84 (EPSG:32601 to 32660\n * north, 32701 to 32760 south) and of ETRS89 (EPSG:25828 to 25838). WGS 84, ETRS89 and RGF93 are taken as one datum:\n * they differ by less than a metre. Any other CRS is plugged in as an object with `forward` and `inverse`, such as\n * `proj4('EPSG:27572')`, directly or by name through `registerCrs`.\n */\nimport type { Feature, FeatureCollection, FeatureData, Geometry, Position } from '../layers/features.ts';\nimport { RAD } from '../util/geo.ts';\nimport { isRecord } from '../util/guards.ts';\n\n/** A CRS: longitudes and latitudes (degrees) to its coordinates (x east, y north), and back. A converter of proj4\n * (`proj4('EPSG:2154')`) is one */\nexport interface Crs {\n forward(lonLat: [number, number]): readonly number[];\n inverse(xy: [number, number]): readonly number[];\n}\n\n/** A CRS by name (`'EPSG:2154'`, `'urn:ogc:def:crs:EPSG::2154'`, `'CRS:84'`…; built in or registered), or itself */\nexport type CrsLike = string | Crs;\n\n/** An ellipsoid: semi-major axis (metres) and flattening */\ntype Ellipsoid = [a: number, f: number];\nconst GRS80: Ellipsoid = [6378137, 1 / 298.257222101];\nconst WGS84: Ellipsoid = [6378137, 1 / 298.257223563];\n\n/** Isometric latitude of a latitude (radians) on an ellipsoid of eccentricity `e` */\nconst isometric = (phi: number, e: number) => Math.atanh(Math.sin(phi)) - e * Math.atanh(e * Math.sin(phi));\n\n/** Latitude (radians) of an isometric latitude, by fixed-point iteration (converges by e² at each step) */\nconst fromIsometric = (psi: number, e: number): number => {\n let phi = Math.asin(Math.tanh(psi));\n\n for (let i = 0; i < 20; i += 1) {\n const next = Math.asin(Math.tanh(psi + e * Math.atanh(e * Math.sin(phi))));\n\n if (Math.abs(next - phi) < 1e-15) return next;\n phi = next;\n }\n\n return phi;\n};\n\n/** An angle (radians) brought into [-π, π] */\nconst wrap = (angle: number) => angle - 2 * Math.PI * Math.round(angle / (2 * Math.PI));\n\n/**\n * Lambert Conformal Conic with two standard parallels (EPSG method 9802), angles in degrees: the projection of\n * Lambert-93 and of the CC zones, and of many national grids\n */\nexport const lambertConformalConic = (p: {\n /** Semi-major axis (metres) and flattening (default GRS80) */\n ellipsoid?: [a: number, f: number];\n lat0: number;\n lon0: number;\n lat1: number;\n lat2: number;\n x0: number;\n y0: number;\n}): Crs => {\n const [a, f] = p.ellipsoid ?? GRS80;\n const e = Math.sqrt(f * (2 - f));\n const m = (phi: number) => Math.cos(phi) / Math.sqrt(1 - (e * Math.sin(phi)) ** 2);\n const [phi1, phi2] = [p.lat1 * RAD, p.lat2 * RAD];\n const n =\n phi1 === phi2\n ? Math.sin(phi1)\n : (Math.log(m(phi1)) - Math.log(m(phi2))) / (isometric(phi2, e) - isometric(phi1, e));\n const aF = (a * m(phi1) * Math.exp(n * isometric(phi1, e))) / n;\n const r0 = aF * Math.exp(-n * isometric(p.lat0 * RAD, e));\n const lon0 = p.lon0 * RAD;\n\n return {\n forward: ([lon, lat]) => {\n const r = aF * Math.exp(-n * isometric(lat * RAD, e));\n const theta = n * wrap(lon * RAD - lon0);\n\n return [p.x0 + r * Math.sin(theta), p.y0 + r0 - r * Math.cos(theta)];\n },\n inverse: ([x, y]) => {\n const s = Math.sign(n);\n const [dx, dy] = [x - p.x0, r0 - (y - p.y0)];\n const r = s * Math.hypot(dx, dy);\n const theta = Math.atan2(s * dx, s * dy);\n\n return [(theta / n + lon0) / RAD, fromIsometric(-Math.log(r / aF) / n, e) / RAD];\n },\n };\n};\n\n/**\n * Transverse Mercator (EPSG method 9807) by Krüger's series to the sixth order (Karney, 2011), angles in degrees:\n * exact to the tenth of a millimetre within 4000 km of the central meridian. The projection of the UTM zones\n */\nexport const transverseMercator = (p: {\n /** Semi-major axis (metres) and flattening (default GRS80) */\n ellipsoid?: [a: number, f: number];\n lon0: number;\n /** Scale on the central meridian */\n k0: number;\n x0: number;\n y0: number;\n}): Crs => {\n const [a, f] = p.ellipsoid ?? GRS80;\n const e = Math.sqrt(f * (2 - f));\n const n = f / (2 - f);\n const [n2, n3, n4, n5, n6] = [n ** 2, n ** 3, n ** 4, n ** 5, n ** 6];\n const kA = (p.k0 * a * (1 + n2 / 4 + n4 / 64 + n6 / 256)) / (1 + n);\n const alpha = [\n n / 2 - (2 * n2) / 3 + (5 * n3) / 16 + (41 * n4) / 180 - (127 * n5) / 288 + (7891 * n6) / 37800,\n (13 * n2) / 48 - (3 * n3) / 5 + (557 * n4) / 1440 + (281 * n5) / 630 - (1983433 * n6) / 1935360,\n (61 * n3) / 240 - (103 * n4) / 140 + (15061 * n5) / 26880 + (167603 * n6) / 181440,\n (49561 * n4) / 161280 - (179 * n5) / 168 + (6601661 * n6) / 7257600,\n (34729 * n5) / 80640 - (3418889 * n6) / 1995840,\n (212378941 * n6) / 319334400,\n ];\n const beta = [\n n / 2 - (2 * n2) / 3 + (37 * n3) / 96 - n4 / 360 - (81 * n5) / 512 + (96199 * n6) / 604800,\n n2 / 48 + n3 / 15 - (437 * n4) / 1440 + (46 * n5) / 105 - (1118711 * n6) / 3870720,\n (17 * n3) / 480 - (37 * n4) / 840 - (209 * n5) / 4480 + (5569 * n6) / 90720,\n (4397 * n4) / 161280 - (11 * n5) / 504 - (830251 * n6) / 7257600,\n (4583 * n5) / 161280 - (108847 * n6) / 3991680,\n (20648693 * n6) / 638668800,\n ];\n /** ξ, η moved by the series of coefficients `c`, added (forward) or subtracted (inverse) */\n const series = (xi: number, eta: number, c: number[], sign: number): [number, number] => {\n let [x, y] = [xi, eta];\n\n c.forEach((k, j) => {\n const w = 2 * (j + 1);\n\n x += sign * k * Math.sin(w * xi) * Math.cosh(w * eta);\n y += sign * k * Math.cos(w * xi) * Math.sinh(w * eta);\n });\n\n return [x, y];\n };\n const lon0 = p.lon0 * RAD;\n\n return {\n forward: ([lon, lat]) => {\n const lambda = wrap(lon * RAD - lon0);\n // The conformal latitude's tangent\n const t = Math.sinh(isometric(lat * RAD, e));\n const [xi, eta] = series(\n Math.atan2(t, Math.cos(lambda)),\n Math.asinh(Math.sin(lambda) / Math.hypot(t, Math.cos(lambda))),\n alpha,\n 1,\n );\n\n return [p.x0 + kA * eta, p.y0 + kA * xi];\n },\n inverse: ([x, y]) => {\n const [xi, eta] = series((y - p.y0) / kA, (x - p.x0) / kA, beta, -1);\n const t = Math.sin(xi) / Math.hypot(Math.sinh(eta), Math.cos(xi));\n\n return [(lon0 + Math.atan2(Math.sinh(eta), Math.cos(xi))) / RAD, fromIsometric(Math.asinh(t), e) / RAD];\n },\n };\n};\n\n/** Longitudes and latitudes themselves */\nconst GEOGRAPHIC: Crs = {\n forward: ([lon, lat]) => [lon, lat],\n inverse: ([x, y]) => [x, y],\n};\n\n/** Web Mercator in metres (EPSG:3857) */\nconst R = 6378137;\nconst WEB_MERCATOR: Crs = {\n forward: ([lon, lat]) => [R * lon * RAD, R * Math.log(Math.tan(Math.PI / 4 + (lat * RAD) / 2))],\n inverse: ([x, y]) => [x / R / RAD, (2 * Math.atan(Math.exp(y / R)) - Math.PI / 2) / RAD],\n};\n\n/** The CRSs registered by the application, by name */\nconst registered = new Map<string, Crs>();\n/** The built-in CRSs made so far, by EPSG code */\nconst made = new Map<number, Crs>();\n\n/**\n * The EPSG code of a CRS name: `EPSG:2154`, `urn:ogc:def:crs:EPSG::2154`, `urn:ogc:def:crs:EPSG:6.3:2154`,\n * `http://www.opengis.net/def/crs/EPSG/0/2154`; `CRS:84`, `OGC:CRS84` and the IGN's `IGNF:WGS84G` are 4326, its\n * `IGNF:LAMB93` 2154, the old names of Web Mercator 3857. Undefined for another name\n */\nexport const epsgCode = (name: string): number | undefined => {\n const n = name.trim().toUpperCase();\n\n if (/CRS:?84$/.test(n) || n === 'IGNF:WGS84G') return 4326;\n if (n === 'IGNF:LAMB93') return 2154;\n\n const code = /EPSG(?::+|\\/)(?:[\\d.]+[:/]+)?(\\d+)$/.exec(n)?.[1];\n\n if (code === undefined) return undefined;\n\n const c = Number(code);\n\n return c === 900913 || c === 3785 || c === 102100 || c === 102113 ? 3857 : c;\n};\n\n/** A built-in CRS by EPSG code; undefined if not built in */\nconst builtin = (code: number): Crs | undefined => {\n if (code === 4326 || code === 4258 || code === 4171) return GEOGRAPHIC;\n if (code === 3857) return WEB_MERCATOR;\n if (code === 2154) {\n return lambertConformalConic({ lat0: 46.5, lon0: 3, lat1: 49, lat2: 44, x0: 700000, y0: 6600000 });\n }\n if (code >= 3942 && code <= 3950) {\n const lat0 = code - 3900;\n const y0 = (lat0 - 41) * 1000000 + 200000;\n\n return lambertConformalConic({ lat0, lon0: 3, lat1: lat0 - 0.75, lat2: lat0 + 0.75, x0: 1700000, y0 });\n }\n\n const utm = (zone: number, south: boolean, ellipsoid: Ellipsoid) =>\n transverseMercator({ ellipsoid, lon0: zone * 6 - 183, k0: 0.9996, x0: 500000, y0: south ? 10000000 : 0 });\n\n if (code >= 32601 && code <= 32660) return utm(code - 32600, false, WGS84);\n if (code >= 32701 && code <= 32760) return utm(code - 32700, true, WGS84);\n if (code >= 25828 && code <= 25838) return utm(code - 25800, false, GRS80);\n\n return undefined;\n};\n\n/** Whether a CRS name is longitudes and latitudes (needs no reprojection) */\nexport const isGeographic = (name: string): boolean => {\n const code = epsgCode(name);\n\n return !registered.has(normalize(name)) && code !== undefined && builtin(code) === GEOGRAPHIC;\n};\n\nconst normalize = (name: string) => {\n const code = epsgCode(name);\n\n return code === undefined ? name.trim().toUpperCase() : `EPSG:${code}`;\n};\n\n/**\n * Names a CRS for every place that takes one (`registerCrs('EPSG:27572', proj4('EPSG:27572'))`): the `crs` of a tile\n * grid, the `crs` member of GeoJSON, `reproject`. A registered name wins over a built-in one\n */\nexport const registerCrs = (name: string, crs: Crs): void => {\n registered.set(normalize(name), crs);\n};\n\n/** The CRS of a name (registered or built in), or the CRS given; throws for an unknown name */\nexport const getCrs = (crs: CrsLike): Crs => {\n if (typeof crs !== 'string') return crs;\n\n const found = registered.get(normalize(crs));\n\n if (found) return found;\n\n const code = epsgCode(crs);\n\n if (code !== undefined) {\n const c = made.get(code) ?? builtin(code);\n\n if (c) {\n made.set(code, c);\n\n return c;\n }\n }\n throw new Error(`isard: unknown CRS ${crs}: registerCrs('${crs}', proj4('${crs}')) names it`);\n};\n\n/** The name in the legacy `crs` member of GeoJSON (`{ type: 'name', properties: { name } }`), if any */\nexport const crsOf = (data: unknown): string | undefined => {\n const member = isRecord(data) ? data.crs : undefined;\n const properties = isRecord(member) ? member.properties : undefined;\n const name = isRecord(properties) ? properties.name : undefined;\n\n return typeof name === 'string' ? name : undefined;\n};\n\n/** A geometry with its positions mapped */\nconst mapGeometry = (g: Geometry, f: (p: Position) => Position): Geometry => {\n switch (g.type) {\n case 'Point':\n return { type: g.type, coordinates: f(g.coordinates) };\n case 'MultiPoint':\n case 'LineString':\n return { type: g.type, coordinates: g.coordinates.map(f) };\n case 'MultiLineString':\n case 'Polygon':\n return { type: g.type, coordinates: g.coordinates.map((line) => line.map(f)) };\n case 'MultiPolygon':\n return { type: g.type, coordinates: g.coordinates.map((poly) => poly.map((line) => line.map(f))) };\n case 'GeometryCollection':\n return { type: g.type, geometries: g.geometries.map((child) => mapGeometry(child, f)) };\n }\n};\n\n/**\n * GeoJSON in `from` (default: the CRS its `crs` member names) as GeoJSON in longitudes and latitudes, for the feature\n * layers: `map.addFills({ data: reproject(parcels, 'EPSG:2154') })`. The features are copied with new geometries, their\n * properties shared; altitudes are kept. Data without a CRS, or in longitudes and latitudes, comes back as it is.\n * The feature layers do this by themselves for a collection whose `crs` member names its CRS (a WFS's output in\n * EPSG:2154)\n */\nexport const reproject = <P>(data: FeatureData<P>, from?: CrsLike): FeatureCollection<P> => {\n const featuresOf = (): Feature<P>[] => {\n if (Array.isArray(data)) return data;\n if (data.type === 'FeatureCollection') return data.features;\n\n return [data];\n };\n const features = featuresOf();\n const source = from ?? crsOf(data);\n\n if (source === undefined || (typeof source === 'string' && isGeographic(source))) {\n return { type: 'FeatureCollection', features };\n }\n\n const crs = getCrs(source);\n const f = (p: Position): Position => {\n const [lon, lat] = crs.inverse([p[0], p[1]]);\n\n return [lon ?? Number.NaN, lat ?? Number.NaN, ...p.slice(2)];\n };\n\n return {\n type: 'FeatureCollection',\n features: features.map(\n (feature): Feature<P> => ({\n ...feature,\n geometry: feature.geometry && mapGeometry(feature.geometry, f),\n }),\n ),\n };\n};\n"]}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * IFC models (the BIM tools' own format: Revit, ArchiCAD, Tekla, Allplan, Bonsai…) read by web-ifc (ThatOpen,
3
+ * MPL-2.0) in a worker of their own, web-ifc fetched on first use from a CDN (or a folder of yours): the model's
4
+ * storeys and elements at once, each storey's geometry when asked (a glTF binary for `map.addModels({ data })`, each
5
+ * element a feature of it, picked by the map: `hit.index` is the element's), the elements' properties on demand, and
6
+ * where the model stands (its map conversion in a projected CRS, else its site's latitude and longitude).
7
+ */
8
+ /** web-ifc's build used by default: its module (`web-ifc-api.js`) and its WebAssembly (`web-ifc.wasm`) */
9
+ export declare const WEB_IFC = "https://cdn.jsdelivr.net/npm/web-ifc@0.0.78/";
10
+ export interface IfcOptions {
11
+ /** Folder of `web-ifc-api.js` and `web-ifc.wasm` (ending with `/`; `WEB_IFC` by default): self-host them for offline
12
+ * or locked-down networks. The worker imports the module from a `blob:` URL: a Content Security Policy needs
13
+ * `blob:` in `worker-src` */
14
+ webIfc?: string;
15
+ /** Request options of the file's fetch (headers of a private source) */
16
+ init?: RequestInit;
17
+ }
18
+ /** An element of the model (a wall, a slab, a window, a stair…) */
19
+ export interface IfcElement {
20
+ /** Its IFC id (STEP line number) */
21
+ id: number;
22
+ /** Its IFC class (`IfcWall`, `IfcSlab`, `IfcWindow`…) */
23
+ type: string;
24
+ name: string;
25
+ /** Its storey in `IfcModel.storeys` */
26
+ storey: number;
27
+ }
28
+ /** A storey of the model: its elements, its geometry when asked */
29
+ export interface IfcStorey {
30
+ id: number;
31
+ name: string;
32
+ /** Metres above the model's origin */
33
+ elevation: number;
34
+ /** Its elements (`IfcModel.elements`' indices) */
35
+ elements: number[];
36
+ /**
37
+ * Its elements' geometry as a glTF binary (their features: `IfcModel.elements`' indices) in the model's frame: y up,
38
+ * its north toward +z (`IfcModel.place.heading` turns it), its origin at the model's; meshed in the worker on the
39
+ * first call (a large model's storeys one at a time, those in view only)
40
+ */
41
+ load(): Promise<Uint8Array<ArrayBuffer>>;
42
+ }
43
+ /** An element's properties: its attributes, then its property and quantity sets, by name */
44
+ export type IfcProperties = Record<string, Record<string, string | number | boolean | null>>;
45
+ /** Where a model stands: its origin's position and height, the way its north faces */
46
+ export interface IfcPlace {
47
+ lonLat: [number, number];
48
+ /** Metres above the sea (its map conversion's height, its site's `RefElevation`) */
49
+ elevation: number;
50
+ /** Degrees clockwise from the north of the model's north (an instance's `heading`) */
51
+ heading: number;
52
+ /** How it is known: its map conversion (exact, `crs` its projected CRS), or its site's latitude and longitude */
53
+ from: 'map' | 'site';
54
+ crs?: string;
55
+ }
56
+ export interface IfcModel {
57
+ /** Its storeys from the lowest up, elements outside any storey (the site's) in one of their own at the start */
58
+ storeys: IfcStorey[];
59
+ /** Its elements, the features of the storeys' models */
60
+ elements: IfcElement[];
61
+ /** Where it stands, if the file says (`IfcMapConversion` in a CRS isard knows, else `IfcSite`'s position) */
62
+ place?: IfcPlace;
63
+ /** An element's properties, read from the file kept open in the worker */
64
+ properties(element: number): Promise<IfcProperties>;
65
+ /** Closes the file and its worker */
66
+ close(): void;
67
+ }
68
+ /** A part of the model: an element's geometry in one color */
69
+ interface Part {
70
+ feature: number;
71
+ color: [number, number, number, number];
72
+ positions: Float32Array;
73
+ indices: Uint32Array;
74
+ }
75
+ /** A storey's parts as a glTF binary: a primitive per color, each vertex its element (`_BATCHID`) */
76
+ export declare const storeyModel: (parts: readonly Part[]) => Uint8Array<ArrayBuffer>;
77
+ /** What places a model, as the worker reads it: web-ifc's shift of it (metres, its y-up frame), its project's metres
78
+ * per unit, its map conversion (eastings, northings, height, x axis' abscissa and ordinate, scale) and its CRS, its
79
+ * site's longitude, latitude and elevation, its true north (in its plan) */
80
+ export interface IfcPlacing {
81
+ shift: number[];
82
+ unit: number;
83
+ map?: number[];
84
+ crs?: string | null;
85
+ site?: [number, number, number];
86
+ north?: number[];
87
+ }
88
+ /**
89
+ * Where a model's origin (its glTF's) stands: by its map conversion when its CRS is known (the origin in the file's
90
+ * frame, before web-ifc's shift, taken to the map's eastings and northings, then to longitude and latitude; its north
91
+ * turned by the conversion's x axis and the grid's convergence there), else by its site's latitude and longitude
92
+ * turned by its true north
93
+ */
94
+ export declare const placeIfc: ({ shift, unit, map, crs, site, north }: IfcPlacing) => IfcPlace | undefined;
95
+ /**
96
+ * An IFC file (its URL, or its bytes) opened by web-ifc in a worker: its storeys and elements, each storey's geometry
97
+ * when asked, the elements' properties on demand, where it stands
98
+ */
99
+ export declare const loadIfc: (source: string | ArrayBuffer, options?: IfcOptions) => Promise<IfcModel>;
100
+ export {};
@@ -0,0 +1,371 @@
1
+ /**
2
+ * IFC models (the BIM tools' own format: Revit, ArchiCAD, Tekla, Allplan, Bonsai…) read by web-ifc (ThatOpen,
3
+ * MPL-2.0) in a worker of their own, web-ifc fetched on first use from a CDN (or a folder of yours): the model's
4
+ * storeys and elements at once, each storey's geometry when asked (a glTF binary for `map.addModels({ data })`, each
5
+ * element a feature of it, picked by the map: `hit.index` is the element's), the elements' properties on demand, and
6
+ * where the model stands (its map conversion in a projected CRS, else its site's latitude and longitude).
7
+ */
8
+ import { METRES_PER_DEGREE } from "../util/geo.js";
9
+ import { bounds, bufferBuilder, glbOf } from "../util/gltf.js";
10
+ import { getCrs } from "./crs.js";
11
+ /** web-ifc's build used by default: its module (`web-ifc-api.js`) and its WebAssembly (`web-ifc.wasm`) */
12
+ export const WEB_IFC = 'https://cdn.jsdelivr.net/npm/web-ifc@0.0.78/';
13
+ /**
14
+ * The worker's code: web-ifc imported from `base`, the file opened; its storeys, its elements (the spatial structure's
15
+ * products) and what places it (its map conversion, its site, its true north) given at once, a storey's meshes when
16
+ * asked (positions put in the model's frame, colors), the properties asked for
17
+ */
18
+ const WORKER = `
19
+ let api, model, W;
20
+ const text = (v) => (v && typeof v.value !== 'undefined' ? v.value : null);
21
+ const degrees = (v) => {
22
+ const parts = text(v);
23
+ if (!Array.isArray(parts)) return undefined;
24
+ const [d = 0, m = 0, s = 0, u = 0] = parts.map((p) => text(p) ?? p);
25
+ return d + m / 60 + s / 3600 + u / 3600e6;
26
+ };
27
+ const plain = (line) => Object.fromEntries(
28
+ Object.entries(line ?? {})
29
+ // Values, not references to other lines (type 5) nor lists
30
+ .filter(([k, v]) => v && typeof v === 'object' && 'value' in v && v.type !== 5 && typeof v.value !== 'object' && k !== 'expressID')
31
+ .map(([k, v]) => [k, v.value]),
32
+ );
33
+ const ids = (type) => { const v = api.GetLineIDsWithType(model, type); return Array.from({ length: v.size() }, (_, i) => v.get(i)); };
34
+ const line = (ref) => (ref && ref.value !== undefined ? api.GetLine(model, ref.value) : undefined);
35
+ // The spatial structure's containers, and the products drawn by no element of their own (the site is one when it has
36
+ // a shape: its terrain)
37
+ const SPATIAL = new Set(['IFCPROJECT', 'IFCBUILDING', 'IFCBUILDINGSTOREY', 'IFCSPACE', 'IFCOPENINGELEMENT']);
38
+ const PREFIXES = { EXA: 1e18, PETA: 1e15, TERA: 1e12, GIGA: 1e9, MEGA: 1e6, KILO: 1e3, HECTO: 100, DECA: 10, DECI: 0.1, CENTI: 0.01, MILLI: 0.001, MICRO: 1e-6 };
39
+ /** Metres per length unit of the project */
40
+ const unitScale = () => {
41
+ const project = ids(W.IFCPROJECT).map((id) => api.GetLine(model, id))[0];
42
+ const units = line(project?.UnitsInContext)?.Units ?? [];
43
+ for (const ref of units) {
44
+ const unit = line(ref);
45
+ if (text(unit?.UnitType) !== 'LENGTHUNIT') continue;
46
+ if (unit.Prefix !== undefined || text(unit.Name) === 'METRE') return PREFIXES[text(unit.Prefix)] ?? 1;
47
+ // A conversion-based unit (the foot): its factor, in metres when its unit is
48
+ const factor = line(unit.ConversionFactor);
49
+ const value = Number(text(factor?.ValueComponent) ?? NaN);
50
+ if (Number.isFinite(value)) return value * (PREFIXES[text(line(factor?.UnitComponent)?.Prefix)] ?? 1);
51
+ }
52
+ return 1;
53
+ };
54
+ onmessage = async ({ data }) => {
55
+ try {
56
+ if (data.type === 'open') {
57
+ W = await import(data.base + 'web-ifc-api.js');
58
+ api = new W.IfcAPI();
59
+ api.SetWasmPath(data.base, true);
60
+ await api.Init();
61
+ model = api.OpenModel(new Uint8Array(data.bytes), { COORDINATE_TO_ORIGIN: true });
62
+ const unit = unitScale();
63
+ const storeys = ids(W.IFCBUILDINGSTOREY).map((id) => {
64
+ const l = api.GetLine(model, id);
65
+ return { id, name: text(l.Name) ?? '', elevation: Number(text(l.Elevation) ?? 0) * unit };
66
+ });
67
+ // The products of the spatial structure and their storeys
68
+ const elements = [];
69
+ const walk = (node, storey) => {
70
+ const type = String(node.type);
71
+ const here = type.toUpperCase() === 'IFCBUILDINGSTOREY' ? node.expressID : storey;
72
+ const drawn = type.toUpperCase() !== 'IFCSITE' || api.GetLine(model, node.expressID)?.Representation;
73
+ if (!SPATIAL.has(type.toUpperCase()) && drawn) {
74
+ elements.push({ id: node.expressID, type, name: text(api.GetLine(model, node.expressID)?.Name) ?? '', storey: here ?? -1 });
75
+ }
76
+ (node.children ?? []).forEach((c) => walk(c, here));
77
+ };
78
+ walk(await api.properties.getSpatialStructure(model), undefined);
79
+ // What places it: the shift web-ifc made to bring it near the origin (metres, its y-up frame), the map
80
+ // conversion and its CRS, the site's latitude and longitude, the true north
81
+ const shift = api.GetCoordinationMatrix(model).slice(12, 15);
82
+ const conversion = ids(W.IFCMAPCONVERSION).map((id) => api.GetLine(model, id))[0];
83
+ const site = ids(W.IFCSITE).map((id) => api.GetLine(model, id))[0];
84
+ const north = ids(W.IFCGEOMETRICREPRESENTATIONCONTEXT)
85
+ .map((id) => line(api.GetLine(model, id).TrueNorth))
86
+ .find((d) => d)?.DirectionRatios?.map((r) => text(r) ?? r);
87
+ const [lat, lon] = [degrees(site?.RefLatitude), degrees(site?.RefLongitude)];
88
+ postMessage({
89
+ type: 'model',
90
+ storeys,
91
+ elements,
92
+ place: {
93
+ shift,
94
+ unit,
95
+ ...(conversion && {
96
+ map: ['Eastings', 'Northings', 'OrthogonalHeight', 'XAxisAbscissa', 'XAxisOrdinate', 'Scale'].map((k) => Number(text(conversion[k]) ?? (k === 'Scale' || k === 'XAxisAbscissa' ? 1 : 0))),
97
+ crs: text(line(conversion.TargetCRS)?.Name),
98
+ }),
99
+ ...(lat !== undefined && lon !== undefined && { site: [lon, lat, Number(text(site.RefElevation) ?? 0) * unit] }),
100
+ ...(north && { north }),
101
+ },
102
+ });
103
+ } else if (data.type === 'storey') {
104
+ const parts = [];
105
+ const feature = new Map(data.ids.map((id, i) => [id, data.features[i]]));
106
+ // web-ifc 0.0.78's browser build takes three arguments where its API passes four: called directly then
107
+ const stream = (callback) => {
108
+ try {
109
+ api.StreamMeshes(model, data.ids, callback);
110
+ } catch (error) {
111
+ if (!/arguments/.test(String(error))) throw error;
112
+ api.wasmModule.StreamMeshes(model, data.ids, callback);
113
+ }
114
+ };
115
+ stream((mesh) => {
116
+ for (let i = 0; i < mesh.geometries.size(); i++) {
117
+ const placed = mesh.geometries.get(i);
118
+ const geometry = api.GetGeometry(model, placed.geometryExpressID);
119
+ const v = api.GetVertexArray(geometry.GetVertexData(), geometry.GetVertexDataSize());
120
+ const indices = api.GetIndexArray(geometry.GetIndexData(), geometry.GetIndexDataSize()).slice();
121
+ const m = placed.flatTransformation;
122
+ const positions = new Float32Array((v.length / 6) * 3);
123
+ for (let k = 0, p = 0; k < v.length; k += 6, p += 3) {
124
+ const [x, y, z] = [v[k], v[k + 1], v[k + 2]];
125
+ // Turned half a turn round y: the model's north (-z of web-ifc's y-up frame) toward +z, glTF's front
126
+ positions[p] = -(m[0] * x + m[4] * y + m[8] * z + m[12]);
127
+ positions[p + 1] = m[1] * x + m[5] * y + m[9] * z + m[13];
128
+ positions[p + 2] = -(m[2] * x + m[6] * y + m[10] * z + m[14]);
129
+ }
130
+ const c = placed.color;
131
+ parts.push({ feature: feature.get(mesh.expressID) ?? 0, color: [c.x, c.y, c.z, c.w], positions, indices });
132
+ geometry.delete();
133
+ }
134
+ });
135
+ postMessage({ type: 'storey', request: data.request, parts }, parts.flatMap((p) => [p.positions.buffer, p.indices.buffer]));
136
+ } else if (data.type === 'properties') {
137
+ const properties = { Attributes: plain(api.GetLine(model, data.id)) };
138
+ const sets = await api.properties.getPropertySets(model, data.id, true);
139
+ for (const set of sets) {
140
+ const values = {};
141
+ for (const p of [...(set.HasProperties ?? []), ...(set.Quantities ?? [])]) {
142
+ const name = text(p.Name);
143
+ if (!name) continue;
144
+ const value = p.NominalValue ?? p.LengthValue ?? p.AreaValue ?? p.VolumeValue ?? p.CountValue ?? p.WeightValue;
145
+ values[name] = text(value);
146
+ }
147
+ properties[text(set.Name) ?? 'Set ' + set.expressID] = values;
148
+ }
149
+ postMessage({ type: 'properties', request: data.request, properties });
150
+ }
151
+ } catch (error) {
152
+ postMessage({ type: 'error', request: data.request, message: String(error?.message ?? error) });
153
+ }
154
+ };
155
+ `;
156
+ /** A storey's parts as a glTF binary: a primitive per color, each vertex its element (`_BATCHID`) */
157
+ export const storeyModel = (parts) => {
158
+ const byColor = new Map();
159
+ parts.forEach((p) => {
160
+ const key = p.color.map((c) => c.toFixed(3)).join(',');
161
+ byColor.set(key, [...(byColor.get(key) ?? []), p]);
162
+ });
163
+ const { views, append, bin: buffer } = bufferBuilder();
164
+ const accessors = [];
165
+ const groups = [...byColor.values()];
166
+ const primitives = groups.map((group, material) => {
167
+ const count = group.reduce((n, p) => n + p.positions.length / 3, 0);
168
+ const positions = new Float32Array(count * 3);
169
+ const features = new Float32Array(count);
170
+ const indices = new Uint32Array(group.reduce((n, p) => n + p.indices.length, 0));
171
+ let [vertex, index] = [0, 0];
172
+ group.forEach((p) => {
173
+ positions.set(p.positions, vertex * 3);
174
+ features.fill(p.feature, vertex, vertex + p.positions.length / 3);
175
+ p.indices.forEach((i, k) => {
176
+ indices[index + k] = i + vertex;
177
+ });
178
+ vertex += p.positions.length / 3;
179
+ index += p.indices.length;
180
+ });
181
+ accessors.push({
182
+ bufferView: append(new Uint8Array(positions.buffer), 34962),
183
+ componentType: 5126,
184
+ count,
185
+ type: 'VEC3',
186
+ ...bounds([...positions]),
187
+ }, { bufferView: append(new Uint8Array(features.buffer), 34962), componentType: 5126, count, type: 'SCALAR' }, {
188
+ bufferView: append(new Uint8Array(indices.buffer), 34963),
189
+ componentType: 5125,
190
+ count: indices.length,
191
+ type: 'SCALAR',
192
+ });
193
+ const at = accessors.length - 3;
194
+ return { attributes: { POSITION: at, _BATCHID: at + 1 }, indices: at + 2, material };
195
+ });
196
+ const bin = buffer();
197
+ return glbOf({
198
+ asset: { version: '2.0', generator: 'isard (IFC)' },
199
+ scene: 0,
200
+ scenes: [{ nodes: [0] }],
201
+ nodes: [{ mesh: 0 }],
202
+ meshes: [{ primitives }],
203
+ materials: groups.map((group) => {
204
+ const color = group[0]?.color ?? [0.8, 0.8, 0.8, 1];
205
+ return {
206
+ pbrMetallicRoughness: { baseColorFactor: color, metallicFactor: 0, roughnessFactor: 1 },
207
+ ...(color[3] < 1 && { alphaMode: 'BLEND' }),
208
+ doubleSided: true,
209
+ };
210
+ }),
211
+ accessors,
212
+ bufferViews: views,
213
+ buffers: [{ byteLength: bin.byteLength }],
214
+ }, bin);
215
+ };
216
+ /** Degrees clockwise from the north of the true north to (x, y) in a plan whose y would be north */
217
+ const bearingOf = (x, y) => (Math.atan2(x, y) * 180) / Math.PI;
218
+ /**
219
+ * Where a model's origin (its glTF's) stands: by its map conversion when its CRS is known (the origin in the file's
220
+ * frame, before web-ifc's shift, taken to the map's eastings and northings, then to longitude and latitude; its north
221
+ * turned by the conversion's x axis and the grid's convergence there), else by its site's latitude and longitude
222
+ * turned by its true north
223
+ */
224
+ export const placeIfc = ({ shift, unit, map, crs, site, north }) => {
225
+ // The origin in the file's frame (metres, z up): web-ifc's y-up shift undone
226
+ const [sx = 0, sy = 0, sz = 0] = shift;
227
+ const [x, y, z] = [-sx, sz, -sy];
228
+ if (map && crs) {
229
+ const projection = (() => {
230
+ try {
231
+ return getCrs(crs);
232
+ }
233
+ catch {
234
+ return undefined;
235
+ }
236
+ })();
237
+ const [e = 0, n = 0, h = 0, ax = 1, ay = 0, scale = 1] = map;
238
+ if (projection) {
239
+ const length = Math.hypot(ax, ay) || 1;
240
+ const [a, b] = [ax / length, ay / length];
241
+ // The conversion's scale takes the project's units to the map's; the geometry is in metres already
242
+ const k = scale / unit;
243
+ const [east, northing] = [e + k * (a * x - b * y), n + k * (b * x + a * y)];
244
+ const [lon = 0, lat = 0] = projection.inverse([east, northing]);
245
+ const [lon2 = 0, lat2 = 0] = projection.inverse([east, northing + 100]);
246
+ // The grid's north from the true north there, and the file's north (its y) from the grid's
247
+ const convergence = bearingOf((lon2 - lon) * Math.cos((lat * Math.PI) / 180), lat2 - lat);
248
+ return {
249
+ lonLat: [lon, lat],
250
+ elevation: h + k * z,
251
+ heading: bearingOf(-b, a) + convergence,
252
+ from: 'map',
253
+ crs,
254
+ };
255
+ }
256
+ }
257
+ if (!site)
258
+ return undefined;
259
+ // The true north in the plan: the plan's y turned from it the other way
260
+ const [nx = 0, ny = 1] = north ?? [];
261
+ const heading = -bearingOf(nx, ny);
262
+ const [lon, lat, elevation] = site;
263
+ // The origin's offset from the site's (metres, the plan turned to the north)
264
+ const turn = (heading * Math.PI) / 180;
265
+ const [east, northing] = [x * Math.cos(turn) + y * Math.sin(turn), -x * Math.sin(turn) + y * Math.cos(turn)];
266
+ return {
267
+ lonLat: [lon + east / (METRES_PER_DEGREE * Math.cos((lat * Math.PI) / 180)), lat + northing / METRES_PER_DEGREE],
268
+ elevation: elevation + z,
269
+ heading,
270
+ from: 'site',
271
+ };
272
+ };
273
+ /**
274
+ * An IFC file (its URL, or its bytes) opened by web-ifc in a worker: its storeys and elements, each storey's geometry
275
+ * when asked, the elements' properties on demand, where it stands
276
+ */
277
+ export const loadIfc = async (source, options = {}) => {
278
+ const bytes = typeof source === 'string'
279
+ ? await fetch(source, options.init).then((r) => {
280
+ if (!r.ok)
281
+ throw new Error(`isard: ${source}: ${r.status}`);
282
+ return r.arrayBuffer();
283
+ })
284
+ : source;
285
+ const script = URL.createObjectURL(new Blob([WORKER], { type: 'text/javascript' }));
286
+ const worker = new Worker(script, { type: 'module' });
287
+ /** The answers awaited, by request */
288
+ const pending = new Map();
289
+ let request = 0;
290
+ const ask = (message) => new Promise((resolve, reject) => {
291
+ request += 1;
292
+ pending.set(request, { resolve: (answer) => resolve(answer), reject });
293
+ worker.postMessage({ ...message, request });
294
+ });
295
+ URL.revokeObjectURL(script);
296
+ const opened = await new Promise((resolve, reject) => {
297
+ // The worker failing: the model not opened, or (once it is) every answer awaited
298
+ const fail = (error) => {
299
+ reject(error);
300
+ pending.forEach((waiting) => {
301
+ waiting.reject(error);
302
+ });
303
+ pending.clear();
304
+ };
305
+ worker.onmessage = ({ data }) => {
306
+ if (data.type === 'model')
307
+ resolve(data);
308
+ else if (data.request === undefined)
309
+ fail(new Error(`isard: IFC: ${data.type === 'error' ? data.message : ''}`));
310
+ else {
311
+ const waiting = pending.get(data.request);
312
+ pending.delete(data.request);
313
+ if (data.type === 'error')
314
+ waiting?.reject(new Error(`isard: IFC: ${data.message}`));
315
+ else
316
+ waiting?.resolve(data);
317
+ }
318
+ };
319
+ worker.onerror = (e) => {
320
+ fail(new Error(`isard: IFC worker: ${e.message}`));
321
+ };
322
+ worker.postMessage({ type: 'open', base: options.webIfc ?? WEB_IFC, bytes }, [bytes]);
323
+ }).catch((error) => {
324
+ worker.terminate();
325
+ throw error;
326
+ });
327
+ // The storeys holding elements from the lowest up, the elements outside any in one of their own first (at the
328
+ // lowest storey's elevation)
329
+ const used = new Set(opened.elements.map((e) => e.storey));
330
+ const sorted = opened.storeys.filter((s) => used.has(s.id)).sort((a, b) => a.elevation - b.elevation);
331
+ const outside = opened.elements.some((e) => !sorted.some((s) => s.id === e.storey));
332
+ const list = [...(outside ? [{ id: -1, name: 'Site', elevation: sorted[0]?.elevation ?? 0 }] : []), ...sorted];
333
+ const storeyIndex = new Map(list.map((s, i) => [s.id, i]));
334
+ const elements = opened.elements.map((e) => ({ ...e, storey: storeyIndex.get(e.storey) ?? 0 }));
335
+ const storeys = list.map((s, i) => {
336
+ const members = elements.flatMap((e, k) => (e.storey === i ? [k] : []));
337
+ let loaded;
338
+ return {
339
+ ...s,
340
+ elements: members,
341
+ load: () => {
342
+ loaded ??= ask({
343
+ type: 'storey',
344
+ ids: members.map((k) => elements[k]?.id ?? 0),
345
+ features: members,
346
+ }).then(({ parts }) => storeyModel(parts));
347
+ return loaded;
348
+ },
349
+ };
350
+ });
351
+ const place = placeIfc(opened.place);
352
+ return {
353
+ storeys,
354
+ elements,
355
+ ...(place && { place }),
356
+ properties: (element) => {
357
+ const id = elements[element]?.id;
358
+ if (id === undefined)
359
+ return Promise.reject(new Error(`isard: IFC: no element ${element}`));
360
+ return ask({ type: 'properties', id }).then((a) => a.properties);
361
+ },
362
+ close: () => {
363
+ worker.terminate();
364
+ pending.forEach(({ reject }) => {
365
+ reject(new Error('isard: IFC model closed'));
366
+ });
367
+ pending.clear();
368
+ },
369
+ };
370
+ };
371
+ //# sourceMappingURL=ifc.js.map