@opendfieldmap/map 0.2.1-beta → 0.2.3-beta
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/dist/index.js +2 -1
- package/dist/index.js.map +2 -2
- package/dist/runtime/geometry.d.ts +13 -0
- package/dist/runtime/helpers.d.ts +12 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/layers.d.ts +19 -0
- package/dist/runtime/oem.d.ts +145 -0
- package/dist/{runtime-YB3JS7EZ.js → runtime-6QYIDK3F.js} +240 -104
- package/dist/runtime-6QYIDK3F.js.map +7 -0
- package/dist/runtime.d.ts +2 -139
- package/dist/style.css +4 -4
- package/package.json +2 -2
- package/dist/runtime-YB3JS7EZ.js.map +0 -7
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// packages/map/src/runtime.ts
|
|
2
|
-
import
|
|
1
|
+
// packages/map/src/runtime/oem.ts
|
|
2
|
+
import L5 from "leaflet";
|
|
3
3
|
import "leaflet.markercluster";
|
|
4
4
|
import {
|
|
5
5
|
createOEMPointUrl,
|
|
@@ -13,25 +13,8 @@ import {
|
|
|
13
13
|
toOEMLeafletPosition
|
|
14
14
|
} from "@opendfieldmap/core";
|
|
15
15
|
|
|
16
|
-
// packages/map/src/atlos/smoothTileLayer.ts
|
|
17
|
-
import L from "leaflet";
|
|
18
|
-
var SmoothTileLayer = class extends L.TileLayer {
|
|
19
|
-
_setZoomTransform(level, center, zoom) {
|
|
20
|
-
const map = this._map;
|
|
21
|
-
if (!map)
|
|
22
|
-
return;
|
|
23
|
-
const scale = map.getZoomScale(zoom, level.zoom);
|
|
24
|
-
const translate = level.origin.multiplyBy(scale).subtract(map._getNewPixelOrigin(center, zoom));
|
|
25
|
-
if (L.Browser.any3d) {
|
|
26
|
-
L.DomUtil.setTransform(level.el, translate, scale);
|
|
27
|
-
} else {
|
|
28
|
-
L.DomUtil.setPosition(level.el, translate);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
|
|
33
16
|
// packages/map/src/atlos/smoothWheelZoom.ts
|
|
34
|
-
import
|
|
17
|
+
import L from "leaflet";
|
|
35
18
|
import { WHEEL_GESTURE_IDLE_MS, WheelInputRouter } from "trackpad-input";
|
|
36
19
|
var ZOOM_PER_WHEEL_PIXEL = 3e-3;
|
|
37
20
|
var TRACKPAD_PINCH_ZOOM_PER_PIXEL = 0.01;
|
|
@@ -74,7 +57,7 @@ var SmoothWheelZoom = class {
|
|
|
74
57
|
lastZoomInputTime = null;
|
|
75
58
|
inertiaStep = 0;
|
|
76
59
|
lastFrameTime = null;
|
|
77
|
-
pendingPanOffset =
|
|
60
|
+
pendingPanOffset = L.point(0, 0);
|
|
78
61
|
panRawCenterPoint = null;
|
|
79
62
|
gestureMode = null;
|
|
80
63
|
gestureActive = false;
|
|
@@ -138,7 +121,7 @@ var SmoothWheelZoom = class {
|
|
|
138
121
|
this.handleZoom(event);
|
|
139
122
|
}
|
|
140
123
|
handleZoom(event) {
|
|
141
|
-
const wheelDelta =
|
|
124
|
+
const wheelDelta = L.DomEvent.getWheelDelta(event);
|
|
142
125
|
if (!wheelDelta)
|
|
143
126
|
return;
|
|
144
127
|
const zoomDelta = event.ctrlKey && event.deltaMode === 0 ? -event.deltaY * TRACKPAD_PINCH_ZOOM_PER_PIXEL : wheelDelta * ZOOM_PER_WHEEL_PIXEL;
|
|
@@ -160,7 +143,7 @@ var SmoothWheelZoom = class {
|
|
|
160
143
|
this.scheduleGestureEnd();
|
|
161
144
|
}
|
|
162
145
|
handleTrackpadPan(event) {
|
|
163
|
-
const offset =
|
|
146
|
+
const offset = L.point(event.deltaX, event.deltaY);
|
|
164
147
|
if (offset.x === 0 && offset.y === 0) {
|
|
165
148
|
if (this.gestureActive && !this.overdragSettling) {
|
|
166
149
|
this.scheduleGestureEnd();
|
|
@@ -251,7 +234,7 @@ var SmoothWheelZoom = class {
|
|
|
251
234
|
if (!this.gestureActive || this.gestureMode !== "pan")
|
|
252
235
|
return;
|
|
253
236
|
const offset = this.pendingPanOffset;
|
|
254
|
-
this.pendingPanOffset =
|
|
237
|
+
this.pendingPanOffset = L.point(0, 0);
|
|
255
238
|
if (offset.x !== 0 || offset.y !== 0) {
|
|
256
239
|
const overdragAmount = this.applyConstrainedPan(offset);
|
|
257
240
|
this.map.fire("move").fire("drag");
|
|
@@ -277,12 +260,12 @@ var SmoothWheelZoom = class {
|
|
|
277
260
|
this.map._rawPanBy(offset);
|
|
278
261
|
return 0;
|
|
279
262
|
}
|
|
280
|
-
const maxBounds = configuredBounds instanceof
|
|
263
|
+
const maxBounds = configuredBounds instanceof L.LatLngBounds ? configuredBounds : L.latLngBounds(configuredBounds);
|
|
281
264
|
const rawCenter = this.map.unproject(this.panRawCenterPoint, zoom);
|
|
282
265
|
const limitedCenter = this.map._limitCenter(rawCenter, zoom, maxBounds);
|
|
283
266
|
const limitedCenterPoint = this.map.project(limitedCenter, zoom);
|
|
284
267
|
const rawOverdrag = this.panRawCenterPoint.subtract(limitedCenterPoint);
|
|
285
|
-
const visualOverdrag =
|
|
268
|
+
const visualOverdrag = L.point(this.resistOverdrag(rawOverdrag.x), this.resistOverdrag(rawOverdrag.y));
|
|
286
269
|
const visualCenterPoint = limitedCenterPoint.add(visualOverdrag);
|
|
287
270
|
const visualOffset = visualCenterPoint.subtract(currentCenterPoint);
|
|
288
271
|
if (visualOffset.x !== 0 || visualOffset.y !== 0) {
|
|
@@ -329,7 +312,7 @@ var SmoothWheelZoom = class {
|
|
|
329
312
|
let center = this.map.unproject(this.map.project(this.anchorLatLng, zoom).subtract(cursorOffset), zoom);
|
|
330
313
|
const configuredBounds = this.map.options.maxBounds;
|
|
331
314
|
if (configuredBounds) {
|
|
332
|
-
const maxBounds = configuredBounds instanceof
|
|
315
|
+
const maxBounds = configuredBounds instanceof L.LatLngBounds ? configuredBounds : L.latLngBounds(configuredBounds);
|
|
333
316
|
center = this.map._limitCenter(center, zoom, maxBounds);
|
|
334
317
|
}
|
|
335
318
|
this.map._move(center, zoom, CONTINUOUS_ZOOM_EVENT_DATA);
|
|
@@ -384,7 +367,7 @@ var SmoothWheelZoom = class {
|
|
|
384
367
|
this.lastZoomInputTime = null;
|
|
385
368
|
this.inertiaStep = 0;
|
|
386
369
|
this.lastFrameTime = null;
|
|
387
|
-
this.pendingPanOffset =
|
|
370
|
+
this.pendingPanOffset = L.point(0, 0);
|
|
388
371
|
this.panRawCenterPoint = null;
|
|
389
372
|
this.gestureMode = null;
|
|
390
373
|
this.trackpadDragging = false;
|
|
@@ -411,13 +394,13 @@ var SmoothWheelZoom = class {
|
|
|
411
394
|
var enableSmoothWheelZoom = (map, options) => new SmoothWheelZoom(map, options);
|
|
412
395
|
|
|
413
396
|
// packages/map/src/atlos/mapOverdrag.ts
|
|
414
|
-
import
|
|
397
|
+
import L2 from "leaflet";
|
|
415
398
|
var toMapBounds = (bounds) => {
|
|
416
399
|
if (!bounds)
|
|
417
400
|
return null;
|
|
418
|
-
if (bounds instanceof
|
|
401
|
+
if (bounds instanceof L2.LatLngBounds)
|
|
419
402
|
return bounds;
|
|
420
|
-
return Array.isArray(bounds) && bounds.length === 2 ?
|
|
403
|
+
return Array.isArray(bounds) && bounds.length === 2 ? L2.latLngBounds(bounds[0], bounds[1]) : null;
|
|
421
404
|
};
|
|
422
405
|
var isMapOverdragged = (map, bounds) => {
|
|
423
406
|
const constrainedMap = map;
|
|
@@ -426,6 +409,76 @@ var isMapOverdragged = (map, bounds) => {
|
|
|
426
409
|
return map.project(center, map.getZoom()).distanceTo(map.project(constrainedCenter, map.getZoom())) > 1;
|
|
427
410
|
};
|
|
428
411
|
|
|
412
|
+
// packages/map/src/assets/ghicon.svg
|
|
413
|
+
var ghicon_default = '<svg width="83" height="81" viewBox="0 0 83 81" xmlns="http://www.w3.org/2000/svg">\n<path fill-rule="evenodd" clip-rule="evenodd" d="M41.3763 0C18.4963 0 0 18.5625 0 41.5268C0 59.8835 11.8512 75.422 28.292 80.9215C30.3475 81.335 31.1004 80.028 31.1004 78.9286C31.1004 77.9659 31.0327 74.666 31.0327 71.2277C19.5228 73.7032 17.1259 66.2774 17.1259 66.2774C15.2762 61.4647 12.5355 60.2277 12.5355 60.2277C8.76836 57.6838 12.8099 57.6838 12.8099 57.6838C16.9887 57.9589 19.1815 61.9464 19.1815 61.9464C22.8801 68.2712 28.84 66.4841 31.2376 65.3839C31.5798 62.7024 32.6766 60.8462 33.8411 59.8151C24.6612 58.8524 15.0027 55.2774 15.0027 39.3263C15.0027 34.7887 16.6457 31.0762 19.2492 28.1888C18.8385 27.1578 17.3995 22.8943 19.6608 17.188C19.6608 17.188 23.1545 16.0878 31.0318 21.4507C34.4044 20.5417 37.8825 20.0792 41.3763 20.0753C44.87 20.0753 48.4314 20.5571 51.72 21.4507C59.5982 16.0878 63.0919 17.188 63.0919 17.188C65.3532 22.8943 63.9134 27.1578 63.5026 28.1888C66.1747 31.0762 67.75 34.7887 67.75 39.3263C67.75 55.2774 58.0915 58.7832 48.843 59.8151C50.3505 61.1213 51.6514 63.596 51.6514 67.5152C51.6514 73.0839 51.5837 77.5533 51.5837 78.9277C51.5837 80.028 52.3374 81.335 54.3921 80.9224C70.8329 75.4211 82.6841 59.8835 82.6841 41.5268C82.7518 18.5625 64.1878 0 41.3763 0Z"/>\n</svg>\n';
|
|
414
|
+
|
|
415
|
+
// packages/map/src/runtime/geometry.ts
|
|
416
|
+
var parseBoundaryCollection = (value, path) => {
|
|
417
|
+
const collection = Array.isArray(value) ? { count: value.length, boundaries: value } : value;
|
|
418
|
+
if (!collection || !Number.isInteger(collection.count) || !Array.isArray(collection.boundaries) || collection.count !== collection.boundaries.length) {
|
|
419
|
+
throw new Error(`Invalid OEM boundary data: ${path}`);
|
|
420
|
+
}
|
|
421
|
+
for (const boundary of collection.boundaries) {
|
|
422
|
+
if (!boundary || typeof boundary.id !== "string" || !boundary.id || !Array.isArray(boundary.rings) || boundary.rings.some((ring) => !Array.isArray(ring) || ring.length < 3 || ring.some((point) => !point || !Number.isFinite(point.x) || !Number.isFinite(point.z)))) {
|
|
423
|
+
throw new Error(`Invalid OEM boundary data: ${path}`);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return collection.boundaries;
|
|
427
|
+
};
|
|
428
|
+
var pointOnSegment = (point, start, end) => {
|
|
429
|
+
const cross = (point.x - start.x) * (end.z - start.z) - (point.z - start.z) * (end.x - start.x);
|
|
430
|
+
if (Math.abs(cross) > 1e-7) return false;
|
|
431
|
+
return point.x >= Math.min(start.x, end.x) - 1e-7 && point.x <= Math.max(start.x, end.x) + 1e-7 && point.z >= Math.min(start.z, end.z) - 1e-7 && point.z <= Math.max(start.z, end.z) + 1e-7;
|
|
432
|
+
};
|
|
433
|
+
var pointInRing = (point, ring) => {
|
|
434
|
+
let inside = false;
|
|
435
|
+
for (let index = 0, previous = ring.length - 1; index < ring.length; previous = index++) {
|
|
436
|
+
const current = ring[index];
|
|
437
|
+
const prior = ring[previous];
|
|
438
|
+
if (pointOnSegment(point, prior, current)) return true;
|
|
439
|
+
const crosses = current.z > point.z !== prior.z > point.z;
|
|
440
|
+
if (crosses && point.x < (prior.x - current.x) * (point.z - current.z) / (prior.z - current.z) + current.x) inside = !inside;
|
|
441
|
+
}
|
|
442
|
+
return inside;
|
|
443
|
+
};
|
|
444
|
+
var distanceSquaredToSegment = (point, start, end) => {
|
|
445
|
+
const dx = end.x - start.x;
|
|
446
|
+
const dz = end.z - start.z;
|
|
447
|
+
const lengthSquared = dx * dx + dz * dz;
|
|
448
|
+
if (!lengthSquared) return (point.x - start.x) ** 2 + (point.z - start.z) ** 2;
|
|
449
|
+
const projection = Math.max(0, Math.min(1, ((point.x - start.x) * dx + (point.z - start.z) * dz) / lengthSquared));
|
|
450
|
+
const nearestX = start.x + projection * dx;
|
|
451
|
+
const nearestZ = start.z + projection * dz;
|
|
452
|
+
return (point.x - nearestX) ** 2 + (point.z - nearestZ) ** 2;
|
|
453
|
+
};
|
|
454
|
+
var boundaryScore = (boundary, point) => {
|
|
455
|
+
const rings = boundary.rings.map((ring) => ring);
|
|
456
|
+
const distances = rings.flatMap((ring) => ring.map((start, index) => distanceSquaredToSegment(point, start, ring[(index + 1) % ring.length])));
|
|
457
|
+
const insideOuter = rings.length > 0 && pointInRing(point, rings[0]);
|
|
458
|
+
const insideHole = rings.slice(1).some((ring) => pointInRing(point, ring));
|
|
459
|
+
return { id: boundary.id, inside: insideOuter && !insideHole, distance: Math.min(...distances, Infinity) };
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
// packages/map/src/runtime/layers.ts
|
|
463
|
+
import L4 from "leaflet";
|
|
464
|
+
|
|
465
|
+
// packages/map/src/atlos/smoothTileLayer.ts
|
|
466
|
+
import L3 from "leaflet";
|
|
467
|
+
var SmoothTileLayer = class extends L3.TileLayer {
|
|
468
|
+
_setZoomTransform(level, center, zoom) {
|
|
469
|
+
const map = this._map;
|
|
470
|
+
if (!map)
|
|
471
|
+
return;
|
|
472
|
+
const scale = map.getZoomScale(zoom, level.zoom);
|
|
473
|
+
const translate = level.origin.multiplyBy(scale).subtract(map._getNewPixelOrigin(center, zoom));
|
|
474
|
+
if (L3.Browser.any3d) {
|
|
475
|
+
L3.DomUtil.setTransform(level.el, translate, scale);
|
|
476
|
+
} else {
|
|
477
|
+
L3.DomUtil.setPosition(level.el, translate);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
|
|
429
482
|
// packages/map/src/tileVersion.ts
|
|
430
483
|
var lookupOEMTile = (coverage, floor, zoom, x, y) => {
|
|
431
484
|
const ranges = coverage[String(zoom)]?.[floor.id]?.[String(y)] ?? [];
|
|
@@ -445,32 +498,7 @@ var lookupOEMTile = (coverage, floor, zoom, x, y) => {
|
|
|
445
498
|
};
|
|
446
499
|
var appendOEMTileVersion = (url, version) => version ? `${url}${url.includes("?") ? "&" : "?"}v=${encodeURIComponent(version)}` : url;
|
|
447
500
|
|
|
448
|
-
// packages/map/src/
|
|
449
|
-
var ghicon_default = '<svg width="83" height="81" viewBox="0 0 83 81" xmlns="http://www.w3.org/2000/svg">\n<path fill-rule="evenodd" clip-rule="evenodd" d="M41.3763 0C18.4963 0 0 18.5625 0 41.5268C0 59.8835 11.8512 75.422 28.292 80.9215C30.3475 81.335 31.1004 80.028 31.1004 78.9286C31.1004 77.9659 31.0327 74.666 31.0327 71.2277C19.5228 73.7032 17.1259 66.2774 17.1259 66.2774C15.2762 61.4647 12.5355 60.2277 12.5355 60.2277C8.76836 57.6838 12.8099 57.6838 12.8099 57.6838C16.9887 57.9589 19.1815 61.9464 19.1815 61.9464C22.8801 68.2712 28.84 66.4841 31.2376 65.3839C31.5798 62.7024 32.6766 60.8462 33.8411 59.8151C24.6612 58.8524 15.0027 55.2774 15.0027 39.3263C15.0027 34.7887 16.6457 31.0762 19.2492 28.1888C18.8385 27.1578 17.3995 22.8943 19.6608 17.188C19.6608 17.188 23.1545 16.0878 31.0318 21.4507C34.4044 20.5417 37.8825 20.0792 41.3763 20.0753C44.87 20.0753 48.4314 20.5571 51.72 21.4507C59.5982 16.0878 63.0919 17.188 63.0919 17.188C65.3532 22.8943 63.9134 27.1578 63.5026 28.1888C66.1747 31.0762 67.75 34.7887 67.75 39.3263C67.75 55.2774 58.0915 58.7832 48.843 59.8151C50.3505 61.1213 51.6514 63.596 51.6514 67.5152C51.6514 73.0839 51.5837 77.5533 51.5837 78.9277C51.5837 80.028 52.3374 81.335 54.3921 80.9224C70.8329 75.4211 82.6841 59.8835 82.6841 41.5268C82.7518 18.5625 64.1878 0 41.3763 0Z"/>\n</svg>\n';
|
|
450
|
-
|
|
451
|
-
// packages/map/src/runtime.ts
|
|
452
|
-
var mounted = /* @__PURE__ */ new WeakSet();
|
|
453
|
-
var CLUSTER_SUBCATEGORIES = /* @__PURE__ */ new Set(["boss", "collection", "mob", "natural", "valuable", "exploration"]);
|
|
454
|
-
var FEATURE_NAMES = ["points", "labels", "boundaries"];
|
|
455
|
-
var BRAND_URL = "https://oem.re/";
|
|
456
|
-
var GITHUB_URL = "https://github.com/Terra-Online/OEM-SDK";
|
|
457
|
-
var TERMS_URL = "https://blog.opendfieldmap.org/docs/tos#intellectual-property-and-copyright";
|
|
458
|
-
var cloneFilter = (filter) => ({
|
|
459
|
-
types: filter.types ? [...filter.types] : void 0,
|
|
460
|
-
subregions: filter.subregions ? [...filter.subregions] : void 0,
|
|
461
|
-
floorOnly: filter.floorOnly
|
|
462
|
-
});
|
|
463
|
-
var sameList = (left, right) => left === right || !!left && !!right && left.length === right.length && left.every((value, index) => value === right[index]);
|
|
464
|
-
var sameFilter = (left, right) => left.floorOnly === right.floorOnly && sameList(left.types, right.types) && sameList(left.subregions, right.subregions);
|
|
465
|
-
var clonePoint = (point) => ({
|
|
466
|
-
...point,
|
|
467
|
-
raw: { ...point.raw },
|
|
468
|
-
position: { ...point.position }
|
|
469
|
-
});
|
|
470
|
-
var cloneCustomPoint = (point) => ({
|
|
471
|
-
...point,
|
|
472
|
-
position: { ...point.position }
|
|
473
|
-
});
|
|
501
|
+
// packages/map/src/runtime/layers.ts
|
|
474
502
|
var OEMMarker = class extends L4.Marker {
|
|
475
503
|
update() {
|
|
476
504
|
const marker = this;
|
|
@@ -497,6 +525,56 @@ var CoveredTileLayer = class extends SmoothTileLayer {
|
|
|
497
525
|
return prototype._isValidTile.call(this, coords) && lookupOEMTile(this.coverage, this.floor, coords.z, coords.x, coords.y).covered;
|
|
498
526
|
}
|
|
499
527
|
};
|
|
528
|
+
|
|
529
|
+
// packages/map/src/runtime/helpers.ts
|
|
530
|
+
var cloneFilter = (filter) => ({
|
|
531
|
+
types: filter.types ? [...filter.types] : void 0,
|
|
532
|
+
subregions: filter.subregions ? [...filter.subregions] : void 0,
|
|
533
|
+
floorOnly: filter.floorOnly
|
|
534
|
+
});
|
|
535
|
+
var sameList = (left, right) => left === right || !!left && !!right && left.length === right.length && left.every((value, index) => value === right[index]);
|
|
536
|
+
var sameFilter = (left, right) => left.floorOnly === right.floorOnly && sameList(left.types, right.types) && sameList(left.subregions, right.subregions);
|
|
537
|
+
var clonePoint = (point) => ({
|
|
538
|
+
...point,
|
|
539
|
+
raw: { ...point.raw },
|
|
540
|
+
position: { ...point.position }
|
|
541
|
+
});
|
|
542
|
+
var cloneCustomPoint = (point) => ({
|
|
543
|
+
...point,
|
|
544
|
+
position: { ...point.position }
|
|
545
|
+
});
|
|
546
|
+
var CLUSTER_SUBCATEGORIES = /* @__PURE__ */ new Set(["boss", "collection", "mob", "natural", "valuable", "exploration"]);
|
|
547
|
+
var FEATURE_NAMES = ["points", "labels", "boundaries"];
|
|
548
|
+
var BRAND_URL = "https://oem.re/";
|
|
549
|
+
var GITHUB_URL = "https://github.com/Terra-Online/OEM-SDK";
|
|
550
|
+
var TERMS_URL = "https://blog.opendfieldmap.org/docs/tos#intellectual-property-and-copyright";
|
|
551
|
+
|
|
552
|
+
// packages/map/src/runtime/oem.ts
|
|
553
|
+
var mounted = /* @__PURE__ */ new WeakSet();
|
|
554
|
+
var decodeAtlosPoint = (raw, region, fallbackSubregionId) => {
|
|
555
|
+
if (!Array.isArray(raw) && raw && "position" in raw && "raw" in raw) return raw;
|
|
556
|
+
const value = Array.isArray(raw) ? { id: raw[0], z: raw[1], x: raw[2], y: raw[3], tier: raw[4], type: raw[5] } : raw;
|
|
557
|
+
if (value?.id == null) return void 0;
|
|
558
|
+
const x = value.x ?? value.pos?.[1] ?? 0;
|
|
559
|
+
const z = value.z ?? value.pos?.[0] ?? 0;
|
|
560
|
+
const y = value.y ?? value.pos?.[2] ?? 0;
|
|
561
|
+
const tier = value.tier ?? 0;
|
|
562
|
+
if (![x, y, z, tier].every(Number.isFinite)) return void 0;
|
|
563
|
+
const subregionId = value.subregId ?? fallbackSubregionId;
|
|
564
|
+
const floorId = tier === 0 ? "M" : `${tier < 0 ? "B" : "L"}${Math.abs(Math.trunc(tier))}`;
|
|
565
|
+
const mapPosition = { regionId: region.id, subregionId, x, z, floorId };
|
|
566
|
+
const game = mapToGameXZPosition(mapPosition, region, subregionId);
|
|
567
|
+
const scale = 2 ** region.maxNativeZoom;
|
|
568
|
+
return {
|
|
569
|
+
id: String(value.id),
|
|
570
|
+
regionId: region.id,
|
|
571
|
+
subregionId,
|
|
572
|
+
type: value.type ?? "",
|
|
573
|
+
tier,
|
|
574
|
+
raw: { x: game.x, y, z: game.z },
|
|
575
|
+
position: { ...mapPosition, x: x * scale, z: z * scale }
|
|
576
|
+
};
|
|
577
|
+
};
|
|
500
578
|
var OEM = class {
|
|
501
579
|
constructor(container, manifest, options) {
|
|
502
580
|
this.container = container;
|
|
@@ -518,8 +596,8 @@ var OEM = class {
|
|
|
518
596
|
this.root.dataset.theme = options.theme ?? "light";
|
|
519
597
|
container.append(this.root);
|
|
520
598
|
mounted.add(container);
|
|
521
|
-
this.map =
|
|
522
|
-
crs:
|
|
599
|
+
this.map = L5.map(this.root, {
|
|
600
|
+
crs: L5.CRS.Simple,
|
|
523
601
|
minZoom: 0,
|
|
524
602
|
maxZoom: 3,
|
|
525
603
|
zoomControl: false,
|
|
@@ -599,11 +677,11 @@ var OEM = class {
|
|
|
599
677
|
requests = /* @__PURE__ */ new Map();
|
|
600
678
|
baseTiles;
|
|
601
679
|
floorTiles;
|
|
602
|
-
pointsLayer =
|
|
603
|
-
customPointsLayer =
|
|
680
|
+
pointsLayer = L5.layerGroup();
|
|
681
|
+
customPointsLayer = L5.layerGroup();
|
|
604
682
|
pointClusters = /* @__PURE__ */ new Map();
|
|
605
|
-
labelsLayer =
|
|
606
|
-
boundariesLayer =
|
|
683
|
+
labelsLayer = L5.layerGroup();
|
|
684
|
+
boundariesLayer = L5.layerGroup();
|
|
607
685
|
points = [];
|
|
608
686
|
customPoints = [];
|
|
609
687
|
clickPoints = [];
|
|
@@ -613,6 +691,8 @@ var OEM = class {
|
|
|
613
691
|
pointIndex;
|
|
614
692
|
pointIndexRequest;
|
|
615
693
|
pointShardRequests = /* @__PURE__ */ new Map();
|
|
694
|
+
boundaryData = /* @__PURE__ */ new Map();
|
|
695
|
+
boundaryDataRequests = /* @__PURE__ */ new Map();
|
|
616
696
|
types = {};
|
|
617
697
|
labels = [];
|
|
618
698
|
visibleLabelType;
|
|
@@ -651,21 +731,22 @@ var OEM = class {
|
|
|
651
731
|
if (!point.position || typeof point.position.regionId !== "string") {
|
|
652
732
|
throw new Error(`Invalid custom point position: ${id}`);
|
|
653
733
|
}
|
|
734
|
+
const position = point.position;
|
|
654
735
|
if (point.style !== "framed" && point.style !== "no-frame") {
|
|
655
736
|
throw new Error(`Invalid custom point style: ${id}`);
|
|
656
737
|
}
|
|
657
738
|
if (typeof point.icon !== "string" || !point.icon) {
|
|
658
739
|
throw new Error(`Custom point icon must be a non-empty URL: ${id}`);
|
|
659
740
|
}
|
|
660
|
-
const pointRegion = getOEMRegion(this.manifest,
|
|
661
|
-
toOEMLeafletMapPosition(
|
|
662
|
-
if (
|
|
663
|
-
throw new Error(`Unknown custom point subregion ${
|
|
741
|
+
const pointRegion = getOEMRegion(this.manifest, position.regionId);
|
|
742
|
+
toOEMLeafletMapPosition(position);
|
|
743
|
+
if (position.subregionId && !pointRegion.subregions.some((subregion) => subregion.id === position.subregionId)) {
|
|
744
|
+
throw new Error(`Unknown custom point subregion ${position.subregionId} in ${position.regionId}`);
|
|
664
745
|
}
|
|
665
|
-
if (
|
|
666
|
-
throw new Error(`Unknown custom point floor ${
|
|
746
|
+
if (position.floorId && !pointRegion.floors.some((floor) => floor.id === position.floorId)) {
|
|
747
|
+
throw new Error(`Unknown custom point floor ${position.floorId} in ${position.regionId}`);
|
|
667
748
|
}
|
|
668
|
-
return { ...cloneCustomPoint(point), id };
|
|
749
|
+
return { ...cloneCustomPoint({ ...point, position }), id };
|
|
669
750
|
});
|
|
670
751
|
}
|
|
671
752
|
normalizeClickPointOptions(options) {
|
|
@@ -684,25 +765,70 @@ var OEM = class {
|
|
|
684
765
|
position(latlng) {
|
|
685
766
|
return fromOEMLeafletPosition(latlng.lat, latlng.lng, this.region, this.floorId);
|
|
686
767
|
}
|
|
768
|
+
loadBoundaryData(reference) {
|
|
769
|
+
const cached = this.boundaryData.get(reference.path);
|
|
770
|
+
if (cached) return Promise.resolve(cached);
|
|
771
|
+
const pending = this.boundaryDataRequests.get(reference.path);
|
|
772
|
+
if (pending) return pending;
|
|
773
|
+
const request = fetchOEMJson(resolveOEMAsset(this.options.resources.baseUrl, reference.path), this.options.signal).then((value) => {
|
|
774
|
+
const boundaries = parseBoundaryCollection(value, reference.path);
|
|
775
|
+
this.boundaryData.set(reference.path, boundaries);
|
|
776
|
+
return boundaries;
|
|
777
|
+
}).finally(() => {
|
|
778
|
+
if (this.boundaryDataRequests.get(reference.path) === request) this.boundaryDataRequests.delete(reference.path);
|
|
779
|
+
});
|
|
780
|
+
this.boundaryDataRequests.set(reference.path, request);
|
|
781
|
+
return request;
|
|
782
|
+
}
|
|
783
|
+
/** Preloads OEM subregion geometry so map clicks can resolve an exact subregion. */
|
|
784
|
+
async prepareSubregionBoundaries() {
|
|
785
|
+
if (!this.region.boundaries) return;
|
|
786
|
+
try {
|
|
787
|
+
await this.loadBoundaryData(this.region.boundaries);
|
|
788
|
+
} catch {
|
|
789
|
+
}
|
|
790
|
+
}
|
|
687
791
|
inferSubregionId(x, z) {
|
|
688
792
|
const selected = this.filter.subregions?.filter((id) => this.region.subregions.some((subregion) => subregion.id === id));
|
|
689
|
-
if (selected?.length === 1) {
|
|
690
|
-
const subregion = this.region.subregions.find((entry) => entry.id === selected[0]);
|
|
691
|
-
if (!subregion?.bounds) return subregion?.id;
|
|
692
|
-
const scale2 = 2 ** this.region.maxNativeZoom;
|
|
693
|
-
const [[minX, minY], [maxX, maxY]] = subregion.bounds;
|
|
694
|
-
const pixelX2 = x * scale2;
|
|
695
|
-
const pixelZ2 = z * scale2;
|
|
696
|
-
if (pixelX2 >= minX && pixelX2 <= maxX && pixelZ2 >= minY && pixelZ2 <= maxY) return subregion.id;
|
|
697
|
-
}
|
|
698
793
|
const scale = 2 ** this.region.maxNativeZoom;
|
|
699
|
-
const
|
|
700
|
-
const
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
794
|
+
const point = { x: x * scale, z: z * scale };
|
|
795
|
+
const allowed = selected?.length ? new Set(selected) : void 0;
|
|
796
|
+
const geometries = this.region.boundaries ? this.boundaryData.get(this.region.boundaries.path) ?? [] : [];
|
|
797
|
+
const scores = geometries.filter((boundary) => this.region.subregions.some((subregion) => subregion.id === boundary.id) && (!allowed || allowed.has(boundary.id))).map((boundary) => boundaryScore(boundary, point));
|
|
798
|
+
const inside = scores.filter((score) => score.inside);
|
|
799
|
+
if (inside.length) {
|
|
800
|
+
const ranked = inside.map((score) => ({ ...score, wins: 0, margin: 0 }));
|
|
801
|
+
for (let leftIndex = 0; leftIndex < ranked.length; leftIndex += 1) {
|
|
802
|
+
for (let rightIndex = leftIndex + 1; rightIndex < ranked.length; rightIndex += 1) {
|
|
803
|
+
const left = ranked[leftIndex];
|
|
804
|
+
const right = ranked[rightIndex];
|
|
805
|
+
const delta = left.distance - right.distance;
|
|
806
|
+
if (Math.abs(delta) <= 1e-9) continue;
|
|
807
|
+
if (delta > 0) {
|
|
808
|
+
left.wins += 1;
|
|
809
|
+
left.margin += delta;
|
|
810
|
+
right.margin -= delta;
|
|
811
|
+
} else {
|
|
812
|
+
right.wins += 1;
|
|
813
|
+
right.margin -= delta;
|
|
814
|
+
left.margin += delta;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
ranked.sort((left, right) => right.wins - left.wins || right.margin - left.margin || right.distance - left.distance || left.id.localeCompare(right.id));
|
|
819
|
+
return ranked[0].id;
|
|
820
|
+
}
|
|
821
|
+
if (scores.length) return void 0;
|
|
822
|
+
const bounds = this.region.subregions.filter((subregion) => subregion.bounds && (!allowed || allowed.has(subregion.id))).flatMap((subregion) => {
|
|
823
|
+
const [[minX, minZ], [maxX, maxZ]] = subregion.bounds;
|
|
824
|
+
const insideX = point.x >= minX && point.x <= maxX;
|
|
825
|
+
const insideZ = point.z >= minZ && point.z <= maxZ;
|
|
826
|
+
if (!insideX || !insideZ) return [];
|
|
827
|
+
const dx = Math.min(point.x - minX, maxX - point.x);
|
|
828
|
+
const dz = Math.min(point.z - minZ, maxZ - point.z);
|
|
829
|
+
return [{ id: subregion.id, distance: Math.min(dx, dz) ** 2 }];
|
|
830
|
+
}).sort((left, right) => right.distance - left.distance || left.id.localeCompare(right.id));
|
|
831
|
+
return bounds[0]?.id;
|
|
706
832
|
}
|
|
707
833
|
emitMapClick = (event) => {
|
|
708
834
|
if (this.destroyed) return;
|
|
@@ -781,7 +907,7 @@ var OEM = class {
|
|
|
781
907
|
this.floorTiles?.remove();
|
|
782
908
|
this.floorTiles = void 0;
|
|
783
909
|
this.floorId = "M";
|
|
784
|
-
this.map.setMaxBounds(
|
|
910
|
+
this.map.setMaxBounds(L5.latLngBounds([]));
|
|
785
911
|
this.map.setMinZoom(this.region.minZoom);
|
|
786
912
|
this.map.setMaxZoom(this.region.maxZoom);
|
|
787
913
|
const target = view ?? this.region.initialView;
|
|
@@ -793,7 +919,7 @@ var OEM = class {
|
|
|
793
919
|
/** Converts the region's published pixel extent to Simple CRS bounds. */
|
|
794
920
|
regionBounds() {
|
|
795
921
|
const { x, z } = this.region.boundsOffset;
|
|
796
|
-
return
|
|
922
|
+
return L5.latLngBounds(
|
|
797
923
|
toOEMLeafletPosition({ regionId: this.region.id, x, z }, this.region),
|
|
798
924
|
toOEMLeafletPosition({ regionId: this.region.id, x: x + this.region.dimensions[0], z: z + this.region.dimensions[1] }, this.region)
|
|
799
925
|
);
|
|
@@ -840,7 +966,7 @@ var OEM = class {
|
|
|
840
966
|
/** Fits the map to an OEM pixel-coordinate extent. */
|
|
841
967
|
fitBounds(bounds) {
|
|
842
968
|
this.assertAlive();
|
|
843
|
-
this.map.fitBounds(
|
|
969
|
+
this.map.fitBounds(L5.latLngBounds(toOEMLeafletPosition(bounds[0], this.region), toOEMLeafletPosition(bounds[1], this.region)), { animate: false });
|
|
844
970
|
}
|
|
845
971
|
/** Switches regions and reloads only the features currently enabled. */
|
|
846
972
|
async setRegion(regionId) {
|
|
@@ -860,6 +986,7 @@ var OEM = class {
|
|
|
860
986
|
this.emit("regionchange", { regionId });
|
|
861
987
|
this.emit("floorchange", { floorId: "M" });
|
|
862
988
|
this.emitView();
|
|
989
|
+
await this.prepareSubregionBoundaries();
|
|
863
990
|
await this.loadFeatures();
|
|
864
991
|
}
|
|
865
992
|
/** Switches the rendered floor while retaining the current region view. */
|
|
@@ -926,7 +1053,7 @@ var OEM = class {
|
|
|
926
1053
|
this.labelsLayer.clearLayers();
|
|
927
1054
|
} else this.boundariesLayer.clearLayers();
|
|
928
1055
|
}
|
|
929
|
-
await Promise.
|
|
1056
|
+
await Promise.allSettled(loads);
|
|
930
1057
|
}
|
|
931
1058
|
/** Replaces host-defined points without reloading static map data. */
|
|
932
1059
|
setCustomPoints(points) {
|
|
@@ -1047,8 +1174,9 @@ var OEM = class {
|
|
|
1047
1174
|
const cached = this.pointShardRequests.get(path);
|
|
1048
1175
|
if (cached) return cached;
|
|
1049
1176
|
const request = fetchOEMJson(resolveOEMAsset(this.options.resources.baseUrl, path), this.options.signal).then((value) => {
|
|
1050
|
-
|
|
1051
|
-
|
|
1177
|
+
const region = this.manifest.regions.find((entry) => entry.points.some((ref) => ref.path === path));
|
|
1178
|
+
if (!region || !Array.isArray(value)) throw new Error(`Invalid OEM point shard: ${path}`);
|
|
1179
|
+
return this.decodePointShard(value, path, region);
|
|
1052
1180
|
}).catch((error) => {
|
|
1053
1181
|
if (this.pointShardRequests.get(path) === request) this.pointShardRequests.delete(path);
|
|
1054
1182
|
throw error;
|
|
@@ -1056,6 +1184,10 @@ var OEM = class {
|
|
|
1056
1184
|
this.pointShardRequests.set(path, request);
|
|
1057
1185
|
return request;
|
|
1058
1186
|
}
|
|
1187
|
+
decodePointShard(value, shardPath, region = this.region) {
|
|
1188
|
+
const fallbackSubregionId = shardPath.split("/").at(-1)?.replace(/\.json$/, "") ?? "";
|
|
1189
|
+
return value.map((entry) => decodeAtlosPoint(entry, region, fallbackSubregionId)).filter((entry) => !!entry);
|
|
1190
|
+
}
|
|
1059
1191
|
cancelRequest(feature) {
|
|
1060
1192
|
if (!this.requests.has(feature)) return;
|
|
1061
1193
|
this.requests.get(feature).abort();
|
|
@@ -1066,7 +1198,7 @@ var OEM = class {
|
|
|
1066
1198
|
for (const feature of this.requests.keys()) this.cancelRequest(feature);
|
|
1067
1199
|
}
|
|
1068
1200
|
async loadFeatures() {
|
|
1069
|
-
await Promise.
|
|
1201
|
+
await Promise.allSettled(FEATURE_NAMES.filter((feature) => this.features[feature]).map((feature) => this.loadFeature(feature)));
|
|
1070
1202
|
}
|
|
1071
1203
|
/** Loads one feature with a request token so stale responses are ignored. */
|
|
1072
1204
|
async loadFeature(feature) {
|
|
@@ -1078,7 +1210,11 @@ var OEM = class {
|
|
|
1078
1210
|
try {
|
|
1079
1211
|
if (feature === "points") {
|
|
1080
1212
|
const [groups, types] = await Promise.all([
|
|
1081
|
-
Promise.all(this.region.points.map((ref) =>
|
|
1213
|
+
Promise.all(this.region.points.map(async (ref) => {
|
|
1214
|
+
const value = await read(ref);
|
|
1215
|
+
if (!Array.isArray(value)) throw new Error(`Invalid OEM point shard: ${ref.path}`);
|
|
1216
|
+
return this.decodePointShard(value, ref.path);
|
|
1217
|
+
})),
|
|
1082
1218
|
Object.keys(this.types).length ? this.types : read(this.manifest.types)
|
|
1083
1219
|
]);
|
|
1084
1220
|
if (request.signal.aborted) return;
|
|
@@ -1096,7 +1232,7 @@ var OEM = class {
|
|
|
1096
1232
|
this.renderLabels(true);
|
|
1097
1233
|
} else {
|
|
1098
1234
|
const reference = this.boundarySource === "game" ? this.region.gameBoundaries : this.region.boundaries;
|
|
1099
|
-
const boundaries = reference ? await
|
|
1235
|
+
const boundaries = reference ? await this.loadBoundaryData(reference) : [];
|
|
1100
1236
|
if (request.signal.aborted) return;
|
|
1101
1237
|
this.renderBoundaries(boundaries);
|
|
1102
1238
|
}
|
|
@@ -1164,7 +1300,7 @@ var OEM = class {
|
|
|
1164
1300
|
interactive: false,
|
|
1165
1301
|
keyboard: false,
|
|
1166
1302
|
bubblingMouseEvents: false,
|
|
1167
|
-
icon:
|
|
1303
|
+
icon: L5.divIcon({
|
|
1168
1304
|
html: this.createCustomPointVisual(point),
|
|
1169
1305
|
className: `${point.style === "no-frame" ? "noFrameMarkerIcon" : "frameMarkerIcon"} incompleteMarker`,
|
|
1170
1306
|
iconSize: point.style === "no-frame" ? [50, 50] : [32, 32],
|
|
@@ -1223,7 +1359,7 @@ var OEM = class {
|
|
|
1223
1359
|
interactive: true,
|
|
1224
1360
|
keyboard: false,
|
|
1225
1361
|
bubblingMouseEvents: false,
|
|
1226
|
-
icon:
|
|
1362
|
+
icon: L5.divIcon({
|
|
1227
1363
|
html: this.createMarkerVisual(type, point),
|
|
1228
1364
|
className: `${type.noFrame ? "noFrameMarkerIcon" : "frameMarkerIcon"} incompleteMarker`,
|
|
1229
1365
|
iconSize: type.noFrame ? [50, 50] : [32, 32],
|
|
@@ -1232,13 +1368,13 @@ var OEM = class {
|
|
|
1232
1368
|
});
|
|
1233
1369
|
}
|
|
1234
1370
|
createPointCluster(type) {
|
|
1235
|
-
return
|
|
1371
|
+
return L5.markerClusterGroup({
|
|
1236
1372
|
showCoverageOnHover: false,
|
|
1237
1373
|
zoomToBoundsOnClick: !this.options.lockZoom,
|
|
1238
1374
|
spiderfyOnMaxZoom: !this.options.lockZoom,
|
|
1239
1375
|
disableClusteringAtZoom: 2,
|
|
1240
1376
|
maxClusterRadius: 60,
|
|
1241
|
-
iconCreateFunction: (cluster) =>
|
|
1377
|
+
iconCreateFunction: (cluster) => L5.divIcon({
|
|
1242
1378
|
html: this.createMarkerVisual(type, void 0, cluster.getChildCount()),
|
|
1243
1379
|
className: `${type.noFrame ? "noFrameMarkerIcon" : "frameMarkerIcon"} markerClusterCustom`,
|
|
1244
1380
|
iconSize: type.noFrame ? [50, 50] : [32, 32],
|
|
@@ -1273,14 +1409,14 @@ var OEM = class {
|
|
|
1273
1409
|
renderBoundaries(boundaries) {
|
|
1274
1410
|
this.boundariesLayer.clearLayers();
|
|
1275
1411
|
for (const boundary of boundaries) {
|
|
1276
|
-
const rings = boundary.rings.map((ring) => ring.map((position) => toOEMLeafletPosition(position, this.region)));
|
|
1277
|
-
|
|
1412
|
+
const rings = boundary.rings.map((ring) => ring.map((position) => toOEMLeafletPosition({ ...position, regionId: this.region.id }, this.region)));
|
|
1413
|
+
L5.polygon(rings, {
|
|
1278
1414
|
color: "transparent",
|
|
1279
1415
|
fillOpacity: 0.2,
|
|
1280
1416
|
interactive: false,
|
|
1281
1417
|
className: "subregionBoundaryFill"
|
|
1282
1418
|
}).addTo(this.boundariesLayer);
|
|
1283
|
-
|
|
1419
|
+
L5.polygon(rings, {
|
|
1284
1420
|
weight: 2,
|
|
1285
1421
|
opacity: 0.8,
|
|
1286
1422
|
fill: false,
|
|
@@ -1305,7 +1441,7 @@ var OEM = class {
|
|
|
1305
1441
|
pane: "placeLabels",
|
|
1306
1442
|
interactive: false,
|
|
1307
1443
|
keyboard: false,
|
|
1308
|
-
icon:
|
|
1444
|
+
icon: L5.divIcon({ className: "mapLabel", html: inner, iconSize: [0, 0] })
|
|
1309
1445
|
}).addTo(this.labelsLayer);
|
|
1310
1446
|
}
|
|
1311
1447
|
}
|
|
@@ -1339,4 +1475,4 @@ var OEM = class {
|
|
|
1339
1475
|
export {
|
|
1340
1476
|
OEM
|
|
1341
1477
|
};
|
|
1342
|
-
//# sourceMappingURL=runtime-
|
|
1478
|
+
//# sourceMappingURL=runtime-6QYIDK3F.js.map
|