@deepfuture/dui-map 1.1.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.
- package/README.md +214 -0
- package/cluster-layer/index.d.ts +2 -0
- package/cluster-layer/index.js +2 -0
- package/cluster-layer/map-cluster-layer.d.ts +53 -0
- package/cluster-layer/map-cluster-layer.js +337 -0
- package/controls/index.d.ts +2 -0
- package/controls/index.js +2 -0
- package/controls/map-controls.d.ts +37 -0
- package/controls/map-controls.js +344 -0
- package/heatmap/index.d.ts +2 -0
- package/heatmap/index.js +2 -0
- package/heatmap/map-heatmap.d.ts +39 -0
- package/heatmap/map-heatmap.js +330 -0
- package/index.d.ts +10 -0
- package/index.js +9 -0
- package/map/index.d.ts +5 -0
- package/map/index.js +3 -0
- package/map/map-context.d.ts +8 -0
- package/map/map-context.js +2 -0
- package/map/map.d.ts +120 -0
- package/map/map.js +628 -0
- package/marker/index.d.ts +9 -0
- package/marker/index.js +7 -0
- package/marker/map-marker-content.d.ts +20 -0
- package/marker/map-marker-content.js +135 -0
- package/marker/map-marker-label.d.ts +21 -0
- package/marker/map-marker-label.js +126 -0
- package/marker/map-marker-popup.d.ts +25 -0
- package/marker/map-marker-popup.js +158 -0
- package/marker/map-marker-tooltip.d.ts +22 -0
- package/marker/map-marker-tooltip.js +159 -0
- package/marker/map-marker.d.ts +48 -0
- package/marker/map-marker.js +220 -0
- package/marker/marker-context.d.ts +8 -0
- package/marker/marker-context.js +2 -0
- package/package.json +70 -0
- package/popup/index.d.ts +2 -0
- package/popup/index.js +2 -0
- package/popup/map-popup.d.ts +29 -0
- package/popup/map-popup.js +184 -0
- package/region/index.d.ts +2 -0
- package/region/index.js +2 -0
- package/region/map-region.d.ts +41 -0
- package/region/map-region.js +276 -0
- package/route/index.d.ts +2 -0
- package/route/index.js +2 -0
- package/route/map-route.d.ts +33 -0
- package/route/map-route.js +245 -0
- package/theme/map-theme.d.ts +16 -0
- package/theme/map-theme.js +233 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
35
|
+
import { css, LitElement, html } from "lit";
|
|
36
|
+
import { property } from "lit/decorators.js";
|
|
37
|
+
import { consume } from "@lit/context";
|
|
38
|
+
import { base } from "@deepfuture/dui-primitives/core/base";
|
|
39
|
+
import { mapContext } from "../map/map-context.js";
|
|
40
|
+
const DEFAULT_COLOR_RAMP = [
|
|
41
|
+
"rgba(0,0,255,0)",
|
|
42
|
+
"#00f",
|
|
43
|
+
"#0ff",
|
|
44
|
+
"#0f0",
|
|
45
|
+
"#ff0",
|
|
46
|
+
"#f00",
|
|
47
|
+
];
|
|
48
|
+
const styles = css `
|
|
49
|
+
:host {
|
|
50
|
+
display: contents;
|
|
51
|
+
}
|
|
52
|
+
`;
|
|
53
|
+
/**
|
|
54
|
+
* `<dui-map-heatmap>` — Heatmap density visualization on the map.
|
|
55
|
+
*
|
|
56
|
+
* Accepts a GeoJSON FeatureCollection (or URL string) and renders a heatmap layer
|
|
57
|
+
* with configurable radius, intensity, color ramp, and optional individual points
|
|
58
|
+
* at high zoom levels.
|
|
59
|
+
*/
|
|
60
|
+
let DuiMapHeatmap = (() => {
|
|
61
|
+
let _classSuper = LitElement;
|
|
62
|
+
let _data_decorators;
|
|
63
|
+
let _data_initializers = [];
|
|
64
|
+
let _data_extraInitializers = [];
|
|
65
|
+
let _radius_decorators;
|
|
66
|
+
let _radius_initializers = [];
|
|
67
|
+
let _radius_extraInitializers = [];
|
|
68
|
+
let _intensity_decorators;
|
|
69
|
+
let _intensity_initializers = [];
|
|
70
|
+
let _intensity_extraInitializers = [];
|
|
71
|
+
let _opacity_decorators;
|
|
72
|
+
let _opacity_initializers = [];
|
|
73
|
+
let _opacity_extraInitializers = [];
|
|
74
|
+
let _weight_decorators;
|
|
75
|
+
let _weight_initializers = [];
|
|
76
|
+
let _weight_extraInitializers = [];
|
|
77
|
+
let _maxZoom_decorators;
|
|
78
|
+
let _maxZoom_initializers = [];
|
|
79
|
+
let _maxZoom_extraInitializers = [];
|
|
80
|
+
let _showPoints_decorators;
|
|
81
|
+
let _showPoints_initializers = [];
|
|
82
|
+
let _showPoints_extraInitializers = [];
|
|
83
|
+
let _pointColor_decorators;
|
|
84
|
+
let _pointColor_initializers = [];
|
|
85
|
+
let _pointColor_extraInitializers = [];
|
|
86
|
+
let _colorRamp_decorators;
|
|
87
|
+
let _colorRamp_initializers = [];
|
|
88
|
+
let _colorRamp_extraInitializers = [];
|
|
89
|
+
let _heatmapId_decorators;
|
|
90
|
+
let _heatmapId_initializers = [];
|
|
91
|
+
let _heatmapId_extraInitializers = [];
|
|
92
|
+
let __mapCtx_decorators;
|
|
93
|
+
let __mapCtx_initializers = [];
|
|
94
|
+
let __mapCtx_extraInitializers = [];
|
|
95
|
+
return class DuiMapHeatmap extends _classSuper {
|
|
96
|
+
static {
|
|
97
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
98
|
+
_data_decorators = [property({ type: String })];
|
|
99
|
+
_radius_decorators = [property({ type: Number })];
|
|
100
|
+
_intensity_decorators = [property({ type: Number })];
|
|
101
|
+
_opacity_decorators = [property({ type: Number })];
|
|
102
|
+
_weight_decorators = [property()];
|
|
103
|
+
_maxZoom_decorators = [property({ type: Number, attribute: "max-zoom" })];
|
|
104
|
+
_showPoints_decorators = [property({ type: Boolean, attribute: "show-points" })];
|
|
105
|
+
_pointColor_decorators = [property({ attribute: "point-color" })];
|
|
106
|
+
_colorRamp_decorators = [property({ type: Array, attribute: "color-ramp" })];
|
|
107
|
+
_heatmapId_decorators = [property({ attribute: "heatmap-id" })];
|
|
108
|
+
__mapCtx_decorators = [consume({ context: mapContext, subscribe: true })];
|
|
109
|
+
__esDecorate(this, null, _data_decorators, { kind: "accessor", name: "data", static: false, private: false, access: { has: obj => "data" in obj, get: obj => obj.data, set: (obj, value) => { obj.data = value; } }, metadata: _metadata }, _data_initializers, _data_extraInitializers);
|
|
110
|
+
__esDecorate(this, null, _radius_decorators, { kind: "accessor", name: "radius", static: false, private: false, access: { has: obj => "radius" in obj, get: obj => obj.radius, set: (obj, value) => { obj.radius = value; } }, metadata: _metadata }, _radius_initializers, _radius_extraInitializers);
|
|
111
|
+
__esDecorate(this, null, _intensity_decorators, { kind: "accessor", name: "intensity", static: false, private: false, access: { has: obj => "intensity" in obj, get: obj => obj.intensity, set: (obj, value) => { obj.intensity = value; } }, metadata: _metadata }, _intensity_initializers, _intensity_extraInitializers);
|
|
112
|
+
__esDecorate(this, null, _opacity_decorators, { kind: "accessor", name: "opacity", static: false, private: false, access: { has: obj => "opacity" in obj, get: obj => obj.opacity, set: (obj, value) => { obj.opacity = value; } }, metadata: _metadata }, _opacity_initializers, _opacity_extraInitializers);
|
|
113
|
+
__esDecorate(this, null, _weight_decorators, { kind: "accessor", name: "weight", static: false, private: false, access: { has: obj => "weight" in obj, get: obj => obj.weight, set: (obj, value) => { obj.weight = value; } }, metadata: _metadata }, _weight_initializers, _weight_extraInitializers);
|
|
114
|
+
__esDecorate(this, null, _maxZoom_decorators, { kind: "accessor", name: "maxZoom", static: false, private: false, access: { has: obj => "maxZoom" in obj, get: obj => obj.maxZoom, set: (obj, value) => { obj.maxZoom = value; } }, metadata: _metadata }, _maxZoom_initializers, _maxZoom_extraInitializers);
|
|
115
|
+
__esDecorate(this, null, _showPoints_decorators, { kind: "accessor", name: "showPoints", static: false, private: false, access: { has: obj => "showPoints" in obj, get: obj => obj.showPoints, set: (obj, value) => { obj.showPoints = value; } }, metadata: _metadata }, _showPoints_initializers, _showPoints_extraInitializers);
|
|
116
|
+
__esDecorate(this, null, _pointColor_decorators, { kind: "accessor", name: "pointColor", static: false, private: false, access: { has: obj => "pointColor" in obj, get: obj => obj.pointColor, set: (obj, value) => { obj.pointColor = value; } }, metadata: _metadata }, _pointColor_initializers, _pointColor_extraInitializers);
|
|
117
|
+
__esDecorate(this, null, _colorRamp_decorators, { kind: "accessor", name: "colorRamp", static: false, private: false, access: { has: obj => "colorRamp" in obj, get: obj => obj.colorRamp, set: (obj, value) => { obj.colorRamp = value; } }, metadata: _metadata }, _colorRamp_initializers, _colorRamp_extraInitializers);
|
|
118
|
+
__esDecorate(this, null, _heatmapId_decorators, { kind: "accessor", name: "heatmapId", static: false, private: false, access: { has: obj => "heatmapId" in obj, get: obj => obj.heatmapId, set: (obj, value) => { obj.heatmapId = value; } }, metadata: _metadata }, _heatmapId_initializers, _heatmapId_extraInitializers);
|
|
119
|
+
__esDecorate(this, null, __mapCtx_decorators, { kind: "accessor", name: "_mapCtx", static: false, private: false, access: { has: obj => "_mapCtx" in obj, get: obj => obj._mapCtx, set: (obj, value) => { obj._mapCtx = value; } }, metadata: _metadata }, __mapCtx_initializers, __mapCtx_extraInitializers);
|
|
120
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
121
|
+
}
|
|
122
|
+
static tagName = "dui-map-heatmap";
|
|
123
|
+
static styles = [base, styles];
|
|
124
|
+
#data_accessor_storage = __runInitializers(this, _data_initializers, "");
|
|
125
|
+
/** GeoJSON data URL or inline FeatureCollection. */
|
|
126
|
+
get data() { return this.#data_accessor_storage; }
|
|
127
|
+
set data(value) { this.#data_accessor_storage = value; }
|
|
128
|
+
#radius_accessor_storage = (__runInitializers(this, _data_extraInitializers), __runInitializers(this, _radius_initializers, 20));
|
|
129
|
+
/** Heatmap kernel radius in pixels. */
|
|
130
|
+
get radius() { return this.#radius_accessor_storage; }
|
|
131
|
+
set radius(value) { this.#radius_accessor_storage = value; }
|
|
132
|
+
#intensity_accessor_storage = (__runInitializers(this, _radius_extraInitializers), __runInitializers(this, _intensity_initializers, 1));
|
|
133
|
+
/** Global intensity multiplier. */
|
|
134
|
+
get intensity() { return this.#intensity_accessor_storage; }
|
|
135
|
+
set intensity(value) { this.#intensity_accessor_storage = value; }
|
|
136
|
+
#opacity_accessor_storage = (__runInitializers(this, _intensity_extraInitializers), __runInitializers(this, _opacity_initializers, 0.8));
|
|
137
|
+
/** Heatmap layer opacity (0–1). */
|
|
138
|
+
get opacity() { return this.#opacity_accessor_storage; }
|
|
139
|
+
set opacity(value) { this.#opacity_accessor_storage = value; }
|
|
140
|
+
#weight_accessor_storage = (__runInitializers(this, _opacity_extraInitializers), __runInitializers(this, _weight_initializers, ""));
|
|
141
|
+
/** GeoJSON property name to use as point weight. Empty = equal weight. */
|
|
142
|
+
get weight() { return this.#weight_accessor_storage; }
|
|
143
|
+
set weight(value) { this.#weight_accessor_storage = value; }
|
|
144
|
+
#maxZoom_accessor_storage = (__runInitializers(this, _weight_extraInitializers), __runInitializers(this, _maxZoom_initializers, 9));
|
|
145
|
+
/** Maximum zoom at which the heatmap is visible. Above this, show individual points. */
|
|
146
|
+
get maxZoom() { return this.#maxZoom_accessor_storage; }
|
|
147
|
+
set maxZoom(value) { this.#maxZoom_accessor_storage = value; }
|
|
148
|
+
#showPoints_accessor_storage = (__runInitializers(this, _maxZoom_extraInitializers), __runInitializers(this, _showPoints_initializers, true));
|
|
149
|
+
/** Whether to show individual points when zoomed past maxZoom. */
|
|
150
|
+
get showPoints() { return this.#showPoints_accessor_storage; }
|
|
151
|
+
set showPoints(value) { this.#showPoints_accessor_storage = value; }
|
|
152
|
+
#pointColor_accessor_storage = (__runInitializers(this, _showPoints_extraInitializers), __runInitializers(this, _pointColor_initializers, "#3b82f6"));
|
|
153
|
+
/** Color for individual points (shown above maxZoom). */
|
|
154
|
+
get pointColor() { return this.#pointColor_accessor_storage; }
|
|
155
|
+
set pointColor(value) { this.#pointColor_accessor_storage = value; }
|
|
156
|
+
#colorRamp_accessor_storage = (__runInitializers(this, _pointColor_extraInitializers), __runInitializers(this, _colorRamp_initializers, DEFAULT_COLOR_RAMP));
|
|
157
|
+
/** Array of CSS colors for the heatmap gradient from cool→hot. */
|
|
158
|
+
get colorRamp() { return this.#colorRamp_accessor_storage; }
|
|
159
|
+
set colorRamp(value) { this.#colorRamp_accessor_storage = value; }
|
|
160
|
+
#heatmapId_accessor_storage = (__runInitializers(this, _colorRamp_extraInitializers), __runInitializers(this, _heatmapId_initializers, `heatmap-${Math.random().toString(36).slice(2, 9)}`));
|
|
161
|
+
/** Unique ID for source/layer. Auto-generated if not set. */
|
|
162
|
+
get heatmapId() { return this.#heatmapId_accessor_storage; }
|
|
163
|
+
set heatmapId(value) { this.#heatmapId_accessor_storage = value; }
|
|
164
|
+
#_mapCtx_accessor_storage = (__runInitializers(this, _heatmapId_extraInitializers), __runInitializers(this, __mapCtx_initializers, void 0));
|
|
165
|
+
get _mapCtx() { return this.#_mapCtx_accessor_storage; }
|
|
166
|
+
set _mapCtx(value) { this.#_mapCtx_accessor_storage = value; }
|
|
167
|
+
#sourceId = (__runInitializers(this, __mapCtx_extraInitializers), "");
|
|
168
|
+
#heatmapLayerId = "";
|
|
169
|
+
#pointLayerId = "";
|
|
170
|
+
#layersAdded = false;
|
|
171
|
+
connectedCallback() {
|
|
172
|
+
super.connectedCallback();
|
|
173
|
+
this.#sourceId = `heatmap-source-${this.heatmapId}`;
|
|
174
|
+
this.#heatmapLayerId = `heatmap-layer-${this.heatmapId}`;
|
|
175
|
+
this.#pointLayerId = `heatmap-points-${this.heatmapId}`;
|
|
176
|
+
}
|
|
177
|
+
disconnectedCallback() {
|
|
178
|
+
super.disconnectedCallback();
|
|
179
|
+
this.#removeLayers();
|
|
180
|
+
}
|
|
181
|
+
updated(changed) {
|
|
182
|
+
const map = this._mapCtx?.map;
|
|
183
|
+
const isLoaded = this._mapCtx?.isLoaded;
|
|
184
|
+
if (!map || !isLoaded)
|
|
185
|
+
return;
|
|
186
|
+
if (!this.#layersAdded) {
|
|
187
|
+
this.#addLayers(map);
|
|
188
|
+
}
|
|
189
|
+
// Update source data when data changes (for non-URL data)
|
|
190
|
+
if (changed.has("data") && typeof this.data !== "string") {
|
|
191
|
+
const source = map.getSource(this.#sourceId);
|
|
192
|
+
if (source) {
|
|
193
|
+
source.setData(this.data);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// Update heatmap paint properties
|
|
197
|
+
if (changed.has("radius") || changed.has("maxZoom")) {
|
|
198
|
+
if (map.getLayer(this.#heatmapLayerId)) {
|
|
199
|
+
map.setPaintProperty(this.#heatmapLayerId, "heatmap-radius", [
|
|
200
|
+
"interpolate", ["linear"], ["zoom"],
|
|
201
|
+
0, 2,
|
|
202
|
+
this.maxZoom, this.radius,
|
|
203
|
+
]);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (changed.has("intensity") || changed.has("maxZoom")) {
|
|
207
|
+
if (map.getLayer(this.#heatmapLayerId)) {
|
|
208
|
+
map.setPaintProperty(this.#heatmapLayerId, "heatmap-intensity", [
|
|
209
|
+
"interpolate", ["linear"], ["zoom"],
|
|
210
|
+
0, 1,
|
|
211
|
+
this.maxZoom, this.intensity,
|
|
212
|
+
]);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (changed.has("opacity") || changed.has("maxZoom")) {
|
|
216
|
+
if (map.getLayer(this.#heatmapLayerId)) {
|
|
217
|
+
map.setPaintProperty(this.#heatmapLayerId, "heatmap-opacity", [
|
|
218
|
+
"interpolate", ["linear"], ["zoom"],
|
|
219
|
+
7, this.opacity,
|
|
220
|
+
this.maxZoom, 0,
|
|
221
|
+
]);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (changed.has("colorRamp")) {
|
|
225
|
+
if (map.getLayer(this.#heatmapLayerId)) {
|
|
226
|
+
map.setPaintProperty(this.#heatmapLayerId, "heatmap-color", this.#buildColorRamp());
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (changed.has("pointColor")) {
|
|
230
|
+
if (map.getLayer(this.#pointLayerId)) {
|
|
231
|
+
map.setPaintProperty(this.#pointLayerId, "circle-color", this.pointColor);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
#buildColorRamp() {
|
|
236
|
+
const ramp = this.colorRamp;
|
|
237
|
+
const expr = ["interpolate", ["linear"], ["heatmap-density"]];
|
|
238
|
+
for (let i = 0; i < ramp.length; i++) {
|
|
239
|
+
expr.push(i / (ramp.length - 1));
|
|
240
|
+
expr.push(ramp[i]);
|
|
241
|
+
}
|
|
242
|
+
return expr;
|
|
243
|
+
}
|
|
244
|
+
#addLayers(map) {
|
|
245
|
+
if (map.getSource(this.#sourceId))
|
|
246
|
+
return;
|
|
247
|
+
map.addSource(this.#sourceId, {
|
|
248
|
+
type: "geojson",
|
|
249
|
+
data: this.data,
|
|
250
|
+
});
|
|
251
|
+
// Heatmap weight expression
|
|
252
|
+
const heatmapWeight = this.weight
|
|
253
|
+
? ["interpolate", ["linear"], ["get", this.weight], 0, 0, 6, 1]
|
|
254
|
+
: 1;
|
|
255
|
+
// Heatmap layer
|
|
256
|
+
map.addLayer({
|
|
257
|
+
id: this.#heatmapLayerId,
|
|
258
|
+
type: "heatmap",
|
|
259
|
+
source: this.#sourceId,
|
|
260
|
+
maxzoom: this.maxZoom,
|
|
261
|
+
paint: {
|
|
262
|
+
"heatmap-weight": heatmapWeight,
|
|
263
|
+
"heatmap-intensity": [
|
|
264
|
+
"interpolate", ["linear"], ["zoom"],
|
|
265
|
+
0, 1,
|
|
266
|
+
this.maxZoom, this.intensity,
|
|
267
|
+
],
|
|
268
|
+
"heatmap-color": this.#buildColorRamp(),
|
|
269
|
+
"heatmap-radius": [
|
|
270
|
+
"interpolate", ["linear"], ["zoom"],
|
|
271
|
+
0, 2,
|
|
272
|
+
this.maxZoom, this.radius,
|
|
273
|
+
],
|
|
274
|
+
"heatmap-opacity": [
|
|
275
|
+
"interpolate", ["linear"], ["zoom"],
|
|
276
|
+
7, this.opacity,
|
|
277
|
+
this.maxZoom, 0,
|
|
278
|
+
],
|
|
279
|
+
},
|
|
280
|
+
});
|
|
281
|
+
// Individual points layer (visible above maxZoom)
|
|
282
|
+
if (this.showPoints) {
|
|
283
|
+
map.addLayer({
|
|
284
|
+
id: this.#pointLayerId,
|
|
285
|
+
type: "circle",
|
|
286
|
+
source: this.#sourceId,
|
|
287
|
+
minzoom: this.maxZoom,
|
|
288
|
+
paint: {
|
|
289
|
+
"circle-radius": [
|
|
290
|
+
"interpolate", ["linear"], ["zoom"],
|
|
291
|
+
this.maxZoom, 2,
|
|
292
|
+
22, 8,
|
|
293
|
+
],
|
|
294
|
+
"circle-color": this.pointColor,
|
|
295
|
+
"circle-stroke-width": 1,
|
|
296
|
+
"circle-stroke-color": "#fff",
|
|
297
|
+
"circle-opacity": [
|
|
298
|
+
"interpolate", ["linear"], ["zoom"],
|
|
299
|
+
this.maxZoom, 0,
|
|
300
|
+
this.maxZoom + 1, 1,
|
|
301
|
+
],
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
this.#layersAdded = true;
|
|
306
|
+
}
|
|
307
|
+
#removeLayers() {
|
|
308
|
+
const map = this._mapCtx?.map;
|
|
309
|
+
if (!map)
|
|
310
|
+
return;
|
|
311
|
+
try {
|
|
312
|
+
if (map.getLayer(this.#pointLayerId))
|
|
313
|
+
map.removeLayer(this.#pointLayerId);
|
|
314
|
+
if (map.getLayer(this.#heatmapLayerId))
|
|
315
|
+
map.removeLayer(this.#heatmapLayerId);
|
|
316
|
+
if (map.getSource(this.#sourceId))
|
|
317
|
+
map.removeSource(this.#sourceId);
|
|
318
|
+
}
|
|
319
|
+
catch {
|
|
320
|
+
// Map may already be destroyed
|
|
321
|
+
}
|
|
322
|
+
this.#layersAdded = false;
|
|
323
|
+
}
|
|
324
|
+
render() {
|
|
325
|
+
return html ``;
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
})();
|
|
329
|
+
export { DuiMapHeatmap };
|
|
330
|
+
customElements.define(DuiMapHeatmap.tagName, DuiMapHeatmap);
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { DuiMap, viewportChangeEvent, mapLoadEvent, mapClickEvent, mapDblClickEvent, mapContextMenuEvent, mapContext, } from "./map/index.js";
|
|
2
|
+
export type { MapContext, MapViewport, MapClickDetail } from "./map/index.js";
|
|
3
|
+
export { DuiMapMarker, DuiMapMarkerContent, DuiMapMarkerPopup, DuiMapMarkerTooltip, DuiMapMarkerLabel, dragStartEvent, dragEvent, dragEndEvent, markerContext, } from "./marker/index.js";
|
|
4
|
+
export type { MarkerContext, LngLat } from "./marker/index.js";
|
|
5
|
+
export { DuiMapControls, locateEvent } from "./controls/index.js";
|
|
6
|
+
export { DuiMapPopup, popupCloseEvent } from "./popup/index.js";
|
|
7
|
+
export { DuiMapRoute, routeClickEvent } from "./route/index.js";
|
|
8
|
+
export { DuiMapRegion, regionClickEvent } from "./region/index.js";
|
|
9
|
+
export { DuiMapClusterLayer, pointClickEvent, clusterClickEvent } from "./cluster-layer/index.js";
|
|
10
|
+
export { DuiMapHeatmap } from "./heatmap/index.js";
|
package/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// --- Components (self-registering) ---
|
|
2
|
+
export { DuiMap, viewportChangeEvent, mapLoadEvent, mapClickEvent, mapDblClickEvent, mapContextMenuEvent, mapContext, } from "./map/index.js";
|
|
3
|
+
export { DuiMapMarker, DuiMapMarkerContent, DuiMapMarkerPopup, DuiMapMarkerTooltip, DuiMapMarkerLabel, dragStartEvent, dragEvent, dragEndEvent, markerContext, } from "./marker/index.js";
|
|
4
|
+
export { DuiMapControls, locateEvent } from "./controls/index.js";
|
|
5
|
+
export { DuiMapPopup, popupCloseEvent } from "./popup/index.js";
|
|
6
|
+
export { DuiMapRoute, routeClickEvent } from "./route/index.js";
|
|
7
|
+
export { DuiMapRegion, regionClickEvent } from "./region/index.js";
|
|
8
|
+
export { DuiMapClusterLayer, pointClickEvent, clusterClickEvent } from "./cluster-layer/index.js";
|
|
9
|
+
export { DuiMapHeatmap } from "./heatmap/index.js";
|
package/map/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { DuiMap, viewportChangeEvent, mapLoadEvent, mapClickEvent, mapDblClickEvent, mapContextMenuEvent } from "./map.js";
|
|
2
|
+
export { DuiMap, viewportChangeEvent, mapLoadEvent, mapClickEvent, mapDblClickEvent, mapContextMenuEvent, };
|
|
3
|
+
export { mapContext } from "./map-context.js";
|
|
4
|
+
export type { MapContext } from "./map-context.js";
|
|
5
|
+
export type { MapViewport, MapClickDetail } from "./map.js";
|
package/map/index.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { DuiMap, viewportChangeEvent, mapLoadEvent, mapClickEvent, mapDblClickEvent, mapContextMenuEvent, } from "./map.js";
|
|
2
|
+
export { DuiMap, viewportChangeEvent, mapLoadEvent, mapClickEvent, mapDblClickEvent, mapContextMenuEvent, };
|
|
3
|
+
export { mapContext } from "./map-context.js";
|
package/map/map.d.ts
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { LitElement, type PropertyValues, type TemplateResult } from "lit";
|
|
2
|
+
import MapLibreGL from "maplibre-gl";
|
|
3
|
+
import { type MapContext } from "./map-context.js";
|
|
4
|
+
/** Fired when the map viewport changes (pan, zoom, rotate, pitch). */
|
|
5
|
+
export declare const viewportChangeEvent: (detail: MapViewport) => CustomEvent<MapViewport>;
|
|
6
|
+
/** Fired when the map finishes initial load. */
|
|
7
|
+
export declare const mapLoadEvent: (detail: void) => CustomEvent<void>;
|
|
8
|
+
export type MapClickDetail = {
|
|
9
|
+
lngLat: {
|
|
10
|
+
lng: number;
|
|
11
|
+
lat: number;
|
|
12
|
+
};
|
|
13
|
+
point: {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
/** Fired on single click on the map canvas. */
|
|
19
|
+
export declare const mapClickEvent: (detail: MapClickDetail) => CustomEvent<MapClickDetail>;
|
|
20
|
+
/** Fired on double-click on the map canvas. */
|
|
21
|
+
export declare const mapDblClickEvent: (detail: MapClickDetail) => CustomEvent<MapClickDetail>;
|
|
22
|
+
/** Fired on right-click / long-press on the map canvas. */
|
|
23
|
+
export declare const mapContextMenuEvent: (detail: MapClickDetail) => CustomEvent<MapClickDetail>;
|
|
24
|
+
export type MapViewport = {
|
|
25
|
+
center: [number, number];
|
|
26
|
+
zoom: number;
|
|
27
|
+
bearing: number;
|
|
28
|
+
pitch: number;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* `<dui-map>` — Root map component wrapping MapLibre GL JS.
|
|
32
|
+
*
|
|
33
|
+
* Initializes a MapLibre map inside its shadow DOM with CSS properly adopted.
|
|
34
|
+
* Provides map context to child components via Lit Context.
|
|
35
|
+
* Auto-detects light/dark theme from `data-theme` attribute on `<html>`.
|
|
36
|
+
*
|
|
37
|
+
* @slot - Map overlay content (controls, markers, popups, routes, etc.)
|
|
38
|
+
* @csspart container - The map container div.
|
|
39
|
+
* @csspart loader - The loading indicator overlay.
|
|
40
|
+
* @fires dui-map-viewport-change - Fired on pan/zoom/rotate/pitch. Detail: MapViewport
|
|
41
|
+
* @fires dui-map-load - Fired when map finishes loading.
|
|
42
|
+
* @fires dui-map-click - Fired on single click. Detail: MapClickDetail
|
|
43
|
+
* @fires dui-map-dblclick - Fired on double-click. Detail: MapClickDetail
|
|
44
|
+
* @fires dui-map-contextmenu - Fired on right-click / long-press. Detail: MapClickDetail
|
|
45
|
+
*/
|
|
46
|
+
export declare class DuiMap extends LitElement {
|
|
47
|
+
#private;
|
|
48
|
+
static tagName: "dui-map";
|
|
49
|
+
static styles: import("lit").CSSResult[];
|
|
50
|
+
/**
|
|
51
|
+
* Center coordinates as `[longitude, latitude]`.
|
|
52
|
+
* Accepts a JSON array string or is set programmatically.
|
|
53
|
+
*/
|
|
54
|
+
accessor center: [number, number];
|
|
55
|
+
/** Zoom level (0–22). */
|
|
56
|
+
accessor zoom: number;
|
|
57
|
+
/** Bearing (rotation) in degrees. */
|
|
58
|
+
accessor bearing: number;
|
|
59
|
+
/** Pitch (tilt) in degrees. */
|
|
60
|
+
accessor pitch: number;
|
|
61
|
+
/** Force a specific theme. When unset, auto-detects from document. */
|
|
62
|
+
accessor theme: "light" | "dark" | undefined;
|
|
63
|
+
/** Custom style URL for light theme. */
|
|
64
|
+
accessor styleLight: string | undefined;
|
|
65
|
+
/** Custom style URL for dark theme. */
|
|
66
|
+
accessor styleDark: string | undefined;
|
|
67
|
+
/** Show loading overlay. */
|
|
68
|
+
accessor loading: boolean;
|
|
69
|
+
/** Disable world copies (repeating map). */
|
|
70
|
+
accessor noWorldCopies: boolean;
|
|
71
|
+
/** Whether the viewport is controlled externally. */
|
|
72
|
+
accessor controlled: boolean;
|
|
73
|
+
/** Minimum zoom level (0–22). */
|
|
74
|
+
accessor minZoom: number;
|
|
75
|
+
/** Maximum zoom level (0–22). */
|
|
76
|
+
accessor maxZoom: number;
|
|
77
|
+
/** SW and NE corners constraining the viewable area. */
|
|
78
|
+
accessor maxBounds: [[number, number], [number, number]] | undefined;
|
|
79
|
+
/** SW and NE corners as [[swLng, swLat], [neLng, neLat]]. Flies to fit when set. */
|
|
80
|
+
accessor bounds: [[number, number], [number, number]] | undefined;
|
|
81
|
+
/** Padding in pixels applied to fitBounds calls. */
|
|
82
|
+
accessor boundsPadding: number;
|
|
83
|
+
accessor _ctx: MapContext;
|
|
84
|
+
connectedCallback(): void;
|
|
85
|
+
disconnectedCallback(): void;
|
|
86
|
+
firstUpdated(): void;
|
|
87
|
+
updated(changed: PropertyValues): void;
|
|
88
|
+
/** Get the raw MapLibre GL instance. */
|
|
89
|
+
getMapInstance(): MapLibreGL.Map | null;
|
|
90
|
+
/** Animate to a position with a parabolic flight path. */
|
|
91
|
+
flyTo(options: {
|
|
92
|
+
center?: [number, number];
|
|
93
|
+
zoom?: number;
|
|
94
|
+
bearing?: number;
|
|
95
|
+
pitch?: number;
|
|
96
|
+
duration?: number;
|
|
97
|
+
curve?: number;
|
|
98
|
+
}): void;
|
|
99
|
+
/** Animate to a position with a linear ease. */
|
|
100
|
+
easeTo(options: {
|
|
101
|
+
center?: [number, number];
|
|
102
|
+
zoom?: number;
|
|
103
|
+
bearing?: number;
|
|
104
|
+
pitch?: number;
|
|
105
|
+
duration?: number;
|
|
106
|
+
}): void;
|
|
107
|
+
/** Fly to fit the given bounds. */
|
|
108
|
+
fitBounds(bounds: [[number, number], [number, number]], options?: {
|
|
109
|
+
padding?: number;
|
|
110
|
+
maxZoom?: number;
|
|
111
|
+
duration?: number;
|
|
112
|
+
}): void;
|
|
113
|
+
/** Compute a bounding box from all child dui-map-marker elements and fly to fit them. */
|
|
114
|
+
fitToMarkers(options?: {
|
|
115
|
+
padding?: number;
|
|
116
|
+
maxZoom?: number;
|
|
117
|
+
duration?: number;
|
|
118
|
+
}): void;
|
|
119
|
+
render(): TemplateResult;
|
|
120
|
+
}
|