@honua/app-platform 0.1.11-beta.0 → 0.1.13
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.
- package/columnar/apache-arrow.d.ts +17 -0
- package/columnar/apache-arrow.d.ts.map +1 -0
- package/columnar/apache-arrow.js +1036 -0
- package/columnar/batch-cache-conformance.d.ts +66 -0
- package/columnar/batch-cache-conformance.d.ts.map +1 -0
- package/columnar/batch-cache-conformance.js +317 -0
- package/columnar/batch-cache-indexeddb.d.ts +31 -0
- package/columnar/batch-cache-indexeddb.d.ts.map +1 -0
- package/columnar/batch-cache-indexeddb.js +148 -0
- package/columnar/batch-cache.d.ts +298 -0
- package/columnar/batch-cache.d.ts.map +1 -0
- package/columnar/batch-cache.js +757 -0
- package/columnar/geoarrow-aggregate.d.ts +178 -0
- package/columnar/geoarrow-aggregate.d.ts.map +1 -0
- package/columnar/geoarrow-aggregate.js +976 -0
- package/columnar/geoarrow-patch.d.ts +382 -0
- package/columnar/geoarrow-patch.d.ts.map +1 -0
- package/columnar/geoarrow-patch.js +1656 -0
- package/columnar/geoarrow-reproject.d.ts +22 -0
- package/columnar/geoarrow-reproject.d.ts.map +1 -0
- package/columnar/geoarrow-reproject.js +119 -0
- package/columnar/geoarrow-serialization.d.ts +68 -0
- package/columnar/geoarrow-serialization.d.ts.map +1 -0
- package/columnar/geoarrow-serialization.js +331 -0
- package/columnar/geoarrow-types.d.ts +271 -0
- package/columnar/geoarrow-types.d.ts.map +1 -0
- package/columnar/geoarrow-types.js +15 -0
- package/columnar/geoarrow.d.ts +52 -0
- package/columnar/geoarrow.d.ts.map +1 -0
- package/columnar/geoarrow.js +1469 -0
- package/columnar/index.d.ts +43 -0
- package/columnar/index.d.ts.map +1 -0
- package/columnar/index.js +29 -0
- package/columnar/operators.d.ts +70 -0
- package/columnar/operators.d.ts.map +1 -0
- package/columnar/operators.js +307 -0
- package/columnar/result.d.ts +369 -0
- package/columnar/result.d.ts.map +1 -0
- package/columnar/result.js +815 -0
- package/columnar/telemetry.d.ts +152 -0
- package/columnar/telemetry.d.ts.map +1 -0
- package/columnar/telemetry.js +265 -0
- package/columnar/transfer.d.ts +28 -0
- package/columnar/transfer.d.ts.map +1 -0
- package/columnar/transfer.js +669 -0
- package/columnar/types.d.ts +175 -0
- package/columnar/types.d.ts.map +1 -0
- package/columnar/types.js +22 -0
- package/columnar/worker.d.ts +157 -0
- package/columnar/worker.d.ts.map +1 -0
- package/columnar/worker.js +1059 -0
- package/contract/pmtiles.d.ts +6 -5
- package/contract/pmtiles.d.ts.map +1 -1
- package/contract/pmtiles.js +30 -5
- package/control-plane/generated/admin-operations.d.ts +3 -3
- package/control-plane/generated/admin-operations.d.ts.map +1 -1
- package/control-plane/generated/admin-operations.js +3 -3
- package/controls/catalog.d.ts.map +1 -1
- package/controls/catalog.js +110 -0
- package/controls/index.d.ts +1 -1
- package/controls/index.js +1 -1
- package/controls/types.d.ts +1 -1
- package/controls/types.js +1 -1
- package/core/client.d.ts.map +1 -1
- package/core/client.js +87 -19
- package/core/deprecation-notice.d.ts +28 -0
- package/core/deprecation-notice.d.ts.map +1 -0
- package/core/deprecation-notice.js +22 -0
- package/core/esri-geojson.d.ts.map +1 -1
- package/core/esri-geojson.js +10 -6
- package/core/optional-grpc-peer.d.ts +15 -0
- package/core/optional-grpc-peer.d.ts.map +1 -0
- package/core/optional-grpc-peer.js +60 -0
- package/esri-compat/basemap-gallery.d.ts +2 -0
- package/esri-compat/basemap-gallery.d.ts.map +1 -1
- package/esri-compat/basemap-gallery.js +12 -0
- package/esri-compat/basemap.d.ts +4 -0
- package/esri-compat/basemap.d.ts.map +1 -1
- package/esri-compat/basemap.js +70 -0
- package/esri-compat/bookmarks.d.ts +2 -0
- package/esri-compat/bookmarks.d.ts.map +1 -1
- package/esri-compat/bookmarks.js +12 -0
- package/esri-compat/controls.d.ts +18 -0
- package/esri-compat/controls.d.ts.map +1 -1
- package/esri-compat/controls.js +120 -57
- package/esri-compat/directions.d.ts +4 -0
- package/esri-compat/directions.d.ts.map +1 -1
- package/esri-compat/directions.js +30 -20
- package/esri-compat/editor.d.ts +4 -0
- package/esri-compat/editor.d.ts.map +1 -1
- package/esri-compat/editor.js +16 -0
- package/esri-compat/esri-config.d.ts +2 -1
- package/esri-compat/esri-config.d.ts.map +1 -1
- package/esri-compat/feature-effect.d.ts +23 -0
- package/esri-compat/feature-effect.d.ts.map +1 -0
- package/esri-compat/feature-effect.js +12 -0
- package/esri-compat/feature-form.d.ts +6 -0
- package/esri-compat/feature-form.d.ts.map +1 -1
- package/esri-compat/feature-form.js +63 -0
- package/esri-compat/feature-layer.d.ts +21 -2
- package/esri-compat/feature-layer.d.ts.map +1 -1
- package/esri-compat/feature-layer.js +172 -1
- package/esri-compat/feature-table.d.ts +5 -0
- package/esri-compat/feature-table.d.ts.map +1 -1
- package/esri-compat/feature-table.js +23 -0
- package/esri-compat/identity-manager.d.ts +1 -1
- package/esri-compat/identity-manager.js +1 -1
- package/esri-compat/legend.d.ts +2 -0
- package/esri-compat/legend.d.ts.map +1 -1
- package/esri-compat/legend.js +98 -0
- package/esri-compat/locator.d.ts +1 -1
- package/esri-compat/locator.js +1 -1
- package/esri-compat/map-view-mount.d.ts +1 -0
- package/esri-compat/map-view-mount.d.ts.map +1 -1
- package/esri-compat/map-view-mount.js +46 -25
- package/esri-compat/map-view.d.ts +13 -0
- package/esri-compat/map-view.d.ts.map +1 -1
- package/esri-compat/map-view.js +94 -8
- package/esri-compat/map.d.ts +5 -1
- package/esri-compat/map.d.ts.map +1 -1
- package/esri-compat/map.js +10 -0
- package/esri-compat/measurement.d.ts +2 -0
- package/esri-compat/measurement.d.ts.map +1 -1
- package/esri-compat/measurement.js +14 -0
- package/esri-compat/point.d.ts +7 -0
- package/esri-compat/point.d.ts.map +1 -1
- package/esri-compat/point.js +33 -3
- package/esri-compat/popup.d.ts +2 -0
- package/esri-compat/popup.d.ts.map +1 -1
- package/esri-compat/popup.js +12 -0
- package/esri-compat/portal.d.ts +1 -1
- package/esri-compat/portal.js +1 -1
- package/esri-compat/print.d.ts +3 -0
- package/esri-compat/print.d.ts.map +1 -1
- package/esri-compat/print.js +15 -0
- package/esri-compat/search.d.ts +4 -0
- package/esri-compat/search.d.ts.map +1 -1
- package/esri-compat/search.js +25 -28
- package/esri-compat/sketch.d.ts +2 -0
- package/esri-compat/sketch.d.ts.map +1 -1
- package/esri-compat/sketch.js +12 -0
- package/esri-compat/widget-host.d.ts +46 -17
- package/esri-compat/widget-host.d.ts.map +1 -1
- package/esri-compat/widget-host.js +84 -20
- package/esri-compat/widget-shell-hosts.d.ts +61 -0
- package/esri-compat/widget-shell-hosts.d.ts.map +1 -0
- package/esri-compat/widget-shell-hosts.js +76 -0
- package/kernel/renderer.d.ts +82 -0
- package/kernel/renderer.js +1 -0
- package/offline/conflict-resolution.d.ts +183 -0
- package/offline/conflict-resolution.d.ts.map +1 -0
- package/offline/conflict-resolution.js +286 -0
- package/offline/credential-screen.d.ts +34 -0
- package/offline/credential-screen.d.ts.map +1 -0
- package/offline/credential-screen.js +78 -0
- package/offline/digest.d.ts +15 -0
- package/offline/digest.d.ts.map +1 -0
- package/offline/digest.js +58 -0
- package/offline/edit-queue.d.ts +403 -0
- package/offline/edit-queue.d.ts.map +1 -0
- package/offline/edit-queue.js +1807 -0
- package/offline/edit-replay.d.ts +116 -0
- package/offline/edit-replay.d.ts.map +1 -0
- package/offline/edit-replay.js +392 -0
- package/offline/fetch-handler.d.ts +12 -0
- package/offline/fetch-handler.d.ts.map +1 -0
- package/offline/fetch-handler.js +65 -0
- package/offline/index.d.ts +52 -0
- package/offline/index.d.ts.map +1 -0
- package/offline/index.js +34 -0
- package/offline/indexeddb.d.ts +135 -0
- package/offline/indexeddb.d.ts.map +1 -0
- package/offline/indexeddb.js +888 -0
- package/offline/memory-store.d.ts +17 -0
- package/offline/memory-store.d.ts.map +1 -0
- package/offline/memory-store.js +183 -0
- package/offline/quota.d.ts +161 -0
- package/offline/quota.d.ts.map +1 -0
- package/offline/quota.js +370 -0
- package/offline/read-gate.d.ts +175 -0
- package/offline/read-gate.d.ts.map +1 -0
- package/offline/read-gate.js +252 -0
- package/offline/read-resource.d.ts +99 -0
- package/offline/read-resource.d.ts.map +1 -0
- package/offline/read-resource.js +156 -0
- package/offline/read.d.ts +50 -0
- package/offline/read.d.ts.map +1 -0
- package/offline/read.js +65 -0
- package/offline/region.d.ts +29 -0
- package/offline/region.d.ts.map +1 -0
- package/offline/region.js +1007 -0
- package/offline/replay-conflict.d.ts +183 -0
- package/offline/replay-conflict.d.ts.map +1 -0
- package/offline/replay-conflict.js +482 -0
- package/offline/selection.d.ts +140 -0
- package/offline/selection.d.ts.map +1 -0
- package/offline/selection.js +391 -0
- package/offline/snapshot.d.ts +132 -0
- package/offline/snapshot.d.ts.map +1 -0
- package/offline/snapshot.js +312 -0
- package/offline/status.d.ts +136 -0
- package/offline/status.d.ts.map +1 -0
- package/offline/status.js +479 -0
- package/offline/store-conformance.d.ts +48 -0
- package/offline/store-conformance.d.ts.map +1 -0
- package/offline/store-conformance.js +233 -0
- package/offline/tile-protocol.d.ts +81 -0
- package/offline/tile-protocol.d.ts.map +1 -0
- package/offline/tile-protocol.js +119 -0
- package/offline/types.d.ts +349 -0
- package/offline/types.d.ts.map +1 -0
- package/offline/types.js +75 -0
- package/package.json +14 -2
- package/scene-workspace/index.d.ts +2 -2
- package/scene-workspace/index.d.ts.map +1 -1
- package/scene-workspace/index.js +1 -1
- package/scene-workspace/scene-discovery.d.ts +111 -91
- package/scene-workspace/scene-discovery.d.ts.map +1 -1
- package/scene-workspace/scene-discovery.js +340 -92
- package/scene-workspace/scene-view.d.ts +6 -6
- package/scene-workspace/scene-view.d.ts.map +1 -1
- package/scene-workspace/scene-view.js +32 -6
- package/web-components/elements.d.ts +34 -0
- package/web-components/elements.d.ts.map +1 -1
- package/web-components/elements.js +82 -8
- package/web-components/index.d.ts +2 -0
- package/web-components/index.d.ts.map +1 -1
- package/web-components/index.js +3 -1
- package/web-components/map-chrome.d.ts +103 -0
- package/web-components/map-chrome.d.ts.map +1 -0
- package/web-components/map-chrome.js +325 -0
- package/web-components/widget-shell.d.ts +68 -0
- package/web-components/widget-shell.d.ts.map +1 -0
- package/web-components/widget-shell.js +224 -0
- package/widget-capabilities.d.ts +67 -0
- package/widget-capabilities.js +152 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map chrome that wraps a MapLibre control, or a home button that returns
|
|
3
|
+
* to the viewpoint stored on the compat shim.
|
|
4
|
+
*/
|
|
5
|
+
import { AttributionControl, FullscreenControl, NavigationControl, ScaleControl, } from "maplibre-gl";
|
|
6
|
+
const HTMLElementBase = globalThis.HTMLElement ?? class {
|
|
7
|
+
};
|
|
8
|
+
function labelOf(element, fallback) {
|
|
9
|
+
return element.getAttribute("label") ?? fallback;
|
|
10
|
+
}
|
|
11
|
+
class HonuaChromeElement extends HTMLElementBase {
|
|
12
|
+
#map;
|
|
13
|
+
#view;
|
|
14
|
+
#control;
|
|
15
|
+
get map() {
|
|
16
|
+
return this.#map;
|
|
17
|
+
}
|
|
18
|
+
set map(map) {
|
|
19
|
+
this.#map = map;
|
|
20
|
+
this.render();
|
|
21
|
+
}
|
|
22
|
+
get view() {
|
|
23
|
+
return this.#view;
|
|
24
|
+
}
|
|
25
|
+
set view(view) {
|
|
26
|
+
this.#view = view;
|
|
27
|
+
this.render();
|
|
28
|
+
}
|
|
29
|
+
/** Compat view pushed by the host. A MapLibre map is not a view. */
|
|
30
|
+
compatView() {
|
|
31
|
+
if (isCompatView(this.#view))
|
|
32
|
+
return this.#view;
|
|
33
|
+
if (isCompatView(this.#map))
|
|
34
|
+
return this.#map;
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
connectedCallback() {
|
|
38
|
+
if (!this.shadowRoot)
|
|
39
|
+
this.attachShadow({ mode: "open" });
|
|
40
|
+
this.render();
|
|
41
|
+
}
|
|
42
|
+
attributeChangedCallback() {
|
|
43
|
+
this.render();
|
|
44
|
+
}
|
|
45
|
+
/** Control chrome wired to the compat view when no MapLibre map is mounted. */
|
|
46
|
+
renderCompat(_section) { }
|
|
47
|
+
render() {
|
|
48
|
+
if (!this.shadowRoot)
|
|
49
|
+
return;
|
|
50
|
+
const label = labelOf(this, this.fallback());
|
|
51
|
+
this.shadowRoot.innerHTML = `<section aria-label="${escapeAttr(label)}"><slot></slot></section>`;
|
|
52
|
+
const section = this.shadowRoot.querySelector("section");
|
|
53
|
+
if (!section)
|
|
54
|
+
return;
|
|
55
|
+
try {
|
|
56
|
+
this.#control?.onRemove(this.#map);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// A control that failed onAdd can still be replaced on the next render.
|
|
60
|
+
}
|
|
61
|
+
const control = this.control();
|
|
62
|
+
this.#control = control;
|
|
63
|
+
if (control && isMapLibreMap(this.#map)) {
|
|
64
|
+
try {
|
|
65
|
+
section.append(control.onAdd(this.#map));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// The MapLibre control rejected this map. The compat view still gets a control.
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
this.renderCompat(section);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function isMapLibreMap(value) {
|
|
76
|
+
if (!value || typeof value !== "object")
|
|
77
|
+
return false;
|
|
78
|
+
const map = value;
|
|
79
|
+
return (typeof map.getCanvas === "function" &&
|
|
80
|
+
typeof map.getContainer === "function" &&
|
|
81
|
+
typeof map.zoomIn === "function" &&
|
|
82
|
+
typeof map._getUIString === "function");
|
|
83
|
+
}
|
|
84
|
+
function isCompatView(value) {
|
|
85
|
+
return !!value && typeof value === "object" && !isMapLibreMap(value);
|
|
86
|
+
}
|
|
87
|
+
function escapeAttr(value) {
|
|
88
|
+
return value.replaceAll("&", "&").replaceAll('"', """).replaceAll("<", "<");
|
|
89
|
+
}
|
|
90
|
+
function escapeText(value) {
|
|
91
|
+
return escapeAttr(value);
|
|
92
|
+
}
|
|
93
|
+
export class HonuaZoomElement extends HonuaChromeElement {
|
|
94
|
+
static get observedAttributes() {
|
|
95
|
+
return ["label"];
|
|
96
|
+
}
|
|
97
|
+
fallback() {
|
|
98
|
+
return "Zoom";
|
|
99
|
+
}
|
|
100
|
+
control() {
|
|
101
|
+
if (this.compatView() || !isMapLibreMap(this.map))
|
|
102
|
+
return undefined;
|
|
103
|
+
return new NavigationControl({ showCompass: false, showZoom: true });
|
|
104
|
+
}
|
|
105
|
+
renderCompat(section) {
|
|
106
|
+
const group = document.createElement("div");
|
|
107
|
+
group.className = "maplibregl-ctrl maplibregl-ctrl-group";
|
|
108
|
+
group.append(this.zoomButton("maplibregl-ctrl-zoom-in", "Zoom in", 1), this.zoomButton("maplibregl-ctrl-zoom-out", "Zoom out", -1));
|
|
109
|
+
section.append(group);
|
|
110
|
+
}
|
|
111
|
+
zoomButton(className, label, delta) {
|
|
112
|
+
const button = document.createElement("button");
|
|
113
|
+
button.type = "button";
|
|
114
|
+
button.className = className;
|
|
115
|
+
button.setAttribute("aria-label", label);
|
|
116
|
+
const icon = document.createElement("span");
|
|
117
|
+
icon.className = "maplibregl-ctrl-icon";
|
|
118
|
+
icon.setAttribute("aria-hidden", "true");
|
|
119
|
+
button.append(icon);
|
|
120
|
+
button.addEventListener("click", () => this.step(delta));
|
|
121
|
+
return button;
|
|
122
|
+
}
|
|
123
|
+
step(delta) {
|
|
124
|
+
const view = this.compatView();
|
|
125
|
+
if (!view)
|
|
126
|
+
return;
|
|
127
|
+
const current = typeof view.zoom === "number" && Number.isFinite(view.zoom) ? view.zoom : 2;
|
|
128
|
+
const next = current + delta;
|
|
129
|
+
view.zoom = next;
|
|
130
|
+
if (typeof view.goTo === "function")
|
|
131
|
+
void view.goTo.call(view, { zoom: next });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
export class HonuaScaleBarElement extends HonuaChromeElement {
|
|
135
|
+
static get observedAttributes() {
|
|
136
|
+
return ["label"];
|
|
137
|
+
}
|
|
138
|
+
#text = "";
|
|
139
|
+
#unit = "metric";
|
|
140
|
+
get text() {
|
|
141
|
+
return this.#text;
|
|
142
|
+
}
|
|
143
|
+
set text(text) {
|
|
144
|
+
this.#text = text ?? "";
|
|
145
|
+
this.render();
|
|
146
|
+
}
|
|
147
|
+
get unit() {
|
|
148
|
+
return this.#unit;
|
|
149
|
+
}
|
|
150
|
+
set unit(unit) {
|
|
151
|
+
this.#unit = unit ?? "metric";
|
|
152
|
+
this.render();
|
|
153
|
+
}
|
|
154
|
+
fallback() {
|
|
155
|
+
return "Scale";
|
|
156
|
+
}
|
|
157
|
+
control() {
|
|
158
|
+
if (this.compatView() || this.#text.trim() || !isMapLibreMap(this.map))
|
|
159
|
+
return undefined;
|
|
160
|
+
const unit = this.#unit === "imperial" || this.#unit === "nautical" ? this.#unit : "metric";
|
|
161
|
+
return new ScaleControl({ maxWidth: 80, unit });
|
|
162
|
+
}
|
|
163
|
+
renderCompat(section) {
|
|
164
|
+
const node = document.createElement("div");
|
|
165
|
+
node.className = "maplibregl-ctrl maplibregl-ctrl-scale";
|
|
166
|
+
node.textContent = this.scaleLabel();
|
|
167
|
+
section.append(node);
|
|
168
|
+
}
|
|
169
|
+
scaleLabel() {
|
|
170
|
+
if (this.#text.trim())
|
|
171
|
+
return this.#text;
|
|
172
|
+
const zoom = this.compatView()?.zoom;
|
|
173
|
+
if (typeof zoom !== "number" || !Number.isFinite(zoom))
|
|
174
|
+
return "";
|
|
175
|
+
return formatScaleBar(zoom, this.#unit);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
export class HonuaFullscreenElement extends HonuaChromeElement {
|
|
179
|
+
static get observedAttributes() {
|
|
180
|
+
return ["label"];
|
|
181
|
+
}
|
|
182
|
+
fallback() {
|
|
183
|
+
return "Fullscreen";
|
|
184
|
+
}
|
|
185
|
+
control() {
|
|
186
|
+
if (this.compatView() || !isMapLibreMap(this.map))
|
|
187
|
+
return undefined;
|
|
188
|
+
return new FullscreenControl();
|
|
189
|
+
}
|
|
190
|
+
renderCompat(section) {
|
|
191
|
+
const button = document.createElement("button");
|
|
192
|
+
button.type = "button";
|
|
193
|
+
button.className = "maplibregl-ctrl-fullscreen";
|
|
194
|
+
button.textContent = labelOf(this, "Fullscreen");
|
|
195
|
+
button.addEventListener("click", () => {
|
|
196
|
+
const container = this.compatView()?.container;
|
|
197
|
+
const target = container instanceof HTMLElement ? container : this.ownerDocument?.documentElement;
|
|
198
|
+
const request = target?.requestFullscreen;
|
|
199
|
+
if (typeof request === "function")
|
|
200
|
+
void request.call(target);
|
|
201
|
+
});
|
|
202
|
+
section.append(button);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
export class HonuaAttributionElement extends HonuaChromeElement {
|
|
206
|
+
static get observedAttributes() {
|
|
207
|
+
return ["label"];
|
|
208
|
+
}
|
|
209
|
+
#attributions = [];
|
|
210
|
+
get attributions() {
|
|
211
|
+
return this.#attributions;
|
|
212
|
+
}
|
|
213
|
+
set attributions(attributions) {
|
|
214
|
+
this.#attributions = attributions ?? [];
|
|
215
|
+
this.render();
|
|
216
|
+
}
|
|
217
|
+
fallback() {
|
|
218
|
+
return "Attribution";
|
|
219
|
+
}
|
|
220
|
+
control() {
|
|
221
|
+
if (!isMapLibreMap(this.map))
|
|
222
|
+
return undefined;
|
|
223
|
+
return new AttributionControl({ compact: false, customAttribution: this.#attributions.join(" | ") });
|
|
224
|
+
}
|
|
225
|
+
renderCompat(section) {
|
|
226
|
+
const node = document.createElement("div");
|
|
227
|
+
node.className = "maplibregl-ctrl maplibregl-ctrl-attrib";
|
|
228
|
+
node.textContent = this.#attributions.join(" | ");
|
|
229
|
+
section.append(node);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
export class HonuaCompassElement extends HTMLElementBase {
|
|
233
|
+
static get observedAttributes() {
|
|
234
|
+
return ["label"];
|
|
235
|
+
}
|
|
236
|
+
#view;
|
|
237
|
+
get view() {
|
|
238
|
+
return this.#view;
|
|
239
|
+
}
|
|
240
|
+
set view(view) {
|
|
241
|
+
this.#view = view;
|
|
242
|
+
this.render();
|
|
243
|
+
}
|
|
244
|
+
connectedCallback() {
|
|
245
|
+
if (!this.shadowRoot)
|
|
246
|
+
this.attachShadow({ mode: "open" });
|
|
247
|
+
this.render();
|
|
248
|
+
}
|
|
249
|
+
attributeChangedCallback() {
|
|
250
|
+
this.render();
|
|
251
|
+
}
|
|
252
|
+
reset() {
|
|
253
|
+
if (this.#view)
|
|
254
|
+
this.#view.rotation = 0;
|
|
255
|
+
void this.#view?.goTo?.({ rotation: 0 });
|
|
256
|
+
this.render();
|
|
257
|
+
}
|
|
258
|
+
render() {
|
|
259
|
+
if (!this.shadowRoot)
|
|
260
|
+
return;
|
|
261
|
+
const label = labelOf(this, "Compass");
|
|
262
|
+
this.shadowRoot.innerHTML = `<section aria-label="${escapeAttr(label)}"><button type="button" class="maplibregl-ctrl-compass">${escapeText(label)}</button></section>`;
|
|
263
|
+
this.shadowRoot.querySelector("button")?.addEventListener("click", () => this.reset());
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
export class HonuaHomeElement extends HTMLElementBase {
|
|
267
|
+
static get observedAttributes() {
|
|
268
|
+
return ["label"];
|
|
269
|
+
}
|
|
270
|
+
#view;
|
|
271
|
+
#viewpoint;
|
|
272
|
+
get view() {
|
|
273
|
+
return this.#view;
|
|
274
|
+
}
|
|
275
|
+
set view(view) {
|
|
276
|
+
this.#view = view;
|
|
277
|
+
}
|
|
278
|
+
get viewpoint() {
|
|
279
|
+
return this.#viewpoint;
|
|
280
|
+
}
|
|
281
|
+
set viewpoint(viewpoint) {
|
|
282
|
+
this.#viewpoint = viewpoint;
|
|
283
|
+
this.render();
|
|
284
|
+
}
|
|
285
|
+
connectedCallback() {
|
|
286
|
+
if (!this.shadowRoot)
|
|
287
|
+
this.attachShadow({ mode: "open" });
|
|
288
|
+
this.render();
|
|
289
|
+
}
|
|
290
|
+
attributeChangedCallback() {
|
|
291
|
+
this.render();
|
|
292
|
+
}
|
|
293
|
+
go() {
|
|
294
|
+
const target = { center: this.#viewpoint?.center, zoom: this.#viewpoint?.zoom };
|
|
295
|
+
void this.#view?.goTo?.(target);
|
|
296
|
+
}
|
|
297
|
+
render() {
|
|
298
|
+
if (!this.shadowRoot)
|
|
299
|
+
return;
|
|
300
|
+
const label = labelOf(this, "Home");
|
|
301
|
+
this.shadowRoot.innerHTML = `<section aria-label="${escapeAttr(label)}"><button type="button" class="maplibregl-ctrl-home">${escapeText(label)}</button></section>`;
|
|
302
|
+
this.shadowRoot.querySelector("button")?.addEventListener("click", () => this.go());
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
function formatScaleBar(zoom, unit) {
|
|
306
|
+
const scale = 591657527.591555 / 2 ** zoom;
|
|
307
|
+
const ratioText = `1:${Math.max(1, Math.round(scale)).toLocaleString("en-US")}`;
|
|
308
|
+
if (unit === "imperial")
|
|
309
|
+
return `${ratioText} | ${formatImperialDistance(scale)}`;
|
|
310
|
+
if (unit === "dual")
|
|
311
|
+
return `${ratioText} | ${formatMetricDistance(scale)} / ${formatImperialDistance(scale)}`;
|
|
312
|
+
return `${ratioText} | ${formatMetricDistance(scale)}`;
|
|
313
|
+
}
|
|
314
|
+
function formatMetricDistance(scale) {
|
|
315
|
+
const meters = Math.max(1, Math.round(scale * 0.00028));
|
|
316
|
+
if (meters >= 1000)
|
|
317
|
+
return `${Math.round(meters / 1000)} km`;
|
|
318
|
+
return `${meters} m`;
|
|
319
|
+
}
|
|
320
|
+
function formatImperialDistance(scale) {
|
|
321
|
+
const feet = Math.max(1, Math.round(scale * 0.0009186351706));
|
|
322
|
+
if (feet >= 5280)
|
|
323
|
+
return `${Math.round(feet / 5280)} mi`;
|
|
324
|
+
return `${feet} ft`;
|
|
325
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feature pager, attachments list, scale range, and route directions.
|
|
3
|
+
* These render fixture data. They do not upload attachments, edit travel
|
|
4
|
+
* modes, or invent route maneuvers.
|
|
5
|
+
*/
|
|
6
|
+
declare const HTMLElementBase: typeof HTMLElement;
|
|
7
|
+
interface PagerFeature {
|
|
8
|
+
title?: string;
|
|
9
|
+
attributes?: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
export declare class HonuaFeaturePagerElement extends HTMLElementBase {
|
|
12
|
+
#private;
|
|
13
|
+
static get observedAttributes(): string[];
|
|
14
|
+
get features(): readonly PagerFeature[];
|
|
15
|
+
set features(features: readonly PagerFeature[] | undefined);
|
|
16
|
+
get index(): number;
|
|
17
|
+
connectedCallback(): void;
|
|
18
|
+
disconnectedCallback(): void;
|
|
19
|
+
attributeChangedCallback(): void;
|
|
20
|
+
next(): void;
|
|
21
|
+
private render;
|
|
22
|
+
}
|
|
23
|
+
export declare class HonuaAttachmentsElement extends HTMLElementBase {
|
|
24
|
+
#private;
|
|
25
|
+
static get observedAttributes(): string[];
|
|
26
|
+
get names(): readonly string[];
|
|
27
|
+
set names(names: readonly string[] | undefined);
|
|
28
|
+
connectedCallback(): void;
|
|
29
|
+
attributeChangedCallback(): void;
|
|
30
|
+
private render;
|
|
31
|
+
}
|
|
32
|
+
export declare class HonuaScaleRangeElement extends HTMLElementBase {
|
|
33
|
+
#private;
|
|
34
|
+
static get observedAttributes(): string[];
|
|
35
|
+
get layer(): {
|
|
36
|
+
minScale?: number;
|
|
37
|
+
maxScale?: number;
|
|
38
|
+
setScaleRange?: (min: number, max: number) => void;
|
|
39
|
+
} | undefined;
|
|
40
|
+
set layer(layer: {
|
|
41
|
+
minScale?: number;
|
|
42
|
+
maxScale?: number;
|
|
43
|
+
setScaleRange?: (min: number, max: number) => void;
|
|
44
|
+
} | undefined);
|
|
45
|
+
connectedCallback(): void;
|
|
46
|
+
attributeChangedCallback(): void;
|
|
47
|
+
setRange(minScale: number, maxScale: number): void;
|
|
48
|
+
private render;
|
|
49
|
+
}
|
|
50
|
+
export interface DirectionsRouteLike {
|
|
51
|
+
summary?: string;
|
|
52
|
+
steps?: readonly {
|
|
53
|
+
text?: string;
|
|
54
|
+
maneuver?: string;
|
|
55
|
+
}[];
|
|
56
|
+
polyline?: unknown;
|
|
57
|
+
}
|
|
58
|
+
export declare class HonuaDirectionsElement extends HTMLElementBase {
|
|
59
|
+
#private;
|
|
60
|
+
static get observedAttributes(): string[];
|
|
61
|
+
get route(): DirectionsRouteLike | undefined;
|
|
62
|
+
set route(route: DirectionsRouteLike | undefined);
|
|
63
|
+
connectedCallback(): void;
|
|
64
|
+
attributeChangedCallback(): void;
|
|
65
|
+
private render;
|
|
66
|
+
}
|
|
67
|
+
export {};
|
|
68
|
+
//# sourceMappingURL=widget-shell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widget-shell.d.ts","sourceRoot":"","sources":["../../../src/web-components/widget-shell.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,QAAA,MAAM,eAAe,EAAE,OAAO,WACmF,CAAC;AAIlH,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAaD,qBAAa,wBAAyB,SAAQ,eAAe;;IAC3D,WAAkB,kBAAkB,IAAI,MAAM,EAAE,CAE/C;IAMD,IAAW,QAAQ,IAAI,SAAS,YAAY,EAAE,CAE7C;IAED,IAAW,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,EAIhE;IAED,IAAW,KAAK,IAAI,MAAM,CAEzB;IAEM,iBAAiB,IAAI,IAAI;IAIzB,oBAAoB,IAAI,IAAI;IAI5B,wBAAwB,IAAI,IAAI;IAIhC,IAAI,IAAI,IAAI;IAYnB,OAAO,CAAC,MAAM;CAqCf;AAiCD,qBAAa,uBAAwB,SAAQ,eAAe;;IAC1D,WAAkB,kBAAkB,IAAI,MAAM,EAAE,CAE/C;IAID,IAAW,KAAK,IAAI,SAAS,MAAM,EAAE,CAEpC;IAED,IAAW,KAAK,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAGpD;IAEM,iBAAiB,IAAI,IAAI;IAIzB,wBAAwB,IAAI,IAAI;IAIvC,OAAO,CAAC,MAAM;CAKf;AAED,qBAAa,sBAAuB,SAAQ,eAAe;;IACzD,WAAkB,kBAAkB,IAAI,MAAM,EAAE,CAE/C;IAMD,IAAW,KAAK,IACZ;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,GAC5F,SAAS,CAEZ;IAED,IAAW,KAAK,CAAC,KAAK,EAClB;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,GAC5F,SAAS,EAKZ;IAEM,iBAAiB,IAAI,IAAI;IAIzB,wBAAwB,IAAI,IAAI;IAIhC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAWzD,OAAO,CAAC,MAAM;CAef;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,qBAAa,sBAAuB,SAAQ,eAAe;;IACzD,WAAkB,kBAAkB,IAAI,MAAM,EAAE,CAE/C;IAID,IAAW,KAAK,IAAI,mBAAmB,GAAG,SAAS,CAElD;IAED,IAAW,KAAK,CAAC,KAAK,EAAE,mBAAmB,GAAG,SAAS,EAGtD;IAEM,iBAAiB,IAAI,IAAI;IAIzB,wBAAwB,IAAI,IAAI;IAIvC,OAAO,CAAC,MAAM;CAYf"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feature pager, attachments list, scale range, and route directions.
|
|
3
|
+
* These render fixture data. They do not upload attachments, edit travel
|
|
4
|
+
* modes, or invent route maneuvers.
|
|
5
|
+
*/
|
|
6
|
+
import { capabilities } from "../contract/types.js";
|
|
7
|
+
import { sourceFeatureSelectionTarget } from "../exploration/selection.js";
|
|
8
|
+
import { createHonuaFeatureInspection, } from "./feature-inspection.js";
|
|
9
|
+
const HTMLElementBase = globalThis.HTMLElement ?? class {
|
|
10
|
+
};
|
|
11
|
+
const PAGER_SOURCE_ID = "honua-widget-shell-features";
|
|
12
|
+
function escapeText(value) {
|
|
13
|
+
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll('"', """);
|
|
14
|
+
}
|
|
15
|
+
function section(element, label, body) {
|
|
16
|
+
if (!element.shadowRoot)
|
|
17
|
+
element.attachShadow({ mode: "open" });
|
|
18
|
+
const shadow = element.shadowRoot;
|
|
19
|
+
if (!shadow)
|
|
20
|
+
return;
|
|
21
|
+
shadow.innerHTML = `<section aria-label="${escapeText(label)}">${body}</section>`;
|
|
22
|
+
}
|
|
23
|
+
export class HonuaFeaturePagerElement extends HTMLElementBase {
|
|
24
|
+
static get observedAttributes() {
|
|
25
|
+
return ["label"];
|
|
26
|
+
}
|
|
27
|
+
#features = [];
|
|
28
|
+
#index = 0;
|
|
29
|
+
#controllers = [];
|
|
30
|
+
get features() {
|
|
31
|
+
return this.#features;
|
|
32
|
+
}
|
|
33
|
+
set features(features) {
|
|
34
|
+
this.#features = features ?? [];
|
|
35
|
+
this.#index = 0;
|
|
36
|
+
this.render();
|
|
37
|
+
}
|
|
38
|
+
get index() {
|
|
39
|
+
return this.#index;
|
|
40
|
+
}
|
|
41
|
+
connectedCallback() {
|
|
42
|
+
this.render();
|
|
43
|
+
}
|
|
44
|
+
disconnectedCallback() {
|
|
45
|
+
this.#releaseControllers();
|
|
46
|
+
}
|
|
47
|
+
attributeChangedCallback() {
|
|
48
|
+
this.render();
|
|
49
|
+
}
|
|
50
|
+
next() {
|
|
51
|
+
if (this.#features.length === 0)
|
|
52
|
+
return;
|
|
53
|
+
this.#index = (this.#index + 1) % this.#features.length;
|
|
54
|
+
this.render();
|
|
55
|
+
}
|
|
56
|
+
#releaseControllers() {
|
|
57
|
+
const controllers = this.#controllers;
|
|
58
|
+
this.#controllers = [];
|
|
59
|
+
for (const controller of controllers)
|
|
60
|
+
controller.dispose();
|
|
61
|
+
}
|
|
62
|
+
render() {
|
|
63
|
+
this.#releaseControllers();
|
|
64
|
+
const label = this.getAttribute("label") ?? "Features";
|
|
65
|
+
const pages = this.#features
|
|
66
|
+
.map((_, index) => {
|
|
67
|
+
const hidden = index === this.#index ? "" : " hidden";
|
|
68
|
+
return `<div data-feature-page="${index}"${hidden}><honua-feature-inspection data-page="${index}"></honua-feature-inspection></div>`;
|
|
69
|
+
})
|
|
70
|
+
.join("");
|
|
71
|
+
section(this, label, `<p>${this.#features.length === 0 ? "0" : this.#index + 1} / ${this.#features.length}</p>${pages}<button type="button" data-next>Next</button>`);
|
|
72
|
+
this.#features.forEach((feature, index) => {
|
|
73
|
+
const inspection = this.shadowRoot?.querySelector(`honua-feature-inspection[data-page="${index}"]`);
|
|
74
|
+
if (!inspection || !("inspection" in inspection))
|
|
75
|
+
return;
|
|
76
|
+
const attributes = inspectionAttributes(feature, index);
|
|
77
|
+
const source = pagerSource(attributes);
|
|
78
|
+
const controller = createHonuaFeatureInspection({
|
|
79
|
+
resolveSource: (sourceId) => (sourceId === PAGER_SOURCE_ID ? source : undefined),
|
|
80
|
+
presentation: { titleField: "name", fields: Object.keys(attributes) },
|
|
81
|
+
loadAttachmentPage: async () => ({ items: [], total: 0 }),
|
|
82
|
+
});
|
|
83
|
+
this.#controllers.push(controller);
|
|
84
|
+
inspection.inspection = controller;
|
|
85
|
+
const id = featureId(attributes, index);
|
|
86
|
+
void controller.open({
|
|
87
|
+
target: sourceFeatureSelectionTarget(PAGER_SOURCE_ID, id),
|
|
88
|
+
feature: { attributes },
|
|
89
|
+
authoritative: true,
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
this.shadowRoot?.querySelector("[data-next]")?.addEventListener("click", () => this.next());
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function inspectionAttributes(feature, index) {
|
|
96
|
+
const attributes = { ...(feature.attributes ?? {}) };
|
|
97
|
+
const named = typeof attributes.name === "string" && attributes.name.trim() ? attributes.name : undefined;
|
|
98
|
+
const titled = typeof attributes.title === "string" && attributes.title.trim() ? attributes.title : undefined;
|
|
99
|
+
const title = feature.title?.trim() || named || titled || `Feature ${index + 1}`;
|
|
100
|
+
attributes.name = title;
|
|
101
|
+
if (!("OBJECTID" in attributes))
|
|
102
|
+
attributes.OBJECTID = index + 1;
|
|
103
|
+
return attributes;
|
|
104
|
+
}
|
|
105
|
+
function featureId(attributes, index) {
|
|
106
|
+
const objectId = attributes.OBJECTID;
|
|
107
|
+
if (typeof objectId === "string" || typeof objectId === "number")
|
|
108
|
+
return objectId;
|
|
109
|
+
return index + 1;
|
|
110
|
+
}
|
|
111
|
+
function pagerSource(attributes) {
|
|
112
|
+
const fields = Object.keys(attributes).map((name) => ({ name, alias: name, type: "esriFieldTypeString" }));
|
|
113
|
+
const advertised = capabilities(["query", "attachments"]);
|
|
114
|
+
return {
|
|
115
|
+
descriptor: {
|
|
116
|
+
id: PAGER_SOURCE_ID,
|
|
117
|
+
protocol: "geoservices-feature-service",
|
|
118
|
+
locator: { url: "https://widgets.honua.invalid/features" },
|
|
119
|
+
capabilities: advertised,
|
|
120
|
+
schema: { primaryKey: "OBJECTID", fields },
|
|
121
|
+
},
|
|
122
|
+
capabilities: advertised,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
export class HonuaAttachmentsElement extends HTMLElementBase {
|
|
126
|
+
static get observedAttributes() {
|
|
127
|
+
return ["label"];
|
|
128
|
+
}
|
|
129
|
+
#names = [];
|
|
130
|
+
get names() {
|
|
131
|
+
return this.#names;
|
|
132
|
+
}
|
|
133
|
+
set names(names) {
|
|
134
|
+
this.#names = names ?? [];
|
|
135
|
+
this.render();
|
|
136
|
+
}
|
|
137
|
+
connectedCallback() {
|
|
138
|
+
this.render();
|
|
139
|
+
}
|
|
140
|
+
attributeChangedCallback() {
|
|
141
|
+
this.render();
|
|
142
|
+
}
|
|
143
|
+
render() {
|
|
144
|
+
const label = this.getAttribute("label") ?? "Attachments";
|
|
145
|
+
const items = this.#names.map((name) => `<li>${escapeText(name)}</li>`).join("");
|
|
146
|
+
section(this, label, `<ul>${items}</ul>`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
export class HonuaScaleRangeElement extends HTMLElementBase {
|
|
150
|
+
static get observedAttributes() {
|
|
151
|
+
return ["label"];
|
|
152
|
+
}
|
|
153
|
+
#layer;
|
|
154
|
+
#min = 0;
|
|
155
|
+
#max = 0;
|
|
156
|
+
get layer() {
|
|
157
|
+
return this.#layer;
|
|
158
|
+
}
|
|
159
|
+
set layer(layer) {
|
|
160
|
+
this.#layer = layer;
|
|
161
|
+
this.#min = layer?.minScale ?? 0;
|
|
162
|
+
this.#max = layer?.maxScale ?? 0;
|
|
163
|
+
this.render();
|
|
164
|
+
}
|
|
165
|
+
connectedCallback() {
|
|
166
|
+
this.render();
|
|
167
|
+
}
|
|
168
|
+
attributeChangedCallback() {
|
|
169
|
+
this.render();
|
|
170
|
+
}
|
|
171
|
+
setRange(minScale, maxScale) {
|
|
172
|
+
this.#min = minScale;
|
|
173
|
+
this.#max = maxScale;
|
|
174
|
+
if (this.#layer?.setScaleRange)
|
|
175
|
+
this.#layer.setScaleRange(minScale, maxScale);
|
|
176
|
+
else if (this.#layer) {
|
|
177
|
+
this.#layer.minScale = minScale;
|
|
178
|
+
this.#layer.maxScale = maxScale;
|
|
179
|
+
}
|
|
180
|
+
this.render();
|
|
181
|
+
}
|
|
182
|
+
render() {
|
|
183
|
+
const label = this.getAttribute("label") ?? "Scale range";
|
|
184
|
+
section(this, label, `<label>Min <input data-min type="number" value="${this.#min}" /></label><label>Max <input data-max type="number" value="${this.#max}" /></label>`);
|
|
185
|
+
const commit = () => {
|
|
186
|
+
const min = Number(this.shadowRoot?.querySelector("[data-min]")?.value);
|
|
187
|
+
const max = Number(this.shadowRoot?.querySelector("[data-max]")?.value);
|
|
188
|
+
if (Number.isFinite(min) && Number.isFinite(max))
|
|
189
|
+
this.setRange(min, max);
|
|
190
|
+
};
|
|
191
|
+
this.shadowRoot?.querySelector("[data-min]")?.addEventListener("change", commit);
|
|
192
|
+
this.shadowRoot?.querySelector("[data-max]")?.addEventListener("change", commit);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
export class HonuaDirectionsElement extends HTMLElementBase {
|
|
196
|
+
static get observedAttributes() {
|
|
197
|
+
return ["label"];
|
|
198
|
+
}
|
|
199
|
+
#route;
|
|
200
|
+
get route() {
|
|
201
|
+
return this.#route;
|
|
202
|
+
}
|
|
203
|
+
set route(route) {
|
|
204
|
+
this.#route = route;
|
|
205
|
+
this.render();
|
|
206
|
+
}
|
|
207
|
+
connectedCallback() {
|
|
208
|
+
this.render();
|
|
209
|
+
}
|
|
210
|
+
attributeChangedCallback() {
|
|
211
|
+
this.render();
|
|
212
|
+
}
|
|
213
|
+
render() {
|
|
214
|
+
const label = this.getAttribute("label") ?? "Directions";
|
|
215
|
+
const steps = (this.#route?.steps ?? [])
|
|
216
|
+
.map((step) => step.text ?? step.maneuver)
|
|
217
|
+
.filter((text) => Boolean(text));
|
|
218
|
+
const summary = this.#route?.summary ?? "";
|
|
219
|
+
const body = steps.length > 0
|
|
220
|
+
? `<p>${escapeText(summary)}</p><ol>${steps.map((step) => `<li>${escapeText(step)}</li>`).join("")}</ol>`
|
|
221
|
+
: `<p>${escapeText(summary)}</p>`;
|
|
222
|
+
section(this, label, body);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers behind sketch snapping, histogram bins, form expressions,
|
|
3
|
+
* multi-feature edits, and elevation samples.
|
|
4
|
+
*/
|
|
5
|
+
export interface SnapPoint {
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function snapVertex(pointer: SnapPoint, vertices: readonly SnapPoint[], enabled: boolean, tolerance?: number): SnapPoint;
|
|
10
|
+
export interface HistogramStats {
|
|
11
|
+
count: number;
|
|
12
|
+
sum: number;
|
|
13
|
+
min: number;
|
|
14
|
+
max: number;
|
|
15
|
+
average: number;
|
|
16
|
+
}
|
|
17
|
+
export interface HistogramBin {
|
|
18
|
+
label: string;
|
|
19
|
+
min: number;
|
|
20
|
+
max: number;
|
|
21
|
+
value: number;
|
|
22
|
+
}
|
|
23
|
+
export declare function histogramBins(values: readonly number[], stats: HistogramStats, classes: number, method: "equal-interval" | "quantile"): HistogramBin[];
|
|
24
|
+
export declare function histogramRangeFilter(min: number, max: number): string;
|
|
25
|
+
export interface FormExpressionField {
|
|
26
|
+
name: string;
|
|
27
|
+
visibleExpression?: string;
|
|
28
|
+
valueExpression?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface FormExpressionResult {
|
|
31
|
+
hidden: string[];
|
|
32
|
+
values: Record<string, unknown>;
|
|
33
|
+
errors: {
|
|
34
|
+
field: string;
|
|
35
|
+
message: string;
|
|
36
|
+
}[];
|
|
37
|
+
}
|
|
38
|
+
export declare function evaluateFormExpressions(fields: readonly FormExpressionField[], feature: {
|
|
39
|
+
attributes?: Record<string, unknown>;
|
|
40
|
+
}): FormExpressionResult;
|
|
41
|
+
export interface FeatureEdit {
|
|
42
|
+
attributes?: Record<string, unknown>;
|
|
43
|
+
}
|
|
44
|
+
export interface ApplyEditsResult {
|
|
45
|
+
error?: string;
|
|
46
|
+
reason?: string;
|
|
47
|
+
}
|
|
48
|
+
export declare function applyToFeatures(features: readonly FeatureEdit[], change: Record<string, unknown>, applyEdits: (edit: {
|
|
49
|
+
update: FeatureEdit;
|
|
50
|
+
}) => Promise<ApplyEditsResult>): Promise<{
|
|
51
|
+
applied: FeatureEdit[];
|
|
52
|
+
rejected: {
|
|
53
|
+
feature: FeatureEdit;
|
|
54
|
+
reason: string;
|
|
55
|
+
}[];
|
|
56
|
+
}>;
|
|
57
|
+
export interface ElevationSample {
|
|
58
|
+
position: [number, number];
|
|
59
|
+
elevation: number;
|
|
60
|
+
}
|
|
61
|
+
export declare function sampleElevations(line: readonly [number, number][], terrain: {
|
|
62
|
+
elevationAt: (longitude: number, latitude: number) => number;
|
|
63
|
+
} | undefined, spacing?: number): {
|
|
64
|
+
samples: ElevationSample[];
|
|
65
|
+
error?: string;
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=widget-capabilities.d.ts.map
|