@watergis/maplibre-gl-terradraw
Version:
This plugin is to add controls to your Maplibre for drawing powered by Terra Draw library.
5,043 lines • 236 kB
JavaScript
var Xe = Object.defineProperty;
var Ke = (s, t, e) => t in s ? Xe(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e;
var B = (s, t, e) => Ke(s, typeof t != "symbol" ? t + "" : t, e);
import "maplibre-gl";
function I() {
return I = Object.assign ? Object.assign.bind() : function(s) {
for (var t = 1; t < arguments.length; t++) {
var e = arguments[t];
for (var i in e) ({}).hasOwnProperty.call(e, i) && (s[i] = e[i]);
}
return s;
}, I.apply(null, arguments);
}
var M;
(function(s) {
s.Commit = "commit", s.Provisional = "provisional", s.Finish = "finish";
})(M || (M = {}));
const V = { SELECTED: "selected", MID_POINT: "midPoint", SELECTION_POINT: "selectionPoint" }, U = "edited", st = "closingPoint", _t = "snappingPoint", Lt = "coordinatePoint", kt = "coordinatePointIds";
function Mt(s) {
return !!(s && typeof s == "object" && s !== null && !Array.isArray(s));
}
function zt(s) {
return !!(s && typeof s == "object" && "properties" in s && typeof s.properties == "object" && s.properties !== null && "mode" in s.properties);
}
function Xt(s) {
return !!function(t) {
return typeof t == "number" && !isNaN(new Date(t).valueOf());
}(s);
}
const Ye = "Feature mode property does not match the mode being added to";
var $;
(function(s) {
s.Drawing = "drawing", s.Select = "select", s.Static = "static", s.Render = "render";
})($ || ($ = {}));
let N = class {
get state() {
return this._state;
}
set state(t) {
throw new Error("Please use the modes lifecycle methods");
}
get styles() {
return this._styles;
}
set styles(t) {
if (typeof t != "object") throw new Error("Styling must be an object");
this.onStyleChange && this.onStyleChange([], "styling"), this._styles = t;
}
registerBehaviors(t) {
}
constructor(t, e = !1) {
this._state = "unregistered", this._styles = {}, this.behaviors = [], this.validate = void 0, this.pointerDistance = 40, this.coordinatePrecision = void 0, this.onStyleChange = void 0, this.store = void 0, this.projection = "web-mercator", this.setDoubleClickToZoom = void 0, this.unproject = void 0, this.project = void 0, this.setCursor = void 0, this.type = $.Drawing, this.mode = "base", e || this.updateOptions(t);
}
updateOptions(t) {
t != null && t.styles && (this.styles = I({}, this._styles, t.styles)), t != null && t.pointerDistance && (this.pointerDistance = t.pointerDistance), t != null && t.validation && (this.validate = t && t.validation), t != null && t.projection && (this.projection = t.projection);
}
setDrawing() {
if (this._state !== "started") throw new Error("Mode must be unregistered or stopped to start");
this._state = "drawing";
}
setStarted() {
if (this._state !== "stopped" && this._state !== "registered" && this._state !== "drawing" && this._state !== "selecting") throw new Error("Mode must be unregistered or stopped to start");
this._state = "started", this.setDoubleClickToZoom(!1);
}
setStopped() {
if (this._state !== "started") throw new Error("Mode must be started to be stopped");
this._state = "stopped", this.setDoubleClickToZoom(!0);
}
register(t) {
if (this._state !== "unregistered") throw new Error("Can not register unless mode is unregistered");
this._state = "registered", this.store = t.store, this.store.registerOnChange(t.onChange), this.setDoubleClickToZoom = t.setDoubleClickToZoom, this.project = t.project, this.unproject = t.unproject, this.onSelect = t.onSelect, this.onDeselect = t.onDeselect, this.setCursor = t.setCursor, this.onStyleChange = t.onChange, this.onFinish = t.onFinish, this.coordinatePrecision = t.coordinatePrecision, this.registerBehaviors({ mode: t.mode, store: this.store, project: this.project, unproject: this.unproject, pointerDistance: this.pointerDistance, coordinatePrecision: t.coordinatePrecision, projection: this.projection });
}
validateFeature(t) {
return this.performFeatureValidation(t);
}
afterFeatureAdded(t) {
}
performFeatureValidation(t) {
if (this._state === "unregistered") throw new Error("Mode must be registered");
const e = function(i, o) {
let r;
if (Mt(i)) if (i.id == null) r = "Feature has no id";
else if (typeof i.id != "string" && typeof i.id != "number") r = "Feature must be string or number as per GeoJSON spec";
else if (o(i.id)) if (Mt(i.geometry)) if (Mt(i.properties)) if (typeof i.geometry.type == "string" && ["Polygon", "LineString", "Point"].includes(i.geometry.type)) if (Array.isArray(i.geometry.coordinates)) {
if (!i.properties.mode || typeof i.properties.mode != "string") return { valid: !1, reason: "Feature does not have a valid mode property" };
} else r = "Feature coordinates is not an array";
else r = "Feature is not Point, LineString or Polygon";
else r = "Feature has no properties";
else r = "Feature has no geometry";
else r = "Feature must match the id strategy (default is UUID4)";
else r = "Feature is not object";
return r ? { valid: !1, reason: r } : { valid: !0 };
}(t, this.store.idStrategy.isValidId);
if (this.validate) {
const i = this.validate(t, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Provisional });
return { valid: e.valid && i.valid, reason: i.reason };
}
return { valid: e.valid, reason: e.reason };
}
validateModeFeature(t, e) {
const i = this.performFeatureValidation(t);
return i.valid ? t.properties.mode !== this.mode ? { valid: !1, reason: Ye } : e(t) : { valid: !1, reason: i.reason };
}
onFinish(t, e) {
}
onDeselect(t) {
}
onSelect(t) {
}
onKeyDown(t) {
}
onKeyUp(t) {
}
onMouseMove(t) {
}
onClick(t) {
}
onDragStart(t, e) {
}
onDrag(t, e) {
}
onDragEnd(t, e) {
}
getHexColorStylingValue(t, e, i) {
return this.getStylingValue(t, e, i);
}
getNumericStylingValue(t, e, i) {
return this.getStylingValue(t, e, i);
}
getStylingValue(t, e, i) {
return t === void 0 ? e : typeof t == "function" ? t(i) : t;
}
}, $e = class extends N {
constructor(...t) {
super(...t), this.type = $.Select;
}
};
function T(s, t) {
const e = (d) => d * Math.PI / 180, i = e(s[1]), o = e(s[0]), r = e(t[1]), n = r - i, a = e(t[0]) - o, l = Math.sin(n / 2) * Math.sin(n / 2) + Math.cos(i) * Math.cos(r) * Math.sin(a / 2) * Math.sin(a / 2);
return 2 * Math.atan2(Math.sqrt(l), Math.sqrt(1 - l)) * 6371e3 / 1e3;
}
const me = 63710088e-1;
function O(s) {
return s % 360 * Math.PI / 180;
}
function ve(s) {
return s / 6371.0088;
}
function R(s) {
return s % (2 * Math.PI) * 180 / Math.PI;
}
function F(s, t = 9) {
const e = Math.pow(10, t);
return Math.round(s * e) / e;
}
const Kt = 57.29577951308232, Yt = 0.017453292519943295, ft = 6378137, x = (s, t) => ({ x: s === 0 ? 0 : s * Yt * ft, y: t === 0 ? 0 : Math.log(Math.tan(Math.PI / 4 + t * Yt / 2)) * ft }), W = (s, t) => ({ lng: s === 0 ? 0 : Kt * (s / ft), lat: t === 0 ? 0 : (2 * Math.atan(Math.exp(t / ft)) - Math.PI / 2) * Kt });
function He(s, t, e) {
const i = O(s[0]), o = O(s[1]), r = O(e), n = ve(t), a = Math.asin(Math.sin(o) * Math.cos(n) + Math.cos(o) * Math.sin(n) * Math.cos(r));
return [R(i + Math.atan2(Math.sin(r) * Math.sin(n) * Math.cos(o), Math.cos(n) - Math.sin(o) * Math.sin(a))), R(a)];
}
function $t(s) {
const { center: t, radiusKilometers: e, coordinatePrecision: i } = s, o = s.steps ? s.steps : 64, r = [];
for (let n = 0; n < o; n++) {
const a = He(t, e, -360 * n / o);
r.push([F(a[0], i), F(a[1], i)]);
}
return r.push(r[0]), { type: "Feature", geometry: { type: "Polygon", coordinates: [r] }, properties: {} };
}
function Bt(s) {
let t;
if (s.geometry.type === "Polygon") t = s.geometry.coordinates;
else {
if (s.geometry.type !== "LineString") throw new Error("Self intersects only accepts Polygons and LineStrings");
t = [s.geometry.coordinates];
}
const e = [];
for (let r = 0; r < t.length; r++) for (let n = 0; n < t[r].length - 1; n++) for (let a = 0; a < t.length; a++) for (let l = 0; l < t[a].length - 1; l++) o(r, n, a, l);
return e.length > 0;
function i(r) {
return r < 0 || r > 1;
}
function o(r, n, a, l) {
const d = t[r][n], h = t[r][n + 1], c = t[a][l], u = t[a][l + 1], p = function(m, v, f, C) {
if (ht(m, f) || ht(m, C) || ht(v, f) || ht(C, f)) return null;
const P = m[0], S = m[1], b = v[0], w = v[1], D = f[0], G = f[1], _ = C[0], j = C[1], z = (P - b) * (G - j) - (S - w) * (D - _);
return z === 0 ? null : [((P * w - S * b) * (D - _) - (P - b) * (D * j - G * _)) / z, ((P * w - S * b) * (G - j) - (S - w) * (D * j - G * _)) / z];
}(d, h, c, u);
if (p === null) return;
let g, y;
g = h[0] !== d[0] ? (p[0] - d[0]) / (h[0] - d[0]) : (p[1] - d[1]) / (h[1] - d[1]), y = u[0] !== c[0] ? (p[0] - c[0]) / (u[0] - c[0]) : (p[1] - c[1]) / (u[1] - c[1]), i(g) || i(y) || (p.toString(), e.push(p));
}
}
function ht(s, t) {
return s[0] === t[0] && s[1] === t[1];
}
function xt(s, t) {
return Ht(s[0]) <= t && Ht(s[1]) <= t;
}
function Wt(s) {
return s.length === 2 && typeof s[0] == "number" && typeof s[1] == "number" && s[0] !== 1 / 0 && s[1] !== 1 / 0 && (e = s[0]) >= -180 && e <= 180 && (t = s[1]) >= -90 && t <= 90;
var t, e;
}
function Ht(s) {
let t = 1, e = 0;
for (; Math.round(s * t) / t !== s; ) t *= 10, e++;
return e;
}
const qe = "Feature has holes", Je = "Feature has less than 4 coordinates", Ze = "Feature has invalid coordinates", Qe = "Feature coordinates are not closed";
function It(s, t) {
if (s.geometry.type !== "Polygon") return { valid: !1, reason: "Feature is not a Polygon" };
if (s.geometry.coordinates.length !== 1) return { valid: !1, reason: qe };
if (s.geometry.coordinates[0].length < 4) return { valid: !1, reason: Je };
for (let o = 0; o < s.geometry.coordinates[0].length; o++) {
if (!Wt(s.geometry.coordinates[0][o])) return { valid: !1, reason: Ze };
if (!xt(s.geometry.coordinates[0][o], t)) return { valid: !1, reason: "Feature has coordinates with excessive precision" };
}
return (e = s.geometry.coordinates[0][0])[0] !== (i = s.geometry.coordinates[0][s.geometry.coordinates[0].length - 1])[0] || e[1] !== i[1] ? { valid: !1, reason: Qe } : { valid: !0 };
var e, i;
}
function lt(s, t) {
const e = It(s, t);
return e.valid ? Bt(s) ? { valid: !1, reason: "Feature intersects itself" } : { valid: !0 } : e;
}
const ti = { cancel: "Escape", finish: "Enter" }, ei = { start: "crosshair" };
class Ce extends N {
constructor(t) {
super(t, !0), this.mode = "circle", this.center = void 0, this.clickCount = 0, this.currentCircleId = void 0, this.keyEvents = ti, this.cursors = ei, this.startingRadiusKilometers = 1e-5, this.cursorMovedAfterInitialCursorDown = !1, this.updateOptions(t);
}
updateOptions(t) {
super.updateOptions(t), t != null && t.cursors && (this.cursors = I({}, this.cursors, t.cursors)), (t == null ? void 0 : t.keyEvents) === null ? this.keyEvents = { cancel: null, finish: null } : t != null && t.keyEvents && (this.keyEvents = I({}, this.keyEvents, t.keyEvents)), t != null && t.startingRadiusKilometers && (this.startingRadiusKilometers = t.startingRadiusKilometers);
}
close() {
if (this.currentCircleId === void 0) return;
const t = this.currentCircleId;
if (this.validate && t) {
const e = this.store.getGeometryCopy(t);
if (!this.validate({ type: "Feature", id: t, geometry: e, properties: {} }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Finish }).valid) return;
}
this.cursorMovedAfterInitialCursorDown = !1, this.center = void 0, this.currentCircleId = void 0, this.clickCount = 0, this.state === "drawing" && this.setStarted(), this.onFinish(t, { mode: this.mode, action: "draw" });
}
start() {
this.setStarted(), this.setCursor(this.cursors.start);
}
stop() {
this.cleanUp(), this.setStopped(), this.setCursor("unset");
}
onClick(t) {
if (this.clickCount === 0) {
this.center = [t.lng, t.lat];
const e = $t({ center: this.center, radiusKilometers: this.startingRadiusKilometers, coordinatePrecision: this.coordinatePrecision }), [i] = this.store.create([{ geometry: e.geometry, properties: { mode: this.mode, radiusKilometers: this.startingRadiusKilometers } }]);
this.currentCircleId = i, this.clickCount++, this.cursorMovedAfterInitialCursorDown = !1, this.setDrawing();
} else this.clickCount === 1 && this.center && this.currentCircleId !== void 0 && this.cursorMovedAfterInitialCursorDown && this.updateCircle(t), this.close();
}
onMouseMove(t) {
this.cursorMovedAfterInitialCursorDown = !0, this.updateCircle(t);
}
onKeyDown() {
}
onKeyUp(t) {
t.key === this.keyEvents.cancel ? this.cleanUp() : t.key === this.keyEvents.finish && this.close();
}
onDragStart() {
}
onDrag() {
}
onDragEnd() {
}
cleanUp() {
const t = this.currentCircleId;
this.center = void 0, this.currentCircleId = void 0, this.clickCount = 0, this.state === "drawing" && this.setStarted();
try {
t !== void 0 && this.store.delete([t]);
} catch {
}
}
styleFeature(t) {
const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
return t.type === "Feature" && t.geometry.type === "Polygon" && t.properties.mode === this.mode && (e.polygonFillColor = this.getHexColorStylingValue(this.styles.fillColor, e.polygonFillColor, t), e.polygonOutlineColor = this.getHexColorStylingValue(this.styles.outlineColor, e.polygonOutlineColor, t), e.polygonOutlineWidth = this.getNumericStylingValue(this.styles.outlineWidth, e.polygonOutlineWidth, t), e.polygonFillOpacity = this.getNumericStylingValue(this.styles.fillOpacity, e.polygonFillOpacity, t), e.zIndex = 10), e;
}
validateFeature(t) {
return this.validateModeFeature(t, (e) => lt(e, this.coordinatePrecision));
}
updateCircle(t) {
if (this.clickCount === 1 && this.center && this.currentCircleId) {
const e = T(this.center, [t.lng, t.lat]);
let i;
if (this.projection === "web-mercator") {
const o = function(r, n) {
const a = 1e3 * T(r, n);
if (a === 0) return 1;
const { x: l, y: d } = x(r[0], r[1]), { x: h, y: c } = x(n[0], n[1]);
return Math.sqrt(Math.pow(h - l, 2) + Math.pow(c - d, 2)) / a;
}(this.center, [t.lng, t.lat]);
i = function(r) {
const { center: n, radiusKilometers: a, coordinatePrecision: l } = r, d = r.steps ? r.steps : 64, h = 1e3 * a, [c, u] = n, { x: p, y: g } = x(c, u), y = [];
for (let m = 0; m < d; m++) {
const v = 360 * m / d * Math.PI / 180, f = h * Math.cos(v), C = h * Math.sin(v), [P, S] = [p + f, g + C], { lng: b, lat: w } = W(P, S);
y.push([F(b, l), F(w, l)]);
}
return y.push(y[0]), { type: "Feature", geometry: { type: "Polygon", coordinates: [y] }, properties: {} };
}({ center: this.center, radiusKilometers: e * o, coordinatePrecision: this.coordinatePrecision });
} else {
if (this.projection !== "globe") throw new Error("Invalid projection");
i = $t({ center: this.center, radiusKilometers: e, coordinatePrecision: this.coordinatePrecision });
}
if (this.validate && !this.validate({ type: "Feature", id: this.currentCircleId, geometry: i.geometry, properties: { radiusKilometers: e } }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Provisional }).valid) return;
this.store.updateGeometry([{ id: this.currentCircleId, geometry: i.geometry }]), this.store.updateProperty([{ id: this.currentCircleId, property: "radiusKilometers", value: e }]);
}
}
}
const E = (s, t) => {
const { x: e, y: i } = s, { x: o, y: r } = t, n = o - e, a = r - i;
return Math.sqrt(a * a + n * n);
};
function dt(s) {
if (!function(e) {
const i = e.coordinates[0];
let o = 0;
for (let r = 0; r < i.length - 1; r++) {
const [n, a] = i[r], [l, d] = i[r + 1];
o += (l - n) * (d + a);
}
return o < 0;
}(s)) return { type: "Polygon", coordinates: [s.coordinates[0].reverse()] };
}
const ii = { cancel: "Escape", finish: "Enter" }, oi = { start: "crosshair", close: "pointer" };
class Pe extends N {
constructor(t) {
super(t, !0), this.mode = "freehand", this.startingClick = !1, this.currentId = void 0, this.closingPointId = void 0, this.minDistance = 20, this.keyEvents = ii, this.cursors = oi, this.preventPointsNearClose = !0, this.autoClose = !1, this.autoCloseTimeout = 500, this.hasLeftStartingPoint = !1, this.preventNewFeature = !1, this.updateOptions(t);
}
updateOptions(t) {
super.updateOptions(t), t != null && t.minDistance && (this.minDistance = t.minDistance), (t == null ? void 0 : t.preventPointsNearClose) !== void 0 && (this.preventPointsNearClose = t.preventPointsNearClose), (t == null ? void 0 : t.autoClose) !== void 0 && (this.autoClose = t.autoClose), t != null && t.autoCloseTimeout && (this.autoCloseTimeout = t.autoCloseTimeout), (t == null ? void 0 : t.keyEvents) === null ? this.keyEvents = { cancel: null, finish: null } : t != null && t.keyEvents && (this.keyEvents = I({}, this.keyEvents, t.keyEvents)), t != null && t.cursors && (this.cursors = I({}, this.cursors, t.cursors));
}
close() {
if (this.currentId === void 0) return;
if (this.currentId) {
const e = dt(this.store.getGeometryCopy(this.currentId));
e && this.store.updateGeometry([{ id: this.currentId, geometry: e }]);
}
const t = this.currentId;
if (this.validate && t) {
const e = this.store.getGeometryCopy(t);
if (!this.validate({ type: "Feature", id: t, geometry: e, properties: {} }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Finish }).valid) return;
}
this.closingPointId && this.store.delete([this.closingPointId]), this.startingClick = !1, this.currentId = void 0, this.closingPointId = void 0, this.hasLeftStartingPoint = !1, this.state === "drawing" && this.setStarted(), this.onFinish(t, { mode: this.mode, action: "draw" });
}
start() {
this.setStarted(), this.setCursor(this.cursors.start);
}
stop() {
this.cleanUp(), this.setStopped(), this.setCursor("unset");
}
onMouseMove(t) {
if (this.currentId === void 0 || this.startingClick === !1) return;
const e = this.store.getGeometryCopy(this.currentId), i = e.coordinates[0].length - 2, [o, r] = e.coordinates[0][i], { x: n, y: a } = this.project(o, r), l = E({ x: n, y: a }, { x: t.containerX, y: t.containerY }), [d, h] = e.coordinates[0][0], { x: c, y: u } = this.project(d, h);
if (E({ x: c, y: u }, { x: t.containerX, y: t.containerY }) < this.pointerDistance) {
if (this.autoClose && this.hasLeftStartingPoint && (this.preventNewFeature = !0, setTimeout(() => {
this.preventNewFeature = !1;
}, this.autoCloseTimeout), this.close()), this.setCursor(this.cursors.close), this.preventPointsNearClose) return;
} else this.hasLeftStartingPoint = !0, this.setCursor(this.cursors.start);
if (l < this.minDistance) return;
e.coordinates[0].pop();
const p = { type: "Polygon", coordinates: [[...e.coordinates[0], [t.lng, t.lat], e.coordinates[0][0]]] };
this.validate && !this.validate({ type: "Feature", id: this.currentId, geometry: p, properties: {} }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Provisional }).valid || this.store.updateGeometry([{ id: this.currentId, geometry: p }]);
}
onClick(t) {
if (!this.preventNewFeature) {
if (this.startingClick === !1) {
const [e, i] = this.store.create([{ geometry: { type: "Polygon", coordinates: [[[t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat]]] }, properties: { mode: this.mode } }, { geometry: { type: "Point", coordinates: [t.lng, t.lat] }, properties: { mode: this.mode, [st]: !0 } }]);
return this.currentId = e, this.closingPointId = i, this.startingClick = !0, void this.setDrawing();
}
this.close();
}
}
onKeyDown() {
}
onKeyUp(t) {
t.key === this.keyEvents.cancel ? this.cleanUp() : t.key === this.keyEvents.finish && this.startingClick === !0 && this.close();
}
onDragStart() {
}
onDrag() {
}
onDragEnd() {
}
cleanUp() {
const t = this.currentId, e = this.closingPointId;
this.closingPointId = void 0, this.currentId = void 0, this.startingClick = !1, this.state === "drawing" && this.setStarted();
try {
t !== void 0 && this.store.delete([t]), e !== void 0 && this.store.delete([e]);
} catch {
}
}
styleFeature(t) {
const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
return t.type === "Feature" && t.geometry.type === "Polygon" && t.properties.mode === this.mode ? (e.polygonFillColor = this.getHexColorStylingValue(this.styles.fillColor, e.polygonFillColor, t), e.polygonOutlineColor = this.getHexColorStylingValue(this.styles.outlineColor, e.polygonOutlineColor, t), e.polygonOutlineWidth = this.getNumericStylingValue(this.styles.outlineWidth, e.polygonOutlineWidth, t), e.polygonFillOpacity = this.getNumericStylingValue(this.styles.fillOpacity, e.polygonFillOpacity, t), e.zIndex = 10, e) : (t.type === "Feature" && t.geometry.type === "Point" && t.properties.mode === this.mode && (e.pointWidth = this.getNumericStylingValue(this.styles.closingPointWidth, e.pointWidth, t), e.pointColor = this.getHexColorStylingValue(this.styles.closingPointColor, e.pointColor, t), e.pointOutlineColor = this.getHexColorStylingValue(this.styles.closingPointOutlineColor, e.pointOutlineColor, t), e.pointOutlineWidth = this.getNumericStylingValue(this.styles.closingPointOutlineWidth, 2, t), e.zIndex = 40), e);
}
validateFeature(t) {
return this.validateModeFeature(t, (e) => It(e, this.coordinatePrecision));
}
}
class k {
constructor({ store: t, mode: e, project: i, unproject: o, pointerDistance: r, coordinatePrecision: n, projection: a }) {
this.store = void 0, this.mode = void 0, this.project = void 0, this.unproject = void 0, this.pointerDistance = void 0, this.coordinatePrecision = void 0, this.projection = void 0, this.store = t, this.mode = e, this.project = i, this.unproject = o, this.pointerDistance = r, this.coordinatePrecision = n, this.projection = a;
}
}
function Se({ unproject: s, point: t, pointerDistance: e }) {
const i = e / 2, { x: o, y: r } = t;
return { type: "Feature", properties: {}, geometry: { type: "Polygon", coordinates: [[s(o - i, r - i), s(o + i, r - i), s(o + i, r + i), s(o - i, r + i), s(o - i, r - i)].map((n) => [n.lng, n.lat])] } };
}
class rt extends k {
constructor(t) {
super(t);
}
create(t) {
const { containerX: e, containerY: i } = t;
return Se({ unproject: this.unproject, point: { x: e, y: i }, pointerDistance: this.pointerDistance });
}
}
class nt extends k {
constructor(t) {
super(t);
}
measure(t, e) {
const { x: i, y: o } = this.project(e[0], e[1]);
return E({ x: i, y: o }, { x: t.containerX, y: t.containerY });
}
}
class mt extends k {
constructor(t, e, i) {
super(t), this.config = void 0, this.pixelDistance = void 0, this.clickBoundingBox = void 0, this.getSnappableCoordinateFirstClick = (o) => this.getSnappable(o, (r) => !!(r.properties && r.properties.mode === this.mode)).coordinate, this.getSnappableCoordinate = (o, r) => this.getSnappable(o, (n) => !!(n.properties && n.properties.mode === this.mode && n.id !== r)).coordinate, this.config = t, this.pixelDistance = e, this.clickBoundingBox = i;
}
getSnappable(t, e) {
const i = this.clickBoundingBox.create(t), o = this.store.search(i, e), r = { featureId: void 0, featureCoordinateIndex: void 0, coordinate: void 0, minDist: 1 / 0 };
return o.forEach((n) => {
let a;
if (n.geometry.type === "Polygon") a = n.geometry.coordinates[0];
else {
if (n.geometry.type !== "LineString") return;
a = n.geometry.coordinates;
}
a.forEach((l, d) => {
const h = this.pixelDistance.measure(t, l);
h < r.minDist && h < this.pointerDistance && (r.coordinate = l, r.minDist = h, r.featureId = n.id, r.featureCoordinateIndex = d);
});
}), r;
}
}
function qt(s, t, e) {
const i = O(s[0]), o = O(s[1]), r = O(e), n = ve(t), a = Math.asin(Math.sin(o) * Math.cos(n) + Math.cos(o) * Math.sin(n) * Math.cos(r));
return [R(i + Math.atan2(Math.sin(r) * Math.sin(n) * Math.cos(o), Math.cos(n) - Math.sin(o) * Math.sin(a))), R(a)];
}
function at({ x: s, y: t }, e, i) {
const o = O(i);
return { x: s + e * Math.cos(o), y: t + e * Math.sin(o) };
}
function Jt(s, t) {
const e = O(s[0]), i = O(t[0]), o = O(s[1]), r = O(t[1]), n = Math.sin(i - e) * Math.cos(r), a = Math.cos(o) * Math.sin(r) - Math.sin(o) * Math.cos(r) * Math.cos(i - e);
return R(Math.atan2(n, a));
}
function A({ x: s, y: t }, { x: e, y: i }) {
let o = Math.atan2(i - t, e - s);
return o *= 180 / Math.PI, o > 180 ? o -= 360 : o < -180 && (o += 360), o;
}
function Y(s) {
return (s + 360) % 360;
}
function si(s, t, e) {
const i = [], o = s.length;
let r, n, a, l = 0;
for (let h = 0; h < s.length && !(t >= l && h === s.length - 1); h++) {
if (l > t && i.length === 0) {
if (r = t - l, !r) return i.push(s[h]), i;
n = Jt(s[h], s[h - 1]) - 180, a = qt(s[h], r, n), i.push(a);
}
if (l >= e) return r = e - l, r ? (n = Jt(s[h], s[h - 1]) - 180, a = qt(s[h], r, n), i.push(a), i) : (i.push(s[h]), i);
if (l >= t && i.push(s[h]), h === s.length - 1) return i;
l += T(s[h], s[h + 1]);
}
if (l < t && s.length === o) throw new Error("Start position is beyond line");
const d = s[s.length - 1];
return [d, d];
}
function ct(s) {
return s * (Math.PI / 180);
}
function Zt(s) {
return s * (180 / Math.PI);
}
class ri extends k {
constructor(t) {
super(t), this.config = void 0, this.config = t;
}
generateInsertionCoordinates(t, e, i) {
const o = [t, e];
let r = 0;
for (let d = 0; d < o.length - 1; d++) r += T(o[0], o[1]);
if (r <= i) return o;
let n = r / i - 1;
Number.isInteger(n) || (n = Math.floor(n) + 1);
const a = [];
for (let d = 0; d < n; d++) {
const h = si(o, i * d, i * (d + 1));
a.push(h);
}
const l = [];
for (let d = 0; d < a.length; d++) l.push(a[d][1]);
return this.limitCoordinates(l);
}
generateInsertionGeodesicCoordinates(t, e, i) {
const o = T(t, e), r = function(n, a, l) {
const d = [], h = ct(n[1]), c = ct(n[0]), u = ct(a[1]), p = ct(a[0]);
l += 1;
const g = 2 * Math.asin(Math.sqrt(Math.sin((u - h) / 2) ** 2 + Math.cos(h) * Math.cos(u) * Math.sin((p - c) / 2) ** 2));
if (g === 0 || isNaN(g)) return d;
for (let y = 0; y <= l; y++) {
const m = y / l, v = Math.sin((1 - m) * g) / Math.sin(g), f = Math.sin(m * g) / Math.sin(g), C = v * Math.cos(h) * Math.cos(c) + f * Math.cos(u) * Math.cos(p), P = v * Math.cos(h) * Math.sin(c) + f * Math.cos(u) * Math.sin(p), S = v * Math.sin(h) + f * Math.sin(u);
if (isNaN(C) || isNaN(P) || isNaN(S)) continue;
const b = Math.atan2(S, Math.sqrt(C ** 2 + P ** 2)), w = Math.atan2(P, C);
isNaN(b) || isNaN(w) || d.push([Zt(w), Zt(b)]);
}
return d.slice(1, -1);
}(t, e, Math.floor(o / i));
return this.limitCoordinates(r);
}
limitCoordinates(t) {
return t.map((e) => [F(e[0], this.config.coordinatePrecision), F(e[1], this.config.coordinatePrecision)]);
}
}
function Z(s, t) {
return s[0] === t[0] && s[1] === t[1];
}
function xe(s, t) {
if (s.geometry.type !== "LineString") return { valid: !1, reason: "Feature is not a LineString" };
if (s.geometry.coordinates.length < 2) return { valid: !1, reason: "Feature has less than 2 coordinates" };
for (let e = 0; e < s.geometry.coordinates.length; e++) {
if (!Wt(s.geometry.coordinates[e])) return { valid: !1, reason: "Feature has invalid coordinates" };
if (!xt(s.geometry.coordinates[e], t)) return { valid: !1, reason: "Feature has coordinates with excessive precision" };
}
return { valid: !0 };
}
function Qt(s) {
return Math.sqrt(Math.pow(s[0], 2) + Math.pow(s[1], 2) + Math.pow(s[2], 2));
}
function X(s, t) {
const e = function(i, o) {
const [r, n, a] = i, [l, d, h] = o;
return r * l + n * d + a * h;
}(s, t) / (Qt(s) * Qt(t));
return Math.acos(Math.min(Math.max(e, -1), 1));
}
function wt(s) {
const t = O(s[1]), e = O(s[0]);
return [Math.cos(t) * Math.cos(e), Math.cos(t) * Math.sin(e), Math.sin(t)];
}
function K(s) {
const [t, e, i] = s, o = R(Math.asin(i));
return [R(Math.atan2(e, t)), o];
}
function ni(s, t, e) {
const i = wt(s), o = wt(t), r = wt(e), [n, a, l] = r, [d, h, c] = function(j, z) {
const [Gt, At, Tt] = j, [Ut, Vt, Rt] = z;
return [At * Rt - Tt * Vt, Tt * Ut - Gt * Rt, Gt * Vt - At * Ut];
}(i, o), u = h * l - c * a, p = c * n - d * l, g = d * a - h * n, y = g * h - p * c, m = u * c - g * d, v = p * d - u * h, f = 1 / Math.sqrt(Math.pow(y, 2) + Math.pow(m, 2) + Math.pow(v, 2)), C = [y * f, m * f, v * f], P = [-1 * y * f, -1 * m * f, -1 * v * f], S = X(i, o), b = X(i, C), w = X(o, C), D = X(i, P), G = X(o, P);
let _;
return _ = b < D && b < G || w < D && w < G ? C : P, X(i, _) > S || X(o, _) > S ? T(K(_), K(i)) <= T(K(_), K(o)) ? [K(i), !0, !1] : [K(o), !1, !0] : [K(_), !1, !1];
}
function ai(s, t, e) {
const i = t.x - s.x, o = t.y - s.y, r = Math.max(0, Math.min(1, ((e.x - s.x) * i + (e.y - s.y) * o) / (i * i + o * o)));
return { x: s.x + r * i, y: s.y + r * o };
}
class Ie extends k {
constructor(t, e, i) {
super(t), this.config = void 0, this.pixelDistance = void 0, this.clickBoundingBox = void 0, this.getSnappableCoordinateFirstClick = (o) => this.getSnappable(o, (r) => !!(r.properties && r.properties.mode === this.mode)).coordinate, this.getSnappableCoordinate = (o, r) => this.getSnappable(o, (n) => !!(n.properties && n.properties.mode === this.mode && n.id !== r)).coordinate, this.config = t, this.pixelDistance = e, this.clickBoundingBox = i;
}
getSnappable(t, e) {
const i = this.clickBoundingBox.create(t), o = this.store.search(i, e), r = { featureId: void 0, featureCoordinateIndex: void 0, coordinate: void 0, minDistance: 1 / 0 };
return o.forEach((n) => {
let a;
if (n.geometry.type === "Polygon") a = n.geometry.coordinates[0];
else {
if (n.geometry.type !== "LineString") return;
a = n.geometry.coordinates;
}
const l = [];
for (let u = 0; u < a.length - 1; u++) l.push([a[u], a[u + 1]]);
let d;
const h = [t.lng, t.lat];
if (this.config.projection === "web-mercator" ? d = function(u, p) {
let g = [1 / 0, 1 / 0], y = 1 / 0, m = 0;
for (let v of p) {
const f = v[0], C = v[1];
let P, S = 1 / 0;
const b = x(f[0], f[1]), w = x(C[0], C[1]), D = x(u[0], u[1]);
if (f[0] === u[0] && f[1] === u[1]) P = f;
else if (C[0] === u[0] && C[1] === u[1]) P = C;
else {
const { x: G, y: _ } = ai(b, w, D), { lng: j, lat: z } = W(G, _);
P = [j, z];
}
P && (S = E(D, x(P[0], P[1])), S < y && (g = P, y = S, m = p.indexOf(v)));
}
return y === 1 / 0 ? void 0 : { coordinate: g, lineIndex: m, distance: y };
}(h, l) : this.config.projection === "globe" && (d = function(u, p) {
let g = [1 / 0, 1 / 0], y = 1 / 0, m = 0;
for (let v of p) {
const f = v[0], C = v[1];
let P, S = 1 / 0;
f[0] === u[0] && f[1] === u[1] ? P = f : C[0] === u[0] && C[1] === u[1] ? P = C : [P] = ni(f, C, u), P && (S = T(u, P), S < y && (g = P, y = S, m = p.indexOf(v)));
}
return y === 1 / 0 ? void 0 : { coordinate: g, distance: y, lineIndex: m };
}(h, l)), !d) return;
const c = this.pixelDistance.measure(t, d.coordinate);
c < r.minDistance && c < this.pointerDistance && (r.featureId = n.id, r.coordinate = d.coordinate, r.featureCoordinateIndex = d.lineIndex, r.minDistance = c);
}), r;
}
}
const li = { cancel: "Escape", finish: "Enter" }, di = { start: "crosshair", close: "pointer", dragStart: "grabbing", dragEnd: "crosshair" };
class be extends N {
constructor(t) {
super(t, !0), this.mode = "linestring", this.currentCoordinate = 0, this.currentId = void 0, this.closingPointId = void 0, this.keyEvents = li, this.snapping = void 0, this.cursors = di, this.mouseMove = !1, this.insertCoordinates = void 0, this.lastCommitedCoordinates = void 0, this.snappedPointId = void 0, this.editable = !1, this.editedFeatureId = void 0, this.editedFeatureCoordinateIndex = void 0, this.editedSnapType = void 0, this.editedInsertIndex = void 0, this.editedPointId = void 0, this.coordinateSnapping = void 0, this.insertPoint = void 0, this.lineSnapping = void 0, this.pixelDistance = void 0, this.clickBoundingBox = void 0, this.updateOptions(t);
}
updateOptions(t) {
super.updateOptions(t), t != null && t.cursors && (this.cursors = I({}, this.cursors, t.cursors)), t != null && t.snapping && (this.snapping = t.snapping), (t == null ? void 0 : t.keyEvents) === null ? this.keyEvents = { cancel: null, finish: null } : t != null && t.keyEvents && (this.keyEvents = I({}, this.keyEvents, t.keyEvents)), t != null && t.insertCoordinates && (this.insertCoordinates = t.insertCoordinates), t && t.editable && (this.editable = t.editable);
}
close() {
if (this.currentId === void 0) return;
const t = this.store.getGeometryCopy(this.currentId);
t.coordinates.pop(), this.updateGeometries([...t.coordinates], void 0, M.Commit);
const e = this.currentId;
this.closingPointId && this.store.delete([this.closingPointId]), this.snappedPointId && this.store.delete([this.snappedPointId]), this.currentCoordinate = 0, this.currentId = void 0, this.closingPointId = void 0, this.snappedPointId = void 0, this.lastCommitedCoordinates = void 0, this.state === "drawing" && this.setStarted(), this.onFinish(e, { mode: this.mode, action: "draw" });
}
updateGeometries(t, e, i) {
if (!this.currentId) return;
const o = { type: "LineString", coordinates: t };
if (this.validate && !this.validate({ type: "Feature", geometry: o }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: i }).valid) return;
const r = [{ id: this.currentId, geometry: o }];
this.closingPointId && e && r.push({ id: this.closingPointId, geometry: { type: "Point", coordinates: e } }), i === "commit" && (this.lastCommitedCoordinates = o.coordinates), this.store.updateGeometry(r);
}
generateInsertCoordinates(t, e) {
if (!this.insertCoordinates || !this.lastCommitedCoordinates) throw new Error("Not able to insert coordinates");
if (this.insertCoordinates.strategy !== "amount") throw new Error("Strategy does not exist");
const i = T(t, e) / (this.insertCoordinates.value + 1);
let o = [];
return this.projection === "globe" ? o = this.insertPoint.generateInsertionGeodesicCoordinates(t, e, i) : this.projection === "web-mercator" && (o = this.insertPoint.generateInsertionCoordinates(t, e, i)), o;
}
createLine(t) {
const [e] = this.store.create([{ geometry: { type: "LineString", coordinates: [t, t] }, properties: { mode: this.mode } }]);
this.lastCommitedCoordinates = [t, t], this.currentId = e, this.currentCoordinate++, this.setDrawing();
}
firstUpdateToLine(t) {
if (!this.currentId) return;
const e = this.store.getGeometryCopy(this.currentId).coordinates, [i] = this.store.create([{ geometry: { type: "Point", coordinates: [...t] }, properties: { mode: this.mode } }]);
this.closingPointId = i, this.setCursor(this.cursors.close);
const o = [...e, t];
this.updateGeometries(o, void 0, M.Commit), this.currentCoordinate++;
}
updateToLine(t, e) {
if (!this.currentId) return;
const i = this.store.getGeometryCopy(this.currentId).coordinates, [o, r] = this.lastCommitedCoordinates ? this.lastCommitedCoordinates[this.lastCommitedCoordinates.length - 1] : i[i.length - 2], { x: n, y: a } = this.project(o, r);
if (E({ x: n, y: a }, { x: e.x, y: e.y }) < this.pointerDistance) return void this.close();
this.setCursor(this.cursors.close);
const l = [...i, t];
this.updateGeometries(l, i[i.length - 1], M.Commit), this.currentCoordinate++;
}
registerBehaviors(t) {
this.coordinateSnapping = new mt(t, new nt(t), new rt(t)), this.insertPoint = new ri(t), this.clickBoundingBox = new rt(t), this.pixelDistance = new nt(t), this.lineSnapping = new Ie(t, this.pixelDistance, this.clickBoundingBox), this.coordinateSnapping = new mt(t, this.pixelDistance, this.clickBoundingBox);
}
start() {
this.setStarted(), this.setCursor(this.cursors.start);
}
stop() {
this.cleanUp(), this.setStopped(), this.setCursor("unset");
}
onMouseMove(t) {
this.mouseMove = !0, this.setCursor(this.cursors.start);
const e = this.snapCoordinate(t);
if (e) {
if (this.snappedPointId) this.store.updateGeometry([{ id: this.snappedPointId, geometry: { type: "Point", coordinates: e } }]);
else {
const [n] = this.store.create([{ geometry: { type: "Point", coordinates: e }, properties: { mode: this.mode, [_t]: !0 } }]);
this.snappedPointId = n;
}
t.lng = e[0], t.lat = e[1];
} else this.snappedPointId && (this.store.delete([this.snappedPointId]), this.snappedPointId = void 0);
const i = e || [t.lng, t.lat];
if (this.currentId === void 0 || this.currentCoordinate === 0) return;
const o = this.store.getGeometryCopy(this.currentId).coordinates;
if (o.pop(), this.closingPointId) {
const [n, a] = o[o.length - 1], { x: l, y: d } = this.project(n, a);
E({ x: l, y: d }, { x: t.containerX, y: t.containerY }) < this.pointerDistance && this.setCursor(this.cursors.close);
}
let r = [...o, i];
if (this.insertCoordinates && this.currentId && this.lastCommitedCoordinates) {
const n = this.lastCommitedCoordinates[this.lastCommitedCoordinates.length - 1], a = i;
if (!Z(n, a)) {
const l = this.generateInsertCoordinates(n, a);
r = [...this.lastCommitedCoordinates.slice(0, -1), ...l, i];
}
}
this.updateGeometries(r, void 0, M.Provisional);
}
onRightClick(t) {
if (!this.editable || this.state !== "started") return;
const { featureId: e, featureCoordinateIndex: i } = this.coordinateSnapping.getSnappable(t, (n) => this.lineStringFilter(n));
if (!e || i === void 0) return;
const o = this.store.getGeometryCopy(e);
let r;
if (o.type === "LineString" && (r = o.coordinates, !(r.length <= 2))) {
if (r.splice(i, 1), this.validate && !this.validate({ id: e, type: "Feature", geometry: o, properties: {} }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Commit }).valid) return;
this.snappedPointId && (this.store.delete([this.snappedPointId]), this.snappedPointId = void 0), this.store.updateGeometry([{ id: e, geometry: o }]), this.onFinish(e, { mode: this.mode, action: "edit" });
}
}
onLeftClick(t) {
this.snappedPointId && (this.store.delete([this.snappedPointId]), this.snappedPointId = void 0);
const e = this.snapCoordinate(t) || [t.lng, t.lat];
this.currentCoordinate === 0 ? this.createLine(e) : this.currentCoordinate === 1 && this.currentId ? this.firstUpdateToLine(e) : this.currentId && this.updateToLine(e, { x: t.containerX, y: t.containerY });
}
onClick(t) {
this.currentCoordinate > 0 && !this.mouseMove && this.onMouseMove(t), this.mouseMove = !1, t.button === "right" ? this.onRightClick(t) : t.button === "left" && this.onLeftClick(t);
}
onKeyDown() {
}
onKeyUp(t) {
t.key === this.keyEvents.cancel && this.cleanUp(), t.key === this.keyEvents.finish && this.close();
}
onDragStart(t, e) {
if (!this.editable) return;
let i;
if (this.state === "started") {
const o = this.lineSnapping.getSnappable(t, (n) => this.lineStringFilter(n));
o.coordinate && (this.editedSnapType = "line", this.editedFeatureCoordinateIndex = o.featureCoordinateIndex, this.editedFeatureId = o.featureId, i = o.coordinate);
const r = this.coordinateSnapping.getSnappable(t, (n) => this.lineStringFilter(n));
r.coordinate && (this.editedSnapType = "coordinate", this.editedFeatureCoordinateIndex = r.featureCoordinateIndex, this.editedFeatureId = r.featureId, i = r.coordinate);
}
if (this.editedFeatureId && i) {
if (!this.editedPointId) {
const [o] = this.store.create([{ geometry: { type: "Point", coordinates: i }, properties: { mode: this.mode, [U]: !0 } }]);
this.editedPointId = o;
}
this.setCursor(this.cursors.dragStart), e(!1);
}
}
onDrag(t, e) {
if (this.editedFeatureId === void 0 || this.editedFeatureCoordinateIndex === void 0) return;
const i = this.store.getGeometryCopy(this.editedFeatureId);
this.editedSnapType === "coordinate" || this.editedSnapType === "line" && this.editedInsertIndex !== void 0 ? i.coordinates[this.editedFeatureCoordinateIndex] = [t.lng, t.lat] : this.editedSnapType === "line" && this.editedInsertIndex === void 0 && (this.editedInsertIndex = this.editedFeatureCoordinateIndex + 1, i.coordinates.splice(this.editedInsertIndex, 0, [t.lng, t.lat]), this.editedFeatureCoordinateIndex++);
const o = { type: "LineString", coordinates: i.coordinates };
this.validate && !this.validate({ type: "Feature", geometry: o, properties: this.store.getPropertiesCopy(this.editedFeatureId) }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Provisional }).valid || (this.snapping && this.snappedPointId && (this.store.delete([this.snappedPointId]), this.snappedPointId = void 0), this.store.updateGeometry([{ id: this.editedFeatureId, geometry: o }]), this.editedPointId && this.store.updateGeometry([{ id: this.editedPointId, geometry: { type: "Point", coordinates: [t.lng, t.lat] } }]), this.store.updateProperty([{ id: this.editedFeatureId, property: U, value: !0 }]), e(!0));
}
onDragEnd(t, e) {
this.editedFeatureId !== void 0 && (this.setCursor(this.cursors.dragEnd), this.editedPointId && (this.store.delete([this.editedPointId]), this.editedPointId = void 0), this.store.updateProperty([{ id: this.editedFeatureId, property: U, value: !1 }]), this.onFinish(this.editedFeatureId, { mode: this.mode, action: "edit" }), this.editedFeatureId = void 0, this.editedFeatureCoordinateIndex = void 0, this.editedInsertIndex = void 0, this.editedSnapType = void 0, e(!0));
}
cleanUp() {
const t = this.currentId, e = this.closingPointId, i = this.snappedPointId;
this.closingPointId = void 0, this.snappedPointId = void 0, this.currentId = void 0, this.currentCoordinate = 0, this.state === "drawing" && this.setStarted();
try {
t !== void 0 && this.store.delete([t]), i !== void 0 && this.store.delete([i]), e !== void 0 && this.store.delete([e]);
} catch {
}
}
styleFeature(t) {
const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
if (t.type === "Feature" && t.geometry.type === "LineString" && t.properties.mode === this.mode) return e.lineStringColor = this.getHexColorStylingValue(this.styles.lineStringColor, e.lineStringColor, t), e.lineStringWidth = this.getNumericStylingValue(this.styles.lineStringWidth, e.lineStringWidth, t), e.zIndex = 10, e;
if (t.type === "Feature" && t.geometry.type === "Point" && t.properties.mode === this.mode) {
const i = t.properties[st];
return e.pointColor = this.getHexColorStylingValue(i ? this.styles.closingPointColor : this.styles.snappingPointColor, e.pointColor, t), e.pointWidth = this.getNumericStylingValue(i ? this.styles.closingPointWidth : this.styles.snappingPointWidth, e.pointWidth, t), e.pointOutlineColor = this.getHexColorStylingValue(i ? this.styles.closingPointOutlineColor : this.styles.snappingPointOutlineColor, "#ffffff", t), e.pointOutlineWidth = this.getNumericStylingValue(i ? this.styles.closingPointOutlineWidth : this.styles.snappingPointOutlineWidth, 2, t), e.zIndex = 40, e;
}
return e;
}
validateFeature(t) {
return this.validateModeFeature(t, (e) => xe(e, this.coordinatePrecision));
}
lineStringFilter(t) {
return !!(t.geometry.type === "LineString" && t.properties && t.properties.mode === this.mode);
}
snapCoordinate(t) {
var e, i;
let o;
return (e = this.snapping) != null && e.toCoordinate && (o = this.currentId ? this.coordinateSnapping.getSnappableCoordinate(t, this.currentId) : this.coordinateSnapping.getSnappableCoordinateFirstClick(t)), (i = this.snapping) != null && i.toCustom && (o = this.snapping.toCustom(t)), o;
}
}
const hi = "Feature is not a Point", ci = "Feature has invalid coordinates", ui = "Feature has coordinates with excessive precision";
function Me(s, t) {
return s.geometry.type !== "Point" ? { valid: !1, reason: hi } : Wt(s.geometry.coordinates) ? xt(s.geometry.coordinates, t) ? { valid: !0 } : { valid: !1, reason: ui } : { valid: !1, reason: ci };
}
const pi = { create: "crosshair", dragStart: "grabbing", dragEnd: "crosshair" };
class we extends N {
constructor(t) {
super(t, !0), this.mode = "point", this.cursors = pi, this.editable = !1, this.editedFeatureId = void 0, this.pixelDistance = void 0, this.clickBoundingBox = void 0, this.updateOptions(t);
}
updateOptions(t) {
super.updateOptions(t), t != null && t.cursors && (this.cursors = I({}, this.cursors, t.cursors)), t != null && t.editable && (this.editable = t.editable);
}
start() {
this.setStarted(), this.setCursor(this.cursors.create);
}
stop() {
this.cleanUp(), this.setStopped(), this.setCursor("unset");
}
onClick(t) {
if (!this.store) throw new Error("Mode must be registered first");
t.button === "right" ? this.onRightClick(t) : t.button === "left" && this.onLeftClick(t);
}
onMouseMove() {
}
onKeyDown() {
}
onKeyUp() {
}
cleanUp() {
this.editedFeatureId = void 0;
}
onDragStart(t, e) {
if (this.editable) {
const i = this.getNearestPointFeature(t);
this.editedFeatureId = i == null ? void 0 : i.id;
}
this.editedFeatureId && (this.setCursor(this.cursors.dragStart), e(!1));
}
onDrag(t, e) {
this.editedFeatureId !== void 0 && (this.validate && !this.validate({ type: "Feature", geometry: { type: "Point", coordinates: [t.lng, t.lat] }, properties: this.store.getPropertiesCopy(this.editedFeatureId) }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Finish }).valid || (this.store.updateGeometry([{ id: this.editedFeatureId, geometry: { type: "Point", coordinates: [t.lng, t.lat] } }]), this.store.updateProperty([{ id: this.editedFeatureId, property: U, value: !0 }]), e(!0)));
}
onDragEnd(t, e) {
this.editedFeatureId !== void 0 && (this.onFinish(this.editedFeatureId, { mode: this.mode, action: "edit" }), this.setCursor(this.cursors.dragEnd), this.store.updateProperty([{ id: this.editedFeatureId, property: U, value: !1 }]), this.editedFeatureId = void 0, e(!0));
}
registerBehaviors(t) {
this.pixelDistance = new nt(t), this.clickBoundingBox = new rt(t);
}
styleFeature(t) {
const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
if (t.type === "Feature" && t.geometry.type === "Point" && t.properties.mode === this.mode) {
const i = !!(t.id && this.editedFeatureId === t.id);
e.pointWidth = this.getNumericStylingValue(i ? this.styles.editedPointWidth : this.styles.pointWidth, e.pointWidth, t), e.pointColor = this.getHexColorStylingValue(i ? this.styles.editedPointColor : this.styles.pointColor, e.pointColor, t), e.pointOutlineColor = this.getHexColorStylingValue(i ? this.styles.editedPointOutlineColor : this.styles.pointOutlineColor, e.pointOutlineColor, t), e.pointOutlineWidth = this.getNumericStylingValue(i ? this.styles.editedPointOutlineWidth : this.styles.pointOutlineWidth, 2, t), e.zIndex = 30;
}
return e;
}
validateFeature(t) {
return this.validateModeFeature(t, (e) => Me(e, this.coordinatePrecision));
}
onLeftClick(t) {
const e = { type: "Point", coordinates: [t.lng, t.lat] }, i = { mode: this.mode };
if (this.validate && !this.validate({ type: "Feature", geometry: e, properties: i }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Finish }).valid) return;
const [o] = this.store.create([{ geometry: e, properties: i }]);
this.onFinish(o, { mode: this.mode, action: "draw" });
}
onRightClick(t) {
if (!this.editable) return;
const e = this.getNearestPointFeature(t);
e && this.store.delete([e.id]);
}
getNearestPointFeature(t) {
const e = this.clickBoundingBox.create(t), i = this.store.search(e);
let o, r = 1 / 0;
for (let n = 0; n < i.length; n++) {
const a = i[n];
if (a.geometry.type !== "Point" || a.properties.mode !== this.mode) continue;
const l = this.pixelDistance.measure(t, a.geometry.coordinates);
l > r || l > this.pointerDistance || (r = l, o = a);
}
return o;
}
}
class gi extends k {
constructor(t, e) {
super(t), this.config = void 0, this.pixelDistance = void 0, this._startEndPoints = [], this.config = t, this.pixelDistance = e;
}
get ids() {
return this._startEndPoints.concat();
}
set ids(t) {
}
create(t, e) {
if (this.ids.length) throw new Error("Opening and closing points already created");
if (t.length <= 3) throw new Error("Requires at least 4 coordinates");
this._startEndPoints = this.store.create([{ geometry: { type: "Point", coordinates: t[0] }, properties: { mode: e, [st]: !0 } }, { geometry: { type: "Point", coordinates: t[t.length - 2] }, properties: { mode: e, [st]: !0 } }]);
}
delete() {
this.ids.length && (this.store.delete(this.ids), this._startEndPoints = []);
}
update(t) {
if (this.ids.length !== 2) throw new Error("No closing points to update");
this.store.updateGeometry([{ id: this.ids[0], geometry: { type: "Point", coordinates: t[0] } }, { id: this.ids[1], geometry: { type: "Point", coordinates: t[t.length - 3] } }]);
}
isClosingPoint(t) {
const e = this.store.getGeometryCopy(this.ids[0]), i = this.store.getGeometryCopy(this.ids[1]), o = this.pixelDistance.measure(t, e.coordinates), r = this.pixelDistance.measure(t, i.coordinates);
return { isClosing: o < this.pointerDistance, isPreviousClosing: r < this.pointerDistance };
}
}
class Fe extends k {
constructor(t) {
super(t);
}
createOrUpdate(t) {
const e = this.store.getGeometryCopy(t), i = this.store.getPropertiesCopy(t);
let o;
if (e.type === "Polygon") o = e.coordinates[0].slice(0, -1);
else {
if (e.type !== "LineString") return;
o = e.coordinates;
}
const r = this.store.getPropertiesCopy(t);
if (r.coordinatePointIds) {
const n = r.coordinatePointIds, a = n.map((l) => this.store.getGeometryCopy(l).coordinates);
if (n.length !== o.length) {
this.deleteCoordinatePoints(n);
const l = this.createPoints(o, i.mode);
this.setFeatureCoordinatePoints(t, l);
} else o.forEach((l, d) => {
l[0] === a[d][0] && l[1] === a[d][1] || this.store.updateGeometry([{ id: n[d], geometry: { type: "Point", coordinates: l } }]);
});
} else {
const n = this.createPoints(o, i.mode);
this.setFeatureCoordinatePoints(t, n);
}
}
deletePointsByFeatureIds(t) {
for (const e of t) this.deleteIfPresent(e);
}
getUpdated(t, e) {
const i = this.store.getPropertiesCopy(t);
if (i.coordinatePointIds) return i.coordinatePointIds.map((o, r) => ({ id: o, geometry: I({}, this.store.getGeometryCopy(o), { coordinates: e[r] }) }));
}
createPoints(t, e) {
return this.store.create(t.map((i) => ({ geometry: { type: "Point", coordinates: i }, properties: { mode: e, [Lt]: !0 } })));
}
setFeatureCoordinatePoints(t, e) {
this.store.updateProperty([{ id: t, property: kt, value: e }]);
}
deleteCoordinatePoints(t) {
this.store.delete(t);
}
deleteIfPresent(t) {
const e = this.store.getPropertiesCopy(t);
e.coordinatePointIds && (this.deleteCoordinatePoints(e.coordinatePointIds), this.setFeatureCoordinatePoints(t, null));
}
}
const yi = { cancel: "Escape", finish: "Enter" }, fi = { start: "crosshair", close: "pointer", dragStart: "grabbing", dragEnd: "crosshair" };
class Ee extends N {
constructor(t) {
super(t, !0), this.mode = "polygon", this.currentCoordinate = 0, this.currentId = void 0, this.keyEvents = yi, this.cursors = fi, this.mouseMove = !1, this.showCoordinatePoints = !1, this.snapping = void 0, this.snappedPointId = void 0, this.editable = !1, this.editedFeatureId = void 0, this.editedFeatureCoordinateIndex = void 0, this.editedSnapType = void 0, this.editedInsertIndex = void 0, this.editedPointId = void 0, this.coordinatePoints = void 0, this.lineSnapping = void 0, this.coordinateSnapping = void 0, this.pixelDistance = void 0, this.closingPoints = void 0, this.clickBoundingBox = void 0, this.updateOptions(t);
}
updateOptions(t) {
if (super.updateOptions(t), t != null && t.cursors && (this.cursors = I({}, this.cursors, t.cursors)), (t == null ? void 0 : t.keyEvents) === null ? this.keyEvents = { cancel: null, finish: null } : t != null && t.keyEvents && (this.keyEvents = I({}, this.keyEvents, t.keyEvents)), t != null && t.snapping && (this.snapping = t.snapping), (t == null ? void 0 : t.editable) !== void 0 && (this.editable = t.editable), (t == null ? void 0 : t.showCoordinatePoints) !== void 0) {
if (this.showCoordinatePoints = t.showCoordinatePoints, this.coordinatePoints && t.showCoordinatePoints === !0) this.store.copyAllWhere((e) => e.mode === this.mode).map((e) => e.id).forEach((e) => {
this.coordinatePoints.createOrUpdate(e);
});
else if (this.coordinatePoints && this.showCoordinatePoints === !1) {
const e = this.store.copyAllWhere((i) => i.mode === this.mode && !!i[kt]);
this.coordinatePoints.deletePointsByFeatureIds(e.map((i) => i.id));
}
}
}
close() {
if (this.currentId === void 0) return;
const t = this.store.getGeometryCopy(this.currentId).coordinates[0];
if (t.length < 5 || !this.updatePolygonGeometry([...t.slice(0, -2), t[0]], M.Finish)) return;
const e = this.currentId;
if (this.currentId) {
const i = dt(this.store.getGeometryCopy(this.currentId));
i && this.store.updateGeometry([{ id: this.currentId, geometry: i }]);
}
this.snappedPointId && this.store.delete([this.snappedPointId]), this.currentCoordinate = 0, this.currentId = void 0, this.snappedPointId = void 0, this.closingPoints.delete(), this.state === "drawing" && this.setStarted(), this.onFinish(e, { mode: this.mode, action: "draw" });
}
registerBehaviors(t) {
this.clickBoundingBox = new rt(t), this.pixelDistance = new nt(t), this.lineSnapping = new Ie(t, this.pixelDistance, this.clickBoundingBox), this.coordinateSnapping = new mt(t, this.pixelDistance, this.clickBoundingBox), this.closingPoints = new gi(t, this.pixelDistance), this.coordinatePoints = new Fe(t);
}
start() {
this.setStarted(), this.setCursor(this.cursors.start);
}
stop() {
this.cleanUp(), this.setStopped(), this.setCursor("unset");
}
onMouseMove(t) {
this.mouseMove = !0, this.setCursor(this.cursors.start);
const e = this.snapCoordinate(t);
if (e) {
if (this.snappedPointId) this.store.updateGeometry([{ id: this.snappedPointId, geometry: { type: "Point", coordinates: e } }]);
else {
const [r] = this.store.create([{ geometry: { type: "Point", coordinates: e }, properties: { mode: this.mode, [_t]: !0 } }]);
this.snappedPointId = r;
}
t.lng = e[0], t.lat = e[1];
} else this.snappedPointId && (this.store.delete([this.snappedPointId]), this.snappedPointId = void 0);
if (this.currentId === void 0 || this.currentCoordinate === 0) return;
const i = this.store.getGeometryCopy(this.currentId).coordinates[0];
let o;
if (this.currentCoordinate === 1) {
const r = 1 / Math.pow(10, this.coordinatePrecision - 1), n = Math.max(1e-6, r);
o = [i[0], [t.lng, t.lat], [t.lng, t.lat - n], i[0]];
} else if (this.currentCoordinate === 2) o = [i[0], i[1], [t.lng, t.lat], i[0]];
else {
const { isClosing: r, isPreviousClosing: n } = this.closingPoints.isClosingPoint(t);
n || r ? (this.snappedPointId && (this.store.delete([this.snappedPointId]), this.snappedPointId = void 0), this.setCursor(this.cursors.close), o = [...i.slice(0, -2), i[0], i[0]]) : o = [...i.slice(0, -2), [t.lng, t.lat], i[0]];
}
this.updatePolygonGeometry(o, M.Provisional);
}
updatePolygonGeometry(t, e) {
if (!this.currentId) return !1;
const i = { type: "Polygon", coordinates: [t] };
return !(this.validate && !this.validate({ type: "Feature", geometry: i }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: e }).valid || (this.store.updateGeometry([{ id: this.currentId, geometry: i }]), this.showCoordinatePoints && this.coordinatePoints.createOrUpdate(this.currentId), 0));
}
snapCoordinate(t) {
var e, i, o;
let r;
if ((e = this.snapping) != null && e.toLine) {
let n;
n = this.currentId ? this.lineSnapping.getSnappableCoordinate(t, this.currentId) : this.lineSnapping.getSnappableCoordinateFirstClick(t), n && (r = n);
}
if ((i = this.snapping) != null && i.toCoordinate) {
let n;
n = this.currentId ? this.coordinateSnapping.getSnappableCoordinate(t, this.currentId) : this.coordinateSnapping.getSnappableCoordinateFirstClick(t), n && (r = n);
}
return (o = this.snapping) != null && o.toCustom && (r = this.snapping.toCustom(t, { currentCoordinate: this.currentCoordinate, currentId: this.currentId, getCurrentGeometrySnapshot: this.currentId ? () => this.store.getGeometryCopy(this.currentId) : () => null, project: this.project, unproject: this.unproject })), r;
}
polygonFilter(t) {
return !!(t.geometry.type === "Polygon" && t.properties && t.properties.mode === this.mode);
}
onRightClick(t) {
if (!this.editable) return;
const { featureId: e, featureCoordinateIndex: i } = this.coordinateSnapping.getSnappable(t, (n) => this.polygonFilter(n));
if (!e || i === void 0) return;
const o = this.store.getGeometryCopy(e);
let r;
o.type === "Polygon" && (r = o.coordinates[0], r.length <= 4 || (o.type !== "Polygon" || i !== 0 && i !== r.length - 1 ? r.splice(i, 1) : (r.shift(), r.pop(), r.push([r[0][0], r[0][1]])), (!this.validate || this.validate({ id: e, type: "Feature", geometry: o, properties: {} }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Commit }).valid) && (this.snappedPointId && (this.store.delete([this.snappedPointId]), this.snappedPointId = void 0), this.store.updateGeometry([{ id: e, geometry: o }]), this.showCoordinatePoints && this.coordinatePoints.createOrUpdate(e), this.onFinish(e, { mode: this.mode, action: "edit" }))));
}
onLeftClick(t) {
if (this.snappedPointId && (this.store.delete([this.snappedPointId]), this.snappedPointId = void 0), this.currentCoordinate === 0) {
const e = this.snapCoordinate(t);
e && (t.lng = e[0], t.lat = e[1]);
const [i] = this.store.create([{ geometry: { type: "Polygon", coordinates: [[[t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat]]] }, properties: { mode: this.mode } }]);
this.currentId = i, this.currentCoordinate++, this.setDrawing();
} else if (this.currentCoordinate === 1 && this.currentId) {
const e = this.snapCoordinate(t);
e && (t.lng = e[0], t.lat = e[1]);
const i = this.store.getGeometryCopy(this.currentId);
if (Z([t.lng, t.lat], i.coordinates[0][0]) || !this.updatePolygonGeometry([i.coordinates[0][0], [t.lng, t.lat], [t.lng, t.lat], i.coordinates[0][0]], M.Commit)) return;
this.currentCoordinate++;
} else if (this.currentCoordinate === 2 && this.currentId) {
const e = this.snapCoordinate(t);
e && (t.lng = e[0], t.lat = e[1]);
const i = this.store.getGeometryCopy(this.currentId).coordinates[0];
if (Z([t.lng, t.lat], i[1]) || !this.updatePolygonGeometry([i[0], i[1], [t.lng, t.lat], [t.lng, t.lat], i[0]], M.Commit)) return;
this.currentCoordinate === 2 && this.closingPoints.create(i, "polygon"), this.currentCoordinate++;
} else if (this.currentId) {
const e = this.store.getGeometryCopy(this.currentId).coordinates[0], { isClosing: i, isPreviousClosing: o } = this.closingPoints.isClosingPoint(t);
if (o || i) this.close();
else {
const r = this.snapCoordinate(t);
if (r && (t.lng = r[0], t.lat = r[1]), Z([t.lng, t.lat], e[this.currentCoordinate - 1])) return;
const n = /* @__PURE__ */ function(a = [[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]]) {
return { type: "Feature", geometry: { type: "Polygon", coordinates: a }, properties: {} };
}([[...e.slice(0, -1), [t.lng, t.lat], e[0]]]);
if (!this.updatePolygonGeometry(n.geometry.coordinates[0], M.Commit)) return;
this.currentCoordinate++, this.closingPoints.ids.length && this.closingPoints.update(n.geometry.coordinates[0]);
}
}
}
onClick(t) {
this.currentCoordinate > 0 && !this.mouseMove && this.onMouseMove(t), this.mouseMove = !1, t.button !== "right" ? t.button !== "left" || this.onLeftClick(t) : this.onRightClick(t);
}
onKeyUp(t) {
t.key === this.keyEvents.cancel ? this.cleanUp() : t.key === this.keyEvents.finish && this.close();
}
onKeyDown() {
}
onDragStart(t, e) {
if (!this.editable) return;
let i;
if (this.state === "started") {
const o = this.lineSnapping.getSnappable(t, (n) => this.polygonFilter(n));
o.coordinate && (this.editedSnapType = "line", this.editedFeatureCoordinateIndex = o.featureCoordinateIndex, this.editedFeatureId = o.featureId, i = o.coordinate);
const r = this.coordinateSnapping.getSnappable(t, (n) => this.polygonFilter(n));
r.coordinate && (this.editedSnapType = "coordinate", this.editedFeatureCoordinateIndex = r.featureCoordinateIndex, this.editedFeatureId = r.featureId, i = r.coordinate);
}
if (this.editedFeatureId && i) {
if (!this.editedPointId) {
const [o] = this.store.create([{ geometry: { type: "Point", coordinates: i }, properties: { mode: this.mode, [U]: !0 } }]);
this.editedPointId = o;
}
this.setCursor(this.cursors.dragStart), e(!1);
}
}
onDrag(t, e) {
if (this.editedFeatureId === void 0 || this.editedFeatureCoordinateIndex === void 0) return;
const i = this.store.getGeometryCopy(this.editedFeatureId), o = i.coordinates[0];
this.editedSnapType === "coordinate" || this.editedSnapType === "line" && this.editedInsertIndex !== void 0 ? this.editedFeatureCoordinateIndex === 0 || this.editedFeatureCoordinateIndex === i.coordinates[0].length - 1 ? (o[0] = [t.lng, t.lat], o[o.length - 1] = [t.lng, t.lat]) : o[this.editedFeatureCoordinateIndex] = [t.lng, t.lat] : this.editedSnapType === "line" && this.editedInsertIndex === void 0 && (this.editedInsertIndex = this.editedFeatureCoordinateIndex + 1, i.coordinates[0].splice(this.editedInsertIndex, 0, [t.lng, t.lat]), this.editedFeatureCoordinateIndex++);
const r = { type: "Polygon", coordinates: i.coordinates };
this.validate && !this.validate({ type: "Feature", geometry: r, properties: this.store.getPropertiesCopy(this.editedFeatureId) }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Provisional }).valid || (this.snapping && this.snappedPointId && (this.store.delete([this.snappedPointId]), this.snappedPointId = void 0), this.store.updateGeometry([{ id: this.editedFeatureId, geometry: r }]), this.showCoordinatePoints && this.coordinatePoints.createOrUpdate(this.editedFeatureId), this.editedPointId && this.store.updateGeometry([{ id: this.editedPointId, geometry: { type: "Point", coordinates: [t.lng, t.lat] } }]), this.store.updateProperty([{ id: this.editedFeatureId, property: U, value: !0 }]), e(!0));
}
onDragEnd(t, e) {
this.editedFeatureId !== void 0 && (this.setCursor(this.cursors.dragEnd), this.editedPointId && (this.store.delete([this.editedPointId]), this.editedPointId = void 0), this.store.updateProperty([{ id: this.editedFeatureId, property: U, value: !1 }]), this.onFinish(this.editedFeatureId, { mode: this.mode, action: "edit" }), this.editedFeatureId = void 0, this.editedFeatureCoordinateIndex = void 0, this.editedInsertIndex = void 0, this.editedSnapType = void 0, e(!0));
}
cleanUp() {
const t = this.currentId, e = this.snappedPointId, i = this.editedPointId;
this.currentId = void 0, this.snappedPointId = void 0, this.editedPointId = void 0, this.editedFeatureId = void 0, this.editedFeatureCoordinateIndex = void 0, this.editedInsertIndex = void 0, this.editedSnapType = void 0, this.currentCoordinate = 0, this.state === "drawing" && this.setStarted();
try {
t && this.coordinatePoints.deletePointsByFeatureIds([t]), t !== void 0 && this.store.delete([t]), i !== void 0 && this.store.delete([i]), e !== void 0 && this.store.delete([e]), this.closingPoints.ids.length && this.closingPoints.delete();
} catch {
}
}
styleFeature(t) {
const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
if (t.properties.mode === this.mode) {
if (t.geometry.type === "Polygon") return e.polygonFillColor = this.getHexColorStylingValue(this.styles.fillColor, e.polygonFillColor, t), e.polygonOutlineColor = this.getHexColorStylingValue(this.styles.outlineColor, e.polygonOutlineColor, t), e.polygonOutlineWidth = this.getNumericStylingValue(this.styles.outlineWidth, e.polygonOutlineWidth, t), e.polygonFillOpacity = this.getNumericStylingValue(this.styles.fillOpacity, e.polygonFillOpacity, t), e.zIndex = 10, e;
if (t.geometry.type === "Point") {
const i = t.properties[U], o = t.properties[Lt], r = i ? "editedPoint" : t.properties[st] ? "closingPoint" : t.properties[_t] ? "snappingPoint" : o ? "coordinatePoint" : void 0;
if (!r) return e;
const n = { editedPoint: { width: this.styles.editedPointOutlineWidth, color: this.styles.editedPointColor, outlineColor: this.styles.editedPointOutlineColor, outlineWidth: this.styles.editedPointOutlineWidth }, closingPoint: { width: this.styles.closingPointWidth, color: this.styles.closingPointColor, outlineColor: this.styles.closingPointOutlineColor, outlineWidth: this.styles.closingPointOutlineWidth }, snappingPoint: { width: this.styles.snappingPointWidth, color: this.styles.snappingPointColor, outlineColor: this.styles.snappingPointOutlineColor, outlineWidth: this.styles.snappingPointOutlineWidth }, coordinatePoint: { width: this.styles.coordinatePointWidth, color: this.styles.coordinatePointColor, outlineColor: this.styles.coordinatePointOutlineColor, outlineWidth: this.styles.coordinatePointOutlineWidth } };
return e.pointWidth = this.getNumericStylingValue(n[r].width, e.pointWidth, t), e.pointColor = this.getHexColorStylingValue(n[r].color, e.pointColor, t), e.pointOutlineColor = this.getHexColorStylingValue(n[r].outlineColor, e.pointOutlineColor, t), e.pointOutlineWidth = this.getNumericStylingValue(n[r].outlineWidth, 2, t), e.zIndex = i ? 35 : o ? 25 : 30, e;
}
}
return e;
}
afterFeatureAdded(t) {
this.showCoordinatePoints && this.coordinatePoints.createOrUpdate(t.id);
}
validateFeature(t) {
return this.validateModeFeature(t, (e) => It(e, this.coordinatePrecision));
}
}
const mi = { cancel: "Escape", finish: "Enter" }, vi = { start: "crosshair" };
class Oe extends N {
constructor(t) {
super(t, !0), this.mode = "rectangle", this.center = void 0, this.clickCount = 0, this.currentRectangleId = void 0, this.keyEvents = mi, this.cursors = vi, this.updateOptions(t);
}
updateOptions(t) {
super.updateOptions(t), t != null && t.cursors && (this.cursors = I({}, this.cursors, t.cursors)), (t == null ? void 0 : t.keyEvents) === null ? this.keyEvents = { cancel: null, finish: null } : t != null && t.keyEvents && (this.keyEvents = I({}, this.keyEvents, t.keyEvents));
}
updateRectangle(t, e) {
if (this.clickCount === 1 && this.center && this.currentRectangleId) {
const i = this.store.getGeometryCopy(this.currentRectangleId).coordinates[0][0], o = { type: "Polygon", coordinates: [[i, [t.lng, i[1]], [t.lng, t.lat], [i[0], t.lat], i]] };
if (this.validate && !this.validate({ id: this.currentRectangleId, geometry: o }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: e }).valid) return;
this.store.updateGeometry([{ id: this.currentRectangleId, geometry: o }]);
}
}
close() {
const t = this.currentRectangleId;
if (t) {
const e = dt(this.store.getGeometryCopy(t));
e && this.store.updateGeometry([{ id: t, geometry: e }]);
}
this.center = void 0, this.currentRectangleId = void 0, this.clickCount = 0, this.state === "drawing" && this.setStarted(), t !== void 0 && this.onFinish(t, { mode: this.mode, action: "draw" });
}
start() {
this.setStarted(), this.setCursor(this.cursors.start);
}
stop() {
this.cleanUp(), this.setStopped(), this.setCursor("unset");
}
onClick(t) {
if (this.clickCount === 0) {
this.center = [t.lng, t.lat];
const [e] = this.store.create([{ geometry: { type: "Polygon", coordinates: [[[t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat]]] }, properties: { mode: this.mode } }]);
this.currentRectangleId = e, this.clickCount++, this.setDrawing();
} else this.updateRectangle(t, M.Finish), this.close();
}
onMouseMove(t) {
this.updateRectangle(t, M.Provisional);
}
onKeyDown() {
}
onKeyUp(t) {
t.key === this.keyEvents.cancel ? this.cleanUp() : t.key === this.keyEvents.finish && this.close();
}
onDragStart() {
}
onDrag() {
}
onDragEnd() {
}
cleanUp() {
const t = this.currentRectangleId;
this.center = void 0, this.currentRectangleId = void 0, this.clickCount = 0, this.state === "drawing" && this.setStarted(), t !== void 0 && this.store.delete([t]);
}
styleFeature(t) {
const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
return t.type === "Feature" && t.geometry.type === "Polygon" && t.properties.mode === this.mode && (e.polygonFillColor = this.getHexColorStylingValue(this.styles.fillColor, e.polygonFillColor, t), e.polygonOutlineColor = this.getHexColorStylingValue(this.styles.outlineColor, e.polygonOutlineColor, t), e.polygonOutlineWidth = this.getNumericStylingValue(this.styles.outlineWidth, e.polygonOutlineWidth, t), e.polygonFillOpacity = this.getNumericStylingValue(this.styles.fillOpacity, e.polygonFillOpacity, t), e.zIndex = 10), e;
}
validateFeature(t) {
return this.validateModeFeature(t, (e) => lt(e, this.coordinatePrecision));
}
}
class et extends N {
constructor(t) {
if (!t.modeName) throw new Error("Mode name is required for TerraDrawRenderMode");
super(t, !0), this.type = $.Render, this.mode = "render", this.updateOptions(t);
}
updateOptions(t) {
super.updateOptions(t), t != null && t.modeName && (this.mode = t.modeName);
}
registerBehaviors(t) {
this.mode = t.mode;
}
start() {
this.setStarted();
}
stop() {
this.setStopped();
}
onKeyUp() {
}
onKeyDown() {
}
onClick() {
}
onDragStart() {
}
onDrag() {
}
onDragEnd() {
}
onMouseMove() {
}
cleanUp() {
}
styleFeature(t) {
return { pointColor: this.getHexColorStylingValue(this.styles.pointColor, "#3f97e0", t), pointWidth: this.getNumericStylingValue(this.styles.pointWidth, 6, t), pointOutlineColor: this.getHexColorStylingValue(this.styles.pointOutlineColor, "#ffffff", t), pointOutlineWidth: this.getNumericStylingValue(this.styles.pointOutlineWidth, 0, t), polygonFillColor: this.getHexColorStylingValue(this.styles.polygonFillColor, "#3f97e0", t), polygonFillOpacity: this.getNumericStylingValue(this.styles.polygonFillOpacity, 0.3, t), polygonOutlineColor: this.getHexColorStylingValue(this.styles.polygonOutlineColor, "#3f97e0", t), polygonOutlineWidth: this.getNumericStylingValue(this.styles.polygonOutlineWidth, 4, t), lineStringWidth: this.getNumericStylingValue(this.styles.lineStringWidth, 4, t), lineStringColor: this.getHexColorStylingValue(this.styles.lineStringColor, "#3f97e0", t), zIndex: this.getNumericStylingValue(this.styles.zIndex, 0, t) };
}
validateFeature(t) {
const e = super.validateFeature(t);
if (e.valid) {
const i = t, o = Me(i, this.coordinatePrecision).valid || It(i, this.coordinatePrecision).valid || xe(i, this.coordinatePrecision).valid;
return o ? { valid: !0 } : { valid: o, reason: "Feature is not a valid Point, Polygon or LineString feature" };
}
return e;
}
}
function vt(s, t) {
const e = s, i = t, o = O(e[1]), r = O(i[1]);
let n = O(i[0] - e[0]);
n > Math.PI && (n -= 2 * Math.PI), n < -Math.PI && (n += 2 * Math.PI);
const a = Math.log(Math.tan(r / 2 + Math.PI / 4) / Math.tan(o / 2 + Math.PI / 4)), l = (R(Math.atan2(n, a)) + 360) % 360;
return l > 180 ? -(360 - l) : l;
}
function jt(s, t, e) {
let i = t;
t < 0 && (i = -Math.abs(i));
const o = i / me, r = s[0] * Math.PI / 180, n = O(s[1]), a = O(e), l = o * Math.cos(a);
let d = n + l;
Math.abs(d) > Math.PI / 2 && (d = d > 0 ? Math.PI - d : -Math.PI - d);
const h = Math.log(Math.tan(d / 2 + Math.PI / 4) / Math.tan(n / 2 + Math.PI / 4)), c = Math.abs(h) > 1e-11 ? l / h : Math.cos(n), u = [(180 * (r + o * Math.sin(a) / c) / Math.PI + 540) % 360 - 180, 180 * d / Math.PI];
return u[0] += u[0] - s[0] > 180 ? -360 : s[0] - u[0] > 180 ? 360 : 0, u;
}
function De(s, t, e, i, o) {
const r = i(s[0], s[1]), n = i(t[0], t[1]), { lng: a, lat: l } = o((r.x + n.x) / 2, (r.y + n.y) / 2);
return [F(a, e), F(l, e)];
}
function Ci(s, t, e) {
const i = jt(s, 1e3 * T(s, t) / 2, vt(s, t));
return [F(i[0], e), F(i[1], e)];
}
function te({ featureCoords: s, precision: t, unproject: e, project: i, projection: o }) {
const r = [];
for (let n = 0; n < s.length - 1; n++) {
let a;
if (o === "web-mercator") a = De(s[n], s[n + 1], t, i, e);
else {
if (o !== "globe") throw new Error("Invalid projection");
a = Ci(s[n], s[n + 1], t);
}
r.push(a);
}
return r;
}
class Pi extends k {
constructor(t, e, i) {
super(t), this.config = void 0, this.selectionPointBehavior = void 0, this.coordinatePointBehavior = void 0, this._midPoints = [], this.config = t, this.selectionPointBehavior = e, this.coordinatePointBehavior = i;
}
get ids() {
return this._midPoints.concat();
}
set ids(t) {
}
insert(t, e, i) {
const o = this.store.getGeometryCopy(e), { midPointFeatureId: r, midPointSegment: n } = this.store.getPropertiesCopy(e), a = this.store.getGeometryCopy(r), l = a.type === "Polygon" ? a.coordinates[0] : a.coordinates;
l.splice(n + 1, 0, o.coordinates), a.coordinates = a.type === "Polygon" ? [l] : l, this.store.updateGeometry([{ id: r, geometry: a }]), this.store.getPropertiesCopy(t)[kt] && this.coordinatePointBehavior.createOrUpdate(t), this.store.delete([...this._midPoints, ...this.selectionPointBehavior.ids]), this.create(l, r, i), this.selectionPointBehavior.create(l, a.type, r);
}
create(t, e, i) {
if (!this.store.has(e)) throw new Error("Store does not have feature with this id");
this._midPoints = this.store.create(function(o, r, n, a, l, d) {
return te({ featureCoords: o, precision: n, project: a, unproject: l, projection: d }).map((h, c) => ({ geometry: { type: "Point", coordinates: h }, properties: r(c) }));
}(t, (o) => ({ mode: this.mode, [V.MID_POINT]: !0, midPointSegment: o, midPointFeatureId: e }), i, this.config.project, this.config.unproject, this.projection));
}
delete() {
this._midPoints.length && (this.store.delete(this._midPoints), this._midPoints = []);
}
getUpdated(t) {
if (this._midPoints.length !== 0) return te({ featureCoords: t, precision: this.coordinatePrecision, project: this.config.project, unproject: this.config.unproject, projection: this.config.projection }).map((e, i) => ({ id: this._midPoints[i], geometry: { type: "Point", coordinates: e } }));
}
}
class Si extends k {
constructor(t) {
super(t), this._selectionPoints = [];
}
get ids() {
return this._selectionPoints.concat();
}
set ids(t) {
}
create(t, e, i) {
this._selectionPoints = this.store.create(function(o, r, n) {
const a = [], l = r === "Polygon" ? o.length - 1 : o.length;
for (let d = 0; d < l; d++) a.push({ geometry: { type: "Point", coordinates: o[d] }, properties: n(d) });
return a;
}(t, e, (o) => ({ mode: this.mode, selectionPoint: !0, selectionPointFeatureId: i, index: o })));
}
delete() {
this.ids.length && (this.store.delete(this.ids), this._selectionPoints = []);
}
getUpdated(t) {
if (this._selectionPoints.length !== 0) return this._selectionPoints.map((e, i) => ({ id: e, geometry: { type: "Point", coordinates: t[i] } }));
}
getOneUpdated(t, e) {
if (this._selectionPoints[t] !== void 0) return { id: this._selectionPoints[t], geometry: { type: "Point", coordinates: e } };
}
}
function _e(s, t) {
let e = !1;
for (let n = 0, a = t.length; n < a; n++) {
const l = t[n];
for (let d = 0, h = l.length, c = h - 1; d < h; c = d++) (o = l[d])[1] > (i = s)[1] != (r = l[c])[1] > i[1] && i[0] < (r[0] - o[0]) * (i[1] - o[1]) / (r[1] - o[1]) + o[0] && (e = !e);
}
var i, o, r;
return e;
}
const Le = (s, t, e) => {
const i = (r) => r * r, o = (r, n) => i(r.x - n.x) + i(r.y - n.y);
return Math.sqrt(((r, n, a) => {
const l = o(n, a);
if (l === 0) return o(r, n);
let d = ((r.x - n.x) * (a.x - n.x) + (r.y - n.y) * (a.y - n.y)) / l;
return d = Math.max(0, Math.min(1, d)), o(r, { x: n.x + d * (a.x - n.x), y: n.y + d * (a.y - n.y) });
})(s, t, e));
};
class xi extends k {
constructor(t, e, i) {
super(t), this.config = void 0, this.createClickBoundingBox = void 0, this.pixelDistance = void 0, this.config = t, this.createClickBoundingBox = e, this.pixelDistance = i;
}
find(t, e) {
let i, o, r, n, a = 1 / 0, l = 1 / 0, d = 1 / 0;
const h = this.createClickBoundingBox.create(t), c = this.store.search(h);
for (let u = 0; u < c.length; u++) {
const p = c[u], g = p.geometry;
if (g.type === "Point") {
if (p.properties.selectionPoint || p.properties.coordinatePoint || !e && p.properties[V.MID_POINT]) continue;
const y = this.pixelDistance.measure(t, g.coordinates);
p.properties[V.MID_POINT] && y < this.pointerDistance && y < d ? (d = y, r = p) : !p.properties[V.MID_POINT] && y < this.pointerDistance && y < a && (a = y, i = p);
} else if (g.type === "LineString") {
if (i) continue;
for (let y = 0; y < g.coordinates.length - 1; y++) {
const m = g.coordinates[y], v = g.coordinates[y + 1], f = Le({ x: t.containerX, y: t.containerY }, this.project(m[0], m[1]), this.project(v[0], v[1]));
f < this.pointerDistance && f < l && (l = f, o = p);
}
} else if (g.type === "Polygon") {
if (i || o) continue;
_e([t.lng, t.lat], g.coordinates) && (n = p);
}
}
return { clickedFeature: i || o || n, clickedMidPoint: r };
}
}
class Ii extends k {
constructor(t, e, i, o, r) {
super(t), this.config = void 0, this.featuresAtCursorEvent = void 0, this.selectionPoints = void 0, this.midPoints = void 0, this.coordinatePoints = void 0, this.draggedFeatureId = null, this.dragPosition = void 0, this.config = t, this.featuresAtCursorEvent = e, this.selectionPoints = i, this.midPoints = o, this.coordinatePoints = r;
}
startDragging(t, e) {
this.draggedFeatureId = e, this.dragPosition = [t.lng, t.lat];
}
stopDragging() {
this.draggedFeatureId = null, this.dragPosition = void 0;
}
isDragging() {
return this.draggedFeatureId !== null;
}
canDrag(t, e) {
const { clickedFeature: i } = this.featuresAtCursorEvent.find(t, !0);
return !(!i || i.id !== e);
}
drag(t, e) {
if (!this.draggedFeatureId) return;
const i = this.store.getGeometryCopy(this.draggedFeatureId), o = [t.lng, t.lat];
if (i.type === "Polygon" || i.type === "LineString") {
let r, n;
if (i.type === "Polygon" ? (r = i.coordinates[0], n = r.length - 1) : (r = i.coordinates, n = r.length), !this.dragPosition) return !1;
for (let h = 0; h < n; h++) {
const c = r[h];
let u, p;
if (this.config.projection === "web-mercator") {
const g = x(this.dragPosition[0], this.dragPosition[1]), y = x(o[0], o[1]), m = x(c[0], c[1]), v = { x: g.x - y.x, y: g.y - y.y }, f = m.x - v.x, C = m.y - v.y, { lng: P, lat: S } = W(f, C);
u = P, p = S;
} else {
const g = [this.dragPosition[0] - o[0], this.dragPosition[1] - o[1]];
u = c[0] - g[0], p = c[1] - g[1];
}
if (u = F(u, this.config.coordinatePrecision), p = F(p, this.config.coordinatePrecision), u > 180 || u < -180 || p > 90 || p < -90) return !1;
r[h] = [u, p];
}
i.type === "Polygon" && (r[r.length - 1] = [r[0][0], r[0][1]]);
const a = this.selectionPoints.getUpdated(r) || [], l = this.midPoints.getUpdated(r) || [], d = this.coordinatePoints.getUpdated(this.draggedFeatureId, r) || [];
if (e && !e({ type: "Feature", id: this.draggedFeatureId, geometry: i, properties: {} }, { project: this.config.project, unproject: this.config.unproject, coordinatePrecision: this.config.coordinatePrecision, updateType: M.Provisional }).valid) return !1;
this.store.updateGeometry([{ id: this.draggedFeatureId, geometry: i }, ...a, ...l, ...d]), this.dragPosition = [t.lng, t.lat];
} else i.type === "Point" && (this.store.updateGeometry([{ id: this.draggedFeatureId, geometry: { type: "Point", coordinates: o } }]), this.dragPosition = [t.lng, t.lat]);
}
}
class bi extends k {
constructor(t, e, i, o, r, n) {
super(t), this.config = void 0, this.pixelDistance = void 0, this.selectionPoints = void 0, this.midPoints = void 0, this.coordinatePoints = void 0, this.coordinateSnapping = void 0, this.draggedCoordinate = { id: null, index: -1 }, this.config = t, this.pixelDistance = e, this.selectionPoints = i, this.midPoints = o, this.coordinatePoints = r, this.coordinateSnapping = n;
}
getClosestCoordinate(t, e) {
const i = { dist: 1 / 0, index: -1, isFirstOrLastPolygonCoord: !1 };
let o;
if (e.type === "LineString") o = e.coordinates;
else {
if (e.type !== "Polygon") return i;
o = e.coordinates[0];
}
for (let r = 0; r < o.length; r++) {
const n = this.pixelDistance.measure(t, o[r]);
if (n < this.pointerDistance && n < i.dist) {
const a = e.type === "Polygon" && (r === o.length - 1 || r === 0);
i.dist = n, i.index = a ? 0 : r, i.isFirstOrLastPolygonCoord = a;
}
}
return i;
}
getDraggableIndex(t, e) {
const i = this.store.getGeometryCopy(e), o = this.getClosestCoordinate(t, i);
return o.index === -1 ? -1 : o.index;
}
drag(t, e, i, o) {
if (this.draggedCoordinate.id === null) return !1;
const r = this.draggedCoordinate.index, n = this.store.getGeometryCopy(this.draggedCoordinate.id), a = this.store.getPropertiesCopy(this.draggedCoordinate.id), l = n.type === "LineString" ? n.coordinates : n.coordinates[0], d = n.type === "Polygon" && (r === l.length - 1 || r === 0);
let h = [t.lng, t.lat];
if (o) {
let y;
y = this.coordinateSnapping.getSnappable(t, (m) => !!(m.properties && m.properties.mode === a.mode && m.id !== this.draggedCoordinate.id)).coordinate, y && (h = y);
}
if (t.lng > 180 || t.lng < -180 || t.lat > 90 || t.lat < -90) return !1;
if (d) {
const y = l.length - 1;
l[0] = h, l[y] = h;
} else l[r] = h;
const c = this.selectionPoints.getOneUpdated(r, h), u = c ? [c] : [], p = this.midPoints.getUpdated(l) || [], g = this.coordinatePoints.getUpdated(this.draggedCoordinate.id, l) || [];
return !(n.type !== "Point" && !e && Bt({ geometry: n }) || i && !i({ type: "Feature", id: this.draggedCoordinate.id, geometry: n, properties: {} }, { project: this.config.project, unproject: this.config.unproject, coordinatePrecision: this.config.coordinatePrecision, updateType: M.Provisional }).valid || (this.store.updateGeometry([{ id: this.draggedCoordinate.id, geometry: n }, ...u, ...p, ...g]), 0));
}
isDragging() {
return this.draggedCoordinate.id !== null;
}
startDragging(t, e) {
this.draggedCoordinate = { id: t, index: e };
}
stopDragging() {
this.draggedCoordinate = { id: null, index: -1 };
}
}
function Ct(s) {
let t = 0, e = 0, i = 0;
return (s.geometry.type === "Polygon" ? s.geometry.coordinates[0].slice(0, -1) : s.geometry.coordinates).forEach((o) => {
t += o[0], e += o[1], i++;
}, !0), [t / i, e / i];
}
function ke(s, t) {
s[0] += s[0] - t[0] > 180 ? -360 : t[0] - s[0] > 180 ? 360 : 0;
const e = me, i = t[1] * Math.PI / 180, o = s[1] * Math.PI / 180, r = o - i;
let n = Math.abs(s[0] - t[0]) * Math.PI / 180;
n > Math.PI && (n -= 2 * Math.PI);
const a = Math.log(Math.tan(o / 2 + Math.PI / 4) / Math.tan(i / 2 + Math.PI / 4)), l = Math.abs(a) > 1e-11 ? r / a : Math.cos(i);
return Math.sqrt(r * r + l * l * n * n) * e;
}
function Pt(s) {
const t = (s.geometry.type === "Polygon" ? s.geometry.coordinates[0] : s.geometry.coordinates).map((e) => {
const { x: i, y: o } = x(e[0], e[1]);
return [i, o];
});
return s.geometry.type === "Polygon" ? function(e) {
let i = 0, o = 0, r = 0;
const n = e.length;
for (let a = 0; a < n - 1; a++) {
const [l, d] = e[a], [h, c] = e[a + 1], u = l * c - h * d;
i += u, o += (l + h) * u, r += (d + c) * u;
}
return i /= 2, o /= 6 * i, r /= 6 * i, { x: o, y: r };
}(t) : function(e) {
const i = e.length;
let o = 0, r = 0;
for (let n = 0; n < i; n++) {
const [a, l] = e[n];
o += a, r += l;
}
return { x: o / i, y: r / i };
}(t);
}
class Mi extends k {
constructor(t, e, i, o) {
super(t), this.config = void 0, this.selectionPoints = void 0, this.midPoints = void 0, this.coordinatePoints = void 0, this.lastBearing = void 0, this.config = t, this.selectionPoints = e, this.midPoints = i, this.coordinatePoints = o;
}
reset() {
this.lastBearing = void 0;
}
rotate(t, e, i) {
const o = this.store.getGeometryCopy(e);
if (o.type !== "Polygon" && o.type !== "LineString") return;
const r = [t.lng, t.lat];
let n;
const a = { type: "Feature", geometry: o, properties: {} };
if (this.config.projection === "web-mercator") {
if (n = A(Pt(a), x(t.lng, t.lat)), !this.lastBearing) return void (this.lastBearing = n);
((u, p) => {
if (p === 0 || p === 360 || p === -360) return u;
const g = 0.017453292519943295 * p, y = (u.geometry.type === "Polygon" ? u.geometry.coordinates[0] : u.geometry.coordinates).map(([f, C]) => x(f, C)), m = y.reduce((f, C) => ({ x: f.x + C.x, y: f.y + C.y }), { x: 0, y: 0 });
m.x /= y.length, m.y /= y.length;
const v = y.map((f) => ({ x: m.x + (f.x - m.x) * Math.cos(g) - (f.y - m.y) * Math.sin(g), y: m.y + (f.x - m.x) * Math.sin(g) + (f.y - m.y) * Math.cos(g) })).map(({ x: f, y: C }) => [W(f, C).lng, W(f, C).lat]);
u.geometry.type === "Polygon" ? u.geometry.coordinates[0] = v : u.geometry.coordinates = v;
})(a, -(this.lastBearing - n));
} else {
if (this.config.projection !== "globe") throw new Error("Unsupported projection");
if (n = vt(Ct({ geometry: o }), r), !this.lastBearing) return void (this.lastBearing = n + 180);
(function(u, p) {
if (p === 0 || p === 360 || p === -360) return u;
const g = Ct(u);
(u.geometry.type === "Polygon" ? u.geometry.coordinates[0] : u.geometry.coordinates).forEach((y) => {
const m = vt(g, y) + p, v = ke(g, y), f = jt(g, v, m);
y[0] = f[0], y[1] = f[1];
});
})(a, -(this.lastBearing - (n + 180)));
}
const l = o.type === "Polygon" ? o.coordinates[0] : o.coordinates;
l.forEach((u) => {
u[0] = F(u[0], this.coordinatePrecision), u[1] = F(u[1], this.coordinatePrecision);
});
const d = this.midPoints.getUpdated(l) || [], h = this.selectionPoints.getUpdated(l) || [], c = this.coordinatePoints.getUpdated(e, l) || [];
if (i && !i({ id: e, type: "Feature", geometry: o, properties: {} }, { project: this.config.project, unproject: this.config.unproject, coordinatePrecision: this.config.coordinatePrecision, updateType: M.Provisional })) return !1;
this.store.updateGeometry([{ id: e, geometry: o }, ...h, ...d, ...c]), this.projection === "web-mercator" ? this.lastBearing = n : this.projection === "globe" && (this.lastBearing = n + 180);
}
}
class wi extends k {
constructor(t, e, i, o) {
super(t), this.config = void 0, this.selectionPoints = void 0, this.midPoints = void 0, this.coordinatePoints = void 0, this.lastDistance = void 0, this.config = t, this.selectionPoints = e, this.midPoints = i, this.coordinatePoints = o;
}
reset() {
this.lastDistance = void 0;
}
scale(t, e, i) {
const o = this.store.getGeometryCopy(e);
if (o.type !== "Polygon" && o.type !== "LineString") return;
const r = [t.lng, t.lat], n = { type: "Feature", geometry: o, properties: {} };
let a;
const l = Pt(n);
if (this.config.projection === "web-mercator") {
const g = x(t.lng, t.lat);
a = E(l, g);
} else {
if (this.config.projection !== "globe") throw new Error("Invalid projection");
a = T(Ct({ geometry: o }), r);
}
if (!this.lastDistance) return void (this.lastDistance = a);
const d = 1 - (this.lastDistance - a) / a;
if (this.config.projection === "web-mercator") {
const { lng: g, lat: y } = W(l.x, l.y);
(function(m, v, f) {
if (v === 1) return m;
const C = (m.geometry.type === "Polygon" ? m.geometry.coordinates[0] : m.geometry.coordinates).map(([b, w]) => x(b, w)), P = x(f[0], f[1]), S = C.map((b) => ({ x: P.x + (b.x - P.x) * v, y: P.y + (b.y - P.y) * v })).map(({ x: b, y: w }) => [W(b, w).lng, W(b, w).lat]);
m.geometry.type === "Polygon" ? m.geometry.coordinates[0] = S : m.geometry.coordinates = S;
})(n, d, [g, y]);
} else this.config.projection === "globe" && function(g, y, m, v = "xy") {
y === 1 || (g.geometry.type === "Polygon" ? g.geometry.coordinates[0] : g.geometry.coordinates).forEach((f) => {
const C = ke(m, f), P = vt(m, f), S = jt(m, C * y, P);
v !== "x" && v !== "xy" || (f[0] = S[0]), v !== "y" && v !== "xy" || (f[1] = S[1]);
});
}(n, d, Ct(n));
const h = o.type === "Polygon" ? o.coordinates[0] : o.coordinates;
h.forEach((g) => {
g[0] = F(g[0], this.coordinatePrecision), g[1] = F(g[1], this.coordinatePrecision);
});
const c = this.midPoints.getUpdated(h) || [], u = this.selectionPoints.getUpdated(h) || [], p = this.coordinatePoints.getUpdated(e, h) || [];
if (i && !i({ id: e, type: "Feature", geometry: o, properties: {} }, { project: this.config.project, unproject: this.config.unproject, coordinatePrecision: this.config.coordinatePrecision, updateType: M.Provisional })) return !1;
this.store.updateGeometry([{ id: e, geometry: o }, ...u, ...c, ...p]), this.lastDistance = a;
}
}
class Fi extends k {
constructor(t, e, i, o, r) {
super(t), this.config = void 0, this.pixelDistance = void 0, this.selectionPoints = void 0, this.midPoints = void 0, this.coordinatePoints = void 0, this.minimumScale = 1e-4, this.draggedCoordinate = { id: null, index: -1 }, this.boundingBoxMaps = { opposite: { 0: 4, 1: 5, 2: 6, 3: 7, 4: 0, 5: 1, 6: 2, 7: 3 } }, this.config = t, this.pixelDistance = e, this.selectionPoints = i, this.midPoints = o, this.coordinatePoints = r;
}
getClosestCoordinate(t, e) {
const i = { dist: 1 / 0, index: -1, isFirstOrLastPolygonCoord: !1 };
let o;
if (e.type === "LineString") o = e.coordinates;
else {
if (e.type !== "Polygon") return i;
o = e.coordinates[0];
}
for (let r = 0; r < o.length; r++) {
const n = this.pixelDistance.measure(t, o[r]);
if (n < this.pointerDistance && n < i.dist) {
const a = e.type === "Polygon" && (r === o.length - 1 || r === 0);
i.dist = n, i.index = a ? 0 : r, i.isFirstOrLastPolygonCoord = a;
}
}
return i;
}
isValidDragWebMercator(t, e, i) {
switch (t) {
case 0:
if (e <= 0 || i >= 0) return !1;
break;
case 1:
if (i >= 0) return !1;
break;
case 2:
if (e >= 0 || i >= 0) return !1;
break;
case 3:
if (e >= 0) return !1;
break;
case 4:
if (e >= 0 || i <= 0) return !1;
break;
case 5:
if (i <= 0) return !1;
break;
case 6:
if (e <= 0 || i <= 0) return !1;
break;
case 7:
if (e <= 0) return !1;
}
return !0;
}
getSelectedFeatureDataWebMercator() {
if (!this.draggedCoordinate.id || this.draggedCoordinate.index === -1) return null;
const t = this.getFeature(this.draggedCoordinate.id);
if (!t) return null;
const e = this.getNormalisedCoordinates(t.geometry);
return { boundingBox: this.getBBoxWebMercator(e), feature: t, updatedCoords: e, selectedCoordinate: e[this.draggedCoordinate.index] };
}
centerWebMercatorDrag(t) {
const e = this.getSelectedFeatureDataWebMercator();
if (!e) return null;
const { feature: i, boundingBox: o, updatedCoords: r, selectedCoordinate: n } = e, a = Pt(i);
if (!a) return null;
const l = x(n[0], n[1]), { closestBBoxIndex: d } = this.getIndexesWebMercator(o, l), h = x(t.lng, t.lat);
return this.scaleWebMercator({ closestBBoxIndex: d, updatedCoords: r, webMercatorCursor: h, webMercatorSelected: l, webMercatorOrigin: a }), r;
}
centerFixedWebMercatorDrag(t) {
const e = this.getSelectedFeatureDataWebMercator();
if (!e) return null;
const { feature: i, boundingBox: o, updatedCoords: r, selectedCoordinate: n } = e, a = Pt(i);
if (!a) return null;
const l = x(n[0], n[1]), { closestBBoxIndex: d } = this.getIndexesWebMercator(o, l), h = x(t.lng, t.lat);
return this.scaleFixedWebMercator({ closestBBoxIndex: d, updatedCoords: r, webMercatorCursor: h, webMercatorSelected: l, webMercatorOrigin: a }), r;
}
scaleFixedWebMercator({ closestBBoxIndex: t, webMercatorOrigin: e, webMercatorSelected: i, webMercatorCursor: o, updatedCoords: r }) {
if (!this.isValidDragWebMercator(t, e.x - o.x, e.y - o.y)) return null;
let n = E(e, o) / E(e, i);
return n < 0 && (n = this.minimumScale), this.performWebMercatorScale(r, e.x, e.y, n, n), r;
}
oppositeFixedWebMercatorDrag(t) {
const e = this.getSelectedFeatureDataWebMercator();
if (!e) return null;
const { boundingBox: i, updatedCoords: o, selectedCoordinate: r } = e, n = x(r[0], r[1]), { oppositeBboxIndex: a, closestBBoxIndex: l } = this.getIndexesWebMercator(i, n), d = { x: i[a][0], y: i[a][1] }, h = x(t.lng, t.lat);
return this.scaleFixedWebMercator({ closestBBoxIndex: l, updatedCoords: o, webMercatorCursor: h, webMercatorSelected: n, webMercatorOrigin: d }), o;
}
oppositeWebMercatorDrag(t) {
const e = this.getSelectedFeatureDataWebMercator();
if (!e) return null;
const { boundingBox: i, updatedCoords: o, selectedCoordinate: r } = e, n = x(r[0], r[1]), { oppositeBboxIndex: a, closestBBoxIndex: l } = this.getIndexesWebMercator(i, n), d = { x: i[a][0], y: i[a][1] }, h = x(t.lng, t.lat);
return this.scaleWebMercator({ closestBBoxIndex: l, updatedCoords: o, webMercatorCursor: h, webMercatorSelected: n, webMercatorOrigin: d }), o;
}
scaleWebMercator({ closestBBoxIndex: t, webMercatorOrigin: e, webMercatorSelected: i, webMercatorCursor: o, updatedCoords: r }) {
const n = e.x - o.x, a = e.y - o.y;
if (!this.isValidDragWebMercator(t, n, a)) return null;
let l = 1;
n !== 0 && t !== 1 && t !== 5 && (l = 1 - (e.x - i.x - n) / n);
let d = 1;
return a !== 0 && t !== 3 && t !== 7 && (d = 1 - (e.y - i.y - a) / a), this.validateScale(l, d) ? (l < 0 && (l = this.minimumScale), d < 0 && (d = this.minimumScale), this.performWebMercatorScale(r, e.x, e.y, l, d), r) : null;
}
getFeature(t) {
if (this.draggedCoordinate.id === null) return null;
const e = this.store.getGeometryCopy(t);
return e.type !== "Polygon" && e.type !== "LineString" ? null : { id: t, type: "Feature", geometry: e, properties: {} };
}
getNormalisedCoordinates(t) {
return t.type === "Polygon" ? t.coordinates[0] : t.coordinates;
}
validateScale(t, e) {
const i = !isNaN(t) && e < Number.MAX_SAFE_INTEGER, o = !isNaN(e) && e < Number.MAX_SAFE_INTEGER;
return i && o;
}
performWebMercatorScale(t, e, i, o, r) {
t.forEach((n) => {
const { x: a, y: l } = x(n[0], n[1]), d = e + (a - e) * o, h = i + (l - i) * r, { lng: c, lat: u } = W(d, h);
n[0] = c, n[1] = u;
});
}
getBBoxWebMercator(t) {
const e = [1 / 0, 1 / 0, -1 / 0, -1 / 0];
(t = t.map((a) => {
const { x: l, y: d } = x(a[0], a[1]);
return [l, d];
})).forEach(([a, l]) => {
a < e[0] && (e[0] = a), l < e[1] && (e[1] = l), a > e[2] && (e[2] = a), l > e[3] && (e[3] = l);
});
const [i, o, r, n] = e;
return [[i, n], [(i + r) / 2, n], [r, n], [r, n + (o - n) / 2], [r, o], [(i + r) / 2, o], [i, o], [i, n + (o - n) / 2]];
}
getIndexesWebMercator(t, e) {
let i, o = 1 / 0;
for (let r = 0; r < t.length; r++) {
const n = E({ x: e.x, y: e.y }, { x: t[r][0], y: t[r][1] });
n < o && (i = r, o = n);
}
if (i === void 0) throw new Error("No closest coordinate found");
return { oppositeBboxIndex: this.boundingBoxMaps.opposite[i], closestBBoxIndex: i };
}
isDragging() {
return this.draggedCoordinate.id !== null;
}
startDragging(t, e) {
this.draggedCoordinate = { id: t, index: e };
}
stopDragging() {
this.draggedCoordinate = { id: null, index: -1 };
}
getDraggableIndex(t, e) {
const i = this.store.getGeometryCopy(e), o = this.getClosestCoordinate(t, i);
return o.index === -1 ? -1 : o.index;
}
drag(t, e, i) {
if (!this.draggedCoordinate.id) return !1;
const o = this.getFeature(this.draggedCoordinate.id);
if (!o) return !1;
let r = null;
if (e === "center" ? r = this.centerWebMercatorDrag(t) : e === "opposite" ? r = this.oppositeWebMercatorDrag(t) : e === "center-fixed" ? r = this.centerFixedWebMercatorDrag(t) : e === "opposite-fixed" && (r = this.oppositeFixedWebMercatorDrag(t)), !r) return !1;
for (let h = 0; h < r.length; h++) {
const c = r[h];
if (c[0] = F(c[0], this.coordinatePrecision), c[1] = F(c[1], this.coordinatePrecision), !xt(c, this.coordinatePrecision)) return !1;
}
const n = this.midPoints.getUpdated(r) || [], a = this.selectionPoints.getUpdated(r) || [], l = this.coordinatePoints.getUpdated(o.id, r) || [], d = { type: o.geometry.type, coordinates: o.geometry.type === "Polygon" ? [r] : r };
return !(i && !i({ id: this.draggedCoordinate.id, type: "Feature", geometry: d, properties: {} }, { project: this.config.project, unproject: this.config.unproject, coordinatePrecision: this.config.coordinatePrecision, updateType: M.Provisional }).valid || (this.store.updateGeometry([{ id: this.draggedCoordinate.id, geometry: d }, ...a, ...n, ...l]), 0));
}
}
const Ei = { deselect: "Escape", delete: "Delete", rotate: ["Control", "r"], scale: ["Control", "s"] }, ee = { pointerOver: "move", dragStart: "move", dragEnd: "move", insertMidpoint: "crosshair" };
class Be extends $e {
constructor(t) {
super(t, !0), this.mode = "select", this.allowManualDeselection = !0, this.dragEventThrottle = 5, this.dragEventCount = 0, this.selected = [], this.flags = {}, this.keyEvents = Ei, this.cursors = ee, this.validations = {}, this.selectionPoints = void 0, this.midPoints = void 0, this.coordinateSnap = void 0, this.featuresAtMouseEvent = void 0, this.pixelDistance = void 0, this.clickBoundingBox = void 0, this.dragFeature = void 0, this.dragCoordinate = void 0, this.rotateFeature = void 0, this.scaleFeature = void 0, this.dragCoordinateResizeFeature = void 0, this.coordinatePoints = void 0, this.updateOptions(t);
}
updateOptions(t) {
if (super.updateOptions(t), this.cursors = t && t.cursors ? I({}, this.cursors, t.cursors) : ee, (t == null ? void 0 : t.keyEvents) === null ? this.keyEvents = { deselect: null, delete: null, rotate: null, scale: null } : t != null && t.keyEvents && (this.keyEvents = I({}, this.keyEvents, t.keyEvents)), (t == null ? void 0 : t.dragEventThrottle) !== void 0 && (this.dragEventThrottle = t.dragEventThrottle), (t == null ? void 0 : t.allowManualDeselection) !== void 0 && (this.allowManualDeselection = t.allowManualDeselection), t != null && t.flags) {
this.flags = I({}, this.flags, t.flags), this.validations = {};
for (const e in this.flags) {
const i = this.flags[e].feature;
i && i.validation && (this.validations[e] = i.validation);
}
}
}
createOrUpdateCoordinatePoint(t) {
const e = this.store.getPropertiesCopy(t);
e.coordinatePointIds && this.store.delete(e.coordinatePointIds);
const i = this.store.getGeometryCopy(t), o = this.store.create(i.coordinates[0].map((r) => ({ geometry: { type: "Point", coordinates: r }, properties: { mode: this.mode, [Lt]: !0 } })));
this.store.updateProperty([{ id: t, property: "coordinatePointIds", value: o }]);
}
selectFeature(t) {
this.select(t, !1);
}
setSelecting() {
if (this._state !== "started") throw new Error("Mode must be started to move to selecting state");
this._state = "selecting";
}
registerBehaviors(t) {
this.pixelDistance = new nt(t), this.clickBoundingBox = new rt(t), this.featuresAtMouseEvent = new xi(t, this.clickBoundingBox, this.pixelDistance), this.selectionPoints = new Si(t), this.coordinatePoints = new Fe(t), this.midPoints = new Pi(t, this.selectionPoints, this.coordinatePoints), this.coordinateSnap = new mt(t, this.pixelDistance, this.clickBoundingBox), this.rotateFeature = new Mi(t, this.selectionPoints, this.midPoints, this.coordinatePoints), this.scaleFeature = new wi(t, this.selectionPoints, this.midPoints, this.coordinatePoints), this.dragFeature = new Ii(t, this.featuresAtMouseEvent, this.selectionPoints, this.midPoints, this.coordinatePoints), this.dragCoordinate = new bi(t, this.pixelDistance, this.selectionPoints, this.midPoints, this.coordinatePoints, this.coordinateSnap), this.dragCoordinateResizeFeature = new Fi(t, this.pixelDistance, this.selectionPoints, this.midPoints, this.coordinatePoints);
}
deselectFeature() {
this.deselect();
}
deselect() {
const t = this.selected.filter((e) => this.store.has(e)).map((e) => ({ id: e, property: V.SELECTED, value: !1 }));
this.store.updateProperty(t), this.onDeselect(this.selected[0]), this.selected = [], this.selectionPoints.delete(), this.midPoints.delete();
}
deleteSelected() {
this.store.delete(this.selected), this.selected = [];
}
onRightClick(t) {
if (!this.selectionPoints.ids.length) return;
let e, i = 1 / 0;
if (this.selectionPoints.ids.forEach((u) => {
const p = this.store.getGeometryCopy(u), g = this.pixelDistance.measure(t, p.coordinates);
g < this.pointerDistance && g < i && (i = g, e = this.store.getPropertiesCopy(u));
}), !e) return;
const o = e.selectionPointFeatureId, r = e.index, n = this.store.getPropertiesCopy(o), a = this.flags[n.mode], l = this.validations[n.mode];
if (!(a && a.feature && a.feature.coordinates && a.feature.coordinates.deletable)) return;
const d = this.store.getGeometryCopy(o);
let h;
if (d.type === "Polygon") {
if (h = d.coordinates[0], h.length <= 4) return;
} else if (d.type === "LineString" && (h = d.coordinates, h.length <= 2)) return;
if (!h || (d.type !== "Polygon" || r !== 0 && r !== h.length - 1 ? h.splice(r, 1) : (h.shift(), h.pop(), h.push([h[0][0], h[0][1]])), l && !l({ id: o, type: "Feature", geometry: d, properties: n }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Commit }).valid)) return;
const c = [...this.midPoints.ids, ...this.selectionPoints.ids];
this.store.delete(c), this.store.updateGeometry([{ id: o, geometry: d }]), n.coordinatePointIds && this.coordinatePoints.createOrUpdate(o), this.selectionPoints.create(h, d.type, o), a && a.feature && a.feature.coordinates && a.feature.coordinates.midpoints && this.midPoints.create(h, o, this.coordinatePrecision);
}
select(t, e = !0) {
if (this.selected[0] === t) return;
const { mode: i } = this.store.getPropertiesCopy(t), o = this.flags[i];
if (!o || !o.feature) return;
const r = this.selected[0];
if (r) {
if (r === t) return;
this.deselect();
}
e && this.setCursor(this.cursors.pointerOver), this.selected = [t], this.store.updateProperty([{ id: t, property: "selected", value: !0 }]), this.onSelect(t);
const { type: n, coordinates: a } = this.store.getGeometryCopy(t);
if (n !== "LineString" && n !== "Polygon") return;
const l = n === "LineString" ? a : a[0];
l && o && o.feature.coordinates && (this.selectionPoints.create(l, n, t), o.feature.coordinates.midpoints && this.midPoints.create(l, t, this.coordinatePrecision));
}
onLeftClick(t) {
const { clickedFeature: e, clickedMidPoint: i } = this.featuresAtMouseEvent.find(t, this.selected.length > 0);
if (this.selected.length && i) this.midPoints.insert(this.selected[0], i.id, this.coordinatePrecision);
else if (e && e.id) this.select(e.id, !0);
else if (this.selected.length && this.allowManualDeselection) return void this.deselect();
}
start() {
this.setStarted(), this.setSelecting();
}
stop() {
this.cleanUp(), this.setStarted(), this.setStopped();
}
onClick(t) {
t.button !== "right" ? t.button === "left" && this.onLeftClick(t) : this.onRightClick(t);
}
canScale(t) {
return this.keyEvents.scale && this.keyEvents.scale.every((e) => t.heldKeys.includes(e));
}
canRotate(t) {
return this.keyEvents.rotate && this.keyEvents.rotate.every((e) => t.heldKeys.includes(e));
}
preventDefaultKeyEvent(t) {
const e = this.canRotate(t), i = this.canScale(t);
(e || i) && t.preventDefault();
}
onKeyDown(t) {
this.preventDefaultKeyEvent(t);
}
onKeyUp(t) {
if (this.preventDefaultKeyEvent(t), this.keyEvents.delete && t.key === this.keyEvents.delete) {
if (!this.selected.length) return;
this.onDeselect(this.selected[0]), this.deleteSelected(), this.selectionPoints.delete(), this.midPoints.delete();
} else this.keyEvents.deselect && t.key === this.keyEvents.deselect && this.cleanUp();
}
cleanUp() {
this.selected.length && this.deselect();
}
onDragStart(t, e) {
if (!this.selected.length) return;
const i = this.store.getPropertiesCopy(this.selected[0]), o = this.flags[i.mode];
if (!(o && o.feature && (o.feature.draggable || o.feature.coordinates && o.feature.coordinates.draggable || o.feature.coordinates && o.feature.coordinates.resizable || o.feature.coordinates && typeof o.feature.coordinates.midpoints == "object" && o.feature.coordinates.midpoints.draggable))) return;
this.dragEventCount = 0;
const r = this.selected[0], n = this.dragCoordinate.getDraggableIndex(t, r);
if (o && o.feature && o.feature.coordinates && (o.feature.coordinates.draggable || o.feature.coordinates.resizable) && n !== -1) return this.setCursor(this.cursors.dragStart), o.feature.coordinates.resizable ? this.dragCoordinateResizeFeature.startDragging(r, n) : this.dragCoordinate.startDragging(r, n), void e(!1);
if (o && o.feature && o.feature.coordinates && typeof o.feature.coordinates.midpoints == "object" && o.feature.coordinates.midpoints.draggable) {
const { clickedMidPoint: a } = this.featuresAtMouseEvent.find(t, this.selected.length > 0);
if (this.selected.length && a) {
this.midPoints.insert(r, a.id, this.coordinatePrecision);
const l = this.dragCoordinate.getDraggableIndex(t, r);
return this.dragCoordinate.startDragging(r, l), void e(!1);
}
}
return o && o.feature && o.feature.draggable && this.dragFeature.canDrag(t, r) ? (this.setCursor(this.cursors.dragStart), this.dragFeature.startDragging(t, r), void e(!1)) : void 0;
}
onDrag(t, e) {
const i = this.selected[0];
if (!i) return;
const o = this.store.getPropertiesCopy(i), r = this.flags[o.mode], n = (r && r.feature && r.feature.selfIntersectable) === !0;
if (this.dragEventCount++, this.dragEventCount % this.dragEventThrottle == 0) return;
const a = this.validations[o.mode];
if (r && r.feature && r.feature.rotateable && this.canRotate(t)) return e(!1), void this.rotateFeature.rotate(t, i, a);
if (r && r.feature && r.feature.scaleable && this.canScale(t)) return e(!1), void this.scaleFeature.scale(t, i, a);
if (this.dragCoordinateResizeFeature.isDragging() && r.feature && r.feature.coordinates && r.feature.coordinates.resizable) {
if (this.projection === "globe") throw new Error("Globe is currently unsupported projection for resizable");
return e(!1), void this.dragCoordinateResizeFeature.drag(t, r.feature.coordinates.resizable, a);
}
if (this.dragCoordinate.isDragging()) {
var l;
const d = !!(!((l = r.feature) == null || (l = l.coordinates) == null) && l.snappable);
this.dragCoordinate.drag(t, n, a, d);
} else this.dragFeature.isDragging() ? this.dragFeature.drag(t, a) : e(!0);
}
onDragEnd(t, e) {
this.setCursor(this.cursors.dragEnd), this.dragCoordinate.isDragging() ? this.onFinish(this.selected[0], { mode: this.mode, action: "dragCoordinate" }) : this.dragFeature.isDragging() ? this.onFinish(this.selected[0], { mode: this.mode, action: "dragFeature" }) : this.dragCoordinateResizeFeature.isDragging() && this.onFinish(this.selected[0], { mode: this.mode, action: "dragCoordinateResize" }), this.dragCoordinate.stopDragging(), this.dragFeature.stopDragging(), this.dragCoordinateResizeFeature.stopDragging(), this.rotateFeature.reset(), this.scaleFeature.reset(), e(!0);
}
onMouseMove(t) {
if (!this.selected.length) return void this.setCursor("unset");
if (this.dragFeature.isDragging()) return;
let e = !1;
this.midPoints.ids.forEach((r) => {
if (e) return;
const n = this.store.getGeometryCopy(r);
this.pixelDistance.measure(t, n.coordinates) < this.pointerDistance && (e = !0);
});
let i = !1;
if (this.selectionPoints.ids.forEach((r) => {
const n = this.store.getGeometryCopy(r);
this.pixelDistance.measure(t, n.coordinates) < this.pointerDistance && (e = !1, i = !0);
}), e) return void this.setCursor(this.cursors.insertMidpoint);
const { clickedFeature: o } = this.featuresAtMouseEvent.find(t, !0);
this.setCursor(this.selected.length > 0 && (o && o.id === this.selected[0] || i) ? this.cursors.pointerOver : "unset");
}
styleFeature(t) {
const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
if (t.properties.mode === this.mode && t.geometry.type === "Point") {
if (t.properties.selectionPoint) return e.pointColor = this.getHexColorStylingValue(this.styles.selectionPointColor, e.pointColor, t), e.pointOutlineColor = this.getHexColorStylingValue(this.styles.selectionPointOutlineColor, e.pointOutlineColor, t), e.pointWidth = this.getNumericStylingValue(this.styles.selectionPointWidth, e.pointWidth, t), e.pointOutlineWidth = this.getNumericStylingValue(this.styles.selectionPointOutlineWidth, 2, t), e.zIndex = 30, e;
if (t.properties.midPoint) return e.pointColor = this.getHexColorStylingValue(this.styles.midPointColor, e.pointColor, t), e.pointOutlineColor = this.getHexColorStylingValue(this.styles.midPointOutlineColor, e.pointOutlineColor, t), e.pointWidth = this.getNumericStylingValue(this.styles.midPointWidth, 4, t), e.pointOutlineWidth = this.getNumericStylingValue(this.styles.midPointOutlineWidth, 2, t), e.zIndex = 40, e;
} else if (t.properties[V.SELECTED]) {
if (t.geometry.type === "Polygon") return e.polygonFillColor = this.getHexColorStylingValue(this.styles.selectedPolygonColor, e.polygonFillColor, t), e.polygonOutlineWidth = this.getNumericStylingValue(this.styles.selectedPolygonOutlineWidth, e.polygonOutlineWidth, t), e.polygonOutlineColor = this.getHexColorStylingValue(this.styles.selectedPolygonOutlineColor, e.polygonOutlineColor, t), e.polygonFillOpacity = this.getNumericStylingValue(this.styles.selectedPolygonFillOpacity, e.polygonFillOpacity, t), e.zIndex = 10, e;
if (t.geometry.type === "LineString") return e.lineStringColor = this.getHexColorStylingValue(this.styles.selectedLineStringColor, e.lineStringColor, t), e.lineStringWidth = this.getNumericStylingValue(this.styles.selectedLineStringWidth, e.lineStringWidth, t), e.zIndex = 10, e;
if (t.geometry.type === "Point") return e.pointWidth = this.getNumericStylingValue(this.styles.selectedPointWidth, e.pointWidth, t), e.pointColor = this.getHexColorStylingValue(this.styles.selectedPointColor, e.pointColor, t), e.pointOutlineColor = this.getHexColorStylingValue(this.styles.selectedPointOutlineColor, e.pointOutlineColor, t), e.pointOutlineWidth = this.getNumericStylingValue(this.styles.selectedPointOutlineWidth, e.pointOutlineWidth, t), e.zIndex = 10, e;
}
return e;
}
}
class Oi extends N {
constructor(...t) {
super(...t), this.type = $.Static, this.mode = "static";
}
start() {
}
stop() {
}
onKeyUp() {
}
onKeyDown() {
}
onClick() {
}
onDragStart() {
}
onDrag() {
}
onDragEnd() {
}
onMouseMove() {
}
cleanUp() {
}
styleFeature() {
return I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
}
}
function We(s, t, e, i, o) {
for (; i > e; ) {
if (i - e > 600) {
const l = i - e + 1, d = t - e + 1, h = Math.log(l), c = 0.5 * Math.exp(2 * h / 3), u = 0.5 * Math.sqrt(h * c * (l - c) / l) * (d - l / 2 < 0 ? -1 : 1);
We(s, t, Math.max(e, Math.floor(t - d * c / l + u)), Math.min(i, Math.floor(t + (l - d) * c / l + u)), o);
}
const r = s[t];
let n = e, a = i;
for (Q(s, e, t), o(s[i], r) > 0 && Q(s, e, i); n < a; ) {
for (Q(s, n, a), n++, a--; o(s[n], r) < 0; ) n++;
for (; o(s[a], r) > 0; ) a--;
}
o(s[e], r) === 0 ? Q(s, e, a) : (a++, Q(s, a, i)), a <= t && (e = a + 1), t <= a && (i = a - 1);
}
}
function Q(s, t, e) {
const i = s[t];
s[t] = s[e], s[e] = i;
}
function H(s, t) {
it(s, 0, s.children.length, t, s);
}
function it(s, t, e, i, o) {
o || (o = J([])), o.minX = 1 / 0, o.minY = 1 / 0, o.maxX = -1 / 0, o.maxY = -1 / 0;
for (let r = t; r < e; r++) {
const n = s.children[r];
ot(o, s.leaf ? i(n) : n);
}
return o;
}
function ot(s, t) {
return s.minX = Math.min(s.minX, t.minX), s.minY = Math.min(s.minY, t.minY), s.maxX = Math.max(s.maxX, t.maxX), s.maxY = Math.max(s.maxY, t.maxY), s;
}
function Di(s, t) {
return s.minX - t.minX;
}
function _i(s, t) {
return s.minY - t.minY;
}
function Ft(s) {
return (s.maxX - s.minX) * (s.maxY - s.minY);
}
function ut(s) {
return s.maxX - s.minX + (s.maxY - s.minY);
}
function Li(s, t) {
const e = Math.max(s.minX, t.minX), i = Math.max(s.minY, t.minY), o = Math.min(s.maxX, t.maxX), r = Math.min(s.maxY, t.maxY);
return Math.max(0, o - e) * Math.max(0, r - i);
}
function Et(s, t) {
return s.minX <= t.minX && s.minY <= t.minY && t.maxX <= s.maxX && t.maxY <= s.maxY;
}
function pt(s, t) {
return t.minX <= s.maxX && t.minY <= s.maxY && t.maxX >= s.minX && t.maxY >= s.minY;
}
function J(s) {
return { children: s, height: 1, leaf: !0, minX: 1 / 0, minY: 1 / 0, maxX: -1 / 0, maxY: -1 / 0 };
}
function ie(s, t, e, i, o) {
const r = [t, e];
for (; r.length; ) {
if ((e = r.pop()) - (t = r.pop()) <= i) continue;
const n = t + Math.ceil((e - t) / i / 2) * i;
We(s, n, t, e, o), r.push(t, n, n, e);
}
}
class ki {
constructor(t) {
this._maxEntries = void 0, this._minEntries = void 0, this.data = void 0, this._maxEntries = Math.max(4, t), this._minEntries = Math.max(2, Math.ceil(0.4 * this._maxEntries)), this.clear();
}
search(t) {
let e = this.data;
const i = [];
if (!pt(t, e)) return i;
const o = this.toBBox, r = [];
for (; e; ) {
for (let n = 0; n < e.children.length; n++) {
const a = e.children[n], l = e.leaf ? o(a) : a;
pt(t, l) && (e.leaf ? i.push(a) : Et(t, l) ? this._all(a, i) : r.push(a));
}
e = r.pop();
}
return i;
}
collides(t) {
let e = this.data;
if (pt(t, e)) {
const i = [];
for (; e; ) {
for (let o = 0; o < e.children.length; o++) {
const r = e.children[o], n = e.leaf ? this.toBBox(r) : r;
if (pt(t, n)) {
if (e.leaf || Et(t, n)) return !0;
i.push(r);
}
}
e = i.pop();
}
}
return !1;
}
load(t) {
if (t.length < this._minEntries) {
for (let i = 0; i < t.length; i++) this.insert(t[i]);
return;
}
let e = this._build(t.slice(), 0, t.length - 1, 0);
if (this.data.children.length) if (this.data.height === e.height) this._splitRoot(this.data, e);
else {
if (this.data.height < e.height) {
const i = this.data;
this.data = e, e = i;
}
this._insert(e, this.data.height - e.height - 1, !0);
}
else this.data = e;
}
insert(t) {
this._insert(t, this.data.height - 1);
}
clear() {
this.data = J([]);
}
remove(t) {
let e = this.data;
const i = this.toBBox(t), o = [], r = [];
let n, a, l = !1;
for (; e || o.length; ) {
if (e || (e = o.pop(), a = o[o.length - 1], n = r.pop(), l = !0), e.leaf) {
const d = e.children.indexOf(t);
d !== -1 && (e.children.splice(d, 1), o.push(e), this._condense(o));
}
l || e.leaf || !Et(e, i) ? a ? (n++, e = a.children[n], l = !1) : e = null : (o.push(e), r.push(n), n = 0, a = e, e = e.children[0]);
}
}
toBBox(t) {
return t;
}
compareMinX(t, e) {
return t.minX - e.minX;
}
compareMinY(t, e) {
return t.minY - e.minY;
}
_all(t, e) {
const i = [];
for (; t; ) t.leaf ? e.push(...t.children) : i.push(...t.children), t = i.pop();
return e;
}
_build(t, e, i, o) {
const r = i - e + 1;
let n, a = this._maxEntries;
if (r <= a) return n = J(t.slice(e, i + 1)), H(n, this.toBBox), n;
o || (o = Math.ceil(Math.log(r) / Math.log(a)), a = Math.ceil(r / Math.pow(a, o - 1))), n = J([]), n.leaf = !1, n.height = o;
const l = Math.ceil(r / a), d = l * Math.ceil(Math.sqrt(a));
ie(t, e, i, d, this.compareMinX);
for (let h = e; h <= i; h += d) {
const c = Math.min(h + d - 1, i);
ie(t, h, c, l, this.compareMinY);
for (let u = h; u <= c; u += l) {
const p = Math.min(u + l - 1, c);
n.children.push(this._build(t, u, p, o - 1));
}
}
return H(n, this.toBBox), n;
}
_chooseSubtree(t, e, i, o) {
for (; o.push(e), !e.leaf && o.length - 1 !== i; ) {
let a, l = 1 / 0, d = 1 / 0;
for (let h = 0; h < e.children.length; h++) {
const c = e.children[h], u = Ft(c), p = (r = t, n = c, (Math.max(n.maxX, r.maxX) - Math.min(n.minX, r.minX)) * (Math.max(n.maxY, r.maxY) - Math.min(n.minY, r.minY)) - u);
p < d ? (d = p, l = u < l ? u : l, a = c) : p === d && u < l && (l = u, a = c);
}
e = a || e.children[0];
}
var r, n;
return e;
}
_insert(t, e, i) {
const o = i ? t : this.toBBox(t), r = [], n = this._chooseSubtree(o, this.data, e, r);
for (n.children.push(t), ot(n, o); e >= 0 && r[e].children.length > this._maxEntries; ) this._split(r, e), e--;
this._adjustParentBBoxes(o, r, e);
}
_split(t, e) {
const i = t[e], o = i.children.length, r = this._minEntries;
this._chooseSplitAxis(i, r, o);
const n = this._chooseSplitIndex(i, r, o), a = J(i.children.splice(n, i.children.length - n));
a.height = i.height, a.leaf = i.leaf, H(i, this.toBBox), H(a, this.toBBox), e ? t[e - 1].children.push(a) : this._splitRoot(i, a);
}
_splitRoot(t, e) {
this.data = J([t, e]), this.data.height = t.height + 1, this.data.leaf = !1, H(this.data, this.toBBox);
}
_chooseSplitIndex(t, e, i) {
let o, r = 1 / 0, n = 1 / 0;
for (let a = e; a <= i - e; a++) {
const l = it(t, 0, a, this.toBBox), d = it(t, a, i, this.toBBox), h = Li(l, d), c = Ft(l) + Ft(d);
h < r ? (r = h, o = a, n = c < n ? c : n) : h === r && c < n && (n = c, o = a);
}
return o || i - e;
}
_chooseSplitAxis(t, e, i) {
const o = t.leaf ? this.compareMinX : Di, r = t.leaf ? this.compareMinY : _i;
this._allDistMargin(t, e, i, o) < this._allDistMargin(t, e, i, r) && t.children.sort(o);
}
_allDistMargin(t, e, i, o) {
t.children.sort(o);
const r = this.toBBox, n = it(t, 0, e, r), a = it(t, i - e, i, r);
let l = ut(n) + ut(a);
for (let d = e; d < i - e; d++) {
const h = t.children[d];
ot(n, t.leaf ? r(h) : h), l += ut(n);
}
for (let d = i - e - 1; d >= e; d--) {
const h = t.children[d];
ot(a, t.leaf ? r(h) : h), l += ut(a);
}
return l;
}
_adjustParentBBoxes(t, e, i) {
for (let o = i; o >= 0; o--) ot(e[o], t);
}
_condense(t) {
for (let e, i = t.length - 1; i >= 0; i--) t[i].children.length === 0 ? i > 0 ? (e = t[i - 1].children, e.splice(e.indexOf(t[i]), 1)) : this.clear() : H(t[i], this.toBBox);
}
}
class Bi {
constructor(t) {
this.tree = void 0, this.idToNode = void 0, this.nodeToId = void 0, this.tree = new ki(t && t.maxEntries ? t.maxEntries : 9), this.idToNode = /* @__PURE__ */ new Map(), this.nodeToId = /* @__PURE__ */ new Map();
}
setMaps(t, e) {
this.idToNode.set(t.id, e), this.nodeToId.set(e, t.id);
}
toBBox(t) {
const e = [], i = [];
let o;
if (t.geometry.type === "Polygon") o = t.geometry.coordinates[0];
else if (t.geometry.type === "LineString") o = t.geometry.coordinates;
else {
if (t.geometry.type !== "Point") throw new Error("Not a valid feature to turn into a bounding box");
o = [t.geometry.coordinates];
}
for (let a = 0; a < o.length; a++) i.push(o[a][1]), e.push(o[a][0]);
const r = Math.min(...i), n = Math.max(...i);
return { minX: Math.min(...e), minY: r, maxX: Math.max(...e), maxY: n };
}
insert(t) {
if (this.idToNode.get(String(t.id))) throw new Error("Feature already exists");
const e = this.toBBox(t);
this.setMaps(t, e), this.tree.insert(e);
}
load(t) {
const e = [], i = /* @__PURE__ */ new Set();
t.forEach((o) => {
const r = this.toBBox(o);
if (this.setMaps(o, r), i.has(String(o.id))) throw new Error(`Duplicate feature ID found ${o.id}`);
i.add(String(o.id)), e.push(r);
}), this.tree.load(e);
}
update(t) {
this.remove(t.id);
const e = this.toBBox(t);
this.setMaps(t, e), this.tree.insert(e);
}
remove(t) {
const e = this.idToNode.get(t);
if (!e) throw new Error(`${t} not inserted into the spatial index`);
this.tree.remove(e);
}
clear() {
this.tree.clear();
}
search(t) {
return this.tree.search(this.toBBox(t)).map((e) => this.nodeToId.get(e));
}
collides(t) {
return this.tree.collides(this.toBBox(t));
}
}
const Wi = { getId: () => "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(s) {
const t = 16 * Math.random() | 0;
return (s == "x" ? t : 3 & t | 8).toString(16);
}), isValidId: (s) => typeof s == "string" && s.length === 36 };
class ji {
constructor(t) {
this.idStrategy = void 0, this.tracked = void 0, this.spatialIndex = void 0, this.store = void 0, this._onChange = () => {
}, this.store = {}, this.spatialIndex = new Bi(), this.tracked = !t || t.tracked !== !1, this.idStrategy = t && t.idStrategy ? t.idStrategy : Wi;
}
clone(t) {
return JSON.parse(JSON.stringify(t));
}
getId() {
return this.idStrategy.getId();
}
has(t) {
return !!this.store[t];
}
load(t, e, i) {
if (t.length === 0) return [];
let o = this.clone(t);
const r = [], n = [];
return o = o.filter((a) => {
a.id == null && (a.id = this.idStrategy.getId());
const l = a.id;
if (e) {
const d = e(a);
if (!d.valid) return n.push({ id: l, valid: !1, reason: d.reason }), !1;
}
if (this.tracked) {
if (a.properties.createdAt) {
if (!Xt(a.properties.createdAt)) return n.push({ id: a.id, valid: !1, reason: "createdAt is not a valid numeric timestamp" }), !1;
} else a.properties.createdAt = +/* @__PURE__ */ new Date();
if (a.properties.updatedAt) {
if (!Xt(a.properties.updatedAt)) return n.push({ id: a.id, valid: !1, reason: "updatedAt is not a valid numeric timestamp" }), !1;
} else a.properties.updatedAt = +/* @__PURE__ */ new Date();
}
return this.has(l) ? (n.push({ id: l, valid: !1, reason: `Feature already exists with this id: ${l}` }), !1) : (this.store[l] = a, r.push(l), i && i(a), n.push({ id: l, valid: !0 }), !0);
}), this.spatialIndex.load(o), this._onChange(r, "create"), n;
}
search(t, e) {
const i = this.spatialIndex.search(t).map((o) => this.store[o]);
return this.clone(e ? i.filter(e) : i);
}
registerOnChange(t) {
this._onChange = (e, i) => {
t(e, i);
};
}
getGeometryCopy(t) {
const e = this.store[t];
if (!e) throw new Error(`No feature with this id (${t}), can not get geometry copy`);
return this.clone(e.geometry);
}
getPropertiesCopy(t) {
const e = this.store[t];
if (!e) throw new Error(`No feature with this id (${t}), can not get properties copy`);
return this.clone(e.properties);
}
updateProperty(t) {
const e = [];
t.forEach(({ id: i, property: o, value: r }) => {
const n = this.store[i];
if (!n) throw new Error(`No feature with this (${i}), can not update geometry`);
e.push(i), n.properties[o] = r, this.tracked && (n.properties.updatedAt = +/* @__PURE__ */ new Date());
}), this._onChange && this._onChange(e, "update");
}
updateGeometry(t) {
const e = [];
t.forEach(({ id: i, geometry: o }) => {
e.push(i);
const r = this.store[i];
if (!r) throw new Error(`No feature with this (${i}), can not update geometry`);
r.geometry = this.clone(o), this.spatialIndex.update(r), this.tracked && (r.properties.updatedAt = +/* @__PURE__ */ new Date());
}), this._onChange && this._onChange(e, "update");
}
create(t) {
const e = [];
return t.forEach(({ geometry: i, properties: o }) => {
let r, n = I({}, o);
this.tracked && (r = +/* @__PURE__ */ new Date(), o ? (n.createdAt = typeof o.createdAt == "number" ? o.createdAt : r, n.updatedAt = typeof o.updatedAt == "number" ? o.updatedAt : r) : n = { createdAt: r, updatedAt: r });
const a = this.getId(), l = { id: a, type: "Feature", geometry: i, properties: n };
this.store[a] = l, this.spatialIndex.insert(l), e.push(a);
}), this._onChange && this._onChange([...e], "create"), e;
}
delete(t) {
t.forEach((e) => {
if (!this.store[e]) throw new Error("No feature with this id, can not delete");
delete this.store[e], this.spatialIndex.remove(e);
}), this._onChange && this._onChange([...t], "delete");
}
copy(t) {
return this.clone(this.store[t]);
}
copyAll() {
return this.clone(Object.keys(this.store).map((t) => this.store[t]));
}
copyAllWhere(t) {
return this.clone(Object.keys(this.store).map((e) => this.store[e]).filter((e) => e.properties && t(e.properties)));
}
clear() {
this.store = {}, this.spatialIndex.clear();
}
size() {
return Object.keys(this.store).length;
}
}
const Ni = "Feature is not a Polygon or LineString", Gi = "Feature intersects itself", Ai = (s) => s.geometry.type !== "Polygon" && s.geometry.type !== "LineString" ? { valid: !1, reason: Ni } : Bt(s) ? { valid: !1, reason: Gi } : { valid: !0 };
function oe(s, t, e) {
const i = A(s, t);
let o = A(t, e) - i;
return o < 0 && (o += 360), 180 - Math.abs(o - 90 - 90);
}
const Ti = { cancel: "Escape", finish: "Enter" }, Ui = { start: "crosshair", close: "pointer" };
class je extends N {
constructor(t) {
super(t, !0), this.mode = "angled-rectangle", this.currentCoordinate = 0, this.currentId = void 0, this.keyEvents = Ti, this.cursors = Ui, this.mouseMove = !1, this.updateOptions(t);
}
updateOptions(t) {
super.updateOptions(t), t != null && t.cursors && (this.cursors = I({}, this.cursors, t.cursors)), (t == null ? void 0 : t.keyEvents) === null ? this.keyEvents = { cancel: null, finish: null } : t != null && t.keyEvents && (this.keyEvents = I({}, this.keyEvents, t.keyEvents));
}
close() {
if (this.currentId === void 0) return;
const t = this.currentId;
this.currentCoordinate = 0, this.currentId = void 0, this.state === "drawing" && this.setStarted(), this.onFinish(t, { mode: this.mode, action: "draw" });
}
start() {
this.setStarted(), this.setCursor(this.cursors.start);
}
stop() {
this.cleanUp(), this.setStopped(), this.setCursor("unset");
}
onMouseMove(t) {
if (this.mouseMove = !0, this.setCursor(this.cursors.start), this.currentId === void 0 || this.currentCoordinate === 0) return;
const e = this.store.getGeometryCopy(this.currentId).coordinates[0];
let i;
if (this.currentCoordinate === 1) {
const o = 1 / Math.pow(10, this.coordinatePrecision - 1), r = Math.max(1e-6, o);
i = [e[0], [t.lng, t.lat], [t.lng, t.lat - r], e[0]];
} else if (this.currentCoordinate === 2) {
const o = e[0], r = e[1], n = De(o, r, this.coordinatePrecision, this.project, this.unproject), a = x(o[0], o[1]), l = x(n[0], n[1]), d = x(r[0], r[1]), h = x(t.lng, t.lat), c = E(h, a) < E(h, d), u = oe(a, l, h), p = c ? 90 - u : oe(a, l, h) - 90, g = E(l, h), y = Math.cos(O(p)) * g, m = A(a, d) + (function(S, b, w) {
const D = (w.x - b.x) * (S.y - b.y) - (w.y - b.y) * (S.x - b.x);
return D > 1e-10 ? "left" : D < -1e-10 ? "right" : "left";
}(a, d, h) === "right" ? -90 : 90), v = at(a, y, m), f = at(d, y, m), C = W(v.x, v.y), P = W(f.x, f.y);
i = [e[0], e[1], [P.lng, P.lat], [C.lng, C.lat], e[0]];
}
i && this.updatePolygonGeometry(this.currentId, i, M.Provisional);
}
updatePolygonGeometry(t, e, i) {
const o = { type: "Polygon", coordinates: [e] };
return !(this.validate && !this.validate({ type: "Feature", geometry: o }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: i }).valid || (this.store.updateGeometry([{ id: t, geometry: o }]), 0));
}
onClick(t) {
if (this.currentCoordinate > 0 && !this.mouseMove && this.onMouseMove(t), this.mouseMove = !1, this.currentCoordinate === 0) {
const [e] = this.store.create([{ geometry: { type: "Polygon", coordinates: [[[t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat]]] }, properties: { mode: this.mode } }]);
this.currentId = e, this.currentCoordinate++, this.setDrawing();
} else if (this.currentCoordinate === 1 && this.currentId) {
const e = this.store.getGeometryCopy(this.currentId);
if (Z([t.lng, t.lat], e.coordinates[0][0]) || !this.updatePolygonGeometry(this.currentId, [e.coordinates[0][0], [t.lng, t.lat], [t.lng, t.lat], e.coordinates[0][0]], M.Commit)) return;
this.currentCoordinate++;
} else this.currentCoordinate === 2 && this.currentId && this.close();
}
onKeyUp(t) {
if (t.key === this.keyEvents.cancel) this.cleanUp();
else if (t.key === this.keyEvents.finish) {
if (this.currentCoordinate < 2) return void this.cleanUp();
this.close();
}
}
onKeyDown() {
}
onDragStart() {
}
onDrag() {
}
onDragEnd() {
}
cleanUp() {
try {
this.currentId && this.store.delete([this.currentId]);
} catch {
}
this.currentId = void 0, this.currentCoordinate = 0, this.state === "drawing" && this.setStarted();
}
styleFeature(t) {
const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
return t.properties.mode === this.mode && t.geometry.type === "Polygon" && (e.polygonFillColor = this.getHexColorStylingValue(this.styles.fillColor, e.polygonFillColor, t), e.polygonOutlineColor = this.getHexColorStylingValue(this.styles.outlineColor, e.polygonOutlineColor, t), e.polygonOutlineWidth = this.getNumericStylingValue(this.styles.outlineWidth, e.polygonOutlineWidth, t), e.polygonFillOpacity = this.getNumericStylingValue(this.styles.fillOpacity, e.polygonFillOpacity, t), e.zIndex = 10), e;
}
validateFeature(t) {
return this.validateModeFeature(t, (e) => lt(e, this.coordinatePrecision));
}
}
function Ne(s, t, e) {
return (t.x - s.x) * (e.y - s.y) - (t.y - s.y) * (e.x - s.x) <= 0;
}
const Vi = { cancel: "Escape", finish: "Enter" }, Ri = { start: "crosshair", close: "pointer" };
class Ge extends N {
constructor(t) {
super(t, !0), this.mode = "sector", this.currentCoordinate = 0, this.currentId = void 0, this.keyEvents = Vi, this.direction = void 0, this.arcPoints = 64, this.cursors = Ri, this.mouseMove = !1, this.updateOptions(t);
}
updateOptions(t) {
super.updateOptions(t), t != null && t.cursors && (this.cursors = I({}, this.cursors, t.cursors)), (t == null ? void 0 : t.keyEvents) === null ? this.keyEvents = { cancel: null, finish: null } : t != null && t.keyEvents && (this.keyEvents = I({}, this.keyEvents, t.keyEvents)), t != null && t.arcPoints && (this.arcPoints = t.arcPoints);
}
close() {
if (this.currentId === void 0) return;
const t = dt(this.store.getGeometryCopy(this.currentId));
t && this.store.updateGeometry([{ id: this.currentId, geometry: t }]);
const e = this.currentId;
this.currentCoordinate = 0, this.currentId = void 0, this.direction = void 0, this.state === "drawing" && this.setStarted(), this.onFinish(e, { mode: this.mode, action: "draw" });
}
start() {
this.setStarted(), this.setCursor(this.cursors.start);
}
stop() {
this.cleanUp(), this.setStopped(), this.setCursor("unset");
}
onMouseMove(t) {
if (this.mouseMove = !0, this.setCursor(this.cursors.start), this.currentId === void 0 || this.currentCoordinate === 0) return;
const e = this.store.getGeometryCopy(this.currentId).coordinates[0];
let i;
if (this.currentCoordinate === 1) {
const o = 1 / Math.pow(10, this.coordinatePrecision - 1), r = Math.max(1e-6, o);
i = [e[0], [t.lng, t.lat], [t.lng, t.lat - r], e[0]];
} else if (this.currentCoordinate === 2) {
const o = e[0], r = e[1], n = [t.lng, t.lat], a = x(o[0], o[1]), l = x(r[0], r[1]), d = x(n[0], n[1]);
if (this.direction === void 0) {
const C = Ne(a, l, d);
this.direction = C ? "clockwise" : "anticlockwise";
}
const h = E(a, l), c = A(a, l), u = A(a, d), p = this.arcPoints, g = [o], y = Y(c), m = Y(u);
let v;
this.direction === "anticlockwise" ? (v = m - y, v < 0 && (v += 360)) : (v = y - m, v < 0 && (v += 360));
const f = (this.direction === "anticlockwise" ? 1 : -1) * v / p;
g.push(r);
for (let C = 0; C <= p; C++) {
const P = at(a, h, y + C * f), { lng: S, lat: b } = W(P.x, P.y), w = [F(S, this.coordinatePrecision), F(b, this.coordinatePrecision)];
w[0] !== g[g.length - 1][0] && w[1] !== g[g.length - 1][1] && g.push(w);
}
g.push(o), i = [...g];
}
i && this.updatePolygonGeometry(this.currentId, i, M.Provisional);
}
updatePolygonGeometry(t, e, i) {
const o = { type: "Polygon", coordinates: [e] };
return !(this.validate && !this.validate({ type: "Feature", geometry: o }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: i }).valid || (this.store.updateGeometry([{ id: t, geometry: o }]), 0));
}
onClick(t) {
if (this.currentCoordinate > 0 && !this.mouseMove && this.onMouseMove(t), this.mouseMove = !1, this.currentCoordinate === 0) {
const [e] = this.store.create([{ geometry: { type: "Polygon", coordinates: [[[t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat]]] }, properties: { mode: this.mode } }]);
this.currentId = e, this.currentCoordinate++, this.setDrawing();
} else if (this.currentCoordinate === 1 && this.currentId) {
const e = this.store.getGeometryCopy(this.currentId);
if (Z([t.lng, t.lat], e.coordinates[0][0]) || !this.updatePolygonGeometry(this.currentId, [e.coordinates[0][0], [t.lng, t.lat], [t.lng, t.lat], e.coordinates[0][0]], M.Commit)) return;
this.currentCoordinate++;
} else this.currentCoordinate === 2 && this.currentId && this.close();
}
onKeyUp(t) {
t.key === this.keyEvents.cancel ? this.cleanUp() : t.key === this.keyEvents.finish && this.close();
}
onKeyDown() {
}
onDragStart() {
}
onDrag() {
}
onDragEnd() {
}
cleanUp() {
try {
this.currentId && this.store.delete([this.currentId]);
} catch {
}
this.currentId = void 0, this.direction = void 0, this.currentCoordinate = 0, this.state === "drawing" && this.setStarted();
}
styleFeature(t) {
const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
return t.properties.mode === this.mode && t.geometry.type === "Polygon" && (e.polygonFillColor = this.getHexColorStylingValue(this.styles.fillColor, e.polygonFillColor, t), e.polygonOutlineColor = this.getHexColorStylingValue(this.styles.outlineColor, e.polygonOutlineColor, t), e.polygonOutlineWidth = this.getNumericStylingValue(this.styles.outlineWidth, e.polygonOutlineWidth, t), e.polygonFillOpacity = this.getNumericStylingValue(this.styles.fillOpacity, e.polygonFillOpacity, t), e.zIndex = 10), e;
}
validateFeature(t) {
return this.validateModeFeature(t, (e) => lt(e, this.coordinatePrecision));
}
}
const zi = { cancel: "Escape", finish: "Enter" }, Xi = { start: "crosshair", close: "pointer" };
class Ae extends N {
constructor(t) {
super(t, !0), this.mode = "sensor", this.currentCoordinate = 0, this.currentId = void 0, this.currentInitialArcId = void 0, this.currentStartingPointId = void 0, this.keyEvents = zi, this.direction = void 0, this.arcPoints = 64, this.cursors = Xi, this.mouseMove = !1, this.updateOptions(t);
}
updateOptions(t) {
super.updateOptions(t), t != null && t.cursors && (this.cursors = I({}, this.cursors, t.cursors)), (t == null ? void 0 : t.keyEvents) === null ? this.keyEvents = { cancel: null, finish: null } : t != null && t.keyEvents && (this.keyEvents = I({}, this.keyEvents, t.keyEvents)), t != null && t.arcPoints && (this.arcPoints = t.arcPoints);
}
close() {
if (this.currentStartingPointId === void 0) return;
const t = this.currentStartingPointId, e = this.currentInitialArcId, i = this.currentId;
if (t && this.store.delete([t]), e && this.store.delete([e]), this.currentId) {
const o = dt(this.store.getGeometryCopy(this.currentId));
o && this.store.updateGeometry([{ id: this.currentId, geometry: o }]);
}
this.currentCoordinate = 0, this.currentStartingPointId = void 0, this.currentInitialArcId = void 0, this.currentId = void 0, this.direction = void 0, this.state === "drawing" && this.setStarted(), i && this.onFinish(i, { mode: this.mode, action: "draw" });
}
start() {
this.setStarted(), this.setCursor(this.cursors.start);
}
stop() {
this.cleanUp(), this.setStopped(), this.setCursor("unset");
}
onMouseMove(t) {
if (this.mouseMove = !0, this.setCursor(this.cursors.start), this.currentInitialArcId !== void 0 && this.currentStartingPointId !== void 0 && this.currentCoordinate !== 0) {
if (this.currentCoordinate === 2) {
const e = this.store.getGeometryCopy(this.currentInitialArcId).coordinates, i = this.store.getGeometryCopy(this.currentStartingPointId).coordinates, o = e[0], r = [t.lng, t.lat], n = x(o[0], o[1]), a = x(r[0], r[1]), l = x(i[0], i[1]), d = E(l, n);
if (this.direction === void 0) {
const f = Ne(l, n, a);
this.direction = f ? "clockwise" : "anticlockwise";
}
const h = A(l, n), c = A(l, a), u = this.arcPoints, p = [o], g = Y(h), y = Y(c);
let m;
this.direction === "anticlockwise" ? (m = y - g, m < 0 && (m += 360)) : (m = g - y, m < 0 && (m += 360));
const v = (this.direction === "anticlockwise" ? 1 : -1) * m / u;
for (let f = 0; f <= u; f++) {
const C = at(l, d, g + f * v), { lng: P, lat: S } = W(C.x, C.y), b = [F(P, this.coordinatePrecision), F(S, this.coordinatePrecision)];
b[0] !== p[p.length - 1][0] && b[1] !== p[p.length - 1][1] && p.push(b);
}
this.updateLineStringGeometry(this.currentInitialArcId, p, M.Provisional);
} else if (this.currentCoordinate === 3) {
const e = this.store.getGeometryCopy(this.currentInitialArcId).coordinates;
if (e.length < 2 || !this.direction) return;
const i = this.store.getGeometryCopy(this.currentStartingPointId).coordinates, o = e[0], r = e[e.length - 1], n = x(t.lng, t.lat), a = x(o[0], o[1]), l = x(r[0], r[1]), d = x(i[0], i[1]), h = E(d, a), c = E(d, n) < h ? a : n, u = A(d, n), p = A(d, a), g = A(d, l), y = Y(p), m = Y(g), v = Y(u);
if (this.notInSector({ normalizedCursor: v, normalizedStart: y, normalizedEnd: m, direction: this.direction })) return;
const f = this.getDeltaBearing(this.direction, y, m), C = this.arcPoints, P = (this.direction === "anticlockwise" ? 1 : -1) * f / C, S = E(d, c), b = [];
for (let w = 0; w <= C; w++) {
const D = at(d, S, y + w * P), { lng: G, lat: _ } = W(D.x, D.y), j = [F(G, this.coordinatePrecision), F(_, this.coordinatePrecision)];
j[0] !== e[e.length - 1][0] && j[1] !== e[e.length - 1][1] && b.unshift(j);
}
e.push(...b), e.push(e[0]), this.currentId ? this.updatePolygonGeometry(this.currentId, e, M.Provisional) : [this.currentId] = this.store.create([{ geometry: { type: "Polygon", coordinates: [e] }, properties: { mode: this.mode } }]);
}
}
}
updateLineStringGeometry(t, e, i) {
const o = { type: "LineString", coordinates: e };
return !(this.validate && !this.validate({ type: "Feature", geometry: o }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: i }).valid || (this.store.updateGeometry([{ id: t, geometry: o }]), 0));
}
updatePolygonGeometry(t, e, i) {
const o = { type: "Polygon", coordinates: [e] };
return !(this.validate && !this.validate({ type: "Feature", geometry: o }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: i }).valid || (this.store.updateGeometry([{ id: t, geometry: o }]), 0));
}
onClick(t) {
if (this.currentCoordinate > 0 && !this.mouseMove && this.onMouseMove(t), this.mouseMove = !1, this.currentCoordinate === 0) {
const [e] = this.store.create([{ geometry: { type: "Point", coordinates: [t.lng, t.lat] }, properties: { mode: this.mode } }]);
this.currentStartingPointId = e, this.currentCoordinate++, this.setDrawing();
} else if (this.currentCoordinate === 1 && this.currentStartingPointId) {
const [e] = this.store.create([{ geometry: { type: "LineString", coordinates: [[t.lng, t.lat], [t.lng, t.lat]] }, properties: { mode: this.mode } }]);
this.currentInitialArcId = e, this.currentCoordinate++;
} else this.currentCoordinate === 2 && this.currentStartingPointId ? this.currentCoordinate++ : this.currentCoordinate === 3 && this.currentStartingPointId && this.close();
}
onKeyUp(t) {
t.key === this.keyEvents.cancel ? this.cleanUp() : t.key === this.keyEvents.finish && this.close();
}
onKeyDown() {
}
onDragStart() {
}
onDrag() {
}
onDragEnd() {
}
cleanUp() {
try {
this.currentStartingPointId && this.store.delete([this.currentStartingPointId]), this.currentInitialArcId && this.store.delete([this.currentInitialArcId]), this.currentId && this.store.delete([this.currentId]);
} catch {
}
this.currentStartingPointId = void 0, this.direction = void 0, this.currentId = void 0, this.currentCoordinate = 0, this.state === "drawing" && this.setStarted();
}
styleFeature(t) {
const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
return t.properties.mode === this.mode && (t.geometry.type === "Polygon" ? (e.polygonFillColor = this.getHexColorStylingValue(this.styles.fillColor, e.polygonFillColor, t), e.polygonOutlineColor = this.getHexColorStylingValue(this.styles.outlineColor, e.polygonOutlineColor, t), e.polygonOutlineWidth = this.getNumericStylingValue(this.styles.outlineWidth, e.polygonOutlineWidth, t), e.polygonFillOpacity = this.getNumericStylingValue(this.styles.fillOpacity, e.polygonFillOpacity, t), e.zIndex = 10) : t.geometry.type === "LineString" ? (e.lineStringColor = this.getHexColorStylingValue(this.styles.outlineColor, e.polygonOutlineColor, t), e.lineStringWidth = this.getNumericStylingValue(this.styles.outlineWidth, e.polygonOutlineWidth, t), e.zIndex = 10) : t.geometry.type === "Point" && (e.pointColor = this.getHexColorStylingValue(this.styles.centerPointColor, e.pointColor, t), e.pointWidth = this.getNumericStylingValue(this.styles.centerPointWidth, e.pointWidth, t), e.pointOutlineColor = this.getHexColorStylingValue(this.styles.centerPointOutlineColor, e.pointOutlineColor, t), e.pointOutlineWidth = this.getNumericStylingValue(this.styles.centerPointOutlineWidth, e.pointOutlineWidth, t), e.zIndex = 20)), e;
}
validateFeature(t) {
return this.validateModeFeature(t, (e) => lt(e, this.coordinatePrecision));
}
getDeltaBearing(t, e, i) {
let o;
return t === "anticlockwise" ? (o = i - e, o < 0 && (o += 360)) : (o = e - i, o < 0 && (o += 360)), o;
}
notInSector({ normalizedCursor: t, normalizedStart: e, normalizedEnd: i, direction: o }) {
return o === "clockwise" ? e <= i ? t >= e && t <= i : t >= e || t <= i : e >= i ? t <= e && t >= i : t <= e || t >= i;
}
}
class q {
constructor({ name: t, callback: e, unregister: i, register: o }) {
this.name = void 0, this.callback = void 0, this.registered = !1, this.register = void 0, this.unregister = void 0, this.name = t, this.register = () => {
this.registered || (this.registered = !0, o(e));
}, this.unregister = () => {
this.register && (this.registered = !1, i(e));
}, this.callback = e;
}
}
var Ki = { __proto__: null, TerraDrawBaseAdapter: class {
constructor(s) {
this._minPixelDragDistance = void 0, this._minPixelDragDistanceDrawing = void 0, this._minPixelDragDistanceSelecting = void 0, this._lastDrawEvent = void 0, this._coordinatePrecision = void 0, this._heldKeys = /* @__PURE__ */ new Set(), this._listeners = [], this._dragState = "not-dragging", this._currentModeCallbacks = void 0, this._minPixelDragDistance = typeof s.minPixelDragDistance == "number" ? s.minPixelDragDistance : 1, this._minPixelDragDistanceSelecting = typeof s.minPixelDragDistanceSelecting == "number" ? s.minPixelDragDistanceSelecting : 1, this._minPixelDragDistanceDrawing = typeof s.minPixelDragDistanceDrawing == "number" ? s.minPixelDragDistanceDrawing : 8, this._coordinatePrecision = typeof s.coordinatePrecision == "number" ? s.coordinatePrecision : 9;
}
getButton(s) {
return s.button === -1 ? "neither" : s.button === 0 ? "left" : s.button === 1 ? "middle" : s.button === 2 ? "right" : "neither";
}
getMapElementXYPosition(s) {
const t = this.getMapEventElement(), { left: e, top: i } = t.getBoundingClientRect();
return { containerX: s.clientX - e, containerY: s.clientY - i };
}
getDrawEventFromEvent(s) {
const t = this.getLngLatFromEvent(s);
if (!t) return null;
const { lng: e, lat: i } = t, { containerX: o, containerY: r } = this.getMapElementXYPosition(s), n = this.getButton(s), a = Array.from(this._heldKeys);
return { lng: F(e, this._coordinatePrecision), lat: F(i, this._coordinatePrecision), containerX: o, containerY: r, button: n, heldKeys: a };
}
register(s) {
this._currentModeCallbacks = s, this._listeners = this.getAdapterListeners(), this._listeners.forEach((t) => {
t.register();
});
}
getCoordinatePrecision() {
return this._coordinatePrecision;
}
getAdapterListeners() {
return [new q({ name: "pointerdown", callback: (s) => {
if (!this._currentModeCallbacks || !s.isPrimary) return;
const t = this.getDrawEventFromEvent(s);
t && (this._dragState = "pre-dragging", this._lastDrawEvent = t);
}, register: (s) => {
this.getMapEventElement().addEventListener("pointerdown", s);
}, unregister: (s) => {
this.getMapEventElement().removeEventListener("pointerdown", s);
} }), new q({ name: "pointermove", callback: (s) => {
if (!this._currentModeCallbacks || !s.isPrimary) return;
s.preventDefault();
const t = this.getDrawEventFromEvent(s);
if (t) if (this._dragState === "not-dragging") this._currentModeCallbacks.onMouseMove(t), this._lastDrawEvent = t;
else if (this._dragState === "pre-dragging") {
if (!this._lastDrawEvent) return;
const e = { x: this._lastDrawEvent.containerX, y: this._lastDrawEvent.containerY }, i = { x: t.containerX, y: t.containerY }, o = this._currentModeCallbacks.getState(), r = E(e, i);
let n = !1;
if (n = o === "drawing" ? r < this._minPixelDragDistanceDrawing : o === "selecting" ? r < this._minPixelDragDistanceSelecting : r < this._minPixelDragDistance, n) return;
this._dragState = "dragging", this._currentModeCallbacks.onDragStart(t, (a) => {
this.setDraggability.bind(this)(a);
});
} else this._dragState === "dragging" && this._currentModeCallbacks.onDrag(t, (e) => {
this.setDraggability.bind(this)(e);
});
}, register: (s) => {
this.getMapEventElement().addEventListener("pointermove", s);
}, unregister: (s) => {
this.getMapEventElement().removeEventListener("pointermove", s);
} }), new q({ name: "contextmenu", callback: (s) => {
this._currentModeCallbacks && s.preventDefault();
}, register: (s) => {
this.getMapEventElement().addEventListener("contextmenu", s);
}, unregister: (s) => {
this.getMapEventElement().removeEventListener("contextmenu", s);
} }), new q({ name: "pointerup", callback: (s) => {
if (!this._currentModeCallbacks || s.target !== this.getMapEventElement() || !s.isPrimary) return;
const t = this.getDrawEventFromEvent(s);
t && (this._dragState === "dragging" ? this._currentModeCallbacks.onDragEnd(t, (e) => {
this.setDraggability.bind(this)(e);
}) : this._dragState !== "not-dragging" && this._dragState !== "pre-dragging" || this._currentModeCallbacks.onClick(t), this._dragState = "not-dragging", this.setDraggability(!0));
}, register: (s) => {
this.getMapEventElement().addEventListener("pointerup", s);
}, unregister: (s) => {
this.getMapEventElement().removeEventListener("pointerup", s);
} }), new q({ name: "keyup", callback: (s) => {
this._currentModeCallbacks && (this._heldKeys.delete(s.key), this._currentModeCallbacks.onKeyUp({ key: s.key, heldKeys: Array.from(this._heldKeys), preventDefault: () => s.preventDefault() }));
}, register: (s) => {
this.getMapEventElement().addEventListener("keyup", s);
}, unregister: (s) => {
this.getMapEventElement().removeEventListener("keyup", s);
} }), new q({ name: "keydown", callback: (s) => {
this._currentModeCallbacks && (this._heldKeys.add(s.key), this._currentModeCallbacks.onKeyDown({ key: s.key, heldKeys: Array.from(this._heldKeys), preventDefault: () => s.preventDefault() }));
}, register: (s) => {
this.getMapEventElement().addEventListener("keydown", s);
}, unregister: (s) => {
this.getMapEventElement().removeEventListener("keydown", s);
} })];
}
unregister() {
this._listeners.forEach((s) => {
s.unregister();
}), this.clear();
}
} };
class Yi {
constructor(t) {
this._modes = void 0, this._mode = void 0, this._adapter = void 0, this._enabled = !1, this._store = void 0, this._eventListeners = void 0, this._instanceSelectMode = void 0, this._adapter = t.adapter, this._mode = new Oi();
const e = /* @__PURE__ */ new Set(), i = t.modes.reduce((h, c) => {
if (e.has(c.mode)) throw new Error(`There is already a ${c.mode} mode provided`);
return e.add(c.mode), h[c.mode] = c, h;
}, {}), o = Object.keys(i);
if (o.length === 0) throw new Error("No modes provided");
o.forEach((h) => {
if (i[h].type === $.Select) {
if (this._instanceSelectMode) throw new Error("only one type of select mode can be provided");
this._instanceSelectMode = h;
}
}), this._modes = I({}, i, { static: this._mode }), this._eventListeners = { change: [], select: [], deselect: [], finish: [], ready: [] }, this._store = new ji({ tracked: !!t.tracked, idStrategy: t.idStrategy ? t.idStrategy : void 0 });
const r = (h) => {
const c = [], u = this._store.copyAll().filter((p) => !h.includes(p.id) || (c.push(p), !1));
return { changed: c, unchanged: u };
}, n = (h, c) => {
this._enabled && this._eventListeners.finish.forEach((u) => {
u(h, c);
});
}, a = (h, c) => {
if (!this._enabled) return;
this._eventListeners.change.forEach((g) => {
g(h, c);
});
const { changed: u, unchanged: p } = r(h);
c === "create" ? this._adapter.render({ created: u, deletedIds: [], unchanged: p, updated: [] }, this.getModeStyles()) : c === "update" ? this._adapter.render({ created: [], deletedIds: [], unchanged: p, updated: u }, this.getModeStyles()) : c === "delete" ? this._adapter.render({ created: [], deletedIds: h, unchanged: p, updated: [] }, this.getModeStyles()) : c === "styling" && this._adapter.render({ created: [], deletedIds: [], unchanged: p, updated: [] }, this.getModeStyles());
}, l = (h) => {
if (!this._enabled) return;
this._eventListeners.select.forEach((p) => {
p(h);
});
const { changed: c, unchanged: u } = r([h]);
this._adapter.render({ created: [], deletedIds: [], unchanged: u, updated: c }, this.getModeStyles());
}, d = (h) => {
if (!this._enabled) return;
this._eventListeners.deselect.forEach((p) => {
p();
});
const { changed: c, unchanged: u } = r([h]);
c && this._adapter.render({ created: [], deletedIds: [], unchanged: u, updated: c }, this.getModeStyles());
};
Object.keys(this._modes).forEach((h) => {
this._modes[h].register({ mode: h, store: this._store, setCursor: this._adapter.setCursor.bind(this._adapter), project: this._adapter.project.bind(this._adapter), unproject: this._adapter.unproject.bind(this._adapter), setDoubleClickToZoom: this._adapter.setDoubleClickToZoom.bind(this._adapter), onChange: a, onSelect: l, onDeselect: d, onFinish: n, coordinatePrecision: this._adapter.getCoordinatePrecision() });
});
}
checkEnabled() {
if (!this._enabled) throw new Error("Terra Draw is not enabled");
}
getModeStyles() {
const t = {};
return Object.keys(this._modes).forEach((e) => {
t[e] = (i) => this._instanceSelectMode && i.properties[V.SELECTED] ? this._modes[this._instanceSelectMode].styleFeature.bind(this._modes[this._instanceSelectMode])(i) : this._modes[e].styleFeature.bind(this._modes[e])(i);
}), t;
}
featuresAtLocation({ lng: t, lat: e }, i) {
const o = i && i.pointerDistance !== void 0 ? i.pointerDistance : 30, r = !i || i.ignoreSelectFeatures === void 0 || i.ignoreSelectFeatures, n = this._adapter.unproject.bind(this._adapter), a = this._adapter.project.bind(this._adapter), l = a(t, e), d = Se({ unproject: n, point: l, pointerDistance: o });
return this._store.search(d).filter((h) => {
if (r && (h.properties[V.MID_POINT] || h.properties[V.SELECTION_POINT])) return !1;
if (h.geometry.type === "Point") {
const c = h.geometry.coordinates, u = a(c[0], c[1]);
return E(l, u) < o;
}
if (h.geometry.type === "LineString") {
const c = h.geometry.coordinates;
for (let u = 0; u < c.length - 1; u++) {
const p = c[u], g = c[u + 1];
if (Le(l, a(p[0], p[1]), a(g[0], g[1])) < o) return !0;
}
return !1;
}
return !!_e([t, e], h.geometry.coordinates) || void 0;
});
}
getSelectMode() {
if (this.checkEnabled(), !this._instanceSelectMode) throw new Error("No select mode defined in instance");
return this.getMode() !== this._instanceSelectMode && this.setMode(this._instanceSelectMode), this._modes[this._instanceSelectMode];
}
setModeStyles(t, e) {
if (this.checkEnabled(), !this._modes[t]) throw new Error("No mode with this name present");
this._modes[t].styles = e;
}
updateModeOptions(t, e) {
if (this.checkEnabled(), !this._modes[t]) throw new Error("No mode with this name present");
this._modes[t].updateOptions(e);
}
getSnapshot() {
return this._store.copyAll();
}
getSnapshotFeature(t) {
if (this._store.has(t)) return this._store.copy(t);
}
clear() {
this.checkEnabled(), this._adapter.clear();
}
get enabled() {
return this._enabled;
}
set enabled(t) {
throw new Error("Enabled is read only");
}
getMode() {
return this._mode.mode;
}
setMode(t) {
if (this.checkEnabled(), !this._modes[t]) throw new Error("No mode with this name present");
this._mode.stop(), this._mode = this._modes[t], this._mode.start();
}
removeFeatures(t) {
this.checkEnabled(), this._store.delete(t);
}
selectFeature(t) {
this.getSelectMode().selectFeature(t);
}
deselectFeature(t) {
this.getSelectMode().deselectFeature(t);
}
getFeatureId() {
return this._store.getId();
}
hasFeature(t) {
return this._store.has(t);
}
addFeatures(t) {
return this.checkEnabled(), t.length === 0 ? [] : this._store.load(t, (e) => {
if (zt(e)) {
const i = e.properties.mode, o = this._modes[i];
if (!o) return { id: e.id, valid: !1, reason: `${i} mode is not in the list of instantiated modes` };
const r = o.validateFeature.bind(o)(e);
return { id: e.id, valid: r.valid, reason: r.reason ? r.reason : r.valid ? void 0 : "Feature is invalid" };
}
return { id: e.id, valid: !1, reason: "Mode property does not exist" };
}, (e) => {
if (zt(e)) {
const i = this._modes[e.properties.mode];
i && i.afterFeatureAdded && i.afterFeatureAdded(e);
}
});
}
start() {
this._enabled = !0, this._adapter.register({ onReady: () => {
this._eventListeners.ready.forEach((t) => {
t();
});
}, getState: () => this._mode.state, onClick: (t) => {
this._mode.onClick(t);
}, onMouseMove: (t) => {
this._mode.onMouseMove(t);
}, onKeyDown: (t) => {
this._mode.onKeyDown(t);
}, onKeyUp: (t) => {
this._mode.onKeyUp(t);
}, onDragStart: (t, e) => {
this._mode.onDragStart(t, e);
}, onDrag: (t, e) => {
this._mode.onDrag(t, e);
}, onDragEnd: (t, e) => {
this._mode.onDragEnd(t, e);
}, onClear: () => {
this._mode.cleanUp(), this._store.clear();
} });
}
getFeaturesAtLngLat(t, e) {
const { lng: i, lat: o } = t;
return this.featuresAtLocation({ lng: i, lat: o }, e);
}
getFeaturesAtPointerEvent(t, e) {
const i = this._adapter.getLngLatFromEvent.bind(this._adapter)(t);
return i === null ? [] : this.featuresAtLocation(i, e);
}
stop() {
this._enabled = !1, this._adapter.unregister();
}
on(t, e) {
const i = this._eventListeners[t];
i.includes(e) || i.push(e);
}
off(t, e) {
const i = this._eventListeners[t];
i.includes(e) && i.splice(i.indexOf(e), 1);
}
}
class $i extends Ki.TerraDrawBaseAdapter {
constructor(t) {
super(t), this._initialDragPan = void 0, this._initialDragRotate = void 0, this._nextRender = void 0, this._map = void 0, this._container = void 0, this._rendered = !1, this.changedIds = { deletion: !1, points: !1, linestrings: !1, polygons: !1, styling: !1 }, this._map = t.map, this._container = this._map.getContainer(), this._initialDragRotate = this._map.dragRotate.isEnabled(), this._initialDragPan = this._map.dragPan.isEnabled();
}
clearLayers() {
this._rendered && (["point", "linestring", "polygon"].forEach((t) => {
const e = `td-${t.toLowerCase()}`;
this._map.removeLayer(e), t === "polygon" && this._map.removeLayer(e + "-outline"), this._map.removeSource(e);
}), this._rendered = !1, this._nextRender && (cancelAnimationFrame(this._nextRender), this._nextRender = void 0));
}
_addGeoJSONSource(t, e) {
this._map.addSource(t, { type: "geojson", data: { type: "FeatureCollection", features: e }, tolerance: 0 });
}
_addFillLayer(t) {
return this._map.addLayer({ id: t, source: t, type: "fill", paint: { "fill-color": ["get", "polygonFillColor"], "fill-opacity": ["get", "polygonFillOpacity"] } });
}
_addFillOutlineLayer(t) {
return this._map.addLayer({ id: t + "-outline", source: t, type: "line", paint: { "line-width": ["get", "polygonOutlineWidth"], "line-color": ["get", "polygonOutlineColor"] } });
}
_addLineLayer(t) {
return this._map.addLayer({ id: t, source: t, type: "line", paint: { "line-width": ["get", "lineStringWidth"], "line-color": ["get", "lineStringColor"] } });
}
_addPointLayer(t) {
return this._map.addLayer({ id: t, source: t, type: "circle", paint: { "circle-stroke-color": ["get", "pointOutlineColor"], "circle-stroke-width": ["get", "pointOutlineWidth"], "circle-radius": ["get", "pointWidth"], "circle-color": ["get", "pointColor"] } });
}
_addLayer(t, e) {
e === "Point" && this._addPointLayer(t), e === "LineString" && this._addLineLayer(t), e === "Polygon" && (this._addFillLayer(t), this._addFillOutlineLayer(t));
}
_addGeoJSONLayer(t, e) {
const i = `td-${t.toLowerCase()}`;
return this._addGeoJSONSource(i, e), this._addLayer(i, t), i;
}
_setGeoJSONLayerData(t, e) {
const i = `td-${t.toLowerCase()}`;
return this._map.getSource(i).setData({ type: "FeatureCollection", features: e }), i;
}
updateChangedIds(t) {
[...t.updated, ...t.created].forEach((e) => {
e.geometry.type === "Point" ? this.changedIds.points = !0 : e.geometry.type === "LineString" ? this.changedIds.linestrings = !0 : e.geometry.type === "Polygon" && (this.changedIds.polygons = !0);
}), t.deletedIds.length > 0 && (this.changedIds.deletion = !0), t.created.length === 0 && t.updated.length === 0 && t.deletedIds.length === 0 && (this.changedIds.styling = !0);
}
getLngLatFromEvent(t) {
const { left: e, top: i } = this._container.getBoundingClientRect();
return this.unproject(t.clientX - e, t.clientY - i);
}
getMapEventElement() {
return this._map.getCanvas();
}
setDraggability(t) {
t ? (this._initialDragRotate && this._map.dragRotate.enable(), this._initialDragPan && this._map.dragPan.enable()) : (this._initialDragRotate && this._map.dragRotate.disable(), this._initialDragPan && this._map.dragPan.disable());
}
project(t, e) {
const { x: i, y: o } = this._map.project({ lng: t, lat: e });
return { x: i, y: o };
}
unproject(t, e) {
const { lng: i, lat: o } = this._map.unproject({ x: t, y: e });
return { lng: i, lat: o };
}
setCursor(t) {
const e = this._map.getCanvas();
t === "unset" ? e.style.removeProperty("cursor") : e.style.cursor = t;
}
setDoubleClickToZoom(t) {
t ? this._map.doubleClickZoom.enable() : this._map.doubleClickZoom.disable();
}
render(t, e) {
this.updateChangedIds(t), this._nextRender && cancelAnimationFrame(this._nextRender), this._nextRender = requestAnimationFrame(() => {
const i = [...t.created, ...t.updated, ...t.unchanged], o = [], r = [], n = [];
for (let a = 0; a < i.length; a++) {
const l = i[a], { properties: d } = l, h = e[d.mode](l);
l.geometry.type === "Point" ? (d.pointColor = h.pointColor, d.pointOutlineColor = h.pointOutlineColor, d.pointOutlineWidth = h.pointOutlineWidth, d.pointWidth = h.pointWidth, o.push(l)) : l.geometry.type === "LineString" ? (d.lineStringColor = h.lineStringColor, d.lineStringWidth = h.lineStringWidth, r.push(l)) : l.geometry.type === "Polygon" && (d.polygonFillColor = h.polygonFillColor, d.polygonFillOpacity = h.polygonFillOpacity, d.polygonOutlineColor = h.polygonOutlineColor, d.polygonOutlineWidth = h.polygonOutlineWidth, n.push(l));
}
if (this._rendered) {
const a = this.changedIds.deletion || this.changedIds.styling, l = a || this.changedIds.linestrings, d = a || this.changedIds.polygons;
let h;
(a || this.changedIds.points) && (h = this._setGeoJSONLayerData("Point", o)), l && this._setGeoJSONLayerData("LineString", r), d && this._setGeoJSONLayerData("Polygon", n), h && this._map.moveLayer(h);
} else {
const a = this._addGeoJSONLayer("Point", o);
this._addGeoJSONLayer("LineString", r), this._addGeoJSONLayer("Polygon", n), this._rendered = !0, a && this._map.moveLayer(a);
}
this.changedIds = { points: !1, linestrings: !1, polygons: !1, deletion: !1, styling: !1 };
});
}
clear() {
this._currentModeCallbacks && (this._currentModeCallbacks.onClear(), this.clearLayers());
}
getCoordinatePrecision() {
return super.getCoordinatePrecision();
}
unregister() {
return super.unregister();
}
register(t) {
var e;
super.register(t), (e = this._currentModeCallbacks) != null && e.onReady && this._currentModeCallbacks.onReady();
}
}
const ko = [
"render",
"point",
"linestring",
"polygon",
"rectangle",
"circle",
"freehand",
"angled-rectangle",
"sensor",
"sector",
"select",
"delete-selection",
"delete",
"download"
], Hi = {
modes: [
"render",
"point",
"linestring",
"polygon",
"rectangle",
"angled-rectangle",
"sensor",
"sector",
"circle",
"freehand",
"select",
"delete-selection",
"delete",
"download"
],
open: !1
}, yt = {
modes: [
"render",
"point",
"linestring",
"polygon",
"rectangle",
"angled-rectangle",
"sensor",
"sector",
"circle",
"freehand",
"select",
"delete-selection",
"delete",
"download"
],
open: !1,
// see styling parameters of Terra Draw at https://github.com/JamesLMilner/terra-draw/blob/main/guides/5.STYLING.md
modeOptions: {
point: new we({
editable: !0,
styles: {
pointColor: "#FFFFFF",
pointWidth: 5,
pointOutlineColor: "#666666",
pointOutlineWidth: 1
}
}),
linestring: new be({
editable: !0,
styles: {
lineStringColor: "#666666",
lineStringWidth: 2,
closingPointColor: "#FFFFFF",
closingPointWidth: 3,
closingPointOutlineColor: "#666666",
closingPointOutlineWidth: 1
}
}),
polygon: new Ee({
editable: !0,
styles: {
fillColor: "#EDEFF0",
fillOpacity: 0.7,
outlineColor: "#666666",
outlineWidth: 2,
closingPointColor: "#FAFAFA",
closingPointWidth: 3,
closingPointOutlineColor: "#666666",
closingPointOutlineWidth: 1
}
}),
rectangle: new Oe({
styles: {
fillColor: "#EDEFF0",
fillOpacity: 0.7,
outlineColor: "#666666",
outlineWidth: 2
}
}),
"angled-rectangle": new je({
styles: {
fillColor: "#EDEFF0",
fillOpacity: 0.7,
outlineColor: "#666666",
outlineWidth: 2
}
}),
circle: new Ce({
styles: {
fillColor: "#EDEFF0",
fillOpacity: 0.7,
outlineColor: "#666666",
outlineWidth: 2
}
}),
freehand: new Pe({
styles: {
fillColor: "#EDEFF0",
fillOpacity: 0.7,
outlineColor: "#666666",
outlineWidth: 2,
closingPointColor: "#FAFAFA",
closingPointWidth: 3,
closingPointOutlineColor: "#666666",
closingPointOutlineWidth: 1
}
}),
sensor: new Ae({
styles: {
fillColor: "#EDEFF0",
fillOpacity: 0.7,
outlineColor: "#666666",
outlineWidth: 2,
centerPointColor: "#FAFAFA",
centerPointWidth: 3,
centerPointOutlineColor: "#666666",
centerPointOutlineWidth: 1
}
}),
sector: new Ge({
styles: {
fillColor: "#EDEFF0",
fillOpacity: 0.7,
outlineColor: "#666666",
outlineWidth: 2
}
}),
select: new Be({
flags: {
point: {
feature: {
draggable: !1
}
},
polygon: {
feature: {
draggable: !0,
rotateable: !0,
scaleable: !0,
coordinates: {
midpoints: !0,
draggable: !0,
deletable: !0
}
}
},
linestring: {
feature: {
draggable: !0,
rotateable: !0,
scaleable: !0,
coordinates: {
midpoints: !0,
draggable: !0,
deletable: !0
}
}
},
freehand: {
feature: {
draggable: !0,
coordinates: {
midpoints: !0,
draggable: !0,
deletable: !0
}
}
},
circle: {
feature: {
draggable: !0,
coordinates: {
midpoints: !0,
draggable: !0,
deletable: !0
}
}
},
rectangle: {
feature: {
draggable: !0,
rotateable: !0,
scaleable: !0,
coordinates: {
midpoints: !0,
draggable: !0,
deletable: !0
}
}
},
"angled-rectangle": {
feature: {
draggable: !0,
rotateable: !0,
scaleable: !0,
coordinates: {
midpoints: !0,
draggable: !0,
deletable: !0
}
}
},
sensor: {
feature: {
draggable: !0,
rotateable: !0,
scaleable: !0,
coordinates: {
midpoints: !0,
draggable: !0,
deletable: !0
}
}
},
sector: {
feature: {
draggable: !0,
rotateable: !0,
scaleable: !0,
coordinates: {
midpoints: !0,
draggable: !0,
deletable: !0
}
}
}
}
})
},
pointLayerLabelSpec: {
id: "terradraw-measure-point-label",
type: "symbol",
source: "terradraw-measure-point-source",
filter: ["all", ["==", "$type", "Point"], ["==", "mode", "point"]],
layout: {
"text-field": [
"case",
["all", ["has", "elevation"], [">", ["get", "elevation"], 0]],
["concat", "Alt. ", ["to-string", ["floor", ["get", "elevation"]]], " m"],
""
],
"symbol-placement": "point",
"text-size": [
"interpolate",
["linear"],
["zoom"],
5,
10,
10,
12,
13,
14,
14,
16,
18,
18
],
"text-overlap": "always",
"text-variable-anchor": ["left", "right", "top", "bottom"],
"text-radial-offset": 0.5,
"text-justify": "center",
"text-letter-spacing": 0.05
},
paint: {
"text-halo-color": "#F7F7F7",
"text-halo-width": 2,
"text-color": "#232E3D"
}
},
lineLayerLabelSpec: {
id: "terradraw-measure-line-label",
type: "symbol",
source: "terradraw-measure-line-source",
filter: ["==", "$type", "Point"],
layout: {
"text-field": [
"concat",
["to-string", ["get", "distance"]],
" ",
["get", "unit"],
[
"case",
["==", ["get", "total"], 0],
"",
["concat", `
(`, ["to-string", ["get", "total"]], " ", ["get", "totalUnit"], ")"]
],
[
"case",
["all", ["has", "elevation"], [">", ["get", "elevation"], 0]],
["concat", `
Alt. `, ["to-string", ["floor", ["get", "elevation"]]], " m"],
""
]
],
"symbol-placement": "point",
"text-size": [
"interpolate",
["linear"],
["zoom"],
5,
10,
10,
12,
13,
14,
14,
16,
18,
18
],
"text-overlap": "always",
"text-variable-anchor": ["left", "right", "top", "bottom"],
"text-radial-offset": 0.5,
"text-justify": "center",
"text-letter-spacing": 0.05
},
paint: {
"text-halo-color": "#F7F7F7",
"text-halo-width": 2,
"text-color": "#232E3D"
}
},
lineLayerNodeSpec: {
id: "terradraw-measure-line-node",
type: "circle",
source: "terradraw-measure-line-source",
filter: ["==", "$type", "Point"],
layout: {},
paint: {
"circle-radius": 3,
"circle-color": "#FFFFFF",
"circle-stroke-color": "#000000",
"circle-stroke-width": 1
}
},
polygonLayerSpec: {
id: "terradraw-measure-polygon-label",
type: "symbol",
source: "terradraw-measure-polygon-source",
filter: ["==", "$type", "Point"],
layout: {
"text-field": ["concat", ["to-string", ["get", "area"]], " ", ["get", "unit"]],
"symbol-placement": "point",
"text-size": [
"interpolate",
["linear"],
["zoom"],
5,
10,
10,
12,
13,
14,
14,
16,
18,
18
],
"text-overlap": "always",
"text-letter-spacing": 0.05
},
paint: {
"text-halo-color": "#F7F7F7",
"text-halo-width": 2,
"text-color": "#232E3D"
}
},
computeElevation: !1,
terrainSource: {
url: "https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png",
encoding: "terrarium",
tileSize: 256,
minzoom: 5,
maxzoom: 15,
tms: !1
},
distanceUnit: "kilometers",
distancePrecision: 2,
areaUnit: "metric",
areaPrecision: 2
}, qi = () => ({
render: new et({
modeName: "render",
styles: {}
}),
point: new we({
editable: !0
}),
linestring: new be({
editable: !0
}),
polygon: new Ee({
editable: !0,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
validation: (t, e) => {
const i = e.updateType;
return i === "finish" || i === "commit" ? Ai(t) : { valid: !0 };
}
}),
rectangle: new Oe(),
"angled-rectangle": new je(),
circle: new Ce(),
freehand: new Pe(),
sensor: new Ae(),
sector: new Ge(),
select: new Be({
flags: {
point: {
feature: {
draggable: !0
}
},
polygon: {
feature: {
draggable: !0,
rotateable: !0,
scaleable: !0,
coordinates: {
midpoints: !0,
draggable: !0,
deletable: !0
}
}
},
linestring: {
feature: {
draggable: !0,
rotateable: !0,
scaleable: !0,
coordinates: {
midpoints: !0,
draggable: !0,
deletable: !0
}
}
},
freehand: {
feature: {
draggable: !0,
coordinates: {
midpoints: !0,
draggable: !0,
deletable: !0
}
}
},
circle: {
feature: {
draggable: !0,
coordinates: {
midpoints: !0,
draggable: !0,
deletable: !0
}
}
},
rectangle: {
feature: {
draggable: !0,
rotateable: !0,
scaleable: !0,
coordinates: {
midpoints: !0,
draggable: !0,
deletable: !0
}
}
},
"angled-rectangle": {
feature: {
draggable: !0,
rotateable: !0,
scaleable: !0,
coordinates: {
midpoints: !0,
draggable: !0,
deletable: !0
}
}
},
sensor: {
feature: {
draggable: !0,
rotateable: !0,
scaleable: !0,
coordinates: {
midpoints: !0,
draggable: !0,
deletable: !0
}
}
},
sector: {
feature: {
draggable: !0,
rotateable: !0,
scaleable: !0,
coordinates: {
midpoints: !0,
draggable: !0,
deletable: !0
}
}
}
}
}),
delete: new et({
modeName: "delete",
styles: {}
}),
"delete-selection": new et({
modeName: "delete-selection",
styles: {}
}),
download: new et({
modeName: "download",
styles: {}
})
});
var L = 63710088e-1, Ji = {
centimeters: L * 100,
centimetres: L * 100,
degrees: 360 / (2 * Math.PI),
feet: L * 3.28084,
inches: L * 39.37,
kilometers: L / 1e3,
kilometres: L / 1e3,
meters: L,
metres: L,
miles: L / 1609.344,
millimeters: L * 1e3,
millimetres: L * 1e3,
nauticalmiles: L / 1852,
radians: 1,
yards: L * 1.0936
};
function Zi(s, t, e = {}) {
const i = { type: "Feature" };
return (e.id === 0 || e.id) && (i.id = e.id), e.bbox && (i.bbox = e.bbox), i.properties = t || {}, i.geometry = s, i;
}
function Qi(s, t, e = {}) {
if (!s)
throw new Error("coordinates is required");
if (!Array.isArray(s))
throw new Error("coordinates must be an Array");
if (s.length < 2)
throw new Error("coordinates must be at least 2 numbers long");
if (!se(s[0]) || !se(s[1]))
throw new Error("coordinates must contain numbers");
return Zi({
type: "Point",
coordinates: s
}, t, e);
}
function to(s, t = "kilometers") {
const e = Ji[t];
if (!e)
throw new Error(t + " units is invalid");
return s * e;
}
function gt(s) {
return s % 360 * Math.PI / 180;
}
function se(s) {
return !isNaN(s) && s !== null && !Array.isArray(s);
}
function Te(s, t, e) {
if (s !== null)
for (var i, o, r, n, a, l, d, h = 0, c = 0, u, p = s.type, g = p === "FeatureCollection", y = p === "Feature", m = g ? s.features.length : 1, v = 0; v < m; v++) {
d = g ? s.features[v].geometry : y ? s.geometry : s, u = d ? d.type === "GeometryCollection" : !1, a = u ? d.geometries.length : 1;
for (var f = 0; f < a; f++) {
var C = 0, P = 0;
if (n = u ? d.geometries[f] : d, n !== null) {
l = n.coordinates;
var S = n.type;
switch (h = S === "Polygon" || S === "MultiPolygon" ? 1 : 0, S) {
case null:
break;
case "Point":
if (t(
l,
c,
v,
C,
P
) === !1)
return !1;
c++, C++;
break;
case "LineString":
case "MultiPoint":
for (i = 0; i < l.length; i++) {
if (t(
l[i],
c,
v,
C,
P
) === !1)
return !1;
c++, S === "MultiPoint" && C++;
}
S === "LineString" && C++;
break;
case "Polygon":
case "MultiLineString":
for (i = 0; i < l.length; i++) {
for (o = 0; o < l[i].length - h; o++) {
if (t(
l[i][o],
c,
v,
C,
P
) === !1)
return !1;
c++;
}
S === "MultiLineString" && C++, S === "Polygon" && P++;
}
S === "Polygon" && C++;
break;
case "MultiPolygon":
for (i = 0; i < l.length; i++) {
for (P = 0, o = 0; o < l[i].length; o++) {
for (r = 0; r < l[i][o].length - h; r++) {
if (t(
l[i][o][r],
c,
v,
C,
P
) === !1)
return !1;
c++;
}
P++;
}
C++;
}
break;
case "GeometryCollection":
for (i = 0; i < n.geometries.length; i++)
if (Te(n.geometries[i], t) === !1)
return !1;
break;
default:
throw new Error("Unknown Geometry Type");
}
}
}
}
}
function eo(s, t) {
var e, i, o, r, n, a, l, d, h, c, u = 0, p = s.type === "FeatureCollection", g = s.type === "Feature", y = p ? s.features.length : 1;
for (e = 0; e < y; e++) {
for (a = p ? s.features[e].geometry : g ? s.geometry : s, d = p ? s.features[e].properties : g ? s.properties : {}, h = p ? s.features[e].bbox : g ? s.bbox : void 0, c = p ? s.features[e].id : g ? s.id : void 0, l = a ? a.type === "GeometryCollection" : !1, n = l ? a.geometries.length : 1, o = 0; o < n; o++) {
if (r = l ? a.geometries[o] : a, r === null) {
if (t(
null,
u,
d,
h,
c
) === !1)
return !1;
continue;
}
switch (r.type) {
case "Point":
case "LineString":
case "MultiPoint":
case "Polygon":
case "MultiLineString":
case "MultiPolygon": {
if (t(
r,
u,
d,
h,
c
) === !1)
return !1;
break;
}
case "GeometryCollection": {
for (i = 0; i < r.geometries.length; i++)
if (t(
r.geometries[i],
u,
d,
h,
c
) === !1)
return !1;
break;
}
default:
throw new Error("Unknown Geometry Type");
}
}
u++;
}
}
function io(s, t, e) {
var i = e;
return eo(
s,
function(o, r, n, a, l) {
r === 0 && e === void 0 ? i = o : i = t(
i,
o,
r,
n,
a,
l
);
}
), i;
}
function oo(s) {
return io(
s,
(t, e) => t + so(e),
0
);
}
function so(s) {
let t = 0, e;
switch (s.type) {
case "Polygon":
return re(s.coordinates);
case "MultiPolygon":
for (e = 0; e < s.coordinates.length; e++)
t += re(s.coordinates[e]);
return t;
case "Point":
case "MultiPoint":
case "LineString":
case "MultiLineString":
return 0;
}
return 0;
}
function re(s) {
let t = 0;
if (s && s.length > 0) {
t += Math.abs(ne(s[0]));
for (let e = 1; e < s.length; e++)
t -= Math.abs(ne(s[e]));
}
return t;
}
var ro = L * L / 2, Ot = Math.PI / 180;
function ne(s) {
const t = s.length - 1;
if (t <= 2) return 0;
let e = 0, i = 0;
for (; i < t; ) {
const o = s[i], r = s[i + 1 === t ? 0 : i + 1], n = s[i + 2 >= t ? (i + 2) % t : i + 2], a = o[0] * Ot, l = r[1] * Ot, d = n[0] * Ot;
e += (d - a) * Math.sin(l), i++;
}
return e * ro;
}
var no = oo;
const ao = (s, t) => {
let e = s, i = "m²";
return t === "metric" ? s >= 1e6 ? (e = s / 1e6, i = "km²") : s >= 1e4 && (e = s / 1e4, i = "ha") : s >= 258998811e-2 ? (e = s / 258998811e-2, i = "mi²") : s >= 4046.856 ? (e = s / 4046.856, i = "acre") : s >= 0.83612736 && (e = s / 0.83612736, i = "yd²"), { area: e, unit: i };
}, ae = (s, t, e) => {
if (s.geometry.type !== "Polygon") return s;
const i = no(s.geometry), o = ao(i, t);
return o.area = parseFloat(o.area.toFixed(e)), s.properties.area = o.area, s.properties.unit = o.unit, s;
};
function le(s) {
if (!s)
throw new Error("coord is required");
if (!Array.isArray(s)) {
if (s.type === "Feature" && s.geometry !== null && s.geometry.type === "Point")
return [...s.geometry.coordinates];
if (s.type === "Point")
return [...s.coordinates];
}
if (Array.isArray(s) && s.length >= 2 && !Array.isArray(s[0]) && !Array.isArray(s[1]))
return [...s];
throw new Error("coord must be GeoJSON Point or an Array of numbers");
}
function lo(s, t, e = {}) {
var i = le(s), o = le(t), r = gt(o[1] - i[1]), n = gt(o[0] - i[0]), a = gt(i[1]), l = gt(o[1]), d = Math.pow(Math.sin(r / 2), 2) + Math.pow(Math.sin(n / 2), 2) * Math.cos(a) * Math.cos(l);
return to(
2 * Math.atan2(Math.sqrt(d), Math.sqrt(1 - d)),
e.units
);
}
var ho = lo;
const de = (s) => s === "degrees" ? "°" : s === "miles" ? "mi" : s === "radians" ? "rad" : "km", Dt = (s) => {
if (s >= 1)
return {
distance: s,
unit: "km"
};
const t = s * 1e3;
return t >= 1 ? {
distance: t,
unit: "m"
} : {
distance: t * 100,
unit: "cm"
};
}, he = (s, t, e, i, o, r) => {
if (s.geometry.type !== "LineString") return s;
const n = s.geometry.coordinates;
let a = 0;
const l = [];
for (let d = 0; d < n.length - 1; d++) {
const h = n[d], c = n[d + 1], u = ho(h, c, { units: t });
a += u;
const p = JSON.parse(JSON.stringify(s));
if (p.id = `${p.id}-${d}`, p.geometry.coordinates = [h, c], p.properties.originalId = s.id, p.properties.distance = u, p.properties.total = a, p.properties.unit = de(t), p.properties.totalUnit = de(t), o === !0 && r === void 0) {
const g = i == null ? void 0 : i.queryTerrainElevation(h);
g && (p.properties.elevation_start = g);
const y = i == null ? void 0 : i.queryTerrainElevation(c);
y && (p.properties.elevation_end = y);
}
l.push(p);
}
if (s.properties.distance = l[l.length - 1].properties.total, s.properties.unit = l[l.length - 1].properties.unit, s.properties.segments = JSON.parse(JSON.stringify(l)), t === "kilometers") {
const d = Dt(s.properties.distance);
s.properties.distance = d.distance, s.properties.unit = d.unit, s.properties.segments.forEach(
(h) => {
const c = Dt(h.properties.distance);
h.properties.distance = c.distance, h.properties.unit = c.unit;
const u = Dt(h.properties.total);
h.properties.total = u.distance, h.properties.totalUnit = u.unit;
}
);
}
return s.properties.distance = parseFloat(
s.properties.distance.toFixed(e)
), s.properties.segments.forEach(
(d) => {
d.properties.distance = parseFloat(
d.properties.distance.toFixed(e)
), d.properties.total = parseFloat(
d.properties.total.toFixed(e)
);
}
), s;
}, ce = (s) => s.charAt(0).toUpperCase() + s.slice(1), bt = ["td-point", "td-linestring", "td-polygon"];
var ge, ye, fe;
const Bo = [
...bt,
(ge = yt.polygonLayerSpec) == null ? void 0 : ge.source,
(ye = yt.lineLayerLabelSpec) == null ? void 0 : ye.source,
(fe = yt.pointLayerLabelSpec) == null ? void 0 : fe.source
], Ue = (s, t, e = bt) => {
const i = JSON.parse(JSON.stringify(s));
return t && (t.onlyTerraDrawLayers === !0 ? (i.layers = i.layers.filter((o) => "source" in o && e.includes(o.source)), Object.keys(i.sources).forEach((o) => {
e.includes(o) || delete i.sources[o];
})) : t.excludeTerraDrawLayers === !0 && (i.layers = i.layers.filter((o) => "source" in o && !e.includes(o.source)), Object.keys(i.sources).forEach((o) => {
e.includes(o) && delete i.sources[o];
}))), i;
}, co = (s, t = 250) => {
let e;
return (...i) => {
clearTimeout(e), e = setTimeout(() => s(...i), t);
};
}, ue = (s, t, e, i) => {
if (s.geometry.type !== "Point") return s;
const o = s.geometry.coordinates;
if (e === !0 && i === void 0) {
const r = t == null ? void 0 : t.queryTerrainElevation(o);
r && (s.properties.elevation = r);
}
return s;
};
var uo = Object.defineProperty, po = (s, t, e) => t in s ? uo(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e, tt = (s, t, e) => po(s, typeof t != "symbol" ? t + "" : t, e), St = 2 * Math.PI * 6378137 / 2;
function go(s) {
return s = s || 256, 2 * Math.PI * 6378137 / s;
}
function yo(s, t, e = { enable: !0, decimal: 1 }) {
s = Nt(s);
var i = s[0], o = s[1], r = i * St / 180, n = Math.log(Math.tan((90 + o) * Math.PI / 360)) / (Math.PI / 180);
return n = n * St / 180, e.enable && (r = Number(r.toFixed(e.decimal)), n = Number(n.toFixed(e.decimal))), [r, n];
}
function fo(s, t, e) {
var i = s[0], o = s[1], r = xo(t, e), n = (i + St) / r, a = (o + St) / r;
return [n, a, t];
}
function Ve(s, t, e) {
s = Nt(s);
var i = yo(s), o = fo(i, t);
return vo(o);
}
function mo(s, t, e) {
if (s = Nt(s), t === 0)
return [0, 0, 0];
var i = Ve(s, t);
return Co(i);
}
function vo(s, t, e) {
t = t || 256;
var i = s[0], o = s[1], r = s[2];
if (r === 0) return [0, 0, 0];
Re(r);
var n = Math.ceil(i / t) - 1, a = Math.ceil(o / t) - 1;
return n < 0 && (n = 0), a < 0 && (a = 0), [n, a, r];
}
function Co(s, t) {
Po(s);
var e = s[0], i = s[1], o = s[2];
if (o === 0)
return [0, 0, 0];
var r = e, n = Math.pow(2, o) - 1 - i;
return [r, n, o];
}
function Po(s, t) {
var e = s[0], i = s[1], o = s[2];
if (o == null) throw new Error("<zoom> is required");
if (e == null) throw new Error("<x> is required");
if (i == null) throw new Error("<y> is required");
return o = Re(o), s = So(s), s;
}
function So(s) {
var t = s[0], e = s[1], i = s[2], o = Math.pow(2, i);
return t = t % o, t < 0 && (t = t + o), [t, e, i];
}
function Re(s) {
if (s === !1) return s;
if (s == null)
throw new Error("<zoom> is required");
if (s < 0)
throw new Error("<zoom> cannot be less than 0");
if (s > 32)
throw new Error("<zoom> cannot be greater than 32");
return s;
}
function Nt(s, t) {
var e = bo(s[0]), i = Io(s[1]);
return i > 85 && (i = 85), i < -85 && (i = -85), [e, i];
}
function xo(s, t) {
return go(t) / Math.pow(2, s);
}
function Io(s) {
if (s == null) throw new Error("lat is required");
return (s > 90 || s < -90) && (s = s % 180, s > 90 && (s = -180 + s), s < -90 && (s = 180 + s), s === 0 && (s = 0)), s;
}
function bo(s) {
if (s == null) throw new Error("lng is required");
return (s > 180 || s < -180) && (s = s % 360, s > 180 && (s = -360 + s), s < -180 && (s = 360 + s), s === 0 && (s = 0)), s;
}
class ze {
/**
* Constructor
* @param url URL for terrain RGB raster tilesets
* @param tileSize size of tile. 256 or 512
* @param tms whether it is Tile Map Service
* @param minzoom minzoom for terrain RGB raster tilesets
* @param maxzoom maxzoom for terrain RGB raster tilesets
* @param tms whether it is Tile Map Service
*/
constructor(t, e, i, o, r) {
tt(this, "url"), tt(this, "tileSize"), tt(this, "tms"), tt(this, "minzoom"), tt(this, "maxzoom"), this.url = t, this.tileSize = e, this.tms = r, this.minzoom = i, this.maxzoom = o, this.tms = r;
}
/**
* Get the value from target coordinates and zoom level by using certain formula.
* @param lnglat coordinates
* @param z zoom level
* @returns the value calculated by certain formula
*/
getValue(t, e) {
return new Promise(
(i, o) => {
const r = t[0], n = t[1];
let a = e;
e > this.maxzoom ? a = this.maxzoom : e < this.minzoom && (a = this.minzoom);
const l = this.tms ? Ve([r, n], a) : mo([r, n], a), d = this.url.replace(/{x}/g, l[0].toString()).replace(/{y}/g, l[1].toString()).replace(/{z}/g, l[2].toString());
let h = this.getUrlExtension(d);
switch (h || (h = "png"), h) {
case "png":
case "webp":
this.getValueFromRaster(d, l, r, n).then((c) => {
i(c);
});
break;
default:
o(new Error(`Invalid file extension: ${h}`));
break;
}
}
);
}
/**
* Get the value calculated from coordinates on WEBP raster tileset
* @param url tile URL
* @param tile tile index info
* @param lng longitude
* @param lat latitude
* @returns the value calculated from coordinates. If tile does not exist returns undefined
*/
async getValueFromRaster(t, e, i, o) {
const r = await fetch(t);
if (!r.ok) {
if (r.status === 404)
return;
throw new Error(`Failed to fetch tile: ${r.statusText}`);
}
const n = await r.blob();
return new Promise((a, l) => {
const d = new Image();
d.onload = () => {
const h = document.createElement("canvas");
h.width = d.width, h.height = d.height;
const c = h.getContext("2d");
if (!c) return l(new Error("Failed to create canvas context"));
c.drawImage(d, 0, 0);
const u = c.getImageData(0, 0, d.width, d.height).data, p = this.pixels2rgba(new Uint8Array(u), e, i, o), g = this.calc(p[0], p[1], p[2], p[3]);
a(g);
}, d.onerror = () => a(void 0), d.src = URL.createObjectURL(n);
});
}
/**
* Get RGBA values from coordinates information
* @param pixels pixels info
* @param tile tile index info
* @param lng longitude
* @param lat latitude
* @returns RGBA values
*/
pixels2rgba(t, e, i, o) {
const r = [];
for (let d = 0; d < t.length; d += 4) {
const h = t[d], c = t[d + 1], u = t[d + 2], p = t[d + 3], g = [h, c, u, p];
r.push(g);
}
const n = this.tileToBBOX(e), a = this.getPixelPosition(i, o, n), l = a[0] + a[1] * this.tileSize;
return r[l];
}
/**
* Get the position in pixel from the coordinates
* @param lng longitude
* @param lat latitude
* @param bbox bbox (minx, miny, maxx, maxy)
* @returns The position in pixel
*/
getPixelPosition(t, e, i) {
const o = this.tileSize, r = this.tileSize, n = i[2] - i[0], a = i[3] - i[1], l = (t - i[0]) / n, d = (e - i[1]) / a, h = Math.floor(o * l), c = Math.floor(r * (1 - d));
return [h, c];
}
/**
* Get file extenstion name from the URL
* @param url URL for tilesets
* @returns file extenstion either png or webp
*/
getUrlExtension(t) {
let e = t.split(/[#?]/)[0].split(".").pop();
return e && (e = e.trim()), e;
}
/**
* Get the bbox of a tile
* @param {Array<number>} tile
* @returns {Array<number>} bbox
* @example
* var bbox = tileToBBOX([5, 10, 10])
* //=bbox
*/
tileToBBOX(t) {
const e = this.tile2lon(t[0] + 1, t[2]), i = this.tile2lon(t[0], t[2]), o = this.tile2lat(t[1] + 1, t[2]), r = this.tile2lat(t[1], t[2]);
return [i, o, e, r];
}
tile2lon(t, e) {
return t / Math.pow(2, e) * 360 - 180;
}
tile2lat(t, e) {
const i = 180 / Math.PI, o = Math.PI - 2 * Math.PI * t / Math.pow(2, e);
return i * Math.atan(0.5 * (Math.exp(o) - Math.exp(-o)));
}
}
class Mo extends ze {
/**
* Constructor
* @param url URL for terrain RGB raster tilesets
* @param tileSize size of tile. 256 or 512
* @param tms whether it is Tile Map Service
* @param minzoom minzoom for terrain RGB raster tilesets. default is 5
* @param maxzoom maxzoom for terrain RGB raster tilesets. default is 15
*/
constructor(t, e, i = 5, o = 15, r = !1) {
super(t, e, i, o, r);
}
/**
* Get an altitude calculated from terrain RGB information
* @param lnglat coordinates
* @param z zoom level
* @returns an altitude calculated from terrain RGB information
*/
async getElevation(t, e) {
return await this.getValue(t, e);
}
/**
* Formula for calculating an elevation from RGB
* @param r red
* @param g green
* @param b blue
* @returns an elevation calculated
*/
calc(t, e, i) {
return -1e4 + (t * 256 * 256 + e * 256 + i) * 0.1;
}
}
class wo extends ze {
/**
* Constructor
* @param url URL for terrarium raster tilesets
* @param tileSize size of tile. 256 or 512
* @param tms whether it is Tile Map Service
* @param minzoom minzoom for terrain RGB raster tilesets. default is 5
* @param maxzoom maxzoom for terrain RGB raster tilesets. default is 15
*/
constructor(t, e, i = 5, o = 15, r = !1) {
super(t, e, i, o, r);
}
/**
* Get an altitude calculated from terrain RGB information
* @param lnglat coordinates
* @param z zoom level
* @returns an altitude calculated from terrain RGB information
*/
async getElevation(t, e) {
return await this.getValue(t, e);
}
/**
* Formula for calculating an elevation from RGB
* https://github.com/tilezen/joerd/blob/master/docs/formats.md#terrarium
* @param r red
* @param g green
* @param b blue
* @returns an elevation calculated
*/
calc(t, e, i) {
const o = t * 256 + e + i / 256 - 32768;
return parseInt(o.toFixed(0));
}
}
const pe = async (s, t) => {
const e = [];
for (const i of s)
e.push(
new Promise((o) => {
if (i.geometry.type !== "Point" && o(i), t) {
const r = t.url, n = t.encoding ?? "mapbox", a = t.tileSize ?? 512, l = t.minzoom ?? 5, d = t.maxzoom ?? 15, h = t.tms ?? !1;
(n === "mapbox" ? new Mo(r, a, l, d, h) : new wo(r, a, l, d, h)).getElevation(i.geometry.coordinates, d).then((c) => {
c && (i.properties.elevation = c), o(i);
}).catch(() => o(i));
} else
o(i);
})
);
return await Promise.all(e);
}, Wo = (s, t = 9) => {
function e(o) {
return [Number(o[0].toFixed(t)), Number(o[1].toFixed(t))];
}
function i(o) {
const r = o.type;
let n = o.coordinates;
switch (r) {
case "Point":
n = e(n);
break;
case "LineString":
case "MultiPoint":
n = n.map(e);
break;
case "Polygon":
case "MultiLineString":
n = n.map((a) => a.map(e));
break;
case "MultiPolygon":
n = n.map(
(a) => a.map((l) => l.map(e))
);
break;
}
return {
...o,
coordinates: n
};
}
return s.map((o) => ({
...o,
geometry: i(o.geometry)
}));
};
class Fo {
/**
* Constructor
* @param options Plugin control options
*/
constructor(t) {
B(this, "controlContainer");
B(this, "map");
B(this, "modeButtons", {});
B(this, "_isExpanded", !1);
B(this, "terradraw");
B(this, "options", Hi);
B(this, "events", {});
B(this, "defaultMode", "render");
this.modeButtons = {}, t && (this.options = Object.assign(this.options, t));
}
/**
* get the state of whether the control is expanded or collapsed
*/
get isExpanded() {
return this._isExpanded;
}
/**
* set the state of the control either expanded or collapsed.
* terradraw mode will be reset if the state is changed.
* either `expanded` or `collapsed` event is dispatched when changed
*/
set isExpanded(t) {
var o, r;
this._isExpanded = t;
const e = document.getElementsByClassName("maplibregl-terradraw-add-control");
for (let n = 0; n < e.length; n++) {
const a = e.item(n);
a && (this.isExpanded ? a.classList.remove("hidden") : a.classList.add("hidden"));
}
const i = document.getElementsByClassName("maplibregl-terradraw-render-button");
i && i.length > 0 && (this.isExpanded ? (o = i.item(0)) == null || o.classList.add("enabled") : ((r = i.item(0)) == null || r.classList.remove("enabled"), this.resetActiveMode())), this.toggleDeleteSelectionButton(), this.toggleButtonsWhenNoFeature(), this.isExpanded ? this.dispatchEvent("expanded") : this.dispatchEvent("collapsed");
}
/**
* Get the default control position
* @returns default control position. Default is 'top-right'
*/
getDefaultPosition() {
return "top-right";
}
/**
* add the plugin control to maplibre
* @param map Maplibre Map object
* @returns HTML Element
*/
onAdd(t) {
var o, r, n, a, l;
if (this.options && this.options.modes && this.options.modes.length === 0)
throw new Error("At least a mode must be enabled.");
this.map = t;
const e = qi(), i = [];
return (r = (o = this.options) == null ? void 0 : o.modes) == null || r.forEach((d) => {
if (this.options.modeOptions && this.options.modeOptions[d]) {
const h = this.options.modeOptions[d];
if (d === "select") {
const c = e[d];
if (c) {
const u = c.flags;
Object.keys(u).forEach((p) => {
h.flags[p] || (h.flags[p] = u[p]);
});
}
}
i.push(h);
} else e[d] && i.push(e[d]);
}), i.forEach((d) => {
d.state !== "unregistered" && (d._state = "unregistered");
}), (a = (n = this.options) == null ? void 0 : n.modes) != null && a.includes("render") || (i.push(
new et({
modeName: "default",
styles: {}
})
), this.defaultMode = "default"), this.isExpanded = this.options.open === !0, this.terradraw = new Yi({
adapter: new $i({ map: t, ...this.options.adapterOptions }),
modes: i
}), this.terradraw.start(), this.controlContainer = document.createElement("div"), this.controlContainer.classList.add("maplibregl-ctrl"), this.controlContainer.classList.add("maplibregl-ctrl-group"), i.forEach((d) => {
d.mode !== "default" && this.addTerradrawButton(d.mode);
}), Object.values(this.modeButtons).forEach((d) => {
var h;
(h = this.controlContainer) == null || h.appendChild(d);
}), (l = this.terradraw) == null || l.on("change", this.toggleButtonsWhenNoFeature.bind(this)), this.toggleButtonsWhenNoFeature(), this.controlContainer;
}
/**
* Remove the plugin control from maplibre
* @returns void
*/
onRemove() {
!this.controlContainer || !this.controlContainer.parentNode || !this.map || (this.deactivate(), this.modeButtons = {}, this.terradraw = void 0, this.map = void 0, this.controlContainer.parentNode.removeChild(this.controlContainer));
}
/**
* Register an event for the plugin
* @param event event type
* @param callback
*/
on(t, e) {
this.events[t] ? this.events[t].push(e) : this.events[t] = [e];
}
/**
* Unregister an event for the plugin
* @param event event type
* @param callback
* @returns
*/
off(t, e) {
if (!this.events[t]) return;
const i = this.events[t].findIndex((o) => o === e);
i !== -1 && this.events[t].splice(i, 1);
}
/**
* Dispatch an event. Pass the current snapshot of features and mode
* @param event event type
* @param args additional arguments
*/
dispatchEvent(t, e) {
this.events[t] && this.events[t].forEach((i) => {
var n, a;
const o = (n = this.terradraw) == null ? void 0 : n.getSnapshot(), r = o == null ? void 0 : o.filter((l) => l.properties.selected === !0);
i({
feature: r,
mode: (a = this.terradraw) == null ? void 0 : a.getMode(),
...e
});
});
}
/**
* Activate Terra Draw to start drawing
*/
activate() {
this.terradraw && (this.terradraw.enabled || (this.terradraw.start(), this.dispatchEvent("mode-changed")));
}
/**
* Deactivate Terra Draw to stop drawing
*/
deactivate() {
this.terradraw && this.terradraw.enabled && (this.resetActiveMode(), this.dispatchEvent("mode-changed"), this.terradraw.stop());
}
/**
* Get the Terra Draw instance.
* For the Terra Draw API, please refer to https://terradraw.io/#/api
* @returns Terra Draw instance
*/
getTerraDrawInstance() {
return this.terradraw;
}
/**
* Toggle editor control
*/
toggleEditor() {
this.terradraw && (this.isExpanded = !this.isExpanded);
}
/**
* Reset active mode to back to render mode
*/
resetActiveMode() {
var e;
if (!this.terradraw) return;
this.terradraw.enabled || this.terradraw.start();
const t = document.getElementsByClassName("maplibregl-terradraw-add-control");
for (let i = 0; i < t.length; i++) {
const o = t.item(i);
o && o.classList.remove("active");
}
(e = this.terradraw) == null || e.setMode(this.defaultMode);
}
/**
* Add Terra Draw drawing mode button
* @param mode Terra Draw mode name
*/
addTerradrawButton(t) {
const e = document.createElement("button");
e.type = "button", this.modeButtons[t] = e, t === "render" ? (e.classList.add(`maplibregl-terradraw-${t}-button`), this.isExpanded && e.classList.add("enabled"), e.type = "button", e.title = ce("expand or collapse drawing tool"), e.addEventListener("click", this.toggleEditor.bind(this))) : (e.classList.add("maplibregl-terradraw-add-control"), this.isExpanded || e.classList.add("hidden"), e.title = ce(t.replace(/-/g, " ")), t === "delete" ? (e.classList.add(`maplibregl-terradraw-${t}-button`), e.addEventListener("click", () => {
this.terradraw && this.terradraw.enabled && (this.terradraw.clear(), this.deactivate(), this.toggleDeleteSelectionButton(), this.toggleButtonsWhenNoFeature(), this.dispatchEvent("feature-deleted"));
})) : t === "delete-selection" ? (e.classList.add(`maplibregl-terradraw-${t}-button`), e.classList.add("hidden-delete-selection"), e.addEventListener("click", () => {
var r;
if (!this.terradraw || !this.terradraw.enabled) return;
const o = ((r = this.terradraw) == null ? void 0 : r.getSnapshot()).filter((n) => n.properties.selected === !0);
if (o.length > 0) {
const n = o.map((a) => a.id);
this.terradraw.removeFeatures(n);
for (const a of n)
this.terradraw.deselectFeature(a);
this.dispatchEvent("feature-deleted", { deletedIds: n });
}
this.toggleDeleteSelectionButton(), this.toggleButtonsWhenNoFeature();
})) : t === "download" ? (e.classList.add(`maplibregl-terradraw-${t}-button`), e.addEventListener("click", this.handleDownload.bind(this))) : (e.classList.add(`maplibregl-terradraw-add-${t}-button`), e.addEventListener("click", () => {
if (!this.terradraw) return;
const i = e.classList.contains("active");
this.activate(), this.resetActiveMode(), i || (this.terradraw.setMode(t), e.classList.add("active")), this.toggleDeleteSelectionButton(), this.toggleButtonsWhenNoFeature();
})));
}
/**
* get GeoJSON features
* @param onlySelected If true, returns only selected features. Default is false.
* @returns FeatureCollection in GeoJSON format
*/
getFeatures(t = !1) {
var r;
if (!this.terradraw) return;
const o = {
type: "FeatureCollection",
features: ((r = this.terradraw) == null ? void 0 : r.getSnapshot()).filter((n) => n.properties.mode !== "select")
};
return t !== !0 || (o.features = o.features.filter((n) => n.properties.selected === !0)), o;
}
/**
* clean maplibre style to filter only for terradraw related layers or without them.
* If options are not set, returns original style given to the function.
*
* This can be useful incase users only want to get terradraw related layers or without it.
*
* Usage:
* `cleanStyle(map.getStyle, { excludeTerraDrawLayers: true})`
* `cleanStyle(map.getStyle, { onlyTerraDrawLayers: true})`
*
* @param style maplibre style spec
* @param options.excludeTerraDrawLayers return maplibre style without terradraw layers and sources
* @param options.onlyTerraDrawLayers return maplibre style with only terradraw layers and sources
* @returns
*/
cleanStyle(t, e) {
return Ue(t, e, bt);
}
/**
* Download button click event handler
*/
handleDownload() {
const t = this.getFeatures(!1), e = "data:application/json;charset=utf-8," + encodeURIComponent(JSON.stringify(t)), i = document.createElement("a");
i.setAttribute("href", e), i.setAttribute("download", "data.geojson"), document.body.appendChild(i), i.click(), i.remove();
}
/**
* Toggle the state of buttons when there is no features
*/
toggleButtonsWhenNoFeature() {
if (!this.controlContainer) return;
const t = this.getFeatures(!1), e = !!(t && t.features.length > 0), i = [
"maplibregl-terradraw-add-select-button",
"maplibregl-terradraw-download-button",
"maplibregl-terradraw-delete-button"
];
for (const o of i) {
const r = this.controlContainer.getElementsByClassName(o);
for (let n = 0; n < r.length; n++) {
const a = r.item(n);
a && (a.disabled = !e);
}
}
}
/**
* Toggle the state of delete-select button
*/
toggleDeleteSelectionButton() {
var a, l;
const t = ((a = this.terradraw) == null ? void 0 : a.enabled) || !1, e = (l = this.terradraw) == null ? void 0 : l.getMode(), i = this.getFeatures(!1), o = i && i.features.length > 0, r = o && t && e === "select", n = document.getElementsByClassName("maplibregl-terradraw-delete-selection-button");
for (let d = 0; d < n.length; d++) {
const h = n.item(d);
h && (r ? h.classList.remove("hidden-delete-selection") : h.classList.add("hidden-delete-selection"));
}
if (!o) {
const d = document.getElementsByClassName("maplibregl-terradraw-add-select-button");
for (let h = 0; h < d.length; h++) {
const c = d.item(h);
c && c.classList.remove("active");
}
}
}
}
function Eo(s, t = {}) {
let e = 0, i = 0, o = 0;
return Te(
s,
function(r) {
e += r[0], i += r[1], o++;
}
), Qi([e / o, i / o], t.properties);
}
class jo extends Fo {
/**
* Constructor
* @param options Plugin control options
*/
constructor(e) {
let i = yt;
e && (i = Object.assign(i, e));
super({
modes: i.modes,
open: i.open,
modeOptions: i.modeOptions
});
B(this, "measureOptions");
/**
* Handle deselect event of terradraw
*/
B(this, "handleTerradrawDeselect", () => {
if (this.map && this.computeElevation === !0 && this.measureOptions.terrainSource !== void 0) {
const e = this.getTerraDrawInstance();
if (!e) return;
const i = e.getSnapshot(), o = i.filter(
(n) => n.properties.mode === "linestring" && n.geometry.type === "LineString"
);
if (o.length > 0)
for (const n of o)
this.computeElevationByLineFeatureID(n.id);
const r = i.filter(
(n) => n.properties.mode === "point" && n.geometry.type === "Point"
);
if (r.length > 0)
for (const n of r)
this.computeElevationByPointFeatureID(n.id);
}
});
/**
* Handle finish event of terradraw. It will be called after finishing adding a feature
* @param id Feature ID
*/
B(this, "handleTerradrawFeatureReady", co((e) => {
this.map && (this.computeElevationByLineFeatureID(e), this.computeElevationByPointFeatureID(e));
}, 300));
/**
* Compute elevation by a LineString feature ID
* @param id FeatureID
*/
B(this, "computeElevationByLineFeatureID", async (e) => {
if (this.map && this.computeElevation === !0) {
const i = this.map.getStyle().sources[this.measureOptions.lineLayerLabelSpec.source];
if (i && typeof i.data != "string" && i.data.type === "FeatureCollection") {
const o = i.data.features.filter(
(r) => {
var n;
return ((n = r.properties) == null ? void 0 : n.originalId) === e && r.geometry.type === "Point";
}
);
if (o && o.length > 0) {
const r = await pe(
o,
this.measureOptions.terrainSource
);
this.replaceGeoJSONSource(
r,
this.measureOptions.lineLayerLabelSpec.source,
"linestring"
);
}
}
}
});
/**
* Compute elevation by a Point feature ID
* @param id FeatureID
*/
B(this, "computeElevationByPointFeatureID", async (e) => {
if (this.map && this.computeElevation === !0) {
const i = this.map.getStyle().sources[this.measureOptions.pointLayerLabelSpec.source];
if (i && typeof i.data != "string" && i.data.type === "FeatureCollection") {
const o = i.data.features.filter(
(r) => {
var n;
return r.id === e && r.geometry.type === "Point" && ((n = r.properties) == null ? void 0 : n.mode) === "point";
}
);
if (o && o.length > 0) {
const r = await pe(
o,
this.measureOptions.terrainSource
);
this.replaceGeoJSONSource(
r,
this.measureOptions.pointLayerLabelSpec.source,
"point"
);
}
}
}
});
this.measureOptions = i;
}
/**
* The unit of distance can be degrees, radians, miles, or kilometers (default 'kilometers')
* The measuring result will be recalculated once new value is set
*/
get distanceUnit() {
return this.measureOptions.distanceUnit ?? "kilometers";
}
set distanceUnit(e) {
const i = this.measureOptions.distanceUnit === e;
this.measureOptions.distanceUnit = e, this.measureOptions.distanceUnit === "degrees" ? this.distancePrecision = 6 : this.distancePrecision = 2, i || this.recalc();
}
/**
* The precision of distance value. It will be set different value dwhen distance unit is changed. Using setter to override the value if you want.
*/
get distancePrecision() {
return this.measureOptions.distancePrecision ?? 2;
}
set distancePrecision(e) {
const i = this.measureOptions.distancePrecision === e;
this.measureOptions.distancePrecision = e, i || this.recalc();
}
/**
* The unit of area can be metric (m², ha, km²) or imperial (yd², acre, mi²). Default is metric.
* The measuring result will be recalculated once new value is set
*/
get areaUnit() {
return this.measureOptions.areaUnit ?? "metric";
}
set areaUnit(e) {
const i = this.measureOptions.areaUnit === e;
this.measureOptions.areaUnit = e, i || this.recalc();
}
/**
* The precision of area value. Using setter to override the value if you want.
*/
get areaPrecision() {
return this.measureOptions.areaPrecision ?? 2;
}
set areaPrecision(e) {
const i = this.measureOptions.areaPrecision === e;
this.measureOptions.areaPrecision = e, i || this.recalc();
}
/**
* The flag of whether computing elevation. Default is false.
* Using setter to override the value if you want.
*/
get computeElevation() {
return this.measureOptions.computeElevation ?? !1;
}
set computeElevation(e) {
const i = this.measureOptions.computeElevation === e;
this.measureOptions.computeElevation = e, i || this.recalc();
}
/**
* add the plugin control to maplibre
* @param map Maplibre Map object
* @returns HTML Element
*/
onAdd(e) {
return this.controlContainer = super.onAdd(e), this.controlContainer;
}
/**
* Remove the plugin control from maplibre
* @returns void
*/
onRemove() {
this.unregisterMesureControl(), super.onRemove();
}
/**
* Activate Terra Draw to start drawing
*/
activate() {
super.activate(), this.registerMesureControl();
}
/**
* Recalculate area and distance in TerraDraw snapshot
*
* if you use `addFeatures` to restore GeoJSON features to TerraDraw, this recalc method needs to be called to re-measure again.
*
* For example, the below code is an example usage.
* ```
* drawInstance?.addFeatures(initData);
* map?.once('idle', ()=>{
* drawControl.recalc()
* })
* ```
*/
recalc() {
const e = this.getTerraDrawInstance();
if (e) {
this.registerMesureControl();
const i = e.getSnapshot();
for (const o of i) {
const r = o.id, n = o.geometry.type, a = o.properties.mode;
a === "linestring" && n === "LineString" ? (this.measureLine(r), this.computeElevationByLineFeatureID(r)) : a === "point" && n === "Point" ? (this.measurePoint(r), this.computeElevationByPointFeatureID(r)) : !["point", "linestring", "select", "render"].includes(a) && n === "Polygon" && this.measurePolygon(r);
}
}
}
/**
* clean maplibre style to filter only for terradraw related layers or without them.
* If options are not set, returns original style given to the function.
*
* This can be useful incase users only want to get terradraw related layers or without it.
*
* Usage:
* `cleanStyle(map.getStyle, { excludeTerraDrawLayers: true})`
* `cleanStyle(map.getStyle, { onlyTerraDrawLayers: true})`
*
* @param style maplibre style spec
* @param options.excludeTerraDrawLayers return maplibre style without terradraw layers and sources
* @param options.onlyTerraDrawLayers return maplibre style with only terradraw layers and sources
* @returns
*/
cleanStyle(e, i) {
var l, d, h;
const o = bt, r = (l = this.measureOptions.polygonLayerSpec) == null ? void 0 : l.source;
r && o.push(r);
const n = (d = this.measureOptions.lineLayerLabelSpec) == null ? void 0 : d.source;
n && o.push(n);
const a = (h = this.measureOptions.pointLayerLabelSpec) == null ? void 0 : h.source;
return a && o.push(a), Ue(e, i, o);
}
/**
* Register measure control related maplibre sources and layers
*/
registerMesureControl() {
var r, n, a;
if (!this.map) return;
const e = (r = this.options.modes) == null ? void 0 : r.filter((l) => ["linestring"].includes(l));
((n = this.options.modes) == null ? void 0 : n.find((l) => l === "point")) && (this.map.getSource(
this.measureOptions.pointLayerLabelSpec.source
) || this.map.addSource(
this.measureOptions.pointLayerLabelSpec.source,
{
type: "geojson",
data: { type: "FeatureCollection", features: [] }
}
), this.map.getLayer(this.measureOptions.pointLayerLabelSpec.id) || this.map.addLayer(this.measureOptions.pointLayerLabelSpec)), e && e.length > 0 && (this.map.getSource(
this.measureOptions.lineLayerLabelSpec.source
) || this.map.addSource(
this.measureOptions.lineLayerLabelSpec.source,
{
type: "geojson",
data: { type: "FeatureCollection", features: [] }
}
), this.map.getLayer(this.measureOptions.lineLayerNodeSpec.id) || this.map.addLayer(this.measureOptions.lineLayerNodeSpec), this.map.getLayer(this.measureOptions.lineLayerLabelSpec.id) || this.map.addLayer(this.measureOptions.lineLayerLabelSpec));
const o = (a = this.options.modes) == null ? void 0 : a.filter(
(l) => [
"polygon",
"rectangle",
"angled-rectangle",
"circle",
"sector",
"sensor",
"freehand"
].includes(l)
);
if (o && o.length > 0 && (this.map.getSource(
this.measureOptions.polygonLayerSpec.source
) || this.map.addSource(
this.measureOptions.polygonLayerSpec.source,
{
type: "geojson",
data: { type: "FeatureCollection", features: [] }
}
), this.map.getLayer(this.measureOptions.polygonLayerSpec.id) || this.map.addLayer(this.measureOptions.polygonLayerSpec)), e && e.length > 0 || o && o.length > 0) {
const l = this.getTerraDrawInstance();
l && (l.on("change", this.handleTerradrawFeatureChanged.bind(this)), l.on("finish", this.handleTerradrawFeatureReady.bind(this)), l.on("deselect", this.handleTerradrawDeselect.bind(this)), this.on("feature-deleted", this.onFeatureDeleted.bind(this)));
}
}
/**
* Handle change event of TerraDraw
* @param ids Feature IDs
*/
handleTerradrawFeatureChanged(e, i) {
if (!this.map || i === "styling") return;
const r = [
this.measureOptions.pointLayerLabelSpec,
this.measureOptions.lineLayerLabelSpec,
this.measureOptions.lineLayerNodeSpec,
this.measureOptions.polygonLayerSpec
].map((l) => l.source);
if (i === "delete") {
this.clearMeasureFeatures(r, e);
return;
}
const n = this.getTerraDrawInstance();
if (!n) return;
const a = n.getSnapshot();
for (const l of e) {
const d = a.find((h) => h.id === l);
if (d) {
const h = d.geometry.type, c = d.properties.mode;
c === "linestring" && h === "LineString" ? this.measureLine(l) : c === "point" && h === "Point" ? this.measurePoint(l) : !["point", "linestring", "select", "render"].includes(c) && h === "Polygon" && this.measurePolygon(l);
} else
this.clearMeasureFeatures(r, [l]);
}
}
/**
* Unregister measure control related maplibre sources and layers
*/
unregisterMesureControl() {
this.off("feature-deleted", this.onFeatureDeleted.bind(this)), this.map && (this.map.getLayer(this.measureOptions.pointLayerLabelSpec.id) && this.map.removeLayer(
this.measureOptions.pointLayerLabelSpec.id
), this.map.getLayer(this.measureOptions.lineLayerLabelSpec.id) && this.map.removeLayer(this.measureOptions.lineLayerLabelSpec.id), this.map.getLayer(this.measureOptions.lineLayerNodeSpec.id) && this.map.removeLayer(this.measureOptions.lineLayerNodeSpec.id), this.map.getLayer(this.measureOptions.polygonLayerSpec.id) && this.map.removeLayer(this.measureOptions.polygonLayerSpec.id), this.map.getSource(
this.measureOptions.pointLayerLabelSpec.source
) && this.map.removeSource(
this.measureOptions.pointLayerLabelSpec.source
), this.map.getSource(
this.measureOptions.lineLayerLabelSpec.source
) && this.map.removeSource(
this.measureOptions.lineLayerLabelSpec.source
), this.map.getSource(this.measureOptions.polygonLayerSpec.source) && this.map.removeSource(
this.measureOptions.polygonLayerSpec.source
));
}
/**
* Clear GeoJSON feature related to measure control by TerraDraw feature ID
* @param sourceIds the array of source ID to delete
* @param ids the array of feature ID. Optional, if undefined, delete all labels for source
* @returns void
*/
clearMeasureFeatures(e, i = void 0) {
var o;
if (this.map)
for (const r of e) {
const n = this.map.getStyle().sources[r];
n && typeof n.data != "string" && n.data.type === "FeatureCollection" && (i === void 0 ? n.data.features = [] : n.data.features = n.data.features.filter((a) => {
var l;
return (l = a.properties) != null && l.originalId ? !i.includes(a.properties.originalId) : !i.includes(a.id);
}), (o = this.map.getSource(r)) == null || o.setData(n.data));
}
}
/**
* Replace GeoJSON source with updated features for a given source ID
* @param updatedFeatures Updated GeoJSON features
* @param sourceId Source ID to update
* @param type either 'linestring' or 'point'
*/
replaceGeoJSONSource(e, i, o) {
var n, a;
if (!this.map) return;
const r = this.map.getStyle().sources[i];
if (r && typeof r.data != "string" && r.data.type === "FeatureCollection") {
const l = [];
for (const h of e)
(n = this.terradraw) != null && n.getSnapshotFeature(h.id) && l.push(h);
const d = l.map((h) => h.id);
if (typeof r.data != "string" && r.data.type === "FeatureCollection") {
o === "linestring" ? r.data.features = [
...r.data.features = r.data.features.filter(
(c) => {
var u;
return !(d.includes((u = c.properties) == null ? void 0 : u.originalId) && c.geometry.type === "Point");
}
),
...l
] : o === "point" && (r.data.features = [
...r.data.features = r.data.features.filter(
(c) => !(d.includes(c.id) && c.geometry.type === "Point")
),
...l
]);
const h = {};
r.data.features.forEach((c) => {
var p;
const u = c.id;
h[u] ? !h[u].properties.elevation && ((p = c.properties) != null && p.elevation) && (h[u] = c) : h[u] = c;
}), r.data.features = Array.from(Object.values(h)), (a = this.map.getSource(i)) == null || a.setData(r.data);
}
}
}
/**
* measure polygon area for given feature ID
* @param id terradraw feature id
*/
measurePolygon(e) {
var n;
if (!this.map) return;
const i = this.getTerraDrawInstance();
if (!i) return;
const o = i.getSnapshot();
let r = o == null ? void 0 : o.find((a) => a.id === e && a.geometry.type === "Polygon");
if (r) {
const a = this.map.getStyle().sources[this.measureOptions.polygonLayerSpec.source];
if (a) {
typeof a.data != "string" && a.data.type === "FeatureCollection" && (a.data.features = a.data.features.filter(
(d) => {
var h;
return ((h = d.properties) == null ? void 0 : h.originalId) !== e;
}
));
const l = JSON.parse(JSON.stringify(r));
l.id = l.id + "-area-label", l.geometry = Eo(r.geometry).geometry, l.properties.originalId = r.id, r = ae(r, this.areaUnit, this.areaPrecision), l.properties.area = r.properties.area, l.properties.unit = r.properties.unit, typeof a.data != "string" && a.data.type === "FeatureCollection" && a.data.features.push(l), (n = this.map.getSource(
this.measureOptions.polygonLayerSpec.source
)) == null || n.setData(a.data), this.map.moveLayer(this.measureOptions.polygonLayerSpec.id), this.map.getLayer(this.measureOptions.lineLayerLabelSpec.id) && this.map.moveLayer(
this.measureOptions.lineLayerLabelSpec.id
), this.map.getLayer(this.measureOptions.lineLayerNodeSpec.id) && this.map.moveLayer(
this.measureOptions.lineLayerNodeSpec.id
), this.map.getLayer(
this.measureOptions.pointLayerLabelSpec.id
) && this.map.moveLayer(
this.measureOptions.pointLayerLabelSpec.id
);
}
}
}
/**
* measure line distance for given feature ID
* @param id terradraw feature id
*/
measureLine(e) {
var n;
if (!this.map) return;
const i = this.getTerraDrawInstance();
if (!i) return;
const o = i.getSnapshot();
let r = o == null ? void 0 : o.find((a) => a.id === e && a.geometry.type === "LineString");
if (r) {
const a = this.map.getStyle().sources[this.measureOptions.lineLayerLabelSpec.source];
if (a) {
typeof a.data != "string" && a.data.type === "FeatureCollection" && (a.data.features = a.data.features.filter(
(d) => {
var h;
return ((h = d.properties) == null ? void 0 : h.originalId) !== e;
}
)), r = he(
r,
this.distanceUnit,
this.distancePrecision,
this.map,
this.computeElevation,
this.measureOptions.terrainSource
);
const l = r.properties.segments;
for (let d = 0; d < l.length; d++) {
const h = l[d];
typeof a.data != "string" && a.data.type === "FeatureCollection" && a.data.features.push(h);
const c = h.geometry.coordinates, u = c[0], p = c[1];
if (d === 0) {
const y = JSON.parse(JSON.stringify(h));
y.id = `${h.id}-node-${d}`, y.geometry = {
type: "Point",
coordinates: u
}, y.properties.distance = 0, y.properties.total = 0, h.properties.elevation_start && (y.properties.elevation = h.properties.elevation_start), typeof a.data != "string" && a.data.type === "FeatureCollection" && a.data.features.push(y);
}
const g = JSON.parse(JSON.stringify(h));
g.id = `${h.id}-node-${d + 1}`, g.geometry = {
type: "Point",
coordinates: p
}, h.properties.elevation_end && (g.properties.elevation = h.properties.elevation_end), typeof a.data != "string" && a.data.type === "FeatureCollection" && a.data.features.push(g);
}
(n = this.map.getSource(
this.measureOptions.lineLayerLabelSpec.source
)) == null || n.setData(a.data), this.map.getLayer(this.measureOptions.polygonLayerSpec.id) && this.map.moveLayer(this.measureOptions.polygonLayerSpec.id), this.map.moveLayer(this.measureOptions.lineLayerLabelSpec.id), this.map.moveLayer(this.measureOptions.lineLayerNodeSpec.id), this.map.getLayer(
this.measureOptions.pointLayerLabelSpec.id
) && this.map.moveLayer(
this.measureOptions.pointLayerLabelSpec.id
);
}
}
}
/**
* measure point elevation for given feature ID
* @param id terradraw feature id
*/
measurePoint(e) {
var n;
if (!this.map) return;
const i = this.getTerraDrawInstance();
if (!i) return;
const o = i.getSnapshot();
let r = o == null ? void 0 : o.find((a) => a.id === e && a.geometry.type === "Point");
if (r) {
const a = this.map.getStyle().sources[this.measureOptions.pointLayerLabelSpec.source];
a && (typeof a.data != "string" && a.data.type === "FeatureCollection" && (a.data.features = a.data.features.filter((l) => l.id !== e)), r = ue(
r,
this.map,
this.computeElevation,
this.measureOptions.terrainSource
), this.computeElevation === !0 && typeof a.data != "string" && a.data.type === "FeatureCollection" && a.data.features.push(r), (n = this.map.getSource(
this.measureOptions.pointLayerLabelSpec.source
)) == null || n.setData(a.data), this.map.getLayer(this.measureOptions.polygonLayerSpec.id) && this.map.moveLayer(this.measureOptions.polygonLayerSpec.id), this.map.getLayer(this.measureOptions.lineLayerLabelSpec.id) && (this.map.moveLayer(
this.measureOptions.lineLayerLabelSpec.id
), this.map.moveLayer(
this.measureOptions.lineLayerNodeSpec.id
)), this.map.moveLayer(
this.measureOptions.pointLayerLabelSpec.id
));
}
}
/**
* Event definition when feature is deleted by terradraw
*/
onFeatureDeleted(e) {
if (!this.map) return;
if (this.getTerraDrawInstance()) {
let o = [];
typeof e == "object" && e !== null && "deletedIds" in e && (o = e.deletedIds);
const n = [
this.measureOptions.pointLayerLabelSpec,
this.measureOptions.lineLayerLabelSpec,
this.measureOptions.lineLayerNodeSpec,
this.measureOptions.polygonLayerSpec
].map((a) => a.source);
o && o.length > 0 ? this.clearMeasureFeatures(n, o) : this.clearMeasureFeatures(n, void 0);
}
}
/**
* get GeoJSON features
* @param onlySelected If true, returns only selected features. Default is false.
* @returns FeatureCollection in GeoJSON format
*/
getFeatures(e = !1) {
const i = super.getFeatures(e);
if (!i || !this.terradraw) return i;
for (let o = 0; o < i.features.length; o++) {
const r = i.features[o];
if (!this.map || !this.map.loaded()) continue;
const n = r.geometry.type;
n === "LineString" ? i.features[o] = he(
r,
this.distanceUnit,
this.distancePrecision,
this.map,
this.computeElevation,
this.measureOptions.terrainSource
) : n === "Polygon" ? i.features[o] = ae(r, this.areaUnit, this.areaPrecision) : n === "Point" && (i.features[o] = ue(
r,
this.map,
this.computeElevation,
this.measureOptions.terrainSource
));
}
return i;
}
}
export {
ko as AvailableModes,
jo as MaplibreMeasureControl,
Fo as MaplibreTerradrawControl,
Bo as TERRADRAW_MEASURE_SOURCE_IDS,
bt as TERRADRAW_SOURCE_IDS,
ae as calcArea,
he as calcDistance,
ce as capitalize,
Ue as cleanMaplibreStyle,
ao as convertAreaUnit,
Dt as convertMetricDistance,
co as debounce,
Hi as defaultControlOptions,
yt as defaultMeasureControlOptions,
qi as getDefaultModeOptions,
de as getDistanceUnitName,
ue as queryElevationByPoint,
pe as queryElevationFromRasterDEM,
Wo as roundFeatureCoordinates
};
//# sourceMappingURL=maplibre-gl-terradraw.es.js.map